diff --git a/.github/.ghaignore b/.github/.ghaignore index c26a85c3..0ee23466 100644 --- a/.github/.ghaignore +++ b/.github/.ghaignore @@ -1,6 +1,3 @@ -# uses generated client from shank, can't rewrite to solana-bankrun -tools/shank-and-solita/native - # build failed - program outdated tokens/token-extensions/metadata/anchor diff --git a/.gitignore b/.gitignore index e3147d99..0103d507 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ node_modules/ # Exception: escrow native is a standalone (non-workspace) crate, so it keeps # its Cargo.lock tracked for reproducible builds. !finance/escrow/native/Cargo.lock +# Exception: shank-and-codama native is also a standalone (non-workspace) crate. +!tools/shank-and-codama/native/program/Cargo.lock **/*/.anchor **/*/.DS_Store diff --git a/tools/shank-and-codama/native/README.md b/tools/shank-and-codama/native/README.md new file mode 100644 index 00000000..9071c123 --- /dev/null +++ b/tools/shank-and-codama/native/README.md @@ -0,0 +1,128 @@ +# Shank and Codama + +[Shank](https://github.com/metaplex-foundation/shank) lets a **native** Solana +[program](https://solana.com/docs/terminology#program) export an IDL the same +way [Anchor](https://solana.com/docs/terminology#anchor) does. Once you have an +IDL, [Codama](https://github.com/codama-idl/codama) turns it into a typed client +in the language of your choice. + +This example is a small "car rental service" program. It is annotated with Shank +macros, Shank extracts the IDL, and Codama renders a TypeScript client +(`@solana/kit`-based) from that IDL. An in-process [LiteSVM](https://github.com/litesvm/litesvm) +test then drives the program through the generated client — no validator or +devnet required, so it runs in CI. + +> This example used to use [Solita](https://github.com/metaplex-foundation/solita) +> to generate the client. Solita is unmaintained and does not work on the current +> toolchain, so it has been replaced with Codama. The Shank half of the lesson is +> unchanged. + +## Shank + +[Shank](https://github.com/metaplex-foundation/shank) is a set of Rust derive +macros plus a CLI that generates an IDL for your program. + +Mark a struct as an [account](https://solana.com/docs/terminology#account): + +```rust +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankAccount)] +pub struct Car { + pub year: u16, + pub make: String, + pub model: String, +} +``` + +Mark an enum as your [instruction](https://solana.com/docs/terminology#instruction) set, +using `#[account(...)]` attributes to describe each instruction's accounts: + +```rust +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankInstruction)] +pub enum CarRentalServiceInstruction { + #[account(0, writable, name = "car_account", desc = "The account that will represent the Car being created")] + #[account(1, writable, name = "payer", desc = "Fee payer")] + #[account(2, name = "system_program", desc = "The System Program")] + AddCar(AddCarArgs), + // ... +} +``` + +> Shank needs `declare_id!` in your program for the IDL generation to work: +> +> ```rust +> declare_id!("8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ"); +> ``` + +Install the CLI and generate the IDL: + +```bash +cargo install shank-cli +pnpm generate-idl # runs: shank idl --crate-root ./program --out-dir ./program/idl +``` + +The IDL lands in `program/idl/car_rental_service.json` (committed to the repo so +the client can be regenerated without the Rust CLI). Its `metadata.origin` is +`"shank"`, and each instruction carries an explicit single-byte (`u8`) +`discriminant` — this is what distinguishes a Shank IDL from an Anchor IDL. + +### A note on PDAs and `#[seeds(...)]` + +Shank 0.0.x used a `#[seeds(...)]` attribute on a `ShankAccount` to *generate* +`shank_pda` / `shank_seeds_with_bump` helper methods. As of Shank 0.4.x that PDA +code-generation produces unparsable tokens and fails to compile, and the seeds +are not emitted into the IDL either. So this example keeps PDA derivation +explicit in `program/src/state/mod.rs` (`Car::find_pda`, `RentalOrder::find_pda`) +and no longer uses the `#[seeds(...)]` attribute. `ShankAccount` is still used — +it is what tells Shank to include the account layout in the IDL. + +## Codama + +[Codama](https://github.com/codama-idl/codama) reads an IDL and renders a client. +It understands Shank IDLs out of the box. + +Install the pieces used here: + +```bash +pnpm add codama @codama/nodes-from-anchor @codama/renderers-js @solana/kit +``` + +The generator script ([`codama.ts`](./codama.ts)) reads the Shank IDL, sets its +`origin` to `"shank"` so the `u8` discriminants are honoured, builds a Codama +root node, and renders a TypeScript client: + +```ts +import { rootNodeFromAnchor } from "@codama/nodes-from-anchor"; +import { renderVisitor } from "@codama/renderers-js"; +import { createFromRoot } from "codama"; + +const idl = JSON.parse(readFileSync(idlPath, "utf-8")); +const codama = createFromRoot( + rootNodeFromAnchor({ ...idl, metadata: { ...idl.metadata, origin: "shank" } }), +); +await codama.accept(renderVisitor(outDir, { deleteFolderBeforeRendering: true })); +``` + +> Codama also ships `@codama/renderers-rust` if you want a Rust client instead of +> a TypeScript one — swap `renderVisitor` from `@codama/renderers-js` for the Rust +> renderer. + +Generate the client: + +```bash +pnpm generate-client +``` + +The generated TypeScript client lands in `tests/generated/`. + +## Build and test + +```bash +pnpm install +pnpm build # cargo build-sbf -> program/target/so/car_rental_service.so +pnpm build-and-test # build, regenerate the client, then run the LiteSVM test +``` + +The test ([`tests/test.ts`](./tests/test.ts)) loads the compiled `.so` into a +[LiteSVM](https://github.com/litesvm/litesvm) instance and exercises `add_car`, +`book_rental`, and `pick_up_car` through the generated client, asserting on the +resulting on-chain account state. diff --git a/tools/shank-and-codama/native/codama.ts b/tools/shank-and-codama/native/codama.ts new file mode 100644 index 00000000..6117001a --- /dev/null +++ b/tools/shank-and-codama/native/codama.ts @@ -0,0 +1,44 @@ +// Codama client generator. +// +// Reads the Shank-generated IDL (program/idl/car_rental_service.json) and emits +// a TypeScript client built on @solana/kit into tests/generated/. +// +// Flow: read IDL -> rootNodeFromAnchor (origin = "shank" so the u8 instruction +// discriminants are interpreted correctly) -> createFromRoot -> render JS. +// +// Run with: pnpm generate-client + +import { readFileSync, rmSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +import { type AnchorIdl, rootNodeFromAnchor } from "@codama/nodes-from-anchor"; +import { renderVisitor } from "@codama/renderers-js"; +import { createFromRoot } from "codama"; + +const here = dirname(fileURLToPath(import.meta.url)); +const idlPath = join(here, "program", "idl", "car_rental_service.json"); +const outDir = join(here, "tests", "generated"); + +const idl = JSON.parse(readFileSync(idlPath, "utf-8")) as AnchorIdl; + +// Make sure Codama treats this as a Shank IDL. Shank uses single-byte (u8) +// instruction discriminants rather than Anchor's 8-byte hashes, and the +// "origin" field is what tells nodes-from-anchor to honour the explicit +// `discriminant` values in the IDL. +const idlWithOrigin = { + ...idl, + metadata: { ...idl.metadata, origin: "shank" }, +} as AnchorIdl; + +const codama = createFromRoot(rootNodeFromAnchor(idlWithOrigin)); + +await codama.accept(renderVisitor(outDir, { deleteFolderBeforeRendering: true })); + +// The renderer drops a standalone `package.json` (declaring an implicit CommonJS +// package) at the output root. That would shadow this example's +// `"type": "module"` setting and break ESM resolution of the generated `.ts` +// files when the test imports them via tsx, so remove it. +rmSync(join(outDir, "package.json"), { force: true }); + +console.log(`Codama: generated TypeScript client in ${outDir}`); diff --git a/tools/shank-and-codama/native/package.json b/tools/shank-and-codama/native/package.json new file mode 100644 index 00000000..fa3ee05d --- /dev/null +++ b/tools/shank-and-codama/native/package.json @@ -0,0 +1,24 @@ +{ + "type": "module", + "scripts": { + "build": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./program/target/so", + "generate-idl": "shank idl --crate-root ./program --out-dir ./program/idl", + "generate-client": "tsx ./codama.ts", + "test": "node --import tsx --test ./tests/test.ts", + "build-and-test": "pnpm build && pnpm generate-client && pnpm test" + }, + "dependencies": { + "@codama/nodes-from-anchor": "^1.5.0", + "@codama/renderers-js": "^2.2.0", + "@solana-program/system": "^0.12.2", + "@solana/program-client-core": "^6.9.0", + "@solana/kit": "^6.9.0", + "codama": "^1.7.0", + "litesvm": "^1.1.0" + }, + "devDependencies": { + "@types/node": "^25.9.1", + "tsx": "^4.22.4", + "typescript": "^5.9.0" + } +} diff --git a/tools/shank-and-codama/native/pnpm-lock.yaml b/tools/shank-and-codama/native/pnpm-lock.yaml new file mode 100644 index 00000000..69219aeb --- /dev/null +++ b/tools/shank-and-codama/native/pnpm-lock.yaml @@ -0,0 +1,1807 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@codama/nodes-from-anchor': + specifier: ^1.5.0 + version: 1.5.0(typescript@5.9.3) + '@codama/renderers-js': + specifier: ^2.2.0 + version: 2.2.0(typescript@5.9.3) + '@solana-program/system': + specifier: ^0.12.2 + version: 0.12.2(@solana/kit@6.9.0(typescript@5.9.3)) + '@solana/kit': + specifier: ^6.9.0 + version: 6.9.0(typescript@5.9.3) + '@solana/program-client-core': + specifier: ^6.9.0 + version: 6.9.0(typescript@5.9.3) + codama: + specifier: ^1.7.0 + version: 1.7.0 + litesvm: + specifier: ^1.1.0 + version: 1.1.0(typescript@5.9.3) + devDependencies: + '@types/node': + specifier: ^25.9.1 + version: 25.9.1 + tsx: + specifier: ^4.22.4 + version: 4.22.4 + typescript: + specifier: ^5.9.0 + version: 5.9.3 + +packages: + + '@codama/cli@1.5.2': + resolution: {integrity: sha512-d5b6+m0TFYsIii4ALPIWrC6vGNbTLCXOaBqZO5WdI522w4jlk2MQozuSDVhAMBWQjxt9QD/WOJer8PHYwa1rYA==} + hasBin: true + + '@codama/errors@1.7.0': + resolution: {integrity: sha512-N1E4LT3XRYqHHJAnL+eVQ5V3Pc0uSPjsn4Xt6QEO6Fz1p0slF6hbD+/axkFUc7+lNCAfgnkKzhk+6SpFLU/WrQ==} + hasBin: true + + '@codama/fragments@0.1.0': + resolution: {integrity: sha512-rWnSKw4UA9LS7mMQyzKnR1woibVEYrYgp66+i+JB+O1lnvU/i/KCH4TmoV+S6Y3ADL2WyznrwfDA3rBET6U5Cg==} + + '@codama/node-types@1.7.0': + resolution: {integrity: sha512-VDytcSgN6jOGEh4aJ1LgSnqCe1drSEUSdAeKOV92aU0MOYiDi2s2B18+Gx7dx40mex2GfVc3zamu7KGzTlxegA==} + + '@codama/nodes-from-anchor@1.5.0': + resolution: {integrity: sha512-zbDkjNgMk0EGxHIOOlIq/G2KfXQ7rQrfwogw56MR7nQs6UFGKXnNLJUXiq1m8s3CzfoucvTo49z4mNKTEcGDhQ==} + + '@codama/nodes@1.7.0': + resolution: {integrity: sha512-PZ1zI+SbE1PEaGEka0KjdFrAJ7e9O0kPG4CCGYhjsqUo76OBbINRjNVx7pkP4r8Ksa2r/BLbVIfZV1M/n5J5Kg==} + + '@codama/renderers-core@1.3.8': + resolution: {integrity: sha512-xy9Qb5BLYTi1OyvlRhRD7n0HUevOQ3QcHSPq9N3kqoUOgL2ziXPXvoejzzLC0OkvA16M7WvK3ihNx/nf4UEClQ==} + + '@codama/renderers-js@2.2.0': + resolution: {integrity: sha512-/GWVnB329kMkeqlOqX+NWQAmd1k6yybVOp7C5X+LEvrZ2A5w1saQwWFbBMCq/EQPqnFU+CRFoG/+7KubAEa73Q==} + engines: {node: '>=20.18.0'} + + '@codama/validators@1.7.0': + resolution: {integrity: sha512-PBWN4zLikf6sssZD6sDVN7ASbh++fzvZ5pluHu6VlSQDk7lFL3Gsh7P1Q5JgIuXkM2gFntzCrTJSStToDCAW3g==} + + '@codama/visitors-core@1.7.0': + resolution: {integrity: sha512-ii1Z39ORzssMQdpxqpjaHCLbFwO4KZbI1SrsJ1e0r+0g03gxuYEA1H6RoxcrIOuUeOnqNtLb96cErrzHdrx23Q==} + + '@codama/visitors@1.7.0': + resolution: {integrity: sha512-wk8ufgX3AfKOnaok5H4y1UteLyY/WkDIhhKRE7y5MJqOn5JnxLgL9R4MU2+5TmZUF04sdwyUn6fPho0IqTq+BQ==} + + '@esbuild/aix-ppc64@0.28.0': + resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.0': + resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.0': + resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.0': + resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.0': + resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.0': + resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.0': + resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.0': + resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.0': + resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.0': + resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.0': + resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.0': + resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.0': + resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.0': + resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.0': + resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.0': + resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.0': + resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.0': + resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.0': + resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.0': + resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.0': + resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.0': + resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.0': + resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.0': + resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.0': + resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.0': + resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@noble/hashes@2.2.0': + resolution: {integrity: sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==} + engines: {node: '>= 20.19.0'} + + '@solana-program/system@0.12.2': + resolution: {integrity: sha512-MaBeOxlvTruQhA7UYkOb3hVTEHPPagOtd+PvTm6a8rGgvEAP0kD4BbC37NceOaR4ABNqdaCmD5OMVRKgrE6KAg==} + peerDependencies: + '@solana/kit': ^6.4.0 + + '@solana-program/token@0.13.0': + resolution: {integrity: sha512-/Apjrd5lwOJGrPB0J5Rv7EBeclvyEBQPAGA85Scm7wBH+GpkbdLDM9uK3TNg8jjFKyWQYai/JtPHbrx7VgFLSg==} + peerDependencies: + '@solana/kit': ^6.5.0 + + '@solana/accounts@6.9.0': + resolution: {integrity: sha512-g36AJreJrgf9AAjOfbdFHEFUTymBgzbWHoEDElZ+fDKvqBINDiUVKzDApwc7C7kGPMFqQBaoEHnQRxf2IqfKZQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/addresses@6.9.0': + resolution: {integrity: sha512-tWnG2L6lo/ZhcMT019F3myDsH87MM8EZbTO0cgwgvVPlEdIGblROFF3tGVrb7FVCOlbPI0ONCFyPbnrmR58LsA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/assertions@6.9.0': + resolution: {integrity: sha512-FjWWD6e0in+HFsHMvU2zKCbyPfKtDW6iGXZZ9+Qg1QUYpO1AEObsya3F7hb9RkZKUueK4WwWAQnIuvEUp3A1uA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-core@5.5.1': + resolution: {integrity: sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-core@6.9.0': + resolution: {integrity: sha512-F2BmLecG/1nTtnjyD509NsEc254pxJKa2bpvotymv1lL1WfEn3zchcZ9SMIiLyL4G6J8b9F3OKIq2YSZho2AOQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-data-structures@5.5.1': + resolution: {integrity: sha512-97bJWGyUY9WvBz3mX1UV3YPWGDTez6btCfD0ip3UVEXJbItVuUiOkzcO5iFDUtQT5riKT6xC+Mzl+0nO76gd0w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-data-structures@6.9.0': + resolution: {integrity: sha512-f7GYtiHafvJDhqiwzUUSr/6AYSK4DCw6quPmA80NZGtkNiFa+g6LoJy2wbC0wp2dxvCwNpxf6x3ILCYRutAvvg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-numbers@5.5.1': + resolution: {integrity: sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-numbers@6.9.0': + resolution: {integrity: sha512-XMI0FOHV2h7yPAllxWCX8z+J1msidNjXzN1mRjH5KR6C+vfzyKa2xWHve0bNSV/bjVAhqqhc7dQCpBKuF4+ScQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs-strings@5.5.1': + resolution: {integrity: sha512-7klX4AhfHYA+uKKC/nxRGP2MntbYQCR3N6+v7bk1W/rSxYuhNmt+FN8aoThSZtWIKwN6BEyR1167ka8Co1+E7A==} + engines: {node: '>=20.18.0'} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: ^5.0.0 + peerDependenciesMeta: + fastestsmallesttextencoderdecoder: + optional: true + typescript: + optional: true + + '@solana/codecs-strings@6.9.0': + resolution: {integrity: sha512-PTqYQxMsmdfEEq29bV1AnALD4FjFEsSxOj1fYNqooOSTEQEpUoYEQtsd55/kBsnIKltXbvYwXYXBusm19n1sQA==} + engines: {node: '>=20.18.0'} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5.4.0' + peerDependenciesMeta: + fastestsmallesttextencoderdecoder: + optional: true + typescript: + optional: true + + '@solana/codecs@5.5.1': + resolution: {integrity: sha512-Vea29nJub/bXjfzEV7ZZQ/PWr1pYLZo3z0qW0LQL37uKKVzVFRQlwetd7INk3YtTD3xm9WUYr7bCvYUk3uKy2g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + '@solana/codecs@6.9.0': + resolution: {integrity: sha512-oWOybKa1PTGI1D/FyrvGKralADM1jmVZC2AtgEo+4JTKG0+i1p9ZbwNY2UcJqdYsDMDaGHAx0LMAid9LDCxXTQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/errors@5.5.1': + resolution: {integrity: sha512-vFO3p+S7HoyyrcAectnXbdsMfwUzY2zYFUc2DEe5BwpiE9J1IAxPBGjOWO6hL1bbYdBrlmjNx8DXCslqS+Kcmg==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + '@solana/errors@6.9.0': + resolution: {integrity: sha512-7i+b07KMnkbHvFlz7uWade3jvyc22UmVm8o9taxPK8YV3JNM/NkS8oQFvMac2MIaLPAlEs7I8MHyVLUal1yY4g==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/fast-stable-stringify@6.9.0': + resolution: {integrity: sha512-l14zGVsURbT5Aox/kLFQywqV4VaE9/j3h2EvCu9oULVPMwzQB6yezJb1/KyiDwhm/RscooPd0gFQFIKEGQbayw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/fixed-points@6.9.0': + resolution: {integrity: sha512-0K7mbYC4jdAZFlXqXjpNanmEyZxk7K9NtXDLc1zuhGuxwH8J9guvohwdw2V7TQ9bfjCYsprY3Tp2kUVQpECGmA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/functional@6.9.0': + resolution: {integrity: sha512-sgNHOaIjETZZuziZdlwPsU5EjBVj5M0dUbwrSQTTNZe0SxX3pQ1QFVcs5KyvdS7AQcpBVdLjx4CfQjdKXk52GA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/instruction-plans@6.9.0': + resolution: {integrity: sha512-SxTSOetEKD+WPzvDuYRsP1+KkwUp8KqL1n7oFx9ThxjyfEY0ly0i9KdbvX5yYVDOA2TSwrltgdu14y/Pf6y3Cg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/instructions@6.9.0': + resolution: {integrity: sha512-LZfJx3bGdUSbGaswoOEPHygticqkCg3TusRczPJXyCmKhoQzPCcGQQ99qMzP7Wg8pEV5tWA5t7tycf8E237ydg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/keys@6.9.0': + resolution: {integrity: sha512-1g2QARiqSjNqT0EIqLDLQ5vRm7hCsbqgFwFAp5GsMV/8BTYT8s1Ct2wLHDZiJ4eAX6beTHVf8LbOBfVejtn3oQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/kit@6.9.0': + resolution: {integrity: sha512-k7BRz7Akfv8wiRtlCR/xUyDLfuMfYMelMR1+AC5KgwaRRJReDF0BucMLNN1In7WoI+KuWwr1OKv4na/oKpyeAQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/nominal-types@6.9.0': + resolution: {integrity: sha512-ouhrnY7a6nsLXRGcariwcmHDdXroCNqOuzwtdjKt2c8e8Drwao9yxPH2VoViNgpq8IGNJeQMEI1TVnoJZRn0gw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/offchain-messages@6.9.0': + resolution: {integrity: sha512-qK3tqRPb+E0kmTz5qFXZbEdF4pyzfOWRZjyVESHVGemDDeGzZ1SV3zAxcA6HBCnv4wCBnlyaDPw8t+5sryNMAw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/options@5.5.1': + resolution: {integrity: sha512-eo971c9iLNLmk+yOFyo7yKIJzJ/zou6uKpy6mBuyb/thKtS/haiKIc3VLhyTXty3OH2PW8yOlORJnv4DexJB8A==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + '@solana/options@6.9.0': + resolution: {integrity: sha512-H5ZRWNzzLMwHU/fRU9aVx+3TaMN4gDNCUYxsZxq0h7mqiwxFy6mpy95xPsfdldthCHDYtYnUTxe2sBatGbNHig==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/plugin-core@6.9.0': + resolution: {integrity: sha512-KslLSnzY8zbGZibEBVMVUm2ZS8T2xf+cut7F65VjWPoWNAxU+p7933wsMz/az6CF7b65RI7iU3HhCr5/5QF50w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/plugin-interfaces@6.9.0': + resolution: {integrity: sha512-Qj4sk9thkM1UgnFXvWIoezd/CbqpX/2jigLBDsMB5Ed/gmFlkBSTL127LFDSY3OtzBpXl4hROs+Zqv+5xqtguA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/program-client-core@6.9.0': + resolution: {integrity: sha512-+iUnsddhs72QoBJoUO+/yHUXoBvYWa1sGCBRJk35zeg8j7ZXEwRkk6eX0VOrUPxhEpQbYJsIOCrIYApNIt8RFw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/programs@6.9.0': + resolution: {integrity: sha512-L9LAnQtfFFcCDLcbbnxhUtgAmu/kS4aRmrVncdnX5CFyQshlpo0/Qhrq3UA7vnhute4gjYV4pFT+64onH5qGEQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/promises@6.9.0': + resolution: {integrity: sha512-227PlXRi6KZX4ODYTkJitr9InSa79NTquI72slay4gzxO9VmMepgvYdMAX6kawdN5pt+VzaklKhNhWXk50Pi9g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-api@6.9.0': + resolution: {integrity: sha512-3KhXS6A1ie6GqTywW/KEMSXJ1VJEU66fxjhuiiqPILuJstP7kex3ycr3H6DirKydUsy6gaKaPN43rE+LfyS7OA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-parsed-types@6.9.0': + resolution: {integrity: sha512-6ThH8izY+DWDyrVOOlS40vTcFjwjCinjfqnId7zhRk8OxhkfHQ/iEj+OnGwD4Yhe8pGdVa7GNVYlrQgQgzQ3eQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-spec-types@6.9.0': + resolution: {integrity: sha512-A4fY1JRrcKqX3EfttO4Q8L97nGPqdjfekAV0eDyxN5nu9ngf5p7GKenkl7AYDoHLNr6ZX/C96cRADxXjsRJ0iA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-spec@6.9.0': + resolution: {integrity: sha512-3yHRoChc0IpsJbUq0/94l+ar3t9U3Ax58W0HON7eyYe7zFP10UAxpkHn7DPch9DeALyuGph8kVnvl+kXRgJlGg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions-api@6.9.0': + resolution: {integrity: sha512-UA/rPQeNx6zQMUFcS8PPPuB4vzUOtSzIY/igMH0DRoP020NyES2GguIb7Zo7sqDNi4n0gkQRhoW4dPVotcNKdA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions-channel-websocket@6.9.0': + resolution: {integrity: sha512-kT8Yne9HjJD2gooaOFNSyKrvaIfOy2GR0Ymv8OfecBCwFStdz+SPo5eYXq8ZWoZbr5E/MMpHgqsHBanqa2Ffyg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions-spec@6.9.0': + resolution: {integrity: sha512-DbaG67s99vRZQxFMK80UQ7DEKkRJK6JEZeYg/U5UttD6n7ax/vct7qopxGnrt4RCkaaac2fU8Sr+fcnvWQweUg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-subscriptions@6.9.0': + resolution: {integrity: sha512-IMctZQaMxzvRACQ6ooW98lP+7tVoUJnRgOZtkAdzgBizldQAYPIKd3MulP0jbQPCMfdPsa2Hs0NBcUwfgonq3w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-transformers@6.9.0': + resolution: {integrity: sha512-dg4LK2wEBpaY+KRk/SJIkYvrvjdsc1AwD4bkmGY4Fp7EwVlvwBQShAQn78Qi4IP0WQ/0n9ncFyUxgcB1Y01ZuQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-transport-http@6.9.0': + resolution: {integrity: sha512-4gy30fWJcS6jrcXCoP/optFpGJ/gD9xdkE8wDbe1Ys/Y+e4XjyBt45xtTnbdmMdukvdRX+oXS3zgUIYoagpNzQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc-types@6.9.0': + resolution: {integrity: sha512-iFhPzZK3qiQ1lhfNTNBTI7BIs5PfWZSgRLD3enKm8ZAQggzvUklfO3KPh47jVsc/Jsr1UGPH8M3o3m17qjO1Cg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/rpc@6.9.0': + resolution: {integrity: sha512-ny1Kt20+oq3xZErNA56+Magmb2JKYfQgHwZTsBmHKVl/9mBpv1y1+ygV+KNiiX/wWXWstLbdIo1jgPwZPbU2Vg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/signers@6.9.0': + resolution: {integrity: sha512-x7WyoRm9IORMqeSqNivZgyY+RERPkmqWxpINPD13kUH+oaZzonORIgxk2Lz+u5iPRXiJPkdRPrQ4FoFWv8i6kQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/subscribable@6.9.0': + resolution: {integrity: sha512-YV0/BrJNfepf10CTfLwD7kRY1kkELDHd+BbHJZhBeiuiXTY3xQTvvx1RFs3NtfFCcTHG25Uh8NpRacQJnxSSIQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/sysvars@6.9.0': + resolution: {integrity: sha512-e0e+QKr/th9t/O2N1oUoJmcodLghzAtWKUlGb1zyYub0/WJrPImnKqJqp/gDP4tK98mJxopPMcprCeHk4B+TQg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/transaction-confirmation@6.9.0': + resolution: {integrity: sha512-fzYCOih7hhtBzzNSkAnxMjeFeQ8U7e27k9i0RsgQc3/e3OCynF5HoIVNhhqZbwfIBKiaD4ginJR6slRnfqO32Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/transaction-messages@6.9.0': + resolution: {integrity: sha512-OWpryt0w6SHlwHx12Vd1wvx2QwSGBXAIUEHTCtkctcM3AaZRy5cIl7CAq9iD5PgahUsaOyRLBV0zlCJcC2JrJA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@solana/transactions@6.9.0': + resolution: {integrity: sha512-uKPzLwHbjwChfVl82he17ntkh02PfgnMMhN7uOAC+VbkIt1O+EEw8sX87gi6kdG/EV+QBDQXm9PLAo5W0tYylw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + '@types/node@25.9.1': + resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + codama@1.7.0: + resolution: {integrity: sha512-kPB7IPAJkPAllxHiPtNDv6+qhTvfRpetYJgxp1iVa4L+BxztmSXTKMZ3Bsjve4ArENvxuUY4GIAchOYqb3G6nw==} + hasBin: true + + commander@14.0.2: + resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} + engines: {node: '>=20'} + + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + esbuild@0.28.0: + resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==} + engines: {node: '>=18'} + hasBin: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + json-stable-stringify@1.3.0: + resolution: {integrity: sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==} + engines: {node: '>= 0.4'} + + jsonify@0.0.1: + resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + litesvm-darwin-arm64@1.1.0: + resolution: {integrity: sha512-SjcivEOOjBk65U6TgIeMJ7CCnHNKQXHx0qf6K6GIFZC1aHTg7ePrEi+WhAQD6VUBMdDHIMCVKC/uXnXPi6EKIw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + litesvm-darwin-x64@1.1.0: + resolution: {integrity: sha512-hTs+eZ9sHVZXhjggpnn/8A/E+Nt/E6Gf8E2ejdWWL9bBQKmq1Y0VcrDpORbIvqqRpTLHXqbxCuH1wQB2C8frJg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + litesvm-linux-arm64-gnu@1.1.0: + resolution: {integrity: sha512-6EjJ6+E+1SUXdJmCyeyhvlKhNncccqQNH241+P8d4E72rE3zuFxeCtLHhusCQk2p/Xau3dBI0qTLogZ1F1IGSA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + litesvm-linux-arm64-musl@1.1.0: + resolution: {integrity: sha512-mNuBOfX6GnDFT2i/kYPWud7eZGe57dDP0u4lwiSTQPRE0BxQbGZT2aEwX8LTwbonhbc6HSt50LamaZZzK4h4ig==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + litesvm-linux-x64-gnu@1.1.0: + resolution: {integrity: sha512-Ot8RgUVlMKzKJi2nVDxaHVo0hjB5vtYTomYNIf26mIA32DOy0+dQfwOqUhynhvvSMxN3VFec3r/OtCnk6lRBrw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + litesvm-linux-x64-musl@1.1.0: + resolution: {integrity: sha512-6kmneOIsTBSActELRTwxIYVJOVaLm3P6uwlmkqc9BUtDAQ7bRdRmwREWSbM8XxKBGw2LjiUfgRJ5WJGYo8fUFg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + litesvm@1.1.0: + resolution: {integrity: sha512-UOlMIEst50gSUyPnC2pGjGLygH8iC/GOqnNXQIHc8iGwD76m44ReeA/0h0vu/AIieZ2zG5/ERLxFV0kdNxkNsA==} + engines: {node: '>= 20'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + prettier@3.8.3: + resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} + engines: {node: '>=14'} + hasBin: true + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + semver@7.8.2: + resolution: {integrity: sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + tsx@4.22.4: + resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} + + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + +snapshots: + + '@codama/cli@1.5.2': + dependencies: + '@codama/nodes': 1.7.0 + '@codama/visitors': 1.7.0 + '@codama/visitors-core': 1.7.0 + commander: 14.0.3 + picocolors: 1.1.1 + prompts: 2.4.2 + + '@codama/errors@1.7.0': + dependencies: + '@codama/node-types': 1.7.0 + commander: 14.0.3 + picocolors: 1.1.1 + + '@codama/fragments@0.1.0': + dependencies: + '@codama/errors': 1.7.0 + + '@codama/node-types@1.7.0': {} + + '@codama/nodes-from-anchor@1.5.0(typescript@5.9.3)': + dependencies: + '@codama/errors': 1.7.0 + '@codama/nodes': 1.7.0 + '@codama/visitors': 1.7.0 + '@noble/hashes': 2.2.0 + '@solana/codecs': 5.5.1(typescript@5.9.3) + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - typescript + + '@codama/nodes@1.7.0': + dependencies: + '@codama/errors': 1.7.0 + '@codama/node-types': 1.7.0 + + '@codama/renderers-core@1.3.8': + dependencies: + '@codama/errors': 1.7.0 + '@codama/fragments': 0.1.0 + '@codama/nodes': 1.7.0 + '@codama/visitors-core': 1.7.0 + + '@codama/renderers-js@2.2.0(typescript@5.9.3)': + dependencies: + '@codama/errors': 1.7.0 + '@codama/nodes': 1.7.0 + '@codama/renderers-core': 1.3.8 + '@codama/visitors-core': 1.7.0 + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + prettier: 3.8.3 + semver: 7.8.2 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - typescript + + '@codama/validators@1.7.0': + dependencies: + '@codama/errors': 1.7.0 + '@codama/nodes': 1.7.0 + '@codama/visitors-core': 1.7.0 + + '@codama/visitors-core@1.7.0': + dependencies: + '@codama/errors': 1.7.0 + '@codama/nodes': 1.7.0 + json-stable-stringify: 1.3.0 + + '@codama/visitors@1.7.0': + dependencies: + '@codama/errors': 1.7.0 + '@codama/nodes': 1.7.0 + '@codama/visitors-core': 1.7.0 + + '@esbuild/aix-ppc64@0.28.0': + optional: true + + '@esbuild/android-arm64@0.28.0': + optional: true + + '@esbuild/android-arm@0.28.0': + optional: true + + '@esbuild/android-x64@0.28.0': + optional: true + + '@esbuild/darwin-arm64@0.28.0': + optional: true + + '@esbuild/darwin-x64@0.28.0': + optional: true + + '@esbuild/freebsd-arm64@0.28.0': + optional: true + + '@esbuild/freebsd-x64@0.28.0': + optional: true + + '@esbuild/linux-arm64@0.28.0': + optional: true + + '@esbuild/linux-arm@0.28.0': + optional: true + + '@esbuild/linux-ia32@0.28.0': + optional: true + + '@esbuild/linux-loong64@0.28.0': + optional: true + + '@esbuild/linux-mips64el@0.28.0': + optional: true + + '@esbuild/linux-ppc64@0.28.0': + optional: true + + '@esbuild/linux-riscv64@0.28.0': + optional: true + + '@esbuild/linux-s390x@0.28.0': + optional: true + + '@esbuild/linux-x64@0.28.0': + optional: true + + '@esbuild/netbsd-arm64@0.28.0': + optional: true + + '@esbuild/netbsd-x64@0.28.0': + optional: true + + '@esbuild/openbsd-arm64@0.28.0': + optional: true + + '@esbuild/openbsd-x64@0.28.0': + optional: true + + '@esbuild/openharmony-arm64@0.28.0': + optional: true + + '@esbuild/sunos-x64@0.28.0': + optional: true + + '@esbuild/win32-arm64@0.28.0': + optional: true + + '@esbuild/win32-ia32@0.28.0': + optional: true + + '@esbuild/win32-x64@0.28.0': + optional: true + + '@noble/hashes@2.2.0': {} + + '@solana-program/system@0.12.2(@solana/kit@6.9.0(typescript@5.9.3))': + dependencies: + '@solana/kit': 6.9.0(typescript@5.9.3) + + '@solana-program/token@0.13.0(@solana/kit@6.9.0(typescript@5.9.3))': + dependencies: + '@solana-program/system': 0.12.2(@solana/kit@6.9.0(typescript@5.9.3)) + '@solana/kit': 6.9.0(typescript@5.9.3) + + '@solana/accounts@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/addresses@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/assertions': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/nominal-types': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/assertions@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-core@5.5.1(typescript@5.9.3)': + dependencies: + '@solana/errors': 5.5.1(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-core@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-data-structures@5.5.1(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-data-structures@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-numbers@5.5.1(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-numbers@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-strings@5.5.1(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs-strings@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/codecs@5.5.1(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-data-structures': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/options': 5.5.1(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/codecs@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.9.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.9.0(typescript@5.9.3) + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + '@solana/fixed-points': 6.9.0(typescript@5.9.3) + '@solana/options': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/errors@5.5.1(typescript@5.9.3)': + dependencies: + chalk: 5.6.2 + commander: 14.0.2 + optionalDependencies: + typescript: 5.9.3 + + '@solana/errors@6.9.0(typescript@5.9.3)': + dependencies: + chalk: 5.6.2 + commander: 14.0.3 + optionalDependencies: + typescript: 5.9.3 + + '@solana/fast-stable-stringify@6.9.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/fixed-points@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/functional@6.9.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/instruction-plans@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/instructions': 6.9.0(typescript@5.9.3) + '@solana/keys': 6.9.0(typescript@5.9.3) + '@solana/promises': 6.9.0(typescript@5.9.3) + '@solana/transaction-messages': 6.9.0(typescript@5.9.3) + '@solana/transactions': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/instructions@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/keys@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/assertions': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/nominal-types': 6.9.0(typescript@5.9.3) + '@solana/promises': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/kit@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/accounts': 6.9.0(typescript@5.9.3) + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/codecs': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/functional': 6.9.0(typescript@5.9.3) + '@solana/instruction-plans': 6.9.0(typescript@5.9.3) + '@solana/instructions': 6.9.0(typescript@5.9.3) + '@solana/keys': 6.9.0(typescript@5.9.3) + '@solana/offchain-messages': 6.9.0(typescript@5.9.3) + '@solana/plugin-core': 6.9.0(typescript@5.9.3) + '@solana/plugin-interfaces': 6.9.0(typescript@5.9.3) + '@solana/program-client-core': 6.9.0(typescript@5.9.3) + '@solana/programs': 6.9.0(typescript@5.9.3) + '@solana/rpc': 6.9.0(typescript@5.9.3) + '@solana/rpc-api': 6.9.0(typescript@5.9.3) + '@solana/rpc-parsed-types': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.9.0(typescript@5.9.3) + '@solana/rpc-subscriptions': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + '@solana/signers': 6.9.0(typescript@5.9.3) + '@solana/subscribable': 6.9.0(typescript@5.9.3) + '@solana/sysvars': 6.9.0(typescript@5.9.3) + '@solana/transaction-confirmation': 6.9.0(typescript@5.9.3) + '@solana/transaction-messages': 6.9.0(typescript@5.9.3) + '@solana/transactions': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - utf-8-validate + + '@solana/nominal-types@6.9.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/offchain-messages@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.9.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.9.0(typescript@5.9.3) + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/keys': 6.9.0(typescript@5.9.3) + '@solana/nominal-types': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/options@5.5.1(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/codecs-data-structures': 5.5.1(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) + '@solana/codecs-strings': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/options@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.9.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.9.0(typescript@5.9.3) + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/plugin-core@6.9.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/plugin-interfaces@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/instruction-plans': 6.9.0(typescript@5.9.3) + '@solana/keys': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec': 6.9.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + '@solana/signers': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/program-client-core@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/accounts': 6.9.0(typescript@5.9.3) + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/instruction-plans': 6.9.0(typescript@5.9.3) + '@solana/instructions': 6.9.0(typescript@5.9.3) + '@solana/plugin-interfaces': 6.9.0(typescript@5.9.3) + '@solana/rpc-api': 6.9.0(typescript@5.9.3) + '@solana/signers': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/programs@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/promises@6.9.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-api@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/keys': 6.9.0(typescript@5.9.3) + '@solana/rpc-parsed-types': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec': 6.9.0(typescript@5.9.3) + '@solana/rpc-transformers': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + '@solana/transaction-messages': 6.9.0(typescript@5.9.3) + '@solana/transactions': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-parsed-types@6.9.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-spec-types@6.9.0(typescript@5.9.3)': + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-spec@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-subscriptions-api@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/keys': 6.9.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 6.9.0(typescript@5.9.3) + '@solana/rpc-transformers': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + '@solana/transaction-messages': 6.9.0(typescript@5.9.3) + '@solana/transactions': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-subscriptions-channel-websocket@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/functional': 6.9.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 6.9.0(typescript@5.9.3) + '@solana/subscribable': 6.9.0(typescript@5.9.3) + ws: 8.21.0 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@solana/rpc-subscriptions-spec@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/promises': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.9.0(typescript@5.9.3) + '@solana/subscribable': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-subscriptions@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 6.9.0(typescript@5.9.3) + '@solana/functional': 6.9.0(typescript@5.9.3) + '@solana/promises': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.9.0(typescript@5.9.3) + '@solana/rpc-subscriptions-api': 6.9.0(typescript@5.9.3) + '@solana/rpc-subscriptions-channel-websocket': 6.9.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 6.9.0(typescript@5.9.3) + '@solana/rpc-transformers': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + '@solana/subscribable': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - utf-8-validate + + '@solana/rpc-transformers@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/functional': 6.9.0(typescript@5.9.3) + '@solana/nominal-types': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-transport-http@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.9.0(typescript@5.9.3) + undici-types: 8.3.0 + optionalDependencies: + typescript: 5.9.3 + + '@solana/rpc-types@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.9.0(typescript@5.9.3) + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/fixed-points': 6.9.0(typescript@5.9.3) + '@solana/nominal-types': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 6.9.0(typescript@5.9.3) + '@solana/functional': 6.9.0(typescript@5.9.3) + '@solana/rpc-api': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec': 6.9.0(typescript@5.9.3) + '@solana/rpc-spec-types': 6.9.0(typescript@5.9.3) + '@solana/rpc-transformers': 6.9.0(typescript@5.9.3) + '@solana/rpc-transport-http': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/signers@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/instructions': 6.9.0(typescript@5.9.3) + '@solana/keys': 6.9.0(typescript@5.9.3) + '@solana/nominal-types': 6.9.0(typescript@5.9.3) + '@solana/offchain-messages': 6.9.0(typescript@5.9.3) + '@solana/transaction-messages': 6.9.0(typescript@5.9.3) + '@solana/transactions': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/subscribable@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + '@solana/sysvars@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/accounts': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.9.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transaction-confirmation@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/keys': 6.9.0(typescript@5.9.3) + '@solana/promises': 6.9.0(typescript@5.9.3) + '@solana/rpc': 6.9.0(typescript@5.9.3) + '@solana/rpc-subscriptions': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + '@solana/transaction-messages': 6.9.0(typescript@5.9.3) + '@solana/transactions': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - utf-8-validate + + '@solana/transaction-messages@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.9.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/functional': 6.9.0(typescript@5.9.3) + '@solana/instructions': 6.9.0(typescript@5.9.3) + '@solana/nominal-types': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transactions@6.9.0(typescript@5.9.3)': + dependencies: + '@solana/addresses': 6.9.0(typescript@5.9.3) + '@solana/codecs-core': 6.9.0(typescript@5.9.3) + '@solana/codecs-data-structures': 6.9.0(typescript@5.9.3) + '@solana/codecs-numbers': 6.9.0(typescript@5.9.3) + '@solana/codecs-strings': 6.9.0(typescript@5.9.3) + '@solana/errors': 6.9.0(typescript@5.9.3) + '@solana/functional': 6.9.0(typescript@5.9.3) + '@solana/instructions': 6.9.0(typescript@5.9.3) + '@solana/keys': 6.9.0(typescript@5.9.3) + '@solana/nominal-types': 6.9.0(typescript@5.9.3) + '@solana/rpc-types': 6.9.0(typescript@5.9.3) + '@solana/transaction-messages': 6.9.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@types/node@25.9.1': + dependencies: + undici-types: 7.24.6 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + chalk@5.6.2: {} + + codama@1.7.0: + dependencies: + '@codama/cli': 1.5.2 + '@codama/errors': 1.7.0 + '@codama/nodes': 1.7.0 + '@codama/validators': 1.7.0 + '@codama/visitors': 1.7.0 + + commander@14.0.2: {} + + commander@14.0.3: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + esbuild@0.28.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.0 + '@esbuild/android-arm': 0.28.0 + '@esbuild/android-arm64': 0.28.0 + '@esbuild/android-x64': 0.28.0 + '@esbuild/darwin-arm64': 0.28.0 + '@esbuild/darwin-x64': 0.28.0 + '@esbuild/freebsd-arm64': 0.28.0 + '@esbuild/freebsd-x64': 0.28.0 + '@esbuild/linux-arm': 0.28.0 + '@esbuild/linux-arm64': 0.28.0 + '@esbuild/linux-ia32': 0.28.0 + '@esbuild/linux-loong64': 0.28.0 + '@esbuild/linux-mips64el': 0.28.0 + '@esbuild/linux-ppc64': 0.28.0 + '@esbuild/linux-riscv64': 0.28.0 + '@esbuild/linux-s390x': 0.28.0 + '@esbuild/linux-x64': 0.28.0 + '@esbuild/netbsd-arm64': 0.28.0 + '@esbuild/netbsd-x64': 0.28.0 + '@esbuild/openbsd-arm64': 0.28.0 + '@esbuild/openbsd-x64': 0.28.0 + '@esbuild/openharmony-arm64': 0.28.0 + '@esbuild/sunos-x64': 0.28.0 + '@esbuild/win32-arm64': 0.28.0 + '@esbuild/win32-ia32': 0.28.0 + '@esbuild/win32-x64': 0.28.0 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + gopd@1.2.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + isarray@2.0.5: {} + + json-stable-stringify@1.3.0: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + isarray: 2.0.5 + jsonify: 0.0.1 + object-keys: 1.1.1 + + jsonify@0.0.1: {} + + kleur@3.0.3: {} + + litesvm-darwin-arm64@1.1.0: + optional: true + + litesvm-darwin-x64@1.1.0: + optional: true + + litesvm-linux-arm64-gnu@1.1.0: + optional: true + + litesvm-linux-arm64-musl@1.1.0: + optional: true + + litesvm-linux-x64-gnu@1.1.0: + optional: true + + litesvm-linux-x64-musl@1.1.0: + optional: true + + litesvm@1.1.0(typescript@5.9.3): + dependencies: + '@solana-program/system': 0.12.2(@solana/kit@6.9.0(typescript@5.9.3)) + '@solana-program/token': 0.13.0(@solana/kit@6.9.0(typescript@5.9.3)) + '@solana/kit': 6.9.0(typescript@5.9.3) + optionalDependencies: + litesvm-darwin-arm64: 1.1.0 + litesvm-darwin-x64: 1.1.0 + litesvm-linux-arm64-gnu: 1.1.0 + litesvm-linux-arm64-musl: 1.1.0 + litesvm-linux-x64-gnu: 1.1.0 + litesvm-linux-x64-musl: 1.1.0 + transitivePeerDependencies: + - bufferutil + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + + math-intrinsics@1.1.0: {} + + object-keys@1.1.1: {} + + picocolors@1.1.1: {} + + prettier@3.8.3: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + semver@7.8.2: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + sisteransi@1.0.5: {} + + tsx@4.22.4: + dependencies: + esbuild: 0.28.0 + optionalDependencies: + fsevents: 2.3.3 + + typescript@5.9.3: {} + + undici-types@7.24.6: {} + + undici-types@8.3.0: {} + + ws@8.21.0: {} diff --git a/tools/shank-and-codama/native/program/Cargo.lock b/tools/shank-and-codama/native/program/Cargo.lock new file mode 100644 index 00000000..a30bf730 --- /dev/null +++ b/tools/shank-and-codama/native/program/Cargo.lock @@ -0,0 +1,1584 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" + +[[package]] +name = "blake3" +version = "1.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "cpufeatures 0.3.0", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" +dependencies = [ + "borsh-derive", + "bytes", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfcfdc083699101d5a7965e49925975f2f55060f94f9a05e7187be95d530ca59" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "car-rental-service" +version = "0.1.0" +dependencies = [ + "borsh", + "borsh-derive", + "shank", + "solana-program", + "solana-system-interface", +] + +[[package]] +name = "cc" +version = "1.2.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rand_core", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "five8" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f76610e969fa1784327ded240f1e28a3fd9520c9cec93b636fcf62dd37f772" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_const" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a0f1728185f277989ca573a402716ae0beaaea3f76a8ff87ef9dd8fb19436c5" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059c31d7d36c43fe39d89e55711858b4da8be7eb6dabac23c7289b1a19489406" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures 0.2.17", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" + +[[package]] +name = "memchr" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "pastey" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest", +] + +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + +[[package]] +name = "sha3" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shank" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1dc1d3af4ba5f02190110598b2abac0d13ce9dc58408aba4549e1c0f91a24c" +dependencies = [ + "shank_macro", +] + +[[package]] +name = "shank_macro" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63dbf105335507ad339dccacf3b1ea20e4c0b70d992b4de7cc11d5c0b91b0747" +dependencies = [ + "proc-macro2", + "quote", + "shank_macro_impl", + "shank_render", + "syn 1.0.109", +] + +[[package]] +name = "shank_macro_impl" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346563412da6d1a53bc53c81f9d8b102f177952b95fd8de00e5d2203a4685635" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", +] + +[[package]] +name = "shank_render" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8358067ec1787814d2577e76d9ddcc980559ad821e6bd04584f4847f4d1d955c" +dependencies = [ + "proc-macro2", + "quote", + "shank_macro_impl", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "solana-account-info" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9cf16495d9eb53e3d04e72366a33bb1c20c24e78c171d8b8f5978357b63ae95" +dependencies = [ + "bincode", + "serde_core", + "solana-address", + "solana-program-error", + "solana-program-memory", +] + +[[package]] +name = "solana-address" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c93e262f671bf402e1040e4a7e40b05d81da5956c7681948c975a0997517bb" +dependencies = [ + "borsh", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek", + "five8", + "five8_const", + "serde", + "serde_derive", + "sha2-const-stable", + "solana-atomic-u64", + "solana-define-syscall 5.1.0", + "solana-program-error", + "solana-sanitize", + "solana-sha256-hasher", + "wincode", +] + +[[package]] +name = "solana-atomic-u64" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "085db4906d89324cef2a30840d59eaecf3d4231c560ec7c9f6614a93c652f501" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "solana-big-mod-exp" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c80fb6d791b3925d5ec4bf23a7c169ef5090c013059ec3ed7d0b2c04efa085" +dependencies = [ + "num-bigint", + "num-traits", + "solana-define-syscall 3.0.0", +] + +[[package]] +name = "solana-blake3-hasher" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7116e1d942a2432ca3f514625104757ab8a56233787e95144c93950029e31176" +dependencies = [ + "blake3", + "solana-define-syscall 4.0.1", + "solana-hash", +] + +[[package]] +name = "solana-borsh" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c04abbae16f57178a163125805637b8a076175bb5c0002fb04f4792bea901cf7" +dependencies = [ + "borsh", +] + +[[package]] +name = "solana-clock" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea35d8f69b67daddb921a9da7f78ca591b533cf5e98833cd9ae62fdc2e4652c" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-cpi" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dea26709d867aada85d0d3617db0944215c8bb28d3745b912de7db13a23280c" +dependencies = [ + "solana-account-info", + "solana-define-syscall 4.0.1", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-stable-layout", +] + +[[package]] +name = "solana-define-syscall" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9697086a4e102d28a156b8d6b521730335d6951bd39a5e766512bbe09007cee" + +[[package]] +name = "solana-define-syscall" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e5b1c0bc1d4a4d10c88a4100499d954c09d3fecfae4912c1a074dff68b1738" + +[[package]] +name = "solana-define-syscall" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e14a4f604117f379840956a8fc8695e4c84f5b0ebed192f31f60d9b85d581d" + +[[package]] +name = "solana-epoch-rewards" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cddf2388b28291210d9aa60690740733cab527531f06ed153c4d388951e407c" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-schedule" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce264b7b42322325947c4136a09460bf5c73d9aa8262c9b0a2064be63ba8639" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-stake" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "027e6d0b9e7daac5b2ac7c3f9ca1b727861121d9ef05084cf435ff736051e7c2" +dependencies = [ + "solana-define-syscall 5.1.0", + "solana-pubkey", +] + +[[package]] +name = "solana-example-mocks" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eb265ff95e28eceda117e2e3d2d2a611ecbbfe911dfeeeecd1521814540ffab" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-instruction", + "solana-nonce", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", + "thiserror", +] + +[[package]] +name = "solana-fee-calculator" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ee18959f176ba6229105c6c2a2ddaaa04bd53615af9277d834b113571bd205" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-hash" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe51db00ac3aa9f950d1e6201a126acfa26e6d81bc4a183ba64ec02effcad883" +dependencies = [ + "borsh", + "bytemuck", + "bytemuck_derive", + "five8", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-instruction" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ebb0ffd19263051bc3f683fcc086134b8ff23af894dcb63f7563c7137b42f1" +dependencies = [ + "bincode", + "borsh", + "serde", + "serde_derive", + "solana-define-syscall 5.1.0", + "solana-instruction-error", + "solana-pubkey", +] + +[[package]] +name = "solana-instruction-error" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0b188842592fdf6cb96f55263ae1bf11713ab5114401d1d5a881ed7cc41bef6" +dependencies = [ + "num-traits", + "solana-program-error", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e0732294560e88ecdb2bbc656e67383e9f88c78ec09469cef172f0d28cd1bcd" +dependencies = [ + "bitflags", + "solana-account-info", + "solana-instruction", + "solana-instruction-error", + "solana-program-error", + "solana-sanitize", + "solana-sdk-ids", + "solana-serialize-utils", + "solana-sysvar-id", +] + +[[package]] +name = "solana-keccak-hasher" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed1c0d16d6fdeba12291a1f068cdf0d479d9bff1141bf44afd7aa9d485f65ef8" +dependencies = [ + "sha3", + "solana-define-syscall 4.0.1", + "solana-hash", +] + +[[package]] +name = "solana-last-restart-slot" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "426711c6564b790026e45cabec3c64b971864c48b6b2d83c0ebf52a118bb4cda" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-msg" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726b7cbbc6be6f1c6f29146ac824343b9415133eee8cce156452ad1db93f8008" +dependencies = [ + "solana-define-syscall 5.1.0", +] + +[[package]] +name = "solana-native-token" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8dd4c280dca9d046139eb5b7a5ac9ad10403fbd64964c7d7571214950d758f" + +[[package]] +name = "solana-nonce" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95dbc9f2e33b6c10e231df15cb2a3bff9ea7eab6347f9e316fe75c97fd67bbb" +dependencies = [ + "solana-fee-calculator", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-program" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778f08fb0eaf52c9a3bef2978247f7fab0ccfddc44cfddb936d5ad9f98ede886" +dependencies = [ + "memoffset", + "solana-account-info", + "solana-big-mod-exp", + "solana-blake3-hasher", + "solana-borsh", + "solana-clock", + "solana-cpi", + "solana-define-syscall 5.1.0", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-epoch-stake", + "solana-example-mocks", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instruction-error", + "solana-instructions-sysvar", + "solana-keccak-hasher", + "solana-last-restart-slot", + "solana-msg", + "solana-native-token", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-serialize-utils", + "solana-sha256-hasher", + "solana-short-vec", + "solana-slot-hashes", + "solana-slot-history", + "solana-stable-layout", + "solana-sysvar", + "solana-sysvar-id", +] + +[[package]] +name = "solana-program-entrypoint" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c9b0a1ff494e05f503a08b3d51150b73aa639544631e510279d6375f290997" +dependencies = [ + "solana-account-info", + "solana-define-syscall 4.0.1", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "solana-program-error" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f04fa578707b3612b095f0c8e19b66a1233f7c42ca8082fcb3b745afcc0add6" +dependencies = [ + "borsh", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-program-memory" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4068648649653c2c50546e9a7fb761791b5ab0cda054c771bb5808d3a4b9eb52" +dependencies = [ + "solana-define-syscall 4.0.1", +] + +[[package]] +name = "solana-program-option" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a88006a9b8594088cec9027ab77caaaa258a2aaa2083d3f086c44b42e50aeab" + +[[package]] +name = "solana-program-pack" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7701cb15b90667ae1c89ef4ac35a59c61e66ce58ddee13d729472af7f41d59" +dependencies = [ + "solana-program-error", +] + +[[package]] +name = "solana-pubkey" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7db719574990de7e8b0f55a8593ac92a5ccb42c8ce67b3e4bf05b139d5d9ee71" +dependencies = [ + "solana-address", +] + +[[package]] +name = "solana-rent" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9809b081e99bc142ce803bcd7ee18306759ce3b30a96a9da3f6f41c45e50ef0" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sanitize" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf09694a0fc14e5ffb18f9b7b7c0f15ecb6eac5b5610bf76a1853459d19daf9" + +[[package]] +name = "solana-sdk-ids" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def234c1956ff616d46c9dd953f251fa7096ddbaa6d52b165218de97882b7280" +dependencies = [ + "solana-address", +] + +[[package]] +name = "solana-sdk-macro" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8765316242300c48242d84a41614cb3388229ec353ba464f6fe62a733e41806f" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c5f18893d62e6c73117dcba48f8f5e3266d90e5ec3d0a0a90f9785adac36c1" +dependencies = [ + "k256", + "solana-define-syscall 5.1.0", + "thiserror", +] + +[[package]] +name = "solana-serde-varint" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "950e5b83e839dc0f92c66afc124bb8f40e89bc90f0579e8ec5499296d27f54e3" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serialize-utils" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "761357b0853c9623bf12c1d2314b3d6160a85b087b84c45224fb85766d22616b" +dependencies = [ + "solana-instruction-error", + "solana-pubkey", + "solana-sanitize", +] + +[[package]] +name = "solana-sha256-hasher" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db7dc3011ea4c0334aaaa7e7128cb390ecf546b28d412e9bf2064680f57f588f" +dependencies = [ + "sha2", + "solana-define-syscall 4.0.1", + "solana-hash", +] + +[[package]] +name = "solana-short-vec" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bb8cc883fc7b8ce4a7814cb1441b48c06437049ec11847005cf63bcfa85c546" + +[[package]] +name = "solana-slot-hashes" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a57c158c35629f9e302ab385f16b15813f4927a31c27dda72f3df828bb08d93" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-slot-history" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0622d03a823770f7763afd866e012b296d5a3cbbbe51e110b5bd9ab3441efdca" +dependencies = [ + "bv", + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-stable-layout" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9f6a291ba063a37780af29e7db14bdd3dc447584d8ba5b3fc4b88e2bbc982fa" +dependencies = [ + "solana-instruction", + "solana-pubkey", +] + +[[package]] +name = "solana-system-interface" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55b54965bf0b76fa8e2b35376583efddd4d916618cfe595bf48c7d7b55a9e628" +dependencies = [ + "num-traits", + "serde", + "serde_derive", + "solana-address", + "solana-instruction", + "solana-msg", + "solana-program-error", +] + +[[package]] +name = "solana-sysvar" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1632b69b4f72489db5949a10e8308c229dfa003f99ecaa7477b376807c7b81f4" +dependencies = [ + "base64", + "bincode", + "bytemuck", + "bytemuck_derive", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-define-syscall 5.1.0", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-last-restart-slot", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-slot-hashes", + "solana-slot-history", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sysvar-id" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17358d1e9a13e5b9c2264d301102126cf11a47fd394cdf3dec174fe7bc96e1de" +dependencies = [ + "solana-address", + "solana-sdk-ids", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wincode" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d967db7705dc29120bb6e8ce5b5a2e27734ed5976d1c904e95bd238d1c3c5a" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror", + "wincode-derive", +] + +[[package]] +name = "wincode-derive" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15ab90b719560d0fda79c74550ad1c948d17b118765942838055ebaf34d67071" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" diff --git a/tools/shank-and-codama/native/program/Cargo.toml b/tools/shank-and-codama/native/program/Cargo.toml new file mode 100644 index 00000000..1e7dd9d9 --- /dev/null +++ b/tools/shank-and-codama/native/program/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "car-rental-service" +version = "0.1.0" +edition = "2021" + +[dependencies] +borsh = "1.5.7" +borsh-derive = "1.5.7" +shank = "0.4.8" +solana-program = "4.0" +solana-system-interface = { version = "3", features = ["bincode"] } + +# This example is intentionally standalone (not part of the root workspace), +# so it pins its own dependency versions and has its own Cargo.lock. +[workspace] + +[lib] +crate-type = ["cdylib", "lib"] + +[features] +custom-heap = [] +custom-panic = [] + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(target_os, values("solana"))'] } diff --git a/tools/shank-and-solita/native/program/idl/car_rental_service.json b/tools/shank-and-codama/native/program/idl/car_rental_service.json similarity index 84% rename from tools/shank-and-solita/native/program/idl/car_rental_service.json rename to tools/shank-and-codama/native/program/idl/car_rental_service.json index 54af8ec2..bd014148 100644 --- a/tools/shank-and-solita/native/program/idl/car_rental_service.json +++ b/tools/shank-and-codama/native/program/idl/car_rental_service.json @@ -9,19 +9,19 @@ "name": "carAccount", "isMut": true, "isSigner": false, - "desc": "The account that will represent the Car being created" + "docs": ["The account that will represent the Car being created"] }, { "name": "payer", "isMut": true, "isSigner": false, - "desc": "Fee payer" + "docs": ["Fee payer"] }, { "name": "systemProgram", "isMut": false, "isSigner": false, - "desc": "The System Program" + "docs": ["The System Program"] } ], "args": [ @@ -44,25 +44,25 @@ "name": "rentalAccount", "isMut": true, "isSigner": false, - "desc": "The account that will represent the actual order for the rental" + "docs": ["The account that will represent the actual order for the rental"] }, { "name": "carAccount", "isMut": false, "isSigner": false, - "desc": "The account representing the Car being rented in this order" + "docs": ["The account representing the Car being rented in this order"] }, { "name": "payer", "isMut": true, "isSigner": false, - "desc": "Fee payer" + "docs": ["Fee payer"] }, { "name": "systemProgram", "isMut": false, "isSigner": false, - "desc": "The System Program" + "docs": ["The System Program"] } ], "args": [ @@ -85,19 +85,19 @@ "name": "rentalAccount", "isMut": true, "isSigner": false, - "desc": "The account representing the active rental" + "docs": ["The account representing the active rental"] }, { "name": "carAccount", "isMut": false, "isSigner": false, - "desc": "The account representing the Car being rented in this order" + "docs": ["The account representing the Car being rented in this order"] }, { "name": "payer", "isMut": true, "isSigner": false, - "desc": "Fee payer" + "docs": ["Fee payer"] } ], "args": [], @@ -113,19 +113,19 @@ "name": "rentalAccount", "isMut": true, "isSigner": false, - "desc": "The account representing the active rental" + "docs": ["The account representing the active rental"] }, { "name": "carAccount", "isMut": false, "isSigner": false, - "desc": "The account representing the Car being rented in this order" + "docs": ["The account representing the Car being rented in this order"] }, { "name": "payer", "isMut": true, "isSigner": false, - "desc": "Fee payer" + "docs": ["Fee payer"] } ], "args": [], @@ -256,8 +256,6 @@ ], "metadata": { "origin": "shank", - "address": "8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ", - "binaryVersion": "0.0.12", - "libVersion": "0.0.12" + "address": "8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ" } } diff --git a/tools/shank-and-solita/native/program/src/instructions/add_car.rs b/tools/shank-and-codama/native/program/src/instructions/add_car.rs similarity index 57% rename from tools/shank-and-solita/native/program/src/instructions/add_car.rs rename to tools/shank-and-codama/native/program/src/instructions/add_car.rs index 6bc26978..7b195825 100644 --- a/tools/shank-and-solita/native/program/src/instructions/add_car.rs +++ b/tools/shank-and-codama/native/program/src/instructions/add_car.rs @@ -1,20 +1,16 @@ +use crate::state::Car; use { - borsh::{ - BorshDeserialize, - BorshSerialize - }, - shank::ShankAccount, + borsh::{BorshDeserialize, BorshSerialize}, solana_program::{ - account_info::{AccountInfo, next_account_info}, - entrypoint::ProgramResult, + account_info::{next_account_info, AccountInfo}, + entrypoint::ProgramResult, program::invoke_signed, pubkey::Pubkey, rent::Rent, - system_instruction, sysvar::Sysvar, }, + solana_system_interface::instruction as system_instruction, }; -use crate::state::Car; #[derive(BorshDeserialize, BorshSerialize, Clone, Debug)] pub struct AddCarArgs { @@ -23,18 +19,13 @@ pub struct AddCarArgs { pub model: String, } -pub fn add_car( - program_id: &Pubkey, - accounts: &[AccountInfo], - args: AddCarArgs, -) -> ProgramResult { - +pub fn add_car(program_id: &Pubkey, accounts: &[AccountInfo], args: AddCarArgs) -> ProgramResult { let accounts_iter = &mut accounts.iter(); let car_account = next_account_info(accounts_iter)?; let payer = next_account_info(accounts_iter)?; let system_program = next_account_info(accounts_iter)?; - let (car_account_pda, car_account_bump) = Car::shank_pda(program_id, args.make, args.model); + let (car_account_pda, car_account_bump) = Car::find_pda(program_id, &args.make, &args.model); assert!(&car_account_pda == car_account.key); let car_data = Car { @@ -43,24 +34,27 @@ pub fn add_car( model: args.model, }; - let account_span = (car_data.try_to_vec()?).len(); + let account_span = borsh::to_vec(&car_data)?.len(); let lamports_required = (Rent::get()?).minimum_balance(account_span); invoke_signed( &system_instruction::create_account( - &payer.key, - &car_account.key, + payer.key, + car_account.key, lamports_required, account_span as u64, program_id, ), - &[ - payer.clone(), car_account.clone(), system_program.clone() - ], - Car::shank_seeds_with_bump(args.make, args.model, &[car_account_bump]), + &[payer.clone(), car_account.clone(), system_program.clone()], + &[&[ + Car::SEED_PREFIX.as_bytes(), + car_data.make.as_bytes(), + car_data.model.as_bytes(), + &[car_account_bump], + ]], )?; - + car_data.serialize(&mut &mut car_account.data.borrow_mut()[..])?; Ok(()) -} \ No newline at end of file +} diff --git a/tools/shank-and-solita/native/program/src/instructions/book_rental.rs b/tools/shank-and-codama/native/program/src/instructions/book_rental.rs similarity index 63% rename from tools/shank-and-solita/native/program/src/instructions/book_rental.rs rename to tools/shank-and-codama/native/program/src/instructions/book_rental.rs index 9bc7a884..a523ae3d 100644 --- a/tools/shank-and-solita/native/program/src/instructions/book_rental.rs +++ b/tools/shank-and-codama/native/program/src/instructions/book_rental.rs @@ -1,22 +1,15 @@ +use crate::state::{RentalOrder, RentalOrderStatus}; use { - borsh::{ - BorshDeserialize, - BorshSerialize - }, - shank::ShankAccount, + borsh::{BorshDeserialize, BorshSerialize}, solana_program::{ - account_info::{AccountInfo, next_account_info}, - entrypoint::ProgramResult, + account_info::{next_account_info, AccountInfo}, + entrypoint::ProgramResult, program::invoke_signed, pubkey::Pubkey, rent::Rent, - system_instruction, sysvar::Sysvar, }, -}; -use crate::state::{ - RentalOrder, - RentalOrderStatus, + solana_system_interface::instruction as system_instruction, }; #[derive(BorshDeserialize, BorshSerialize, Clone, Debug)] @@ -32,14 +25,14 @@ pub fn book_rental( accounts: &[AccountInfo], args: BookRentalArgs, ) -> ProgramResult { - let accounts_iter = &mut accounts.iter(); let rental_order_account = next_account_info(accounts_iter)?; let car_account = next_account_info(accounts_iter)?; let payer = next_account_info(accounts_iter)?; let system_program = next_account_info(accounts_iter)?; - let (rental_order_account_pda, rental_order_account_bump) = RentalOrder::shank_pda(program_id, car_account.key, payer.key); + let (rental_order_account_pda, rental_order_account_bump) = + RentalOrder::find_pda(program_id, car_account.key, payer.key); assert!(&rental_order_account_pda == rental_order_account.key); let rental_order_data = RentalOrder { @@ -51,24 +44,31 @@ pub fn book_rental( status: RentalOrderStatus::Created, }; - let account_span = (rental_order_data.try_to_vec()?).len(); + let account_span = borsh::to_vec(&rental_order_data)?.len(); let lamports_required = (Rent::get()?).minimum_balance(account_span); invoke_signed( &system_instruction::create_account( - &payer.key, - &rental_order_account.key, + payer.key, + rental_order_account.key, lamports_required, account_span as u64, program_id, ), &[ - payer.clone(), rental_order_account.clone(), system_program.clone() + payer.clone(), + rental_order_account.clone(), + system_program.clone(), ], - RentalOrder::shank_seeds_with_bump(car_account.key, payer.key, &[rental_order_account_bump]), + &[&[ + RentalOrder::SEED_PREFIX.as_bytes(), + car_account.key.as_ref(), + payer.key.as_ref(), + &[rental_order_account_bump], + ]], )?; - + rental_order_data.serialize(&mut &mut rental_order_account.data.borrow_mut()[..])?; Ok(()) -} \ No newline at end of file +} diff --git a/tools/shank-and-codama/native/program/src/instructions/mod.rs b/tools/shank-and-codama/native/program/src/instructions/mod.rs new file mode 100644 index 00000000..3572eae5 --- /dev/null +++ b/tools/shank-and-codama/native/program/src/instructions/mod.rs @@ -0,0 +1,70 @@ +pub mod add_car; +pub mod book_rental; +pub mod pick_up_car; +pub mod return_car; + +pub use add_car::*; +pub use book_rental::*; +pub use pick_up_car::*; +pub use return_car::*; + +use { + borsh::{BorshDeserialize, BorshSerialize}, + shank::ShankInstruction, +}; + +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankInstruction)] +pub enum CarRentalServiceInstruction { + #[account( + 0, + writable, + name = "car_account", + desc = "The account that will represent the Car being created" + )] + #[account(1, writable, name = "payer", desc = "Fee payer")] + #[account(2, name = "system_program", desc = "The System Program")] + AddCar(AddCarArgs), + + #[account( + 0, + writable, + name = "rental_account", + desc = "The account that will represent the actual order for the rental" + )] + #[account( + 1, + name = "car_account", + desc = "The account representing the Car being rented in this order" + )] + #[account(2, writable, name = "payer", desc = "Fee payer")] + #[account(3, name = "system_program", desc = "The System Program")] + BookRental(BookRentalArgs), + + #[account( + 0, + writable, + name = "rental_account", + desc = "The account representing the active rental" + )] + #[account( + 1, + name = "car_account", + desc = "The account representing the Car being rented in this order" + )] + #[account(2, writable, name = "payer", desc = "Fee payer")] + PickUpCar, + + #[account( + 0, + writable, + name = "rental_account", + desc = "The account representing the active rental" + )] + #[account( + 1, + name = "car_account", + desc = "The account representing the Car being rented in this order" + )] + #[account(2, writable, name = "payer", desc = "Fee payer")] + ReturnCar, +} diff --git a/tools/shank-and-solita/native/program/src/instructions/pick_up_car.rs b/tools/shank-and-codama/native/program/src/instructions/pick_up_car.rs similarity index 52% rename from tools/shank-and-solita/native/program/src/instructions/pick_up_car.rs rename to tools/shank-and-codama/native/program/src/instructions/pick_up_car.rs index eb9894fc..8637edb1 100644 --- a/tools/shank-and-solita/native/program/src/instructions/pick_up_car.rs +++ b/tools/shank-and-codama/native/program/src/instructions/pick_up_car.rs @@ -1,37 +1,21 @@ +use crate::state::{RentalOrder, RentalOrderStatus}; use { - borsh::{ - BorshDeserialize, - BorshSerialize, - }, + borsh::{BorshDeserialize, BorshSerialize}, solana_program::{ - account_info::{AccountInfo, next_account_info}, - entrypoint::ProgramResult, + account_info::{next_account_info, AccountInfo}, + entrypoint::ProgramResult, pubkey::Pubkey, }, }; -use crate::state::{ - RentalOrder, - RentalOrderStatus, -}; - -pub fn pick_up_car( - program_id: &Pubkey, - accounts: &[AccountInfo], -) -> ProgramResult { +pub fn pick_up_car(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let accounts_iter = &mut accounts.iter(); let rental_order_account = next_account_info(accounts_iter)?; let car_account = next_account_info(accounts_iter)?; let payer = next_account_info(accounts_iter)?; - let (rental_order_account_pda, _) = Pubkey::find_program_address( - &[ - RentalOrder::SEED_PREFIX.as_bytes().as_ref(), - car_account.key.as_ref(), - payer.key.as_ref(), - ], - program_id, - ); + let (rental_order_account_pda, _) = + RentalOrder::find_pda(program_id, car_account.key, payer.key); assert!(&rental_order_account_pda == rental_order_account.key); let rental_order = &mut RentalOrder::try_from_slice(&rental_order_account.data.borrow())?; @@ -39,4 +23,4 @@ pub fn pick_up_car( rental_order.serialize(&mut &mut rental_order_account.data.borrow_mut()[..])?; Ok(()) -} \ No newline at end of file +} diff --git a/tools/shank-and-solita/native/program/src/instructions/return_car.rs b/tools/shank-and-codama/native/program/src/instructions/return_car.rs similarity index 51% rename from tools/shank-and-solita/native/program/src/instructions/return_car.rs rename to tools/shank-and-codama/native/program/src/instructions/return_car.rs index 328802c8..1962bd3a 100644 --- a/tools/shank-and-solita/native/program/src/instructions/return_car.rs +++ b/tools/shank-and-codama/native/program/src/instructions/return_car.rs @@ -1,37 +1,21 @@ +use crate::state::{RentalOrder, RentalOrderStatus}; use { - borsh::{ - BorshDeserialize, - BorshSerialize, - }, + borsh::{BorshDeserialize, BorshSerialize}, solana_program::{ - account_info::{AccountInfo, next_account_info}, - entrypoint::ProgramResult, + account_info::{next_account_info, AccountInfo}, + entrypoint::ProgramResult, pubkey::Pubkey, }, }; -use crate::state::{ - RentalOrder, - RentalOrderStatus, -}; - -pub fn return_car( - program_id: &Pubkey, - accounts: &[AccountInfo], -) -> ProgramResult { +pub fn return_car(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let accounts_iter = &mut accounts.iter(); let rental_order_account = next_account_info(accounts_iter)?; let car_account = next_account_info(accounts_iter)?; let payer = next_account_info(accounts_iter)?; - let (rental_order_account_pda, _) = Pubkey::find_program_address( - &[ - RentalOrder::SEED_PREFIX.as_bytes().as_ref(), - car_account.key.as_ref(), - payer.key.as_ref(), - ], - program_id, - ); + let (rental_order_account_pda, _) = + RentalOrder::find_pda(program_id, car_account.key, payer.key); assert!(&rental_order_account_pda == rental_order_account.key); let rental_order = &mut RentalOrder::try_from_slice(&rental_order_account.data.borrow())?; @@ -39,4 +23,4 @@ pub fn return_car( rental_order.serialize(&mut &mut rental_order_account.data.borrow_mut()[..])?; Ok(()) -} \ No newline at end of file +} diff --git a/tools/shank-and-solita/native/program/src/lib.rs b/tools/shank-and-codama/native/program/src/lib.rs similarity index 68% rename from tools/shank-and-solita/native/program/src/lib.rs rename to tools/shank-and-codama/native/program/src/lib.rs index 9f8e43c6..376b66be 100644 --- a/tools/shank-and-solita/native/program/src/lib.rs +++ b/tools/shank-and-codama/native/program/src/lib.rs @@ -1,17 +1,14 @@ mod instructions; mod state; +use crate::instructions::*; use { borsh::BorshDeserialize, solana_program::{ - account_info::AccountInfo, - declare_id, - entrypoint, - entrypoint::ProgramResult, + account_info::AccountInfo, declare_id, entrypoint, entrypoint::ProgramResult, pubkey::Pubkey, }, }; -use crate::instructions::*; declare_id!("8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ"); entrypoint!(process_instruction); @@ -21,12 +18,11 @@ pub fn process_instruction( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { - let instruction = CarRentalServiceInstruction::try_from_slice(instruction_data)?; match instruction { - CarRentalServiceInstruction::AddCar(car) => add_car(program_id, accounts, car), - CarRentalServiceInstruction::BookRental(order) => book_rental(program_id, accounts, order), + CarRentalServiceInstruction::AddCar(args) => add_car(program_id, accounts, args), + CarRentalServiceInstruction::BookRental(args) => book_rental(program_id, accounts, args), CarRentalServiceInstruction::PickUpCar => pick_up_car(program_id, accounts), CarRentalServiceInstruction::ReturnCar => return_car(program_id, accounts), } -} \ No newline at end of file +} diff --git a/tools/shank-and-codama/native/program/src/state/mod.rs b/tools/shank-and-codama/native/program/src/state/mod.rs new file mode 100644 index 00000000..cb5fd132 --- /dev/null +++ b/tools/shank-and-codama/native/program/src/state/mod.rs @@ -0,0 +1,68 @@ +use { + borsh::{BorshDeserialize, BorshSerialize}, + shank::ShankAccount, + solana_program::pubkey::Pubkey, +}; + +// NOTE on PDAs and Shank's `#[seeds(...)]` attribute: +// +// Older versions of Shank (0.0.x) used `#[seeds(...)]` on a `ShankAccount` to +// generate `shank_pda` / `shank_seeds_with_bump` helper methods. As of Shank +// 0.4.x that PDA code-generation produces unparsable tokens and breaks +// compilation, and the seeds are *not* emitted into the IDL anyway. Shank 0.4 +// therefore only uses `ShankAccount` to extract the account's layout for the +// IDL. We keep the PDA derivation explicit here (the seed bytes are identical +// to what the old generated helpers produced). + +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankAccount)] +pub struct Car { + pub year: u16, + pub make: String, + pub model: String, +} + +impl Car { + pub const SEED_PREFIX: &'static str = "car"; + + /// Derive the PDA for a `Car` account: `["car", make, model]`. + pub fn find_pda(program_id: &Pubkey, make: &str, model: &str) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[ + Self::SEED_PREFIX.as_bytes(), + make.as_bytes(), + model.as_bytes(), + ], + program_id, + ) + } +} + +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug)] +pub enum RentalOrderStatus { + Created, + PickedUp, + Returned, +} + +#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankAccount)] +pub struct RentalOrder { + pub car: Pubkey, + pub name: String, + pub pick_up_date: String, + pub return_date: String, + pub price: u64, + pub status: RentalOrderStatus, +} + +impl RentalOrder { + pub const SEED_PREFIX: &'static str = "rental_order"; + + /// Derive the PDA for a `RentalOrder` account: + /// `["rental_order", car, payer]`. + pub fn find_pda(program_id: &Pubkey, car: &Pubkey, payer: &Pubkey) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[Self::SEED_PREFIX.as_bytes(), car.as_ref(), payer.as_ref()], + program_id, + ) + } +} diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/accounts/car.ts b/tools/shank-and-codama/native/tests/generated/src/generated/accounts/car.ts new file mode 100644 index 00000000..1da00ac7 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/accounts/car.ts @@ -0,0 +1,113 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +import { + type Account, + type Address, + addDecoderSizePrefix, + addEncoderSizePrefix, + assertAccountExists, + assertAccountsExist, + type Codec, + combineCodec, + type Decoder, + decodeAccount, + type EncodedAccount, + type Encoder, + type FetchAccountConfig, + type FetchAccountsConfig, + fetchEncodedAccount, + fetchEncodedAccounts, + getStructDecoder, + getStructEncoder, + getU16Decoder, + getU16Encoder, + getU32Decoder, + getU32Encoder, + getUtf8Decoder, + getUtf8Encoder, + type MaybeAccount, + type MaybeEncodedAccount, +} from "@solana/kit"; + +export type Car = { year: number; make: string; model: string }; + +export type CarArgs = Car; + +/** Gets the encoder for {@link CarArgs} account data. */ +export function getCarEncoder(): Encoder { + return getStructEncoder([ + ["year", getU16Encoder()], + ["make", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())], + ["model", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())], + ]); +} + +/** Gets the decoder for {@link Car} account data. */ +export function getCarDecoder(): Decoder { + return getStructDecoder([ + ["year", getU16Decoder()], + ["make", addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())], + ["model", addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())], + ]); +} + +/** Gets the codec for {@link Car} account data. */ +export function getCarCodec(): Codec { + return combineCodec(getCarEncoder(), getCarDecoder()); +} + +export function decodeCar( + encodedAccount: EncodedAccount, +): Account; +export function decodeCar( + encodedAccount: MaybeEncodedAccount, +): MaybeAccount; +export function decodeCar( + encodedAccount: EncodedAccount | MaybeEncodedAccount, +): Account | MaybeAccount { + return decodeAccount(encodedAccount as MaybeEncodedAccount, getCarDecoder()); +} + +export async function fetchCar( + rpc: Parameters[0], + address: Address, + config?: FetchAccountConfig, +): Promise> { + const maybeAccount = await fetchMaybeCar(rpc, address, config); + assertAccountExists(maybeAccount); + return maybeAccount; +} + +export async function fetchMaybeCar( + rpc: Parameters[0], + address: Address, + config?: FetchAccountConfig, +): Promise> { + const maybeAccount = await fetchEncodedAccount(rpc, address, config); + return decodeCar(maybeAccount); +} + +export async function fetchAllCar( + rpc: Parameters[0], + addresses: Array
, + config?: FetchAccountsConfig, +): Promise[]> { + const maybeAccounts = await fetchAllMaybeCar(rpc, addresses, config); + assertAccountsExist(maybeAccounts); + return maybeAccounts; +} + +export async function fetchAllMaybeCar( + rpc: Parameters[0], + addresses: Array
, + config?: FetchAccountsConfig, +): Promise[]> { + const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config); + return maybeAccounts.map((maybeAccount) => decodeCar(maybeAccount)); +} diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/accounts/index.ts b/tools/shank-and-codama/native/tests/generated/src/generated/accounts/index.ts new file mode 100644 index 00000000..7b2f3b87 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/accounts/index.ts @@ -0,0 +1,10 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./car"; +export * from "./rentalOrder"; diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/accounts/rentalOrder.ts b/tools/shank-and-codama/native/tests/generated/src/generated/accounts/rentalOrder.ts new file mode 100644 index 00000000..668a53c9 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/accounts/rentalOrder.ts @@ -0,0 +1,141 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +import { + type Account, + type Address, + addDecoderSizePrefix, + addEncoderSizePrefix, + assertAccountExists, + assertAccountsExist, + type Codec, + combineCodec, + type Decoder, + decodeAccount, + type EncodedAccount, + type Encoder, + type FetchAccountConfig, + type FetchAccountsConfig, + fetchEncodedAccount, + fetchEncodedAccounts, + getAddressDecoder, + getAddressEncoder, + getStructDecoder, + getStructEncoder, + getU32Decoder, + getU32Encoder, + getU64Decoder, + getU64Encoder, + getUtf8Decoder, + getUtf8Encoder, + type MaybeAccount, + type MaybeEncodedAccount, +} from "@solana/kit"; +import { + getRentalOrderStatusDecoder, + getRentalOrderStatusEncoder, + type RentalOrderStatus, + type RentalOrderStatusArgs, +} from "../types"; + +export type RentalOrder = { + car: Address; + name: string; + pickUpDate: string; + returnDate: string; + price: bigint; + status: RentalOrderStatus; +}; + +export type RentalOrderArgs = { + car: Address; + name: string; + pickUpDate: string; + returnDate: string; + price: number | bigint; + status: RentalOrderStatusArgs; +}; + +/** Gets the encoder for {@link RentalOrderArgs} account data. */ +export function getRentalOrderEncoder(): Encoder { + return getStructEncoder([ + ["car", getAddressEncoder()], + ["name", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())], + ["pickUpDate", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())], + ["returnDate", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())], + ["price", getU64Encoder()], + ["status", getRentalOrderStatusEncoder()], + ]); +} + +/** Gets the decoder for {@link RentalOrder} account data. */ +export function getRentalOrderDecoder(): Decoder { + return getStructDecoder([ + ["car", getAddressDecoder()], + ["name", addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())], + ["pickUpDate", addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())], + ["returnDate", addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())], + ["price", getU64Decoder()], + ["status", getRentalOrderStatusDecoder()], + ]); +} + +/** Gets the codec for {@link RentalOrder} account data. */ +export function getRentalOrderCodec(): Codec { + return combineCodec(getRentalOrderEncoder(), getRentalOrderDecoder()); +} + +export function decodeRentalOrder( + encodedAccount: EncodedAccount, +): Account; +export function decodeRentalOrder( + encodedAccount: MaybeEncodedAccount, +): MaybeAccount; +export function decodeRentalOrder( + encodedAccount: EncodedAccount | MaybeEncodedAccount, +): Account | MaybeAccount { + return decodeAccount(encodedAccount as MaybeEncodedAccount, getRentalOrderDecoder()); +} + +export async function fetchRentalOrder( + rpc: Parameters[0], + address: Address, + config?: FetchAccountConfig, +): Promise> { + const maybeAccount = await fetchMaybeRentalOrder(rpc, address, config); + assertAccountExists(maybeAccount); + return maybeAccount; +} + +export async function fetchMaybeRentalOrder( + rpc: Parameters[0], + address: Address, + config?: FetchAccountConfig, +): Promise> { + const maybeAccount = await fetchEncodedAccount(rpc, address, config); + return decodeRentalOrder(maybeAccount); +} + +export async function fetchAllRentalOrder( + rpc: Parameters[0], + addresses: Array
, + config?: FetchAccountsConfig, +): Promise[]> { + const maybeAccounts = await fetchAllMaybeRentalOrder(rpc, addresses, config); + assertAccountsExist(maybeAccounts); + return maybeAccounts; +} + +export async function fetchAllMaybeRentalOrder( + rpc: Parameters[0], + addresses: Array
, + config?: FetchAccountsConfig, +): Promise[]> { + const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config); + return maybeAccounts.map((maybeAccount) => decodeRentalOrder(maybeAccount)); +} diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/index.ts b/tools/shank-and-codama/native/tests/generated/src/generated/index.ts new file mode 100644 index 00000000..f4b543bb --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/index.ts @@ -0,0 +1,12 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./accounts"; +export * from "./instructions"; +export * from "./programs"; +export * from "./types"; diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/instructions/addCar.ts b/tools/shank-and-codama/native/tests/generated/src/generated/instructions/addCar.ts new file mode 100644 index 00000000..eed0d904 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/instructions/addCar.ts @@ -0,0 +1,198 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +import { + type AccountMeta, + type Address, + addDecoderSizePrefix, + addEncoderSizePrefix, + type Codec, + combineCodec, + type Decoder, + type Encoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU16Decoder, + getU16Encoder, + getU32Decoder, + getU32Encoder, + getUtf8Decoder, + getUtf8Encoder, + type Instruction, + type InstructionWithAccounts, + type InstructionWithData, + type ReadonlyAccount, + type ReadonlyUint8Array, + SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, + SolanaError, + transformEncoder, + type WritableAccount, +} from "@solana/kit"; +import { getAccountMetaFactory, type ResolvedInstructionAccount } from "@solana/program-client-core"; +import { CAR_RENTAL_SERVICE_PROGRAM_ADDRESS } from "../programs"; + +export const ADD_CAR_DISCRIMINATOR = 0; + +export function getAddCarDiscriminatorBytes(): ReadonlyUint8Array { + return getU8Encoder().encode(ADD_CAR_DISCRIMINATOR); +} + +export type AddCarInstruction< + TProgram extends string = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, + TAccountCarAccount extends string | AccountMeta = string, + TAccountPayer extends string | AccountMeta = string, + TAccountSystemProgram extends string | AccountMeta = "11111111111111111111111111111111", + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountCarAccount extends string ? WritableAccount : TAccountCarAccount, + TAccountPayer extends string ? WritableAccount : TAccountPayer, + TAccountSystemProgram extends string ? ReadonlyAccount : TAccountSystemProgram, + ...TRemainingAccounts, + ] + >; + +export type AddCarInstructionData = { + discriminator: number; + year: number; + make: string; + model: string; +}; + +export type AddCarInstructionDataArgs = { + year: number; + make: string; + model: string; +}; + +export function getAddCarInstructionDataEncoder(): Encoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", getU8Encoder()], + ["year", getU16Encoder()], + ["make", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())], + ["model", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())], + ]), + (value) => ({ ...value, discriminator: ADD_CAR_DISCRIMINATOR }), + ); +} + +export function getAddCarInstructionDataDecoder(): Decoder { + return getStructDecoder([ + ["discriminator", getU8Decoder()], + ["year", getU16Decoder()], + ["make", addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())], + ["model", addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())], + ]); +} + +export function getAddCarInstructionDataCodec(): Codec { + return combineCodec(getAddCarInstructionDataEncoder(), getAddCarInstructionDataDecoder()); +} + +export type AddCarInput< + TAccountCarAccount extends string = string, + TAccountPayer extends string = string, + TAccountSystemProgram extends string = string, +> = { + /** The account that will represent the Car being created */ + carAccount: Address; + /** Fee payer */ + payer: Address; + /** The System Program */ + systemProgram?: Address; + year: AddCarInstructionDataArgs["year"]; + make: AddCarInstructionDataArgs["make"]; + model: AddCarInstructionDataArgs["model"]; +}; + +export function getAddCarInstruction< + TAccountCarAccount extends string, + TAccountPayer extends string, + TAccountSystemProgram extends string, + TProgramAddress extends Address = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, +>( + input: AddCarInput, + config?: { programAddress?: TProgramAddress }, +): AddCarInstruction { + // Program address. + const programAddress = config?.programAddress ?? CAR_RENTAL_SERVICE_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + carAccount: { value: input.carAccount ?? null, isWritable: true }, + payer: { value: input.payer ?? null, isWritable: true }, + systemProgram: { value: input.systemProgram ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.systemProgram.value) { + accounts.systemProgram.value = "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta("carAccount", accounts.carAccount), + getAccountMeta("payer", accounts.payer), + getAccountMeta("systemProgram", accounts.systemProgram), + ], + data: getAddCarInstructionDataEncoder().encode(args as AddCarInstructionDataArgs), + programAddress, + } as AddCarInstruction); +} + +export type ParsedAddCarInstruction< + TProgram extends string = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The account that will represent the Car being created */ + carAccount: TAccountMetas[0]; + /** Fee payer */ + payer: TAccountMetas[1]; + /** The System Program */ + systemProgram: TAccountMetas[2]; + }; + data: AddCarInstructionData; +}; + +export function parseAddCarInstruction( + instruction: Instruction & InstructionWithAccounts & InstructionWithData, +): ParsedAddCarInstruction { + if (instruction.accounts.length < 3) { + throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, { + actualAccountMetas: instruction.accounts.length, + expectedAccountMetas: 3, + }); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + carAccount: getNextAccount(), + payer: getNextAccount(), + systemProgram: getNextAccount(), + }, + data: getAddCarInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/instructions/bookRental.ts b/tools/shank-and-codama/native/tests/generated/src/generated/instructions/bookRental.ts new file mode 100644 index 00000000..d0324b70 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/instructions/bookRental.ts @@ -0,0 +1,226 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +import { + type AccountMeta, + type Address, + addDecoderSizePrefix, + addEncoderSizePrefix, + type Codec, + combineCodec, + type Decoder, + type Encoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + getU32Decoder, + getU32Encoder, + getU64Decoder, + getU64Encoder, + getUtf8Decoder, + getUtf8Encoder, + type Instruction, + type InstructionWithAccounts, + type InstructionWithData, + type ReadonlyAccount, + type ReadonlyUint8Array, + SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, + SolanaError, + transformEncoder, + type WritableAccount, +} from "@solana/kit"; +import { getAccountMetaFactory, type ResolvedInstructionAccount } from "@solana/program-client-core"; +import { CAR_RENTAL_SERVICE_PROGRAM_ADDRESS } from "../programs"; + +export const BOOK_RENTAL_DISCRIMINATOR = 1; + +export function getBookRentalDiscriminatorBytes(): ReadonlyUint8Array { + return getU8Encoder().encode(BOOK_RENTAL_DISCRIMINATOR); +} + +export type BookRentalInstruction< + TProgram extends string = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, + TAccountRentalAccount extends string | AccountMeta = string, + TAccountCarAccount extends string | AccountMeta = string, + TAccountPayer extends string | AccountMeta = string, + TAccountSystemProgram extends string | AccountMeta = "11111111111111111111111111111111", + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRentalAccount extends string ? WritableAccount : TAccountRentalAccount, + TAccountCarAccount extends string ? ReadonlyAccount : TAccountCarAccount, + TAccountPayer extends string ? WritableAccount : TAccountPayer, + TAccountSystemProgram extends string ? ReadonlyAccount : TAccountSystemProgram, + ...TRemainingAccounts, + ] + >; + +export type BookRentalInstructionData = { + discriminator: number; + name: string; + pickUpDate: string; + returnDate: string; + price: bigint; +}; + +export type BookRentalInstructionDataArgs = { + name: string; + pickUpDate: string; + returnDate: string; + price: number | bigint; +}; + +export function getBookRentalInstructionDataEncoder(): Encoder { + return transformEncoder( + getStructEncoder([ + ["discriminator", getU8Encoder()], + ["name", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())], + ["pickUpDate", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())], + ["returnDate", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())], + ["price", getU64Encoder()], + ]), + (value) => ({ ...value, discriminator: BOOK_RENTAL_DISCRIMINATOR }), + ); +} + +export function getBookRentalInstructionDataDecoder(): Decoder { + return getStructDecoder([ + ["discriminator", getU8Decoder()], + ["name", addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())], + ["pickUpDate", addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())], + ["returnDate", addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())], + ["price", getU64Decoder()], + ]); +} + +export function getBookRentalInstructionDataCodec(): Codec { + return combineCodec(getBookRentalInstructionDataEncoder(), getBookRentalInstructionDataDecoder()); +} + +export type BookRentalInput< + TAccountRentalAccount extends string = string, + TAccountCarAccount extends string = string, + TAccountPayer extends string = string, + TAccountSystemProgram extends string = string, +> = { + /** The account that will represent the actual order for the rental */ + rentalAccount: Address; + /** The account representing the Car being rented in this order */ + carAccount: Address; + /** Fee payer */ + payer: Address; + /** The System Program */ + systemProgram?: Address; + name: BookRentalInstructionDataArgs["name"]; + pickUpDate: BookRentalInstructionDataArgs["pickUpDate"]; + returnDate: BookRentalInstructionDataArgs["returnDate"]; + price: BookRentalInstructionDataArgs["price"]; +}; + +export function getBookRentalInstruction< + TAccountRentalAccount extends string, + TAccountCarAccount extends string, + TAccountPayer extends string, + TAccountSystemProgram extends string, + TProgramAddress extends Address = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, +>( + input: BookRentalInput, + config?: { programAddress?: TProgramAddress }, +): BookRentalInstruction< + TProgramAddress, + TAccountRentalAccount, + TAccountCarAccount, + TAccountPayer, + TAccountSystemProgram +> { + // Program address. + const programAddress = config?.programAddress ?? CAR_RENTAL_SERVICE_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + rentalAccount: { value: input.rentalAccount ?? null, isWritable: true }, + carAccount: { value: input.carAccount ?? null, isWritable: false }, + payer: { value: input.payer ?? null, isWritable: true }, + systemProgram: { value: input.systemProgram ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.systemProgram.value) { + accounts.systemProgram.value = "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta("rentalAccount", accounts.rentalAccount), + getAccountMeta("carAccount", accounts.carAccount), + getAccountMeta("payer", accounts.payer), + getAccountMeta("systemProgram", accounts.systemProgram), + ], + data: getBookRentalInstructionDataEncoder().encode(args as BookRentalInstructionDataArgs), + programAddress, + } as BookRentalInstruction< + TProgramAddress, + TAccountRentalAccount, + TAccountCarAccount, + TAccountPayer, + TAccountSystemProgram + >); +} + +export type ParsedBookRentalInstruction< + TProgram extends string = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The account that will represent the actual order for the rental */ + rentalAccount: TAccountMetas[0]; + /** The account representing the Car being rented in this order */ + carAccount: TAccountMetas[1]; + /** Fee payer */ + payer: TAccountMetas[2]; + /** The System Program */ + systemProgram: TAccountMetas[3]; + }; + data: BookRentalInstructionData; +}; + +export function parseBookRentalInstruction( + instruction: Instruction & InstructionWithAccounts & InstructionWithData, +): ParsedBookRentalInstruction { + if (instruction.accounts.length < 4) { + throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, { + actualAccountMetas: instruction.accounts.length, + expectedAccountMetas: 4, + }); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + rentalAccount: getNextAccount(), + carAccount: getNextAccount(), + payer: getNextAccount(), + systemProgram: getNextAccount(), + }, + data: getBookRentalInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/instructions/index.ts b/tools/shank-and-codama/native/tests/generated/src/generated/instructions/index.ts new file mode 100644 index 00000000..818ee3c2 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/instructions/index.ts @@ -0,0 +1,12 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./addCar"; +export * from "./bookRental"; +export * from "./pickUpCar"; +export * from "./returnCar"; diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/instructions/pickUpCar.ts b/tools/shank-and-codama/native/tests/generated/src/generated/instructions/pickUpCar.ts new file mode 100644 index 00000000..a91a2ec0 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/instructions/pickUpCar.ts @@ -0,0 +1,163 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +import { + type AccountMeta, + type Address, + combineCodec, + type FixedSizeCodec, + type FixedSizeDecoder, + type FixedSizeEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + type Instruction, + type InstructionWithAccounts, + type InstructionWithData, + type ReadonlyAccount, + type ReadonlyUint8Array, + SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, + SolanaError, + transformEncoder, + type WritableAccount, +} from "@solana/kit"; +import { getAccountMetaFactory, type ResolvedInstructionAccount } from "@solana/program-client-core"; +import { CAR_RENTAL_SERVICE_PROGRAM_ADDRESS } from "../programs"; + +export const PICK_UP_CAR_DISCRIMINATOR = 2; + +export function getPickUpCarDiscriminatorBytes(): ReadonlyUint8Array { + return getU8Encoder().encode(PICK_UP_CAR_DISCRIMINATOR); +} + +export type PickUpCarInstruction< + TProgram extends string = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, + TAccountRentalAccount extends string | AccountMeta = string, + TAccountCarAccount extends string | AccountMeta = string, + TAccountPayer extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRentalAccount extends string ? WritableAccount : TAccountRentalAccount, + TAccountCarAccount extends string ? ReadonlyAccount : TAccountCarAccount, + TAccountPayer extends string ? WritableAccount : TAccountPayer, + ...TRemainingAccounts, + ] + >; + +export type PickUpCarInstructionData = { discriminator: number }; + +export type PickUpCarInstructionDataArgs = {}; + +export function getPickUpCarInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder(getStructEncoder([["discriminator", getU8Encoder()]]), (value) => ({ + ...value, + discriminator: PICK_UP_CAR_DISCRIMINATOR, + })); +} + +export function getPickUpCarInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([["discriminator", getU8Decoder()]]); +} + +export function getPickUpCarInstructionDataCodec(): FixedSizeCodec< + PickUpCarInstructionDataArgs, + PickUpCarInstructionData +> { + return combineCodec(getPickUpCarInstructionDataEncoder(), getPickUpCarInstructionDataDecoder()); +} + +export type PickUpCarInput< + TAccountRentalAccount extends string = string, + TAccountCarAccount extends string = string, + TAccountPayer extends string = string, +> = { + /** The account representing the active rental */ + rentalAccount: Address; + /** The account representing the Car being rented in this order */ + carAccount: Address; + /** Fee payer */ + payer: Address; +}; + +export function getPickUpCarInstruction< + TAccountRentalAccount extends string, + TAccountCarAccount extends string, + TAccountPayer extends string, + TProgramAddress extends Address = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, +>( + input: PickUpCarInput, + config?: { programAddress?: TProgramAddress }, +): PickUpCarInstruction { + // Program address. + const programAddress = config?.programAddress ?? CAR_RENTAL_SERVICE_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + rentalAccount: { value: input.rentalAccount ?? null, isWritable: true }, + carAccount: { value: input.carAccount ?? null, isWritable: false }, + payer: { value: input.payer ?? null, isWritable: true }, + }; + const accounts = originalAccounts as Record; + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta("rentalAccount", accounts.rentalAccount), + getAccountMeta("carAccount", accounts.carAccount), + getAccountMeta("payer", accounts.payer), + ], + data: getPickUpCarInstructionDataEncoder().encode({}), + programAddress, + } as PickUpCarInstruction); +} + +export type ParsedPickUpCarInstruction< + TProgram extends string = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The account representing the active rental */ + rentalAccount: TAccountMetas[0]; + /** The account representing the Car being rented in this order */ + carAccount: TAccountMetas[1]; + /** Fee payer */ + payer: TAccountMetas[2]; + }; + data: PickUpCarInstructionData; +}; + +export function parsePickUpCarInstruction( + instruction: Instruction & InstructionWithAccounts & InstructionWithData, +): ParsedPickUpCarInstruction { + if (instruction.accounts.length < 3) { + throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, { + actualAccountMetas: instruction.accounts.length, + expectedAccountMetas: 3, + }); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + rentalAccount: getNextAccount(), + carAccount: getNextAccount(), + payer: getNextAccount(), + }, + data: getPickUpCarInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/instructions/returnCar.ts b/tools/shank-and-codama/native/tests/generated/src/generated/instructions/returnCar.ts new file mode 100644 index 00000000..d3ec60a8 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/instructions/returnCar.ts @@ -0,0 +1,163 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +import { + type AccountMeta, + type Address, + combineCodec, + type FixedSizeCodec, + type FixedSizeDecoder, + type FixedSizeEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + type Instruction, + type InstructionWithAccounts, + type InstructionWithData, + type ReadonlyAccount, + type ReadonlyUint8Array, + SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, + SolanaError, + transformEncoder, + type WritableAccount, +} from "@solana/kit"; +import { getAccountMetaFactory, type ResolvedInstructionAccount } from "@solana/program-client-core"; +import { CAR_RENTAL_SERVICE_PROGRAM_ADDRESS } from "../programs"; + +export const RETURN_CAR_DISCRIMINATOR = 3; + +export function getReturnCarDiscriminatorBytes(): ReadonlyUint8Array { + return getU8Encoder().encode(RETURN_CAR_DISCRIMINATOR); +} + +export type ReturnCarInstruction< + TProgram extends string = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, + TAccountRentalAccount extends string | AccountMeta = string, + TAccountCarAccount extends string | AccountMeta = string, + TAccountPayer extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountRentalAccount extends string ? WritableAccount : TAccountRentalAccount, + TAccountCarAccount extends string ? ReadonlyAccount : TAccountCarAccount, + TAccountPayer extends string ? WritableAccount : TAccountPayer, + ...TRemainingAccounts, + ] + >; + +export type ReturnCarInstructionData = { discriminator: number }; + +export type ReturnCarInstructionDataArgs = {}; + +export function getReturnCarInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder(getStructEncoder([["discriminator", getU8Encoder()]]), (value) => ({ + ...value, + discriminator: RETURN_CAR_DISCRIMINATOR, + })); +} + +export function getReturnCarInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([["discriminator", getU8Decoder()]]); +} + +export function getReturnCarInstructionDataCodec(): FixedSizeCodec< + ReturnCarInstructionDataArgs, + ReturnCarInstructionData +> { + return combineCodec(getReturnCarInstructionDataEncoder(), getReturnCarInstructionDataDecoder()); +} + +export type ReturnCarInput< + TAccountRentalAccount extends string = string, + TAccountCarAccount extends string = string, + TAccountPayer extends string = string, +> = { + /** The account representing the active rental */ + rentalAccount: Address; + /** The account representing the Car being rented in this order */ + carAccount: Address; + /** Fee payer */ + payer: Address; +}; + +export function getReturnCarInstruction< + TAccountRentalAccount extends string, + TAccountCarAccount extends string, + TAccountPayer extends string, + TProgramAddress extends Address = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, +>( + input: ReturnCarInput, + config?: { programAddress?: TProgramAddress }, +): ReturnCarInstruction { + // Program address. + const programAddress = config?.programAddress ?? CAR_RENTAL_SERVICE_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + rentalAccount: { value: input.rentalAccount ?? null, isWritable: true }, + carAccount: { value: input.carAccount ?? null, isWritable: false }, + payer: { value: input.payer ?? null, isWritable: true }, + }; + const accounts = originalAccounts as Record; + + const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); + return Object.freeze({ + accounts: [ + getAccountMeta("rentalAccount", accounts.rentalAccount), + getAccountMeta("carAccount", accounts.carAccount), + getAccountMeta("payer", accounts.payer), + ], + data: getReturnCarInstructionDataEncoder().encode({}), + programAddress, + } as ReturnCarInstruction); +} + +export type ParsedReturnCarInstruction< + TProgram extends string = typeof CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The account representing the active rental */ + rentalAccount: TAccountMetas[0]; + /** The account representing the Car being rented in this order */ + carAccount: TAccountMetas[1]; + /** Fee payer */ + payer: TAccountMetas[2]; + }; + data: ReturnCarInstructionData; +}; + +export function parseReturnCarInstruction( + instruction: Instruction & InstructionWithAccounts & InstructionWithData, +): ParsedReturnCarInstruction { + if (instruction.accounts.length < 3) { + throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, { + actualAccountMetas: instruction.accounts.length, + expectedAccountMetas: 3, + }); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + return { + programAddress: instruction.programAddress, + accounts: { + rentalAccount: getNextAccount(), + carAccount: getNextAccount(), + payer: getNextAccount(), + }, + data: getReturnCarInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/programs/carRentalService.ts b/tools/shank-and-codama/native/tests/generated/src/generated/programs/carRentalService.ts new file mode 100644 index 00000000..f054d668 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/programs/carRentalService.ts @@ -0,0 +1,236 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +import { + type Address, + assertIsInstructionWithAccounts, + type ClientWithPayer, + type ClientWithRpc, + type ClientWithTransactionPlanning, + type ClientWithTransactionSending, + containsBytes, + extendClient, + type GetAccountInfoApi, + type GetMultipleAccountsApi, + getU8Encoder, + type Instruction, + type InstructionWithData, + type ReadonlyUint8Array, + SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION, + SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE, + SolanaError, +} from "@solana/kit"; +import { + addSelfFetchFunctions, + addSelfPlanAndSendFunctions, + type SelfFetchFunctions, + type SelfPlanAndSendFunctions, +} from "@solana/program-client-core"; +import { + type Car, + type CarArgs, + getCarCodec, + getRentalOrderCodec, + type RentalOrder, + type RentalOrderArgs, +} from "../accounts"; +import { + type AddCarInput, + type BookRentalInput, + getAddCarInstruction, + getBookRentalInstruction, + getPickUpCarInstruction, + getReturnCarInstruction, + type ParsedAddCarInstruction, + type ParsedBookRentalInstruction, + type ParsedPickUpCarInstruction, + type ParsedReturnCarInstruction, + type PickUpCarInput, + parseAddCarInstruction, + parseBookRentalInstruction, + parsePickUpCarInstruction, + parseReturnCarInstruction, + type ReturnCarInput, +} from "../instructions"; + +export const CAR_RENTAL_SERVICE_PROGRAM_ADDRESS = + "8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ" as Address<"8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ">; + +export enum CarRentalServiceAccount { + Car, + RentalOrder, +} + +export enum CarRentalServiceInstruction { + AddCar, + BookRental, + PickUpCar, + ReturnCar, +} + +export function identifyCarRentalServiceInstruction( + instruction: { data: ReadonlyUint8Array } | ReadonlyUint8Array, +): CarRentalServiceInstruction { + const data = "data" in instruction ? instruction.data : instruction; + if (containsBytes(data, getU8Encoder().encode(0), 0)) { + return CarRentalServiceInstruction.AddCar; + } + if (containsBytes(data, getU8Encoder().encode(1), 0)) { + return CarRentalServiceInstruction.BookRental; + } + if (containsBytes(data, getU8Encoder().encode(2), 0)) { + return CarRentalServiceInstruction.PickUpCar; + } + if (containsBytes(data, getU8Encoder().encode(3), 0)) { + return CarRentalServiceInstruction.ReturnCar; + } + throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION, { + instructionData: data, + programName: "carRentalService", + }); +} + +export type ParsedCarRentalServiceInstruction< + TProgram extends string = "8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ", +> = + | ({ + instructionType: CarRentalServiceInstruction.AddCar; + } & ParsedAddCarInstruction) + | ({ + instructionType: CarRentalServiceInstruction.BookRental; + } & ParsedBookRentalInstruction) + | ({ + instructionType: CarRentalServiceInstruction.PickUpCar; + } & ParsedPickUpCarInstruction) + | ({ + instructionType: CarRentalServiceInstruction.ReturnCar; + } & ParsedReturnCarInstruction); + +export function parseCarRentalServiceInstruction( + instruction: Instruction & InstructionWithData, +): ParsedCarRentalServiceInstruction { + const instructionType = identifyCarRentalServiceInstruction(instruction); + switch (instructionType) { + case CarRentalServiceInstruction.AddCar: { + assertIsInstructionWithAccounts(instruction); + return { + instructionType: CarRentalServiceInstruction.AddCar, + ...parseAddCarInstruction(instruction), + }; + } + case CarRentalServiceInstruction.BookRental: { + assertIsInstructionWithAccounts(instruction); + return { + instructionType: CarRentalServiceInstruction.BookRental, + ...parseBookRentalInstruction(instruction), + }; + } + case CarRentalServiceInstruction.PickUpCar: { + assertIsInstructionWithAccounts(instruction); + return { + instructionType: CarRentalServiceInstruction.PickUpCar, + ...parsePickUpCarInstruction(instruction), + }; + } + case CarRentalServiceInstruction.ReturnCar: { + assertIsInstructionWithAccounts(instruction); + return { + instructionType: CarRentalServiceInstruction.ReturnCar, + ...parseReturnCarInstruction(instruction), + }; + } + default: + throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE, { + instructionType: instructionType as string, + programName: "carRentalService", + }); + } +} + +export type CarRentalServicePlugin = { + accounts: CarRentalServicePluginAccounts; + instructions: CarRentalServicePluginInstructions; +}; + +export type CarRentalServicePluginAccounts = { + car: ReturnType & SelfFetchFunctions; + rentalOrder: ReturnType & SelfFetchFunctions; +}; + +export type CarRentalServicePluginInstructions = { + addCar: ( + input: MakeOptional, + ) => ReturnType & SelfPlanAndSendFunctions; + bookRental: ( + input: MakeOptional, + ) => ReturnType & SelfPlanAndSendFunctions; + pickUpCar: ( + input: MakeOptional, + ) => ReturnType & SelfPlanAndSendFunctions; + returnCar: ( + input: MakeOptional, + ) => ReturnType & SelfPlanAndSendFunctions; +}; + +export type CarRentalServicePluginRequirements = ClientWithRpc & + ClientWithPayer & + ClientWithTransactionPlanning & + ClientWithTransactionSending; + +export function carRentalServiceProgram() { + return ( + client: T, + ): Omit & { + carRentalService: CarRentalServicePlugin; + } => { + return extendClient(client, { + carRentalService: { + accounts: { + car: addSelfFetchFunctions(client, getCarCodec()), + rentalOrder: addSelfFetchFunctions(client, getRentalOrderCodec()), + }, + instructions: { + addCar: (input) => + addSelfPlanAndSendFunctions( + client, + getAddCarInstruction({ + ...input, + payer: input.payer ?? client.payer.address, + }), + ), + bookRental: (input) => + addSelfPlanAndSendFunctions( + client, + getBookRentalInstruction({ + ...input, + payer: input.payer ?? client.payer.address, + }), + ), + pickUpCar: (input) => + addSelfPlanAndSendFunctions( + client, + getPickUpCarInstruction({ + ...input, + payer: input.payer ?? client.payer.address, + }), + ), + returnCar: (input) => + addSelfPlanAndSendFunctions( + client, + getReturnCarInstruction({ + ...input, + payer: input.payer ?? client.payer.address, + }), + ), + }, + }, + }); + }; +} + +type MakeOptional = Omit & Partial>; diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/programs/index.ts b/tools/shank-and-codama/native/tests/generated/src/generated/programs/index.ts new file mode 100644 index 00000000..06d01a8d --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/programs/index.ts @@ -0,0 +1,9 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./carRentalService"; diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/types/index.ts b/tools/shank-and-codama/native/tests/generated/src/generated/types/index.ts new file mode 100644 index 00000000..df062dd9 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/types/index.ts @@ -0,0 +1,9 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +export * from "./rentalOrderStatus"; diff --git a/tools/shank-and-codama/native/tests/generated/src/generated/types/rentalOrderStatus.ts b/tools/shank-and-codama/native/tests/generated/src/generated/types/rentalOrderStatus.ts new file mode 100644 index 00000000..6034aec0 --- /dev/null +++ b/tools/shank-and-codama/native/tests/generated/src/generated/types/rentalOrderStatus.ts @@ -0,0 +1,36 @@ +/** + * This code was AUTOGENERATED using the Codama library. + * Please DO NOT EDIT THIS FILE, instead use visitors + * to add features, then rerun Codama to update it. + * + * @see https://github.com/codama-idl/codama + */ + +import { + combineCodec, + type FixedSizeCodec, + type FixedSizeDecoder, + type FixedSizeEncoder, + getEnumDecoder, + getEnumEncoder, +} from "@solana/kit"; + +export enum RentalOrderStatus { + Created, + PickedUp, + Returned, +} + +export type RentalOrderStatusArgs = RentalOrderStatus; + +export function getRentalOrderStatusEncoder(): FixedSizeEncoder { + return getEnumEncoder(RentalOrderStatus); +} + +export function getRentalOrderStatusDecoder(): FixedSizeDecoder { + return getEnumDecoder(RentalOrderStatus); +} + +export function getRentalOrderStatusCodec(): FixedSizeCodec { + return combineCodec(getRentalOrderStatusEncoder(), getRentalOrderStatusDecoder()); +} diff --git a/tools/shank-and-codama/native/tests/test.ts b/tools/shank-and-codama/native/tests/test.ts new file mode 100644 index 00000000..e74f8368 --- /dev/null +++ b/tools/shank-and-codama/native/tests/test.ts @@ -0,0 +1,141 @@ +// In-process integration test for the car rental service program. +// +// Runs entirely in CI with no network: the program `.so` is loaded into a +// LiteSVM instance and exercised through the Codama-generated client +// (tests/generated). It creates a car (add_car), books a rental +// (book_rental) and picks it up (pick_up_car), asserting on-chain account +// state after each step. + +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { test } from "node:test"; +import { fileURLToPath } from "node:url"; + +import { + type Address, + address, + appendTransactionMessageInstruction, + createTransactionMessage, + generateKeyPairSigner, + getAddressEncoder, + getProgramDerivedAddress, + getUtf8Encoder, + lamports, + pipe, + setTransactionMessageFeePayerSigner, + signTransactionMessageWithSigners, +} from "@solana/kit"; +import { FailedTransactionMetadata, LiteSVM } from "litesvm"; + +import { + CAR_RENTAL_SERVICE_PROGRAM_ADDRESS, + decodeCar, + decodeRentalOrder, + getAddCarInstruction, + getBookRentalInstruction, + getPickUpCarInstruction, + RentalOrderStatus, +} from "./generated/src/generated/index.ts"; + +const here = dirname(fileURLToPath(import.meta.url)); +const programSoPath = join(here, "..", "program", "target", "so", "car_rental_service.so"); + +const utf8 = getUtf8Encoder(); +const addressEncoder = getAddressEncoder(); + +function loadSvm(): { svm: LiteSVM; programId: Address } { + const svm = new LiteSVM(); + const programId = CAR_RENTAL_SERVICE_PROGRAM_ADDRESS; + svm.addProgram(programId, readFileSync(programSoPath)); + return { svm, programId }; +} + +async function carPda(programId: Address, make: string, model: string): Promise
{ + const [pda] = await getProgramDerivedAddress({ + programAddress: programId, + seeds: [utf8.encode("car"), utf8.encode(make), utf8.encode(model)], + }); + return pda; +} + +async function rentalPda(programId: Address, car: Address, payer: Address): Promise
{ + const [pda] = await getProgramDerivedAddress({ + programAddress: programId, + seeds: [utf8.encode("rental_order"), addressEncoder.encode(car), addressEncoder.encode(payer)], + }); + return pda; +} + +async function sendIx( + svm: LiteSVM, + payer: Awaited>, + // deno-lint-ignore no-explicit-any + ix: any, +) { + const tx = await pipe( + createTransactionMessage({ version: 0 }), + (m) => setTransactionMessageFeePayerSigner(payer, m), + (m) => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), + (m) => appendTransactionMessageInstruction(ix, m), + (m) => signTransactionMessageWithSigners(m), + ); + const result = svm.sendTransaction(tx); + if (result instanceof FailedTransactionMetadata) { + throw new Error(`Transaction failed: ${result.err()}\n${result.meta().logs().join("\n")}`); + } + return result; +} + +test("car rental service: add_car, book_rental, pick_up_car", async () => { + const { svm, programId } = loadSvm(); + + const payer = await generateKeyPairSigner(); + svm.airdrop(payer.address, lamports(10_000_000_000n)); + + // 1. add_car + const make = "BMW"; + const model = "iX1"; + const carAccount = await carPda(programId, make, model); + + await sendIx(svm, payer, getAddCarInstruction({ carAccount, payer, year: 2020, make, model })); + + const carRaw = svm.getAccount(carAccount); + assert.ok(carRaw?.exists, "car account should exist"); + const car = decodeCar(carRaw); + assert.equal(car.data.year, 2020); + assert.equal(car.data.make, make); + assert.equal(car.data.model, model); + + // 2. book_rental + const rentalAccount = await rentalPda(programId, carAccount, payer.address); + await sendIx( + svm, + payer, + getBookRentalInstruction({ + rentalAccount, + carAccount, + payer, + name: "Fred Flintstone", + pickUpDate: "01/28/2023 8:00 AM", + returnDate: "01/28/2023 10:00 PM", + price: 300, + }), + ); + + let rentalRaw = svm.getAccount(rentalAccount); + assert.ok(rentalRaw?.exists, "rental account should exist"); + let rental = decodeRentalOrder(rentalRaw); + assert.equal(rental.data.name, "Fred Flintstone"); + assert.equal(rental.data.car, carAccount); + assert.equal(rental.data.price, 300n); + assert.equal(rental.data.status, RentalOrderStatus.Created); + + // 3. pick_up_car + await sendIx(svm, payer, getPickUpCarInstruction({ rentalAccount, carAccount, payer: payer.address })); + + rentalRaw = svm.getAccount(rentalAccount); + assert.ok(rentalRaw?.exists, "rental account should still exist"); + rental = decodeRentalOrder(rentalRaw); + assert.equal(rental.data.status, RentalOrderStatus.PickedUp); +}); diff --git a/tools/shank-and-codama/native/tests/tsconfig.test.json b/tools/shank-and-codama/native/tests/tsconfig.test.json new file mode 100644 index 00000000..22bb5919 --- /dev/null +++ b/tools/shank-and-codama/native/tests/tsconfig.test.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "module": "esnext", + "moduleResolution": "bundler", + "target": "es2022", + "lib": ["es2022"], + "types": ["node"], + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "noEmit": true + }, + "include": ["./**/*.ts", "../codama.ts"] +} diff --git a/tools/shank-and-solita/native/.crates/.crates.toml b/tools/shank-and-solita/native/.crates/.crates.toml deleted file mode 100644 index 13c0b457..00000000 --- a/tools/shank-and-solita/native/.crates/.crates.toml +++ /dev/null @@ -1,2 +0,0 @@ -[v1] -"shank-cli 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = ["shank"] diff --git a/tools/shank-and-solita/native/.crates/.crates2.json b/tools/shank-and-solita/native/.crates/.crates2.json deleted file mode 100644 index f638b54c..00000000 --- a/tools/shank-and-solita/native/.crates/.crates2.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "installs": { - "shank-cli 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)": { - "version_req": "0.0.12", - "bins": ["shank"], - "features": [], - "all_features": false, - "no_default_features": false, - "profile": "release", - "target": "aarch64-apple-darwin", - "rustc": "rustc 1.66.1 (90743e729 2023-01-10)\nbinary: rustc\ncommit-hash: 90743e7298aca107ddaa0c202a4d3604e29bfeb6\ncommit-date: 2023-01-10\nhost: aarch64-apple-darwin\nrelease: 1.66.1\nLLVM version: 15.0.2\n" - } - } -} diff --git a/tools/shank-and-solita/native/.crates/bin/shank b/tools/shank-and-solita/native/.crates/bin/shank deleted file mode 100755 index 89c990f9..00000000 Binary files a/tools/shank-and-solita/native/.crates/bin/shank and /dev/null differ diff --git a/tools/shank-and-solita/native/.solitarc.js b/tools/shank-and-solita/native/.solitarc.js deleted file mode 100644 index a02dc623..00000000 --- a/tools/shank-and-solita/native/.solitarc.js +++ /dev/null @@ -1,14 +0,0 @@ -const path = require("node:path"); -const programDir = path.join(__dirname, "program"); -const idlDir = path.join(programDir, "idl"); -const sdkDir = path.join(__dirname, "tests", "generated"); -const binaryInstallDir = path.join(__dirname, ".crates"); - -module.exports = { - idlGenerator: "shank", - programName: "car_rental_service", - idlDir, - sdkDir, - binaryInstallDir, - programDir, -}; diff --git a/tools/shank-and-solita/native/README.md b/tools/shank-and-solita/native/README.md deleted file mode 100644 index 9fc8c550..00000000 --- a/tools/shank-and-solita/native/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# Shank and Solita - -The Metaplex team built **Shank** and **Solita** so that native Solana [programs](https://solana.com/docs/terminology#program) can have serialization and IDL support similar to [Anchor](https://solana.com/docs/terminology#anchor). - -## Shank - -[Shank](https://github.com/metaplex-foundation/shank) is a Rust crate that generates an IDL for your program. - -Mark a struct as an [account](https://solana.com/docs/terminology#account): - -```rust -#[derive(BorshDeserialize, BorshSerialize, Clone, ShankAccount)] -pub struct Car { - pub year: u16, - pub make: String, - pub model: String, -} -``` - -Mark an enum as your [instruction](https://solana.com/docs/terminology#instruction) set: - -```rust -#[derive(BorshDeserialize, BorshSerialize, Clone, ShankInstruction)] -pub enum CarRentalServiceInstruction { - AddCar(Car), - BookRental(RentalOrder), - PickUpCar, - ReturnCar, -} -``` - -Install the CLI and generate the IDL: - -```bash -cargo install shank-cli -shank idl -``` - -> Shank needs `declare_id!` in your program for the IDL generation to work: -> -> ```rust -> declare_id!("8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ"); -> ``` - -## Solita - -[Solita](https://github.com/metaplex-foundation/solita) is the JavaScript SDK generator. It turns your IDL into a TypeScript client. - -> Solita works with both Shank IDLs and Anchor IDLs. - -Install it: - -```bash -pnpm add -D @metaplex-foundation/solita -``` - -Then add a `.solitarc.js` at the example root: - -```javascript -const path = require("node:path"); -const programDir = path.join(__dirname, "program"); -const idlDir = path.join(programDir, "idl"); -const sdkDir = path.join(__dirname, "tests", "generated"); -const binaryInstallDir = path.join(__dirname, ".crates"); - -module.exports = { - idlGenerator: "shank", - programName: "car_rental_service", - idlDir, - sdkDir, - binaryInstallDir, - programDir, -}; -``` - -Generate the client: - -```bash -pnpm solita -``` - -The generated TypeScript lands in `tests/generated/`. diff --git a/tools/shank-and-solita/native/package.json b/tools/shank-and-solita/native/package.json deleted file mode 100644 index ec6f5867..00000000 --- a/tools/shank-and-solita/native/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "scripts": { - "test": "ts-mocha -p ./tests/tsconfig.test.json -t 1000000 ./tests/test.ts" - }, - "devDependencies": { - "@metaplex-foundation/solita": "^0.19.3", - "@types/chai": "^4.3.4", - "@types/mocha": "^10.0.1", - "chai": "^4.3.7", - "mocha": "^10.2.0", - "ts-mocha": "^10.0.0", - "typescript": "^4.9.4" - } -} diff --git a/tools/shank-and-solita/native/program/Cargo.toml b/tools/shank-and-solita/native/program/Cargo.toml deleted file mode 100644 index f5aa22b3..00000000 --- a/tools/shank-and-solita/native/program/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "car-rental-service" -version = "0.1.0" -edition = "2021" - -[dependencies] -borsh = "0.9.3" -borsh-derive = "0.9.3" -shank = "0.0.12" -solana-program = "1.14.13" - -[lib] -crate-type = ["cdylib", "lib"] diff --git a/tools/shank-and-solita/native/program/src/instructions/mod.rs b/tools/shank-and-solita/native/program/src/instructions/mod.rs deleted file mode 100644 index c03dd8a5..00000000 --- a/tools/shank-and-solita/native/program/src/instructions/mod.rs +++ /dev/null @@ -1,55 +0,0 @@ -pub mod add_car; -pub mod book_rental; -pub mod pick_up_car; -pub mod return_car; - -pub use add_car::*; -pub use book_rental::*; -pub use pick_up_car::*; -pub use return_car::*; - -use { - borsh::{ - BorshDeserialize, - BorshSerialize, - }, - shank::ShankInstruction, -}; - -#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankInstruction)] -pub enum CarRentalServiceInstruction { - - #[account(0, writable, name="car_account", - desc="The account that will represent the Car being created")] - #[account(1, writable, name="payer", - desc = "Fee payer")] - #[account(2, name="system_program", - desc = "The System Program")] - AddCar(AddCarArgs), - - #[account(0, writable, name="rental_account", - desc="The account that will represent the actual order for the rental")] - #[account(1, name="car_account", - desc="The account representing the Car being rented in this order")] - #[account(2, writable, name="payer", - desc = "Fee payer")] - #[account(3, name="system_program", - desc = "The System Program")] - BookRental(BookRentalArgs), - - #[account(0, writable, name="rental_account", - desc="The account representing the active rental")] - #[account(1, name="car_account", - desc="The account representing the Car being rented in this order")] - #[account(2, writable, name="payer", - desc = "Fee payer")] - PickUpCar, - - #[account(0, writable, name="rental_account", - desc="The account representing the active rental")] - #[account(1, name="car_account", - desc="The account representing the Car being rented in this order")] - #[account(2, writable, name="payer", - desc = "Fee payer")] - ReturnCar, -} \ No newline at end of file diff --git a/tools/shank-and-solita/native/program/src/state/mod.rs b/tools/shank-and-solita/native/program/src/state/mod.rs deleted file mode 100644 index 109f2af4..00000000 --- a/tools/shank-and-solita/native/program/src/state/mod.rs +++ /dev/null @@ -1,48 +0,0 @@ -use { - borsh::{ - BorshDeserialize, - BorshSerialize - }, - shank::ShankAccount, - solana_program::pubkey::Pubkey, -}; - -#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankAccount)] -#[seeds( - "car", - program_id, - make("The car's make", String), - model("The car's model", String), -)] -pub struct Car { - pub year: u16, - pub make: String, - pub model: String, -} - -#[derive(BorshDeserialize, BorshSerialize, Clone, Debug)] -pub enum RentalOrderStatus { - Created, - PickedUp, - Returned, -} - -#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, ShankAccount)] -#[seeds( - "rental_order", - program_id, - car_public_key("The car's public key", Pubkey), - payer_public_key("The payer's public key", Pubkey), -)] -pub struct RentalOrder { - pub car: Pubkey, - pub name: String, - pub pick_up_date: String, - pub return_date: String, - pub price: u64, - pub status: RentalOrderStatus, -} - -impl RentalOrder { - pub const SEED_PREFIX: &'static str = "rental_order"; -} diff --git a/tools/shank-and-solita/native/tests/generated/accounts/Car.ts b/tools/shank-and-solita/native/tests/generated/accounts/Car.ts deleted file mode 100644 index 9b046922..00000000 --- a/tools/shank-and-solita/native/tests/generated/accounts/Car.ts +++ /dev/null @@ -1,148 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -import * as beetSolana from "@metaplex-foundation/beet-solana"; -import * as web3 from "@solana/web3.js"; - -/** - * Arguments used to create {@link Car} - * @category Accounts - * @category generated - */ -export type CarArgs = { - year: number; - make: string; - model: string; -}; -/** - * Holds the data for the {@link Car} Account and provides de/serialization - * functionality for that data - * - * @category Accounts - * @category generated - */ -export class Car implements CarArgs { - private constructor( - readonly year: number, - readonly make: string, - readonly model: string, - ) {} - - /** - * Creates a {@link Car} instance from the provided args. - */ - static fromArgs(args: CarArgs) { - return new Car(args.year, args.make, args.model); - } - - /** - * Deserializes the {@link Car} from the data of the provided {@link web3.AccountInfo}. - * @returns a tuple of the account data and the offset up to which the buffer was read to obtain it. - */ - static fromAccountInfo(accountInfo: web3.AccountInfo, offset = 0): [Car, number] { - return Car.deserialize(accountInfo.data, offset); - } - - /** - * Retrieves the account info from the provided address and deserializes - * the {@link Car} from its data. - * - * @throws Error if no account info is found at the address or if deserialization fails - */ - static async fromAccountAddress( - connection: web3.Connection, - address: web3.PublicKey, - commitmentOrConfig?: web3.Commitment | web3.GetAccountInfoConfig, - ): Promise { - const accountInfo = await connection.getAccountInfo(address, commitmentOrConfig); - if (accountInfo == null) { - throw new Error(`Unable to find Car account at ${address}`); - } - return Car.fromAccountInfo(accountInfo, 0)[0]; - } - - /** - * Provides a {@link web3.Connection.getProgramAccounts} config builder, - * to fetch accounts matching filters that can be specified via that builder. - * - * @param programId - the program that owns the accounts we are filtering - */ - static gpaBuilder(programId: web3.PublicKey = new web3.PublicKey("8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ")) { - return beetSolana.GpaBuilder.fromStruct(programId, carBeet); - } - - /** - * Deserializes the {@link Car} from the provided data Buffer. - * @returns a tuple of the account data and the offset up to which the buffer was read to obtain it. - */ - static deserialize(buf: Buffer, offset = 0): [Car, number] { - return carBeet.deserialize(buf, offset); - } - - /** - * Serializes the {@link Car} into a Buffer. - * @returns a tuple of the created Buffer and the offset up to which the buffer was written to store it. - */ - serialize(): [Buffer, number] { - return carBeet.serialize(this); - } - - /** - * Returns the byteSize of a {@link Buffer} holding the serialized data of - * {@link Car} for the provided args. - * - * @param args need to be provided since the byte size for this account - * depends on them - */ - static byteSize(args: CarArgs) { - const instance = Car.fromArgs(args); - return carBeet.toFixedFromValue(instance).byteSize; - } - - /** - * Fetches the minimum balance needed to exempt an account holding - * {@link Car} data from rent - * - * @param args need to be provided since the byte size for this account - * depends on them - * @param connection used to retrieve the rent exemption information - */ - static async getMinimumBalanceForRentExemption( - args: CarArgs, - connection: web3.Connection, - commitment?: web3.Commitment, - ): Promise { - return connection.getMinimumBalanceForRentExemption(Car.byteSize(args), commitment); - } - - /** - * Returns a readable version of {@link Car} properties - * and can be used to convert to JSON and/or logging - */ - pretty() { - return { - year: this.year, - make: this.make, - model: this.model, - }; - } -} - -/** - * @category Accounts - * @category generated - */ -export const carBeet = new beet.FixableBeetStruct( - [ - ["year", beet.u16], - ["make", beet.utf8String], - ["model", beet.utf8String], - ], - Car.fromArgs, - "Car", -); diff --git a/tools/shank-and-solita/native/tests/generated/accounts/RentalOrder.ts b/tools/shank-and-solita/native/tests/generated/accounts/RentalOrder.ts deleted file mode 100644 index 45886160..00000000 --- a/tools/shank-and-solita/native/tests/generated/accounts/RentalOrder.ts +++ /dev/null @@ -1,171 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -import * as beetSolana from "@metaplex-foundation/beet-solana"; -import * as web3 from "@solana/web3.js"; -import { RentalOrderStatus, rentalOrderStatusBeet } from "../types/RentalOrderStatus"; - -/** - * Arguments used to create {@link RentalOrder} - * @category Accounts - * @category generated - */ -export type RentalOrderArgs = { - car: web3.PublicKey; - name: string; - pickUpDate: string; - returnDate: string; - price: beet.bignum; - status: RentalOrderStatus; -}; -/** - * Holds the data for the {@link RentalOrder} Account and provides de/serialization - * functionality for that data - * - * @category Accounts - * @category generated - */ -export class RentalOrder implements RentalOrderArgs { - private constructor( - readonly car: web3.PublicKey, - readonly name: string, - readonly pickUpDate: string, - readonly returnDate: string, - readonly price: beet.bignum, - readonly status: RentalOrderStatus, - ) {} - - /** - * Creates a {@link RentalOrder} instance from the provided args. - */ - static fromArgs(args: RentalOrderArgs) { - return new RentalOrder(args.car, args.name, args.pickUpDate, args.returnDate, args.price, args.status); - } - - /** - * Deserializes the {@link RentalOrder} from the data of the provided {@link web3.AccountInfo}. - * @returns a tuple of the account data and the offset up to which the buffer was read to obtain it. - */ - static fromAccountInfo(accountInfo: web3.AccountInfo, offset = 0): [RentalOrder, number] { - return RentalOrder.deserialize(accountInfo.data, offset); - } - - /** - * Retrieves the account info from the provided address and deserializes - * the {@link RentalOrder} from its data. - * - * @throws Error if no account info is found at the address or if deserialization fails - */ - static async fromAccountAddress( - connection: web3.Connection, - address: web3.PublicKey, - commitmentOrConfig?: web3.Commitment | web3.GetAccountInfoConfig, - ): Promise { - const accountInfo = await connection.getAccountInfo(address, commitmentOrConfig); - if (accountInfo == null) { - throw new Error(`Unable to find RentalOrder account at ${address}`); - } - return RentalOrder.fromAccountInfo(accountInfo, 0)[0]; - } - - /** - * Provides a {@link web3.Connection.getProgramAccounts} config builder, - * to fetch accounts matching filters that can be specified via that builder. - * - * @param programId - the program that owns the accounts we are filtering - */ - static gpaBuilder(programId: web3.PublicKey = new web3.PublicKey("8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ")) { - return beetSolana.GpaBuilder.fromStruct(programId, rentalOrderBeet); - } - - /** - * Deserializes the {@link RentalOrder} from the provided data Buffer. - * @returns a tuple of the account data and the offset up to which the buffer was read to obtain it. - */ - static deserialize(buf: Buffer, offset = 0): [RentalOrder, number] { - return rentalOrderBeet.deserialize(buf, offset); - } - - /** - * Serializes the {@link RentalOrder} into a Buffer. - * @returns a tuple of the created Buffer and the offset up to which the buffer was written to store it. - */ - serialize(): [Buffer, number] { - return rentalOrderBeet.serialize(this); - } - - /** - * Returns the byteSize of a {@link Buffer} holding the serialized data of - * {@link RentalOrder} for the provided args. - * - * @param args need to be provided since the byte size for this account - * depends on them - */ - static byteSize(args: RentalOrderArgs) { - const instance = RentalOrder.fromArgs(args); - return rentalOrderBeet.toFixedFromValue(instance).byteSize; - } - - /** - * Fetches the minimum balance needed to exempt an account holding - * {@link RentalOrder} data from rent - * - * @param args need to be provided since the byte size for this account - * depends on them - * @param connection used to retrieve the rent exemption information - */ - static async getMinimumBalanceForRentExemption( - args: RentalOrderArgs, - connection: web3.Connection, - commitment?: web3.Commitment, - ): Promise { - return connection.getMinimumBalanceForRentExemption(RentalOrder.byteSize(args), commitment); - } - - /** - * Returns a readable version of {@link RentalOrder} properties - * and can be used to convert to JSON and/or logging - */ - pretty() { - return { - car: this.car.toBase58(), - name: this.name, - pickUpDate: this.pickUpDate, - returnDate: this.returnDate, - price: (() => { - const x = <{ toNumber: () => number }>this.price; - if (typeof x.toNumber === "function") { - try { - return x.toNumber(); - } catch (_) { - return x; - } - } - return x; - })(), - status: `RentalOrderStatus.${RentalOrderStatus[this.status]}`, - }; - } -} - -/** - * @category Accounts - * @category generated - */ -export const rentalOrderBeet = new beet.FixableBeetStruct( - [ - ["car", beetSolana.publicKey], - ["name", beet.utf8String], - ["pickUpDate", beet.utf8String], - ["returnDate", beet.utf8String], - ["price", beet.u64], - ["status", rentalOrderStatusBeet], - ], - RentalOrder.fromArgs, - "RentalOrder", -); diff --git a/tools/shank-and-solita/native/tests/generated/accounts/index.ts b/tools/shank-and-solita/native/tests/generated/accounts/index.ts deleted file mode 100644 index 6b514469..00000000 --- a/tools/shank-and-solita/native/tests/generated/accounts/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from "./Car"; -export * from "./RentalOrder"; - -import { Car } from "./Car"; -import { RentalOrder } from "./RentalOrder"; - -export const accountProviders = { Car, RentalOrder }; diff --git a/tools/shank-and-solita/native/tests/generated/index.ts b/tools/shank-and-solita/native/tests/generated/index.ts deleted file mode 100644 index deb4a091..00000000 --- a/tools/shank-and-solita/native/tests/generated/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { PublicKey } from "@solana/web3.js"; - -export * from "./accounts"; -export * from "./instructions"; -export * from "./types"; - -/** - * Program address - * - * @category constants - * @category generated - */ -export const PROGRAM_ADDRESS = "8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ"; - -/** - * Program public key - * - * @category constants - * @category generated - */ -export const PROGRAM_ID = new PublicKey(PROGRAM_ADDRESS); diff --git a/tools/shank-and-solita/native/tests/generated/instructions/AddCar.ts b/tools/shank-and-solita/native/tests/generated/instructions/AddCar.ts deleted file mode 100644 index 38a644ed..00000000 --- a/tools/shank-and-solita/native/tests/generated/instructions/AddCar.ts +++ /dev/null @@ -1,96 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -import * as web3 from "@solana/web3.js"; -import { type AddCarArgs, addCarArgsBeet } from "../types/AddCarArgs"; - -/** - * @category Instructions - * @category AddCar - * @category generated - */ -export type AddCarInstructionArgs = { - addCarArgs: AddCarArgs; -}; -/** - * @category Instructions - * @category AddCar - * @category generated - */ -export const AddCarStruct = new beet.FixableBeetArgsStruct< - AddCarInstructionArgs & { - instructionDiscriminator: number; - } ->( - [ - ["instructionDiscriminator", beet.u8], - ["addCarArgs", addCarArgsBeet], - ], - "AddCarInstructionArgs", -); -/** - * Accounts required by the _AddCar_ instruction - * - * @property [_writable_] carAccount The account that will represent the Car being created - * @property [_writable_] payer Fee payer - * @category Instructions - * @category AddCar - * @category generated - */ -export type AddCarInstructionAccounts = { - carAccount: web3.PublicKey; - payer: web3.PublicKey; - systemProgram?: web3.PublicKey; -}; - -export const addCarInstructionDiscriminator = 0; - -/** - * Creates a _AddCar_ instruction. - * - * @param accounts that will be accessed while the instruction is processed - * @param args to provide as instruction data to the program - * - * @category Instructions - * @category AddCar - * @category generated - */ -export function createAddCarInstruction( - accounts: AddCarInstructionAccounts, - args: AddCarInstructionArgs, - programId = new web3.PublicKey("8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ"), -) { - const [data] = AddCarStruct.serialize({ - instructionDiscriminator: addCarInstructionDiscriminator, - ...args, - }); - const keys: web3.AccountMeta[] = [ - { - pubkey: accounts.carAccount, - isWritable: true, - isSigner: false, - }, - { - pubkey: accounts.payer, - isWritable: true, - isSigner: false, - }, - { - pubkey: accounts.systemProgram ?? web3.SystemProgram.programId, - isWritable: false, - isSigner: false, - }, - ]; - - const ix = new web3.TransactionInstruction({ - programId, - keys, - data, - }); - return ix; -} diff --git a/tools/shank-and-solita/native/tests/generated/instructions/BookRental.ts b/tools/shank-and-solita/native/tests/generated/instructions/BookRental.ts deleted file mode 100644 index 4b2ec9e2..00000000 --- a/tools/shank-and-solita/native/tests/generated/instructions/BookRental.ts +++ /dev/null @@ -1,103 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -import * as web3 from "@solana/web3.js"; -import { type BookRentalArgs, bookRentalArgsBeet } from "../types/BookRentalArgs"; - -/** - * @category Instructions - * @category BookRental - * @category generated - */ -export type BookRentalInstructionArgs = { - bookRentalArgs: BookRentalArgs; -}; -/** - * @category Instructions - * @category BookRental - * @category generated - */ -export const BookRentalStruct = new beet.FixableBeetArgsStruct< - BookRentalInstructionArgs & { - instructionDiscriminator: number; - } ->( - [ - ["instructionDiscriminator", beet.u8], - ["bookRentalArgs", bookRentalArgsBeet], - ], - "BookRentalInstructionArgs", -); -/** - * Accounts required by the _BookRental_ instruction - * - * @property [_writable_] rentalAccount The account that will represent the actual order for the rental - * @property [] carAccount The account representing the Car being rented in this order - * @property [_writable_] payer Fee payer - * @category Instructions - * @category BookRental - * @category generated - */ -export type BookRentalInstructionAccounts = { - rentalAccount: web3.PublicKey; - carAccount: web3.PublicKey; - payer: web3.PublicKey; - systemProgram?: web3.PublicKey; -}; - -export const bookRentalInstructionDiscriminator = 1; - -/** - * Creates a _BookRental_ instruction. - * - * @param accounts that will be accessed while the instruction is processed - * @param args to provide as instruction data to the program - * - * @category Instructions - * @category BookRental - * @category generated - */ -export function createBookRentalInstruction( - accounts: BookRentalInstructionAccounts, - args: BookRentalInstructionArgs, - programId = new web3.PublicKey("8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ"), -) { - const [data] = BookRentalStruct.serialize({ - instructionDiscriminator: bookRentalInstructionDiscriminator, - ...args, - }); - const keys: web3.AccountMeta[] = [ - { - pubkey: accounts.rentalAccount, - isWritable: true, - isSigner: false, - }, - { - pubkey: accounts.carAccount, - isWritable: false, - isSigner: false, - }, - { - pubkey: accounts.payer, - isWritable: true, - isSigner: false, - }, - { - pubkey: accounts.systemProgram ?? web3.SystemProgram.programId, - isWritable: false, - isSigner: false, - }, - ]; - - const ix = new web3.TransactionInstruction({ - programId, - keys, - data, - }); - return ix; -} diff --git a/tools/shank-and-solita/native/tests/generated/instructions/PickUpCar.ts b/tools/shank-and-solita/native/tests/generated/instructions/PickUpCar.ts deleted file mode 100644 index 329a6fce..00000000 --- a/tools/shank-and-solita/native/tests/generated/instructions/PickUpCar.ts +++ /dev/null @@ -1,76 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -import * as web3 from "@solana/web3.js"; - -/** - * @category Instructions - * @category PickUpCar - * @category generated - */ -export const PickUpCarStruct = new beet.BeetArgsStruct<{ - instructionDiscriminator: number; -}>([["instructionDiscriminator", beet.u8]], "PickUpCarInstructionArgs"); -/** - * Accounts required by the _PickUpCar_ instruction - * - * @property [_writable_] rentalAccount The account representing the active rental - * @property [] carAccount The account representing the Car being rented in this order - * @property [_writable_] payer Fee payer - * @category Instructions - * @category PickUpCar - * @category generated - */ -export type PickUpCarInstructionAccounts = { - rentalAccount: web3.PublicKey; - carAccount: web3.PublicKey; - payer: web3.PublicKey; -}; - -export const pickUpCarInstructionDiscriminator = 2; - -/** - * Creates a _PickUpCar_ instruction. - * - * @param accounts that will be accessed while the instruction is processed - * @category Instructions - * @category PickUpCar - * @category generated - */ -export function createPickUpCarInstruction( - accounts: PickUpCarInstructionAccounts, - programId = new web3.PublicKey("8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ"), -) { - const [data] = PickUpCarStruct.serialize({ - instructionDiscriminator: pickUpCarInstructionDiscriminator, - }); - const keys: web3.AccountMeta[] = [ - { - pubkey: accounts.rentalAccount, - isWritable: true, - isSigner: false, - }, - { - pubkey: accounts.carAccount, - isWritable: false, - isSigner: false, - }, - { - pubkey: accounts.payer, - isWritable: true, - isSigner: false, - }, - ]; - - const ix = new web3.TransactionInstruction({ - programId, - keys, - data, - }); - return ix; -} diff --git a/tools/shank-and-solita/native/tests/generated/instructions/ReturnCar.ts b/tools/shank-and-solita/native/tests/generated/instructions/ReturnCar.ts deleted file mode 100644 index 1a7dc0e0..00000000 --- a/tools/shank-and-solita/native/tests/generated/instructions/ReturnCar.ts +++ /dev/null @@ -1,76 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -import * as web3 from "@solana/web3.js"; - -/** - * @category Instructions - * @category ReturnCar - * @category generated - */ -export const ReturnCarStruct = new beet.BeetArgsStruct<{ - instructionDiscriminator: number; -}>([["instructionDiscriminator", beet.u8]], "ReturnCarInstructionArgs"); -/** - * Accounts required by the _ReturnCar_ instruction - * - * @property [_writable_] rentalAccount The account representing the active rental - * @property [] carAccount The account representing the Car being rented in this order - * @property [_writable_] payer Fee payer - * @category Instructions - * @category ReturnCar - * @category generated - */ -export type ReturnCarInstructionAccounts = { - rentalAccount: web3.PublicKey; - carAccount: web3.PublicKey; - payer: web3.PublicKey; -}; - -export const returnCarInstructionDiscriminator = 3; - -/** - * Creates a _ReturnCar_ instruction. - * - * @param accounts that will be accessed while the instruction is processed - * @category Instructions - * @category ReturnCar - * @category generated - */ -export function createReturnCarInstruction( - accounts: ReturnCarInstructionAccounts, - programId = new web3.PublicKey("8avNGHVXDwsELJaWMSoUZ44CirQd4zyU9Ez4ZmP4jNjZ"), -) { - const [data] = ReturnCarStruct.serialize({ - instructionDiscriminator: returnCarInstructionDiscriminator, - }); - const keys: web3.AccountMeta[] = [ - { - pubkey: accounts.rentalAccount, - isWritable: true, - isSigner: false, - }, - { - pubkey: accounts.carAccount, - isWritable: false, - isSigner: false, - }, - { - pubkey: accounts.payer, - isWritable: true, - isSigner: false, - }, - ]; - - const ix = new web3.TransactionInstruction({ - programId, - keys, - data, - }); - return ix; -} diff --git a/tools/shank-and-solita/native/tests/generated/instructions/index.ts b/tools/shank-and-solita/native/tests/generated/instructions/index.ts deleted file mode 100644 index f1522543..00000000 --- a/tools/shank-and-solita/native/tests/generated/instructions/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./AddCar"; -export * from "./BookRental"; -export * from "./PickUpCar"; -export * from "./ReturnCar"; diff --git a/tools/shank-and-solita/native/tests/generated/types/AddCarArgs.ts b/tools/shank-and-solita/native/tests/generated/types/AddCarArgs.ts deleted file mode 100644 index 72be6064..00000000 --- a/tools/shank-and-solita/native/tests/generated/types/AddCarArgs.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -export type AddCarArgs = { - year: number; - make: string; - model: string; -}; - -/** - * @category userTypes - * @category generated - */ -export const addCarArgsBeet = new beet.FixableBeetArgsStruct( - [ - ["year", beet.u16], - ["make", beet.utf8String], - ["model", beet.utf8String], - ], - "AddCarArgs", -); diff --git a/tools/shank-and-solita/native/tests/generated/types/BookRentalArgs.ts b/tools/shank-and-solita/native/tests/generated/types/BookRentalArgs.ts deleted file mode 100644 index f236b7ef..00000000 --- a/tools/shank-and-solita/native/tests/generated/types/BookRentalArgs.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -export type BookRentalArgs = { - name: string; - pickUpDate: string; - returnDate: string; - price: beet.bignum; -}; - -/** - * @category userTypes - * @category generated - */ -export const bookRentalArgsBeet = new beet.FixableBeetArgsStruct( - [ - ["name", beet.utf8String], - ["pickUpDate", beet.utf8String], - ["returnDate", beet.utf8String], - ["price", beet.u64], - ], - "BookRentalArgs", -); diff --git a/tools/shank-and-solita/native/tests/generated/types/RentalOrderStatus.ts b/tools/shank-and-solita/native/tests/generated/types/RentalOrderStatus.ts deleted file mode 100644 index 66d5f5a1..00000000 --- a/tools/shank-and-solita/native/tests/generated/types/RentalOrderStatus.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -/** - * @category enums - * @category generated - */ -export enum RentalOrderStatus { - Created = 0, - PickedUp = 1, - Returned = 2, -} - -/** - * @category userTypes - * @category generated - */ -export const rentalOrderStatusBeet = beet.fixedScalarEnum(RentalOrderStatus) as beet.FixedSizeBeet< - RentalOrderStatus, - RentalOrderStatus ->; diff --git a/tools/shank-and-solita/native/tests/generated/types/index.ts b/tools/shank-and-solita/native/tests/generated/types/index.ts deleted file mode 100644 index dc2300b8..00000000 --- a/tools/shank-and-solita/native/tests/generated/types/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./AddCarArgs"; -export * from "./BookRentalArgs"; -export * from "./RentalOrderStatus"; diff --git a/tools/shank-and-solita/native/tests/test.ts b/tools/shank-and-solita/native/tests/test.ts deleted file mode 100644 index b1ab61ac..00000000 --- a/tools/shank-and-solita/native/tests/test.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { Connection, Keypair, PublicKey, SystemProgram, sendAndConfirmTransaction, Transaction } from "@solana/web3.js"; -import { describe, it } from "mocha"; -import { - type AddCarArgs, - Car, - createAddCarInstruction, - createBookRentalInstruction, - createPickUpCarInstruction, - createReturnCarInstruction, - RentalOrder, - RentalOrderStatus, -} from "./generated"; - -function loadKeypairFromFile(path: string): Keypair { - return Keypair.fromSecretKey(Buffer.from(JSON.parse(require("node:fs").readFileSync(path, "utf-8")))); -} - -const carBmw: AddCarArgs = { - year: 2020, - make: "BMW", - model: "iX1", -}; - -const carMercedes: AddCarArgs = { - year: 2019, - make: "Mercedes-Benz", - model: "EQS", -}; - -const rentalInfo = { - name: "Fred Flinstone", - pickUpDate: "01/28/2023 8:00 AM", - returnDate: "01/28/2023 10:00 PM", - price: 300, -}; - -describe("Car Rental Service", () => { - const connection = new Connection("https://api.devnet.solana.com", "confirmed"); - const payer = loadKeypairFromFile(`${require("node:os").homedir()}/.config/solana/id.json`); - const program = loadKeypairFromFile("./program/target/deploy/car_rental_service-keypair.json"); - - let bmwPublicKey: PublicKey; - let _mercedesPublicKey: PublicKey; - - async function createCar(car: AddCarArgs): Promise { - const carAccountPublicKey = PublicKey.findProgramAddressSync( - [Buffer.from("car"), Buffer.from(car.make), Buffer.from(car.model)], - program.publicKey, - )[0]; - const ix = createAddCarInstruction( - { - carAccount: carAccountPublicKey, - payer: payer.publicKey, - systemProgram: SystemProgram.programId, - }, - { addCarArgs: { ...car } }, - ); - const sx = await sendAndConfirmTransaction(connection, new Transaction().add(ix), [payer], { skipPreflight: true }); - await connection.confirmTransaction(sx); - const carData = await Car.fromAccountAddress(connection, carAccountPublicKey); - console.log("New car created:"); - console.log(` Year : ${carData.year}`); - console.log(` Make : ${carData.make}`); - console.log(` Model : ${carData.model}`); - return carAccountPublicKey; - } - - it("Create a car that can be rented", async () => { - bmwPublicKey = await createCar(carBmw); - }); - it("Create another car that can be rented", async () => { - _mercedesPublicKey = await createCar(carMercedes); - }); - - const evaluateStatus = (status: RentalOrderStatus): string => { - if (status === RentalOrderStatus.Created) return "Created"; - if (status === RentalOrderStatus.PickedUp) return "Picked Up"; - return "Returned"; - }; - - async function printRentalDetails(rentalPublicKey: PublicKey, carPublicKey: PublicKey) { - const rentalData = await RentalOrder.fromAccountAddress(connection, rentalPublicKey); - const carData = await Car.fromAccountAddress(connection, carPublicKey); - console.log("Rental booked:"); - console.log(" Vehicle details:"); - console.log(` Year : ${carData.year}`); - console.log(` Make : ${carData.make}`); - console.log(` Model : ${carData.model}`); - console.log(` Name : ${rentalData.name}`); - console.log(` Pick Up : ${rentalData.pickUpDate}`); - console.log(` Return : ${rentalData.returnDate}`); - console.log(` Price : ${rentalData.price}`); - console.log(` Status : ${evaluateStatus(rentalData.status)}`); - } - - it("Book a new rental", async () => { - const rentalAccountPublicKey = PublicKey.findProgramAddressSync( - [Buffer.from("rental_order"), bmwPublicKey.toBuffer(), payer.publicKey.toBuffer()], - program.publicKey, - )[0]; - const ix = createBookRentalInstruction( - { - rentalAccount: rentalAccountPublicKey, - carAccount: bmwPublicKey, - payer: payer.publicKey, - systemProgram: SystemProgram.programId, - }, - { - bookRentalArgs: { ...rentalInfo }, - }, - ); - const sx = await sendAndConfirmTransaction(connection, new Transaction().add(ix), [payer]); - await connection.confirmTransaction(sx); - await printRentalDetails(rentalAccountPublicKey, bmwPublicKey); - }); - - it("Pick up your rental car", async () => { - const rentalAccountPublicKey = PublicKey.findProgramAddressSync( - [Buffer.from("rental_order"), bmwPublicKey.toBuffer(), payer.publicKey.toBuffer()], - program.publicKey, - )[0]; - const ix = createPickUpCarInstruction({ - rentalAccount: rentalAccountPublicKey, - carAccount: bmwPublicKey, - payer: payer.publicKey, - }); - const sx = await sendAndConfirmTransaction(connection, new Transaction().add(ix), [payer]); - await connection.confirmTransaction(sx); - await printRentalDetails(rentalAccountPublicKey, bmwPublicKey); - }); - - it("Return your rental car", async () => { - const rentalAccountPublicKey = PublicKey.findProgramAddressSync( - [Buffer.from("rental_order"), bmwPublicKey.toBuffer(), payer.publicKey.toBuffer()], - program.publicKey, - )[0]; - const ix = createReturnCarInstruction({ - rentalAccount: rentalAccountPublicKey, - carAccount: bmwPublicKey, - payer: payer.publicKey, - }); - const sx = await sendAndConfirmTransaction(connection, new Transaction().add(ix), [payer]); - await connection.confirmTransaction(sx); - await printRentalDetails(rentalAccountPublicKey, bmwPublicKey); - }); -}); diff --git a/tools/shank-and-solita/native/tests/tsconfig.test.json b/tools/shank-and-solita/native/tests/tsconfig.test.json deleted file mode 100644 index cd5d2e3d..00000000 --- a/tools/shank-and-solita/native/tests/tsconfig.test.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -}