diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index adf82ad085..1a1ca3ff81 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -234,6 +234,36 @@ jobs: - run: cd tests/bpf-upgradeable-state && solana program deploy --program-id program_with_different_programdata.json target/deploy/bpf_upgradeable_state.so - run: cd tests/bpf-upgradeable-state && cp bpf_upgradeable_state-keypair.json target/deploy/bpf_upgradeable_state-keypair.json && anchor deploy && anchor test --skip-deploy --skip-build --skip-lint + test-anchor-init: + needs: setup-anchor-cli + name: Test Anchor Init + runs-on: ubuntu-18.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v2 + - uses: ./.github/actions/setup/ + - uses: ./.github/actions/setup-ts/ + - uses: ./.github/actions/setup-solana/ + + - uses: actions/cache@v2 + name: Cache Cargo registry + index + id: cache-anchor + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ./target/ + key: cargo-${{ runner.os }}-anchor-${{ hashFiles('**/Cargo.lock') }} + + - uses: actions/download-artifact@v2 + with: + name: anchor-binary + path: ~/.cargo/bin/ + + - run: cd "$(mktemp -d)" && anchor init hello-anchor && cd hello-anchor && anchor test + test-programs: needs: setup-anchor-cli name: Test ${{ matrix.node.path }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fae7fbaf2..e72199a1b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,23 @@ incremented for features. ## [Unreleased] +### Features + +* lang: Add new `AccountSysvarMismatch` error code and test cases for sysvars ([#1535](https://github.com/project-serum/anchor/pull/1535)). +* spl: Add support for revoke instruction ([#1493](https://github.com/project-serum/anchor/pull/1493)). + +### Fixes + +* ts: Fix the loss of strict typing using the `methods` namespace on builder functions ([#1539](https://github.com/project-serum/anchor/pull/1539)). + +### Breaking + +* ts: Mark `transaction`, `instruction`, `simulate` and `rpc` program namespaces as deprecated in favor of `methods` ([#1539](https://github.com/project-serum/anchor/pull/1539)). +* ts: No longer allow manual setting of globally resolvable program public keys in `methods#accounts()`. ([#1548][https://github.com/project-serum/anchor/pull/1548]) +* lang: Remove space calculation using [`#[derive(Default)]`] (https://github.com/project-serum/anchor/pull/1519). + +## [0.22.1] - 2022-02-28 + ### Fixes * cli: Fix rust template ([#1488](https://github.com/project-serum/anchor/pull/1488)). @@ -38,7 +55,7 @@ This change will break most programs. Do the following to upgrade: * change all `ProgramResult`'s to `Result<()>` * change `#[error]` to `#[error_code]` * change all `Err(MyError::SomeError.into())` to `Err(error!(MyError::SomeError))` and all `Err(ProgramError::SomeProgramError)` to `Err(ProgramError::SomeProgramError.into())` or `Err(Error::from(ProgramError::SomeProgramError).with_source(source!()))` to provide file and line source of the error (`with_source` is most useful with `ProgramError`s. `error!` already adds source information for custom and anchor internal errors). - * change all `solana_program::program::invoke()` to `solana_program::program::invoke().map_err(Into::into)` and `solana_program::program::invoke_signed()` to `solana_program::program::invoke().map_err(Into::into)` + * change all `solana_program::program::invoke()` to `solana_program::program::invoke().map_err(Into::into)` and `solana_program::program::invoke_signed()` to `solana_program::program::invoke_signed().map_err(Into::into)` ## [0.21.0] - 2022-02-07 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bef20c82d4..c9e19cab6b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,12 +4,37 @@ Thank you for your interest in contributing to Anchor! All contributions are wel matter how big or small. This includes (but is not limited to) filing issues, adding documentation, fixing bugs, creating examples, and implementing features. -If you'd like to contribute, please claim an issue by commenting, forking, and -opening a pull request, even if empty. This allows the maintainers to track who -is working on what issue as to not overlap work. If you're looking to get started, +## Finding issues to work on + +If you're looking to get started, check out [good first issues](https://github.com/project-serum/anchor/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) or issues where [help is wanted](https://github.com/project-serum/anchor/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). -For simple documentation changes, feel free to just open a pull request. +For simple documentation changes or typos, feel free to just open a pull request. If you're considering larger changes or self motivated features, please file an issue -and engage with the maintainers in [Discord](https://discord.com/channels/889577356681945098). +and engage with the maintainers in [Discord](https://discord.gg/sxy4zxBckh). + +## Choosing an issue + +If you'd like to contribute, please claim an issue by commenting, forking, and +opening a pull request, even if empty. This allows the maintainers to track who +is working on what issue as to not overlap work. + +## Issue Guidelines + +Please follow these guidelines: + +Before coding: +- choose a branch name that describes the issue you're working on + +While coding: +- Submit a draft PR asap +- Only change code directly relevant to your PR. Sometimes you might find some code that could really need some refactoring. However, if it's not relevant to your PR, do not touch it. File an issue instead. This allows the reviewer to focus on a single problem at a time. +- If you write comments, do not exceed 80 chars per line. This allows contributors who work with multiple open windows to still read the comments without horizontally scrolling. +- Write adversarial tests. For example, if you're adding a new account type, do not only write tests where the instruction succeeds. Also write tests that test whether the instruction fails, if a check inside the new type is violated. + +After coding: +- If you've moved code around, build the docs with `cargo doc --open` and adjust broken links +- Adjust the cli templates if necessary +- If you made a change to anchor's periphery (avm or cli), make a PR to the `anchor-book` repo if necessary +- If you've added a new folder to the `tests` directory, add it to the [CI](./.github/workflows/tests.yaml). \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 5953bc228e..2245d33e05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ checksum = "6b2d54853319fd101b8dd81de382bcbf3e03410a64d8928bbee85a3e7dcde483" [[package]] name = "anchor-attribute-access-control" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -68,7 +68,7 @@ dependencies = [ [[package]] name = "anchor-attribute-account" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -81,7 +81,7 @@ dependencies = [ [[package]] name = "anchor-attribute-constant" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "proc-macro2 1.0.32", @@ -90,7 +90,7 @@ dependencies = [ [[package]] name = "anchor-attribute-error" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "proc-macro2 1.0.32", @@ -100,7 +100,7 @@ dependencies = [ [[package]] name = "anchor-attribute-event" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -111,7 +111,7 @@ dependencies = [ [[package]] name = "anchor-attribute-interface" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -123,7 +123,7 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -134,7 +134,7 @@ dependencies = [ [[package]] name = "anchor-attribute-state" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "anchor-cli" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-client", "anchor-lang", @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "anchor-client" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-lang", "anyhow", @@ -193,7 +193,7 @@ dependencies = [ [[package]] name = "anchor-derive-accounts" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -204,7 +204,7 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -226,7 +226,7 @@ dependencies = [ [[package]] name = "anchor-spl" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-lang", "serum_dex", @@ -237,7 +237,7 @@ dependencies = [ [[package]] name = "anchor-syn" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anyhow", "bs58 0.3.1", @@ -304,7 +304,7 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "avm" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anyhow", "cfg-if 1.0.0", diff --git a/README.md b/README.md index 7b4685beb0..5c2945a736 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ If you're familiar with developing in Ethereum's [Solidity](https://docs.solidit ## Getting Started -For a quickstart guide and in depth tutorials, see the guided [documentation](https://project-serum.github.io/anchor/getting-started/introduction.html). +For a quickstart guide and in depth tutorials, see the [anchor book](https://book.anchor-lang.com) and the older [documentation](https://project-serum.github.io/anchor/getting-started/introduction.html) that is being phased out. To jump straight to examples, go [here](https://github.com/project-serum/anchor/tree/master/examples). For the latest Rust and TypeScript API documentation, see [docs.rs](https://docs.rs/anchor-lang) and the [typedoc](https://project-serum.github.io/anchor/ts/index.html). ## Packages @@ -58,14 +58,14 @@ declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); mod counter { use super::*; - pub fn initialize(ctx: Context, start: u64) -> ProgramResult { + pub fn initialize(ctx: Context, start: u64) -> Result<()> { let counter = &mut ctx.accounts.counter; counter.authority = *ctx.accounts.authority.key; counter.count = start; Ok(()) } - pub fn increment(ctx: Context) -> ProgramResult { + pub fn increment(ctx: Context) -> Result<()> { let counter = &mut ctx.accounts.counter; counter.count += 1; Ok(()) @@ -107,19 +107,8 @@ licensed as above, without any additional terms or conditions. ## Contribution -Thank you for your interest in contributing to Anchor! All contributions are welcome no -matter how big or small. This includes (but is not limited to) filing issues, -adding documentation, fixing bugs, creating examples, and implementing features. - -If you'd like to contribute, please claim an issue by commenting, forking, and -opening a pull request, even if empty. This allows the maintainers to track who -is working on what issue as to not overlap work. If you're looking to get started, -check out [good first issues](https://github.com/project-serum/anchor/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) -or issues where [help is wanted](https://github.com/project-serum/anchor/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). -For simple documentation changes, feel free to just open a pull request. - -If you're considering larger changes or self motivated features, please file an issue -and engage with the maintainers in [Discord](https://discord.gg/sxy4zxBckh). +Thank you for your interest in contributing to Anchor! +Please see the [CONTRIBUTING.md](./CONTRIBUTING.md) to learn how. ### Thanks ❤️ diff --git a/VERSION b/VERSION index 2157409059..a723ece79b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.22.0 +0.22.1 diff --git a/avm/Cargo.toml b/avm/Cargo.toml index e7f3b8d9a7..c799601e0b 100644 --- a/avm/Cargo.toml +++ b/avm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "avm" -version = "0.22.0" +version = "0.22.1" edition = "2018" [[bin]] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index ecd31b6017..93143242f2 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-cli" -version = "0.22.0" +version = "0.22.1" authors = ["armaniferrante "] edition = "2018" diff --git a/cli/npm-package/package.json b/cli/npm-package/package.json index 510fdec708..9b4d6e7eb0 100644 --- a/cli/npm-package/package.json +++ b/cli/npm-package/package.json @@ -1,6 +1,6 @@ { "name": "@project-serum/anchor-cli", - "version": "0.22.0", + "version": "0.22.1", "description": "Anchor CLI tool", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/cli/src/template.rs b/cli/src/template.rs index 4d1d0806d4..78ae2f5235 100644 --- a/cli/src/template.rs +++ b/cli/src/template.rs @@ -237,6 +237,7 @@ pub fn ts_package_json() -> String { "chai": "^4.3.4", "mocha": "^9.0.3", "ts-mocha": "^8.0.0", + "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", "typescript": "^4.3.5" }} diff --git a/client/Cargo.toml b/client/Cargo.toml index b340390577..ee05ffca4f 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-client" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] edition = "2018" license = "Apache-2.0" @@ -10,7 +10,7 @@ description = "Rust client for Anchor programs" debug = [] [dependencies] -anchor-lang = { path = "../lang", version = "0.22.0" } +anchor-lang = { path = "../lang", version = "0.22.1" } anyhow = "1.0.32" regex = "1.4.5" serde = { version = "1.0.122", features = ["derive"] } diff --git a/docs/src/getting-started/installation.md b/docs/src/getting-started/installation.md index 3759de814d..37edaa4d54 100644 --- a/docs/src/getting-started/installation.md +++ b/docs/src/getting-started/installation.md @@ -44,7 +44,7 @@ npm i -g @project-serum/anchor-cli For now, we can use Cargo to install the CLI. ```bash -cargo install --git https://github.com/project-serum/anchor --tag v0.22.0 anchor-cli --locked +cargo install --git https://github.com/project-serum/anchor --tag v0.22.1 anchor-cli --locked ``` On Linux systems you may need to install additional dependencies if `cargo install` fails. On Ubuntu, diff --git a/docs/src/getting-started/publishing.md b/docs/src/getting-started/publishing.md index 35a3c0fe85..0278b581a9 100644 --- a/docs/src/getting-started/publishing.md +++ b/docs/src/getting-started/publishing.md @@ -30,7 +30,7 @@ have an `Anchor.toml` to define the build. An example `Anchor.toml` config looks as follows, ```toml -anchor_version = "0.22.0" +anchor_version = "0.22.1" [workspace] members = ["programs/multisig"] diff --git a/docs/src/getting-started/verification.md b/docs/src/getting-started/verification.md index 9b72a68b35..d041e847f9 100644 --- a/docs/src/getting-started/verification.md +++ b/docs/src/getting-started/verification.md @@ -32,10 +32,10 @@ If the program has an IDL, it will also check the IDL deployed on chain matches. ## Images -A docker image for each version of Anchor is published on [Docker Hub](https://hub.docker.com/r/projectserum/build). They are tagged in the form `projectserum/build:`. For example, to get the image for Anchor `v0.22.0` one can run +A docker image for each version of Anchor is published on [Docker Hub](https://hub.docker.com/r/projectserum/build). They are tagged in the form `projectserum/build:`. For example, to get the image for Anchor `v0.22.1` one can run ``` -docker pull projectserum/build:v0.22.0 +docker pull projectserum/build:v0.22.1 ``` ## Removing an Image diff --git a/docs/src/tutorials/tutorial-2.md b/docs/src/tutorials/tutorial-2.md index af9a1e2971..e337d2a1ee 100644 --- a/docs/src/tutorials/tutorial-2.md +++ b/docs/src/tutorials/tutorial-2.md @@ -13,7 +13,7 @@ To address these problems, Anchor provides several types, traits, and macros. It from the untrusted `&[AccountInfo]` slice given to a Solana program into a validated struct of deserialized account types. - [#[account]](https://docs.rs/anchor-lang/latest/anchor_lang/attr.account.html): attribute macro implementing [AccountSerialize](https://docs.rs/anchor-lang/latest/anchor_lang/trait.AccountSerialize.html) and [AccountDeserialize](https://docs.rs/anchor-lang/latest/anchor_lang/trait.AnchorDeserialize.html), automatically prepending a unique 8 byte discriminator to the account array. The discriminator is defined by the first 8 bytes of the `Sha256` hash of the account's Rust identifier--i.e., the struct type name--and ensures no account can be substituted for another. -- [Account](https://docs.rs/anchor-lang/latest/anchor_lang/struct.Account.html): a wrapper type for a deserialized account implementing `AccountDeserialize`. Using this type within an `Accounts` struct will ensure the account is **owned** by the address defined by `declare_id!` where the inner account was defined. +- [Account](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/account/struct.Account.html): a wrapper type for a deserialized account implementing `AccountDeserialize`. Using this type within an `Accounts` struct will ensure the account is **owned** by the address defined by `declare_id!` where the inner account was defined. With the above, we can define preconditions for any instruction handler expecting a certain set of accounts, allowing us to more easily reason about the security of our programs. diff --git a/examples/tutorial/basic-0/package.json b/examples/tutorial/basic-0/package.json index 44b07657b2..af63b61d60 100644 --- a/examples/tutorial/basic-0/package.json +++ b/examples/tutorial/basic-0/package.json @@ -1,6 +1,6 @@ { "name": "basic-0", - "version": "0.22.0", + "version": "0.22.1", "license": "(MIT OR Apache-2.0)", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/examples/tutorial/basic-1/package.json b/examples/tutorial/basic-1/package.json index 7ad4e01b41..6705849dbb 100644 --- a/examples/tutorial/basic-1/package.json +++ b/examples/tutorial/basic-1/package.json @@ -1,6 +1,6 @@ { "name": "basic-1", - "version": "0.22.0", + "version": "0.22.1", "license": "(MIT OR Apache-2.0)", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/examples/tutorial/basic-2/package.json b/examples/tutorial/basic-2/package.json index 9c12676ce2..131a262489 100644 --- a/examples/tutorial/basic-2/package.json +++ b/examples/tutorial/basic-2/package.json @@ -1,6 +1,6 @@ { "name": "basic-2", - "version": "0.22.0", + "version": "0.22.1", "license": "(MIT OR Apache-2.0)", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/examples/tutorial/basic-3/package.json b/examples/tutorial/basic-3/package.json index b596176d76..dee1ed6e12 100644 --- a/examples/tutorial/basic-3/package.json +++ b/examples/tutorial/basic-3/package.json @@ -1,6 +1,6 @@ { "name": "basic-3", - "version": "0.22.0", + "version": "0.22.1", "license": "(MIT OR Apache-2.0)", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/examples/tutorial/basic-4/package.json b/examples/tutorial/basic-4/package.json index a4818eae46..dae6300c80 100644 --- a/examples/tutorial/basic-4/package.json +++ b/examples/tutorial/basic-4/package.json @@ -1,6 +1,6 @@ { "name": "basic-4", - "version": "0.22.0", + "version": "0.22.1", "license": "(MIT OR Apache-2.0)", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/examples/tutorial/package.json b/examples/tutorial/package.json index 860b78aa4a..122bee519a 100644 --- a/examples/tutorial/package.json +++ b/examples/tutorial/package.json @@ -13,7 +13,7 @@ "basic-4" ], "dependencies": { - "@project-serum/anchor": "^0.22.0" + "@project-serum/anchor": "^0.22.1" }, "devDependencies": { "mocha": "^9.1.3", diff --git a/lang/Cargo.toml b/lang/Cargo.toml index ef82454010..e4e889b33e 100644 --- a/lang/Cargo.toml +++ b/lang/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-lang" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" edition = "2018" @@ -25,15 +25,15 @@ anchor-debug = [ ] [dependencies] -anchor-attribute-access-control = { path = "./attribute/access-control", version = "0.22.0" } -anchor-attribute-account = { path = "./attribute/account", version = "0.22.0" } -anchor-attribute-constant = { path = "./attribute/constant", version = "0.22.0" } -anchor-attribute-error = { path = "./attribute/error", version = "0.22.0" } -anchor-attribute-program = { path = "./attribute/program", version = "0.22.0" } -anchor-attribute-state = { path = "./attribute/state", version = "0.22.0" } -anchor-attribute-interface = { path = "./attribute/interface", version = "0.22.0" } -anchor-attribute-event = { path = "./attribute/event", version = "0.22.0" } -anchor-derive-accounts = { path = "./derive/accounts", version = "0.22.0" } +anchor-attribute-access-control = { path = "./attribute/access-control", version = "0.22.1" } +anchor-attribute-account = { path = "./attribute/account", version = "0.22.1" } +anchor-attribute-constant = { path = "./attribute/constant", version = "0.22.1" } +anchor-attribute-error = { path = "./attribute/error", version = "0.22.1" } +anchor-attribute-program = { path = "./attribute/program", version = "0.22.1" } +anchor-attribute-state = { path = "./attribute/state", version = "0.22.1" } +anchor-attribute-interface = { path = "./attribute/interface", version = "0.22.1" } +anchor-attribute-event = { path = "./attribute/event", version = "0.22.1" } +anchor-derive-accounts = { path = "./derive/accounts", version = "0.22.1" } arrayref = "0.3.6" base64 = "0.13.0" borsh = "0.9" diff --git a/lang/attribute/access-control/Cargo.toml b/lang/attribute/access-control/Cargo.toml index d51f6022f4..1cb3a17a74 100644 --- a/lang/attribute/access-control/Cargo.toml +++ b/lang/attribute/access-control/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-access-control" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,5 +18,5 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } regex = "1.0" diff --git a/lang/attribute/account/Cargo.toml b/lang/attribute/account/Cargo.toml index 6d8339ed2f..1cc678554c 100644 --- a/lang/attribute/account/Cargo.toml +++ b/lang/attribute/account/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-account" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,6 +18,6 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0", features = ["hash"] } +anchor-syn = { path = "../../syn", version = "0.22.1", features = ["hash"] } rustversion = "1.0.3" bs58 = "0.4.0" \ No newline at end of file diff --git a/lang/attribute/account/src/lib.rs b/lang/attribute/account/src/lib.rs index fc0c445a1c..c31b9cbcca 100644 --- a/lang/attribute/account/src/lib.rs +++ b/lang/attribute/account/src/lib.rs @@ -42,7 +42,7 @@ mod id; /// /// This can be used to conveniently implement /// [`ZeroCopy`](./trait.ZeroCopy.html) so that the account can be used -/// with [`Loader`](./struct.Loader.html). +/// with [`AccountLoader`](./accounts/account_loader/struct.AccountLoader.html). /// /// Other than being more efficient, the most salient benefit this provides is /// the ability to define account types larger than the max stack or heap size. diff --git a/lang/attribute/constant/Cargo.toml b/lang/attribute/constant/Cargo.toml index 1d0870eefe..7ce36f2f1e 100644 --- a/lang/attribute/constant/Cargo.toml +++ b/lang/attribute/constant/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-constant" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -16,4 +16,4 @@ anchor-debug = ["anchor-syn/anchor-debug"] [dependencies] proc-macro2 = "1.0" syn = { version = "1.0.60", features = ["full"] } -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } diff --git a/lang/attribute/error/Cargo.toml b/lang/attribute/error/Cargo.toml index e43a0176c0..d0ce963ec1 100644 --- a/lang/attribute/error/Cargo.toml +++ b/lang/attribute/error/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-error" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -17,4 +17,4 @@ anchor-debug = ["anchor-syn/anchor-debug"] proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } diff --git a/lang/attribute/event/Cargo.toml b/lang/attribute/event/Cargo.toml index 29e41b113a..8f83a072a3 100644 --- a/lang/attribute/event/Cargo.toml +++ b/lang/attribute/event/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-event" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,4 +18,4 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0", features = ["hash"] } +anchor-syn = { path = "../../syn", version = "0.22.1", features = ["hash"] } diff --git a/lang/attribute/interface/Cargo.toml b/lang/attribute/interface/Cargo.toml index 91d959026e..765cf39c6f 100644 --- a/lang/attribute/interface/Cargo.toml +++ b/lang/attribute/interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-interface" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,5 +18,5 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } heck = "0.3.2" diff --git a/lang/attribute/program/Cargo.toml b/lang/attribute/program/Cargo.toml index f6a0e3c1de..13020a4631 100644 --- a/lang/attribute/program/Cargo.toml +++ b/lang/attribute/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-program" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,4 +18,4 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } diff --git a/lang/attribute/state/Cargo.toml b/lang/attribute/state/Cargo.toml index 9b6e950004..a112165208 100644 --- a/lang/attribute/state/Cargo.toml +++ b/lang/attribute/state/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-state" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,4 +18,4 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } diff --git a/lang/derive/accounts/Cargo.toml b/lang/derive/accounts/Cargo.toml index 21dc6f1de4..0e63f58103 100644 --- a/lang/derive/accounts/Cargo.toml +++ b/lang/derive/accounts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-derive-accounts" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -20,4 +20,4 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } diff --git a/lang/derive/accounts/src/lib.rs b/lang/derive/accounts/src/lib.rs index 02704f5628..66fbdfec80 100644 --- a/lang/derive/accounts/src/lib.rs +++ b/lang/derive/accounts/src/lib.rs @@ -89,7 +89,6 @@ use syn::parse_macro_input; /// /// /// -/// #[account(init, payer = <target_account>)]

/// #[account(init, payer = <target_account>, space = <num_bytes>)] /// /// @@ -110,14 +109,12 @@ use syn::parse_macro_input; /// and be called system_program. /// ///
  • -/// Requires that the space constraint is specified -/// or, if creating an Account type, the T of Account -/// to implement the rust std Default trait.
    +/// Requires that the space constraint is specified. /// When using the space constraint, one must remember to add 8 to it -/// which is the size of the account discriminator.
    -/// The given number is the size of the account in bytes, so accounts that hold -/// a variable number of items such as a Vec should use the space -/// constraint instead of using the Default trait and allocate sufficient space for all items that may +/// which is the size of the account discriminator. This only has to be done +/// for accounts owned by anchor programs.
    +/// The given space number is the size of the account in bytes, so accounts that hold +/// a variable number of items such as a Vec should allocate sufficient space for all items that may /// be added to the data structure because account size is fixed. Check out the borsh library /// (which anchor uses under the hood for serialization) specification to learn how much /// space different data structures require. @@ -126,20 +123,13 @@ use syn::parse_macro_input; /// Example: ///
     /// #[account]
    -/// #[derive(Default)]
     /// pub struct MyData {
     ///     pub data: u64
     /// }
    
    -/// #[account]
    -/// pub struct OtherData {
    -///     pub data: u64
    -/// }
    
     /// #[derive(Accounts)]
     /// pub struct Initialize<'info> {
    -///     #[account(init, payer = payer)]
    -///     pub data_account: Account<'info, MyData>,
     ///     #[account(init, payer = payer, space = 8 + 8)]
    -///     pub data_account_two: Account<'info, OtherData>,
    +///     pub data_account_two: Account<'info, MyData>,
     ///     #[account(mut)]
     ///     pub payer: Signer<'info>,
     ///     pub system_program: Program<'info, System>,
    @@ -172,7 +162,7 @@ use syn::parse_macro_input;
     /// #[instruction(bump: u8)]
     /// pub struct Initialize<'info> {
     ///     #[account(
    -///         init, payer = payer,
    +///         init, payer = payer, space = 8 + 8
     ///         seeds = [b"example_seed".as_ref()], bump = bump
     ///     )]
     ///     pub pda_data_account: Account<'info, MyData>,
    @@ -182,7 +172,7 @@ use syn::parse_macro_input;
     ///     )]
     ///     pub account_for_other_program: AccountInfo<'info>,
     ///     #[account(
    -///         init,payer = payer, space = 8 + 8,
    +///         init, payer = payer, space = 8 + 8,
     ///         owner = other_program.key(),
     ///         seeds = [b"other_seed".as_ref()], bump
     ///     )]
    diff --git a/lang/src/accounts/sysvar.rs b/lang/src/accounts/sysvar.rs
    index 25e8698f3f..3c10ee45a7 100644
    --- a/lang/src/accounts/sysvar.rs
    +++ b/lang/src/accounts/sysvar.rs
    @@ -46,10 +46,13 @@ impl<'info, T: solana_program::sysvar::Sysvar + fmt::Debug> fmt::Debug for Sysva
     
     impl<'info, T: solana_program::sysvar::Sysvar> Sysvar<'info, T> {
         pub fn from_account_info(acc_info: &AccountInfo<'info>) -> Result> {
    -        Ok(Sysvar {
    -            info: acc_info.clone(),
    -            account: T::from_account_info(acc_info)?,
    -        })
    +        match T::from_account_info(acc_info) {
    +            Ok(val) => Ok(Sysvar {
    +                info: acc_info.clone(),
    +                account: val,
    +            }),
    +            Err(_) => Err(ErrorCode::AccountSysvarMismatch.into()),
    +        }
         }
     }
     
    diff --git a/lang/src/error.rs b/lang/src/error.rs
    index ce2b519ecf..60a4bb9dee 100644
    --- a/lang/src/error.rs
    +++ b/lang/src/error.rs
    @@ -152,6 +152,9 @@ pub enum ErrorCode {
         /// 3014 - The given account is not the associated token account
         #[msg("The given account is not the associated token account")]
         AccountNotAssociatedTokenAccount,
    +    /// 3015 - The given public key does not match the required sysvar
    +    #[msg("The given public key does not match the required sysvar")]
    +    AccountSysvarMismatch,
     
         // State.
         /// 4000 - The given state account does not have the correct address
    diff --git a/lang/syn/Cargo.toml b/lang/syn/Cargo.toml
    index 4b0324e781..c0e20d1708 100644
    --- a/lang/syn/Cargo.toml
    +++ b/lang/syn/Cargo.toml
    @@ -1,6 +1,6 @@
     [package]
     name = "anchor-syn"
    -version = "0.22.0"
    +version = "0.22.1"
     authors = ["Serum Foundation "]
     repository = "https://github.com/project-serum/anchor"
     license = "Apache-2.0"
    diff --git a/lang/syn/src/codegen/accounts/__client_accounts.rs b/lang/syn/src/codegen/accounts/__client_accounts.rs
    index 24079e51e1..343239d349 100644
    --- a/lang/syn/src/codegen/accounts/__client_accounts.rs
    +++ b/lang/syn/src/codegen/accounts/__client_accounts.rs
    @@ -22,7 +22,8 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
                 AccountField::CompositeField(s) => {
                     let name = &s.ident;
                     let docs = if !s.docs.is_empty() {
    -                    proc_macro2::TokenStream::from_str(&format!("#[doc = \"{}\"]", s.docs)).unwrap()
    +                    proc_macro2::TokenStream::from_str(&format!("#[doc = r#\"{}\"#]", s.docs))
    +                        .unwrap()
                     } else {
                         quote!()
                     };
    @@ -41,7 +42,8 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
                 AccountField::Field(f) => {
                     let name = &f.ident;
                     let docs = if !f.docs.is_empty() {
    -                    proc_macro2::TokenStream::from_str(&format!("#[doc = \"{}\"]", f.docs)).unwrap()
    +                    proc_macro2::TokenStream::from_str(&format!("#[doc = r#\"{}\"#]", f.docs))
    +                        .unwrap()
                     } else {
                         quote!()
                     };
    diff --git a/lang/syn/src/codegen/accounts/__cpi_client_accounts.rs b/lang/syn/src/codegen/accounts/__cpi_client_accounts.rs
    index 823647c705..86adeb97a0 100644
    --- a/lang/syn/src/codegen/accounts/__cpi_client_accounts.rs
    +++ b/lang/syn/src/codegen/accounts/__cpi_client_accounts.rs
    @@ -23,7 +23,8 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
                 AccountField::CompositeField(s) => {
                     let name = &s.ident;
                     let docs = if !s.docs.is_empty() {
    -                    proc_macro2::TokenStream::from_str(&format!("#[doc = \"{}\"]", s.docs)).unwrap()
    +                    proc_macro2::TokenStream::from_str(&format!("#[doc = r#\"{}\"#]", s.docs))
    +                        .unwrap()
                     } else {
                         quote!()
                     };
    @@ -42,7 +43,8 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
                 AccountField::Field(f) => {
                     let name = &f.ident;
                     let docs = if !f.docs.is_empty() {
    -                    proc_macro2::TokenStream::from_str(&format!("#[doc = \"{}\"]", f.docs)).unwrap()
    +                    proc_macro2::TokenStream::from_str(&format!("#[doc = r#\"{}\"#]", f.docs))
    +                        .unwrap()
                     } else {
                         quote!()
                     };
    diff --git a/lang/syn/src/codegen/accounts/constraints.rs b/lang/syn/src/codegen/accounts/constraints.rs
    index fc9dc79255..95afd3d1dc 100644
    --- a/lang/syn/src/codegen/accounts/constraints.rs
    +++ b/lang/syn/src/codegen/accounts/constraints.rs
    @@ -480,29 +480,7 @@ fn generate_constraint_init_group(f: &Field, c: &ConstraintInitGroup) -> proc_ma
             }
             InitKind::Program { owner } => {
                 // Define the space variable.
    -            let space = match space {
    -                // If no explicit space param was given, serialize the type to bytes
    -                // and take the length (with +8 for the discriminator.)
    -                None => {
    -                    let account_ty = f.account_ty();
    -                    match matches!(f.ty, Ty::Loader(_) | Ty::AccountLoader(_)) {
    -                        false => {
    -                            quote! {
    -                                let space = 8 + #account_ty::default().try_to_vec().unwrap().len();
    -                            }
    -                        }
    -                        true => {
    -                            quote! {
    -                                let space = 8 + anchor_lang::__private::bytemuck::bytes_of(&#account_ty::default()).len();
    -                            }
    -                        }
    -                    }
    -                }
    -                // Explicit account size given. Use it.
    -                Some(s) => quote! {
    -                    let space = #s;
    -                },
    -            };
    +            let space = quote! {let space = #space;};
     
                 // Define the owner of the account being created. If not specified,
                 // default to the currently executing program.
    diff --git a/lang/syn/src/idl/file.rs b/lang/syn/src/idl/file.rs
    index 8dda95f28f..7814c9cb92 100644
    --- a/lang/syn/src/idl/file.rs
    +++ b/lang/syn/src/idl/file.rs
    @@ -353,7 +353,7 @@ fn parse_account_derives(ctx: &CrateContext) -> HashMap
         ctx.structs()
             .filter_map(|i_strct| {
                 for attr in &i_strct.attrs {
    -                if attr.tokens.to_string().contains(DERIVE_NAME) {
    +                if attr.path.is_ident("derive") && attr.tokens.to_string().contains(DERIVE_NAME) {
                         let strct = accounts::parse(i_strct).expect("Code not parseable");
                         return Some((strct.ident.to_string(), strct));
                     }
    diff --git a/lang/syn/src/lib.rs b/lang/syn/src/lib.rs
    index ca652f81d5..cf00ca23ed 100644
    --- a/lang/syn/src/lib.rs
    +++ b/lang/syn/src/lib.rs
    @@ -721,7 +721,7 @@ pub enum ConstraintRentExempt {
     pub struct ConstraintInitGroup {
         pub if_needed: bool,
         pub seeds: Option,
    -    pub payer: Option,
    +    pub payer: Expr,
         pub space: Option,
         pub kind: InitKind,
     }
    diff --git a/lang/syn/src/parser/accounts/constraints.rs b/lang/syn/src/parser/accounts/constraints.rs
    index 533d5053fc..42454fec4f 100644
    --- a/lang/syn/src/parser/accounts/constraints.rs
    +++ b/lang/syn/src/parser/accounts/constraints.rs
    @@ -505,17 +505,28 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
                 }
             }
     
    -        // SPL Space.
    -        if self.init.is_some()
    -            && self.seeds.is_some()
    -            && self.token_mint.is_some()
    -            && (self.mint_authority.is_some() || self.token_authority.is_some())
    -            && self.space.is_some()
    -        {
    -            return Err(ParseError::new(
    -                self.space.as_ref().unwrap().span(),
    -                "space is not required for initializing an spl account",
    -            ));
    +        // Space.
    +        if let Some(i) = &self.init {
    +            let initializing_token_program_acc = self.token_mint.is_some()
    +                || self.mint_authority.is_some()
    +                || self.token_authority.is_some()
    +                || self.associated_token_authority.is_some();
    +
    +            match (self.space.is_some(), initializing_token_program_acc) {
    +                (true, true) => {
    +                    return Err(ParseError::new(
    +                        self.space.as_ref().unwrap().span(),
    +                        "space is not required for initializing an spl account",
    +                    ));
    +                }
    +                (false, false) => {
    +                    return Err(ParseError::new(
    +                        i.span(),
    +                        "space must be provided with init",
    +                    ));
    +                }
    +                _ => (),
    +            }
             }
     
             let ConstraintGroupBuilder {
    @@ -593,7 +604,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
                 init: init.as_ref().map(|i| Ok(ConstraintInitGroup {
                     if_needed: i.if_needed,
                     seeds: seeds.clone(),
    -                payer: into_inner!(payer.clone()).map(|a| a.target),
    +                payer: into_inner!(payer.clone()).unwrap().target,
                     space: space.clone().map(|s| s.space.clone()),
                     kind: if let Some(tm) = &token_mint {
                         InitKind::Token {
    diff --git a/lang/syn/src/parser/accounts/mod.rs b/lang/syn/src/parser/accounts/mod.rs
    index e375cbc159..b0178af5f5 100644
    --- a/lang/syn/src/parser/accounts/mod.rs
    +++ b/lang/syn/src/parser/accounts/mod.rs
    @@ -93,8 +93,7 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> {
     
             for field in init_fields {
                 // Get payer for init-ed account
    -            let associated_payer_name = match field.constraints.init.clone().unwrap().payer.unwrap()
    -            {
    +            let associated_payer_name = match field.constraints.init.clone().unwrap().payer {
                     // composite payer, check not supported
                     Expr::Field(_) => continue,
                     field_name => field_name.to_token_stream().to_string(),
    diff --git a/spl/Cargo.toml b/spl/Cargo.toml
    index dd3c13e440..7afdc7798c 100644
    --- a/spl/Cargo.toml
    +++ b/spl/Cargo.toml
    @@ -1,6 +1,6 @@
     [package]
     name = "anchor-spl"
    -version = "0.22.0"
    +version = "0.22.1"
     authors = ["Serum Foundation "]
     edition = "2018"
     license = "Apache-2.0"
    @@ -17,7 +17,7 @@ devnet = []
     dex = ["serum_dex"]
     
     [dependencies]
    -anchor-lang = { path = "../lang", version = "0.22.0", features = ["derive"] }
    +anchor-lang = { path = "../lang", version = "0.22.1", features = ["derive"] }
     serum_dex = { git = "https://github.com/project-serum/serum-dex", rev = "1be91f2", version = "0.4.0", features = ["no-entrypoint"], optional = true }
     solana-program = "1.8.5"
     spl-token = { version = "3.1.1", features = ["no-entrypoint"], optional = true }
    diff --git a/spl/src/associated_token.rs b/spl/src/associated_token.rs
    index 4effe4d457..c46b09b8fd 100644
    --- a/spl/src/associated_token.rs
    +++ b/spl/src/associated_token.rs
    @@ -1,11 +1,11 @@
     use anchor_lang::solana_program::account_info::AccountInfo;
    -use anchor_lang::solana_program::entrypoint::ProgramResult;
     use anchor_lang::solana_program::pubkey::Pubkey;
    +use anchor_lang::Result;
     use anchor_lang::{context::CpiContext, Accounts};
     
     pub use spl_associated_token_account::{get_associated_token_address, ID};
     
    -pub fn create<'info>(ctx: CpiContext<'_, '_, '_, 'info, Create<'info>>) -> ProgramResult {
    +pub fn create<'info>(ctx: CpiContext<'_, '_, '_, 'info, Create<'info>>) -> Result<()> {
         let ix = spl_associated_token_account::create_associated_token_account(
             ctx.accounts.payer.key,
             ctx.accounts.authority.key,
    @@ -24,6 +24,7 @@ pub fn create<'info>(ctx: CpiContext<'_, '_, '_, 'info, Create<'info>>) -> Progr
             ],
             ctx.signer_seeds,
         )
    +    .map_err(Into::into)
     }
     
     #[derive(Accounts)]
    diff --git a/spl/src/token.rs b/spl/src/token.rs
    index 2ed7558a13..669a195b65 100644
    --- a/spl/src/token.rs
    +++ b/spl/src/token.rs
    @@ -104,6 +104,21 @@ pub fn approve<'a, 'b, 'c, 'info>(
         .map_err(Into::into)
     }
     
    +pub fn revoke<'a, 'b, 'c, 'info>(ctx: CpiContext<'a, 'b, 'c, 'info, Revoke<'info>>) -> Result<()> {
    +    let ix = spl_token::instruction::revoke(
    +        &spl_token::ID,
    +        ctx.accounts.source.key,
    +        ctx.accounts.authority.key,
    +        &[],
    +    )?;
    +    solana_program::program::invoke_signed(
    +        &ix,
    +        &[ctx.accounts.source.clone(), ctx.accounts.authority.clone()],
    +        ctx.signer_seeds,
    +    )
    +    .map_err(Into::into)
    +}
    +
     pub fn initialize_account<'a, 'b, 'c, 'info>(
         ctx: CpiContext<'a, 'b, 'c, 'info, InitializeAccount<'info>>,
     ) -> Result<()> {
    @@ -270,6 +285,12 @@ pub struct Approve<'info> {
         pub authority: AccountInfo<'info>,
     }
     
    +#[derive(Accounts)]
    +pub struct Revoke<'info> {
    +    pub source: AccountInfo<'info>,
    +    pub authority: AccountInfo<'info>,
    +}
    +
     #[derive(Accounts)]
     pub struct InitializeAccount<'info> {
         pub account: AccountInfo<'info>,
    diff --git a/tests/bpf-upgradeable-state/package.json b/tests/bpf-upgradeable-state/package.json
    index f20be7b530..8af10cabb5 100644
    --- a/tests/bpf-upgradeable-state/package.json
    +++ b/tests/bpf-upgradeable-state/package.json
    @@ -1,6 +1,6 @@
     {
         "dependencies": {
    -        "@project-serum/anchor": "^0.22.0"
    +        "@project-serum/anchor": "^0.22.1"
         },
         "devDependencies": {
             "chai": "^4.3.4",
    diff --git a/tests/bpf-upgradeable-state/programs/bpf-upgradeable-state/src/lib.rs b/tests/bpf-upgradeable-state/programs/bpf-upgradeable-state/src/lib.rs
    index 09087114d5..fca03bb7df 100644
    --- a/tests/bpf-upgradeable-state/programs/bpf-upgradeable-state/src/lib.rs
    +++ b/tests/bpf-upgradeable-state/programs/bpf-upgradeable-state/src/lib.rs
    @@ -32,11 +32,14 @@ pub mod bpf_upgradeable_state {
     }
     
     #[account]
    -#[derive(Default, Debug)]
     pub struct Settings {
         admin_data: u64,
     }
     
    +impl Settings {
    +    pub const LEN: usize = 8;
    +}
    +
     #[error_code]
     pub enum CustomError {
         InvalidProgramDataAddress,
    @@ -49,7 +52,7 @@ pub struct SetAdminSettings<'info> {
         // In a real program, this should be a PDA,
         // so the authority cannot create multiple settings accounts.
         // Not done here for easier testing
    -    #[account(init, payer = authority)]
    +    #[account(init, payer = authority, space = Settings::LEN + 8)]
         pub settings: Account<'info, Settings>,
         #[account(mut)]
         pub authority: Signer<'info>,
    @@ -65,7 +68,7 @@ pub struct SetAdminSettingsUseProgramState<'info> {
         // In a real program, this should be a PDA,
         // so the authority cannot create multiple settings accounts.
         // Not done here for easier testing
    -    #[account(init, payer = authority)]
    +    #[account(init, payer = authority, space = Settings::LEN + 8)]
         pub settings: Account<'info, Settings>,
         #[account(mut)]
         pub authority: Signer<'info>,
    diff --git a/tests/cashiers-check/package.json b/tests/cashiers-check/package.json
    index cbf96d9871..1824909e52 100644
    --- a/tests/cashiers-check/package.json
    +++ b/tests/cashiers-check/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "cashiers-check",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/cfo/package.json b/tests/cfo/package.json
    index 81c6201681..e404069b84 100644
    --- a/tests/cfo/package.json
    +++ b/tests/cfo/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "cfo",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/cfo/programs/cfo/src/lib.rs b/tests/cfo/programs/cfo/src/lib.rs
    index 99e759adff..480cb04ece 100644
    --- a/tests/cfo/programs/cfo/src/lib.rs
    +++ b/tests/cfo/programs/cfo/src/lib.rs
    @@ -195,7 +195,7 @@ pub mod cfo {
             let expiry_ts = 1853942400; // 9/30/2028.
             let expiry_receiver = *ctx.accounts.officer.to_account_info().key;
             let locked_kind = {
    -            let start_ts = 1633017600; // 9/30.22.0.
    +            let start_ts = 1633017600; // 9/30.22.1.
                 let end_ts = 1822320000; // 9/30/2027.
                 let period_count = 2191;
                 RewardVendorKind::Locked {
    @@ -324,6 +324,7 @@ pub struct CreateOfficer<'info> {
             seeds = [dex_program.key.as_ref()],
             bump,
             payer = authority,
    +        space = Officer::LEN + 8
         )]
         officer: Box>,
         #[account(
    @@ -332,7 +333,7 @@ pub struct CreateOfficer<'info> {
             bump,
             payer = authority,
             token::mint = srm_mint,
    -        token::authority = officer,
    +        token::authority = officer
         )]
         srm_vault: Box>,
         #[account(
    @@ -341,7 +342,7 @@ pub struct CreateOfficer<'info> {
             bump,
             payer = authority,
             token::mint = usdc_mint,
    -        token::authority = officer,
    +        token::authority = officer
         )]
         usdc_vault: Box>,
         #[account(
    @@ -350,7 +351,7 @@ pub struct CreateOfficer<'info> {
             bump,
             payer = authority,
             token::mint = srm_mint,
    -        token::authority = officer,
    +        token::authority = officer
         )]
         stake: Box>,
         #[account(
    @@ -359,7 +360,7 @@ pub struct CreateOfficer<'info> {
             bump,
             payer = authority,
             token::mint = srm_mint,
    -        token::authority = officer,
    +        token::authority = officer
         )]
         treasury: Box>,
         #[account(mut)]
    @@ -392,6 +393,7 @@ pub struct AuthorizeMarket<'info> {
             payer = payer,
             seeds = [b"market-auth", officer.key().as_ref(), market.key.as_ref()],
             bump,
    +        space = MarketAuth::LEN + 8
         )]
         market_auth: Account<'info, MarketAuth>,
         #[account(mut)]
    @@ -421,7 +423,7 @@ pub struct CreateOfficerToken<'info> {
             bump,
             token::mint = mint,
             token::authority = officer,
    -        payer = payer,
    +        payer = payer
         )]
         token: Account<'info, TokenAccount>,
         mint: Account<'info, Mint>,
    @@ -666,28 +668,31 @@ pub struct DropStakeRewardPool<'info> {
     ///
     /// PDA - [dex_program_id].
     #[account]
    -#[derive(Default)]
     pub struct Officer {
         // Priviledged account.
    -    pub authority: Pubkey,
    +    pub authority: Pubkey, // 32
         // Vault holding the officer's SRM tokens prior to distribution.
    -    pub srm_vault: Pubkey,
    +    pub srm_vault: Pubkey, // 32
         // Escrow SRM vault holding tokens which are dropped onto stakers.
    -    pub stake: Pubkey,
    +    pub stake: Pubkey, // 32
         // SRM token account to send treasury earned tokens to.
    -    pub treasury: Pubkey,
    +    pub treasury: Pubkey, // 32
         // Defines the fee distribution, i.e., what percent each fee category gets.
    -    pub distribution: Distribution,
    +    pub distribution: Distribution, // Distribution::LEN
         // Swap frontend for the dex.
    -    pub swap_program: Pubkey,
    +    pub swap_program: Pubkey, // 32
         // Dex program the officer is associated with.
    -    pub dex_program: Pubkey,
    +    pub dex_program: Pubkey, // 32
         // SRM stake pool address
    -    pub registrar: Pubkey,
    +    pub registrar: Pubkey, // 32
         // MSRM stake pool address.
    -    pub msrm_registrar: Pubkey,
    +    pub msrm_registrar: Pubkey, // 32
         // Bump seeds for pdas.
    -    pub bumps: OfficerBumps,
    +    pub bumps: OfficerBumps, // OfficerBumps::LEN
    +}
    +
    +impl Officer {
    +    pub const LEN: usize = 8 * 32 + Distribution::LEN + OfficerBumps::LEN;
     }
     
     /// MarketAuth represents an authorization token created by the Officer
    @@ -702,26 +707,37 @@ pub struct Officer {
     ///
     /// PDA - [b"market-auth", officer, market_address]
     #[account]
    -#[derive(Default)]
     pub struct MarketAuth {
         // Bump seed for this account's PDA.
    -    pub bump: u8,
    +    pub bump: u8, // 1
    +}
    +
    +impl MarketAuth {
    +    pub const LEN: usize = 1;
     }
     
     #[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)]
     pub struct OfficerBumps {
    -    pub bump: u8,
    -    pub srm: u8,
    -    pub usdc: u8,
    -    pub stake: u8,
    -    pub treasury: u8,
    +    pub bump: u8,     // 1
    +    pub srm: u8,      // 1
    +    pub usdc: u8,     // 1
    +    pub stake: u8,    // 1
    +    pub treasury: u8, // 1
    +}
    +
    +impl OfficerBumps {
    +    pub const LEN: usize = 5;
     }
     
     #[derive(AnchorSerialize, AnchorDeserialize, Default, Clone)]
     pub struct Distribution {
    -    burn: u8,
    -    stake: u8,
    -    treasury: u8,
    +    burn: u8,     // 1
    +    stake: u8,    // 1
    +    treasury: u8, // 1
    +}
    +
    +impl Distribution {
    +    pub const LEN: usize = 3;
     }
     
     // CpiContext transformations.
    diff --git a/tests/chat/package.json b/tests/chat/package.json
    index bbfb9c0e26..f6da52bcb2 100644
    --- a/tests/chat/package.json
    +++ b/tests/chat/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "chat",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/composite/package.json b/tests/composite/package.json
    index 026ff5c772..3bf8d762d2 100644
    --- a/tests/composite/package.json
    +++ b/tests/composite/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "composite",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/declare-id/package.json b/tests/declare-id/package.json
    index 54659e924f..b01c5f1162 100644
    --- a/tests/declare-id/package.json
    +++ b/tests/declare-id/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "declare-id",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/docs/package.json b/tests/docs/package.json
    index 8be73d64a2..1b800b8ec2 100644
    --- a/tests/docs/package.json
    +++ b/tests/docs/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "errors",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/docs/programs/docs/src/lib.rs b/tests/docs/programs/docs/src/lib.rs
    index fbfe0fa838..710a2fe026 100644
    --- a/tests/docs/programs/docs/src/lib.rs
    +++ b/tests/docs/programs/docs/src/lib.rs
    @@ -24,6 +24,7 @@ pub struct Hello<'info> {
         pub rent: Sysvar<'info, Rent>,
         /// Composite accounts test.
         /// Multiple lines supported.
    +    /// You can also include "double quotes".
         pub other: HelloComposite<'info>,
     }
     
    diff --git a/tests/errors/package.json b/tests/errors/package.json
    index 8be73d64a2..1b800b8ec2 100644
    --- a/tests/errors/package.json
    +++ b/tests/errors/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "errors",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/escrow/package.json b/tests/escrow/package.json
    index 44d3f5cfb5..bbb644d23d 100644
    --- a/tests/escrow/package.json
    +++ b/tests/escrow/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "escrow",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/events/package.json b/tests/events/package.json
    index bafd6d6e9e..eb7e84440b 100644
    --- a/tests/events/package.json
    +++ b/tests/events/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "events",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/floats/package.json b/tests/floats/package.json
    index 38ba52f28a..a9be4eac00 100644
    --- a/tests/floats/package.json
    +++ b/tests/floats/package.json
    @@ -1,6 +1,6 @@
     {
         "name": "floats",
    -    "version": "0.22.0",
    +    "version": "0.22.1",
         "license": "(MIT OR Apache-2.0)",
         "homepage": "https://github.com/project-serum/anchor#readme",
         "bugs": {
    diff --git a/tests/ido-pool/package.json b/tests/ido-pool/package.json
    index da2ff3bc09..804598047e 100644
    --- a/tests/ido-pool/package.json
    +++ b/tests/ido-pool/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "ido-pool",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/ido-pool/programs/ido-pool/src/lib.rs b/tests/ido-pool/programs/ido-pool/src/lib.rs
    index 2a2abfb7ed..ca7b0320fb 100644
    --- a/tests/ido-pool/programs/ido-pool/src/lib.rs
    +++ b/tests/ido-pool/programs/ido-pool/src/lib.rs
    @@ -295,7 +295,9 @@ pub struct InitializePool<'info> {
         #[account(init,
             seeds = [ido_name.as_bytes()],
             bump,
    -        payer = ido_authority)]
    +        payer = ido_authority,
    +        space = IdoAccount::LEN + 8
    +    )]
         pub ido_account: Box>,
         // TODO Confirm USDC mint address on mainnet or leave open as an option for other stables
         #[account(constraint = usdc_mint.decimals == DECIMALS)]
    @@ -305,7 +307,8 @@ pub struct InitializePool<'info> {
             mint::authority = ido_account,
             seeds = [ido_name.as_bytes(), b"redeemable_mint".as_ref()],
             bump,
    -        payer = ido_authority)]
    +        payer = ido_authority
    +    )]
         pub redeemable_mint: Box>,
         #[account(constraint = watermelon_mint.key() == ido_authority_watermelon.mint)]
         pub watermelon_mint: Box>,
    @@ -314,14 +317,16 @@ pub struct InitializePool<'info> {
             token::authority = ido_account,
             seeds = [ido_name.as_bytes(), b"pool_watermelon"],
             bump,
    -        payer = ido_authority)]
    +        payer = ido_authority
    +    )]
         pub pool_watermelon: Box>,
         #[account(init,
             token::mint = usdc_mint,
             token::authority = ido_account,
             seeds = [ido_name.as_bytes(), b"pool_usdc"],
             bump,
    -        payer = ido_authority)]
    +        payer = ido_authority
    +    )]
         pub pool_usdc: Box>,
         // Programs and Sysvars
         pub system_program: Program<'info, System>,
    @@ -341,7 +346,8 @@ pub struct InitUserRedeemable<'info> {
                 ido_account.ido_name.as_ref().trim_ascii_whitespace(),
                 b"user_redeemable"],
             bump,
    -        payer = user_authority)]
    +        payer = user_authority
    +    )]
         pub user_redeemable: Box>,
         // IDO Accounts
         #[account(seeds = [ido_account.ido_name.as_ref().trim_ascii_whitespace()],
    @@ -401,7 +407,8 @@ pub struct InitEscrowUsdc<'info> {
                 ido_account.ido_name.as_ref().trim_ascii_whitespace(),
                 b"escrow_usdc"],
             bump,
    -        payer = user_authority)]
    +        payer = user_authority
    +    )]
         pub escrow_usdc: Box>,
         #[account(seeds = [ido_account.ido_name.as_ref().trim_ascii_whitespace()],
             bump = ido_account.bumps.ido_account,
    @@ -541,36 +548,39 @@ pub struct WithdrawFromEscrow<'info> {
     }
     
     #[account]
    -#[derive(Default)]
     pub struct IdoAccount {
    -    pub ido_name: [u8; 10], // Setting an arbitrary max of ten characters in the ido name.
    -    pub bumps: PoolBumps,
    -    pub ido_authority: Pubkey,
    -
    -    pub usdc_mint: Pubkey,
    -    pub redeemable_mint: Pubkey,
    -    pub watermelon_mint: Pubkey,
    -    pub pool_usdc: Pubkey,
    -    pub pool_watermelon: Pubkey,
    -
    -    pub num_ido_tokens: u64,
    -    pub ido_times: IdoTimes,
    +    pub ido_name: [u8; 10], // Setting an arbitrary max of ten characters in the ido name. // 10
    +    pub bumps: PoolBumps,   // 4
    +    pub ido_authority: Pubkey, // 32
    +
    +    pub usdc_mint: Pubkey,       // 32
    +    pub redeemable_mint: Pubkey, // 32
    +    pub watermelon_mint: Pubkey, // 32
    +    pub pool_usdc: Pubkey,       // 32
    +    pub pool_watermelon: Pubkey, // 32
    +
    +    pub num_ido_tokens: u64, // 8
    +    pub ido_times: IdoTimes, // 32
    +}
    +
    +impl IdoAccount {
    +    pub const LEN: usize = 10 + 4 + 32 + 5 * 32 + 8 + 32;
     }
     
     #[derive(AnchorSerialize, AnchorDeserialize, Default, Clone, Copy)]
     pub struct IdoTimes {
    -    pub start_ido: i64,
    -    pub end_deposits: i64,
    -    pub end_ido: i64,
    -    pub end_escrow: i64,
    +    pub start_ido: i64,    // 8
    +    pub end_deposits: i64, // 8
    +    pub end_ido: i64,      // 8
    +    pub end_escrow: i64,   // 8
     }
     
     #[derive(AnchorSerialize, AnchorDeserialize, Default, Clone)]
     pub struct PoolBumps {
    -    pub ido_account: u8,
    -    pub redeemable_mint: u8,
    -    pub pool_watermelon: u8,
    -    pub pool_usdc: u8,
    +    pub ido_account: u8,     // 1
    +    pub redeemable_mint: u8, // 1
    +    pub pool_watermelon: u8, // 1
    +    pub pool_usdc: u8,       // 1
     }
     
     #[error_code]
    diff --git a/tests/interface/package.json b/tests/interface/package.json
    index 25fb02e537..134ec60243 100644
    --- a/tests/interface/package.json
    +++ b/tests/interface/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "interface",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/lockup/package.json b/tests/lockup/package.json
    index 0d99b402a9..2ef3a21db5 100644
    --- a/tests/lockup/package.json
    +++ b/tests/lockup/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "lockup",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/misc/package.json b/tests/misc/package.json
    index ff25b4e2da..db450e64a0 100644
    --- a/tests/misc/package.json
    +++ b/tests/misc/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "misc",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/misc/programs/misc/src/account.rs b/tests/misc/programs/misc/src/account.rs
    index b94e1fdcf4..4a5fc13c5c 100644
    --- a/tests/misc/programs/misc/src/account.rs
    +++ b/tests/misc/programs/misc/src/account.rs
    @@ -1,50 +1,63 @@
     use anchor_lang::prelude::*;
     
    +macro_rules! size {
    +    ($name: ident, $size:expr) => {
    +        impl $name {
    +            pub const LEN: usize = $size;
    +        }
    +    };
    +}
    +
     pub const MAX_SIZE: usize = 10;
     
     #[account]
     pub struct Data {
    -    pub udata: u128,
    -    pub idata: i128,
    +    pub udata: u128, // 16
    +    pub idata: i128, // 16
     }
    +size!(Data, 32);
     
     #[account]
    -#[derive(Default)]
     pub struct DataU16 {
    -    pub data: u16,
    +    pub data: u16, // 2
     }
    +size!(DataU16, 32);
     
     #[account]
    -#[derive(Default)]
     pub struct DataI8 {
    -    pub data: i8,
    +    pub data: i8, // 1
     }
    +size!(DataI8, 1);
     
     #[account]
     pub struct DataI16 {
    -    pub data: i16,
    +    pub data: i16, // 2
     }
    +size!(DataI16, 2);
     
     #[account(zero_copy)]
    -#[derive(Default)]
     pub struct DataZeroCopy {
    -    pub data: u16,
    -    pub bump: u8,
    +    pub data: u16,    // 2
    +    pub _padding: u8, // 1
    +    pub bump: u8,     // 1
     }
    +size!(DataZeroCopy, 4);
     
     #[account]
    -#[derive(Default)]
     pub struct DataWithFilter {
    -    pub authority: Pubkey,
    -    pub filterable: Pubkey,
    +    pub authority: Pubkey,  // 32
    +    pub filterable: Pubkey, // 32
     }
    +size!(DataWithFilter, 64);
     
     #[account]
     pub struct DataMultidimensionalArray {
    -    pub data: [[u8; 10]; 10],
    +    pub data: [[u8; 10]; 10], // 100
     }
    +size!(DataMultidimensionalArray, 100);
     
     #[account]
     pub struct DataConstArraySize {
    -    pub data: [u8; MAX_SIZE],
    +    pub data: [u8; MAX_SIZE], // 10
     }
    +size!(DataConstArraySize, MAX_SIZE);
    diff --git a/tests/misc/programs/misc/src/context.rs b/tests/misc/programs/misc/src/context.rs
    index cda496cbe8..e34c6c71eb 100644
    --- a/tests/misc/programs/misc/src/context.rs
    +++ b/tests/misc/programs/misc/src/context.rs
    @@ -16,15 +16,17 @@ pub struct TestTokenSeedsInit<'info> {
             payer = authority,
             mint::decimals = 6,
             mint::authority = authority,
    +        
         )]
         pub mint: Account<'info, Mint>,
         #[account(
             init,
    -        seeds = [b"my-token-seed".as_ref(),],
    +        seeds = [b"my-token-seed".as_ref()],
             bump,
             payer = authority,
             token::mint = mint,
             token::authority = authority,
    +        
         )]
         pub my_pda: Account<'info, TokenAccount>,
         #[account(mut)]
    @@ -42,6 +44,7 @@ pub struct TestInitAssociatedToken<'info> {
             payer = payer,
             associated_token::mint = mint,
             associated_token::authority = payer,
    +        
         )]
         pub token: Account<'info, TokenAccount>,
         pub mint: Account<'info, Mint>,
    @@ -86,6 +89,7 @@ pub struct TestPdaInit<'info> {
             seeds = [b"my-seed", domain.as_bytes(), foo.key.as_ref(), &seed],
             bump,
             payer = my_payer,
    +        space = DataU16::LEN + 8
         )]
         pub my_pda: Account<'info, DataU16>,
         #[account(mut)]
    @@ -102,8 +106,9 @@ pub struct TestPdaInitZeroCopy<'info> {
             seeds = [b"my-seed".as_ref()],
             bump,
             payer = my_payer,
    +        space = DataZeroCopy::LEN + 8
         )]
    -    pub my_pda: Loader<'info, DataZeroCopy>,
    +    pub my_pda: AccountLoader<'info, DataZeroCopy>,
         #[account(mut)]
         pub my_payer: Signer<'info>,
         pub system_program: Program<'info, System>,
    @@ -116,7 +121,7 @@ pub struct TestPdaMutZeroCopy<'info> {
             seeds = [b"my-seed".as_ref()],
             bump = my_pda.load()?.bump,
         )]
    -    pub my_pda: Loader<'info, DataZeroCopy>,
    +    pub my_pda: AccountLoader<'info, DataZeroCopy>,
         /// CHECK:
         pub my_payer: AccountInfo<'info>,
     }
    @@ -204,7 +209,7 @@ pub struct TestI8<'info> {
     
     #[derive(Accounts)]
     pub struct TestInit<'info> {
    -    #[account(init, payer = payer)]
    +    #[account(init, payer = payer, space = DataI8::LEN + 8)]
         pub data: Account<'info, DataI8>,
         #[account(mut)]
         pub payer: Signer<'info>,
    @@ -213,7 +218,7 @@ pub struct TestInit<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitZeroCopy<'info> {
    -    #[account(init, payer = payer, space = 8 + size_of::())]
    +    #[account(init, payer = payer, space = DataZeroCopy::LEN + 8)]
         pub data: Loader<'info, DataZeroCopy>,
         #[account(mut)]
         pub payer: Signer<'info>,
    @@ -222,7 +227,7 @@ pub struct TestInitZeroCopy<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitMint<'info> {
    -    #[account(init, mint::decimals = 6, mint::authority = payer, mint::freeze_authority = payer, payer = payer)]
    +    #[account(init, mint::decimals = 6, mint::authority = payer, mint::freeze_authority = payer, payer = payer, )]
         pub mint: Account<'info, Mint>,
         #[account(mut)]
         pub payer: Signer<'info>,
    @@ -233,7 +238,7 @@ pub struct TestInitMint<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitToken<'info> {
    -    #[account(init, token::mint = mint, token::authority = payer, payer = payer)]
    +    #[account(init, token::mint = mint, token::authority = payer, payer = payer, )]
         pub token: Account<'info, TokenAccount>,
         pub mint: Account<'info, Mint>,
         #[account(mut)]
    @@ -246,14 +251,14 @@ pub struct TestInitToken<'info> {
     #[derive(Accounts)]
     pub struct TestCompositePayer<'info> {
         pub composite: TestInit<'info>,
    -    #[account(init, payer = composite.payer, space = 8 + size_of::())]
    +    #[account(init, payer = composite.payer, space = Data::LEN + 8)]
         pub data: Account<'info, Data>,
         pub system_program: Program<'info, System>,
     }
     
     #[derive(Accounts)]
     pub struct TestFetchAll<'info> {
    -    #[account(init, payer = authority)]
    +    #[account(init, payer = authority, space = DataWithFilter::LEN + 8)]
         pub data: Account<'info, DataWithFilter>,
         #[account(mut)]
         pub authority: Signer<'info>,
    @@ -262,7 +267,7 @@ pub struct TestFetchAll<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitWithEmptySeeds<'info> {
    -    #[account(init, seeds = [], bump, payer = authority, space = 8 + size_of::())]
    +    #[account(init, seeds = [], bump, payer = authority, space = Data::LEN + 8)]
         pub pda: Account<'info, Data>,
         #[account(mut)]
         pub authority: Signer<'info>,
    @@ -278,7 +283,7 @@ pub struct TestEmptySeedsConstraint<'info> {
     
     #[derive(Accounts)]
     pub struct InitWithSpace<'info> {
    -    #[account(init, payer = payer)]
    +    #[account(init, payer = payer, space = DataU16::LEN + 8)]
         pub data: Account<'info, DataU16>,
         #[account(mut)]
         pub payer: Signer<'info>,
    @@ -287,7 +292,8 @@ pub struct InitWithSpace<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitIfNeeded<'info> {
    -    #[account(init_if_needed, payer = payer, space = 500)]
    +    // intentionally using more space (+500) to check whether space is checked when using init_if_needed
    +    #[account(init_if_needed, payer = payer, space = DataU16::LEN + 8 + 500)]
         pub data: Account<'info, DataU16>,
         #[account(mut)]
         pub payer: Signer<'info>,
    @@ -335,7 +341,7 @@ pub struct TestInitMintIfNeeded<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitTokenIfNeeded<'info> {
    -    #[account(init_if_needed, token::mint = mint, token::authority = authority, payer = payer)]
    +    #[account(init_if_needed, token::mint = mint, token::authority = authority, payer = payer, )]
         pub token: Account<'info, TokenAccount>,
         pub mint: Account<'info, Mint>,
         #[account(mut)]
    @@ -353,7 +359,7 @@ pub struct TestInitAssociatedTokenIfNeeded<'info> {
             init_if_needed,
             payer = payer,
             associated_token::mint = mint,
    -        associated_token::authority = authority,
    +        associated_token::authority = authority
         )]
         pub token: Account<'info, TokenAccount>,
         pub mint: Account<'info, Mint>,
    diff --git a/tests/misc/tests/misc.js b/tests/misc/tests/misc.js
    index fc1b7983d6..3e6cd982f4 100644
    --- a/tests/misc/tests/misc.js
    +++ b/tests/misc/tests/misc.js
    @@ -1002,7 +1002,8 @@ describe("misc", () => {
     
       it("init_if_needed throws if account exists but is not the expected space", async () => {
         const newAcc = anchor.web3.Keypair.generate();
    -    await program.rpc.initWithSpace(3, {
    +    const _irrelevantForTest = 3;
    +    await program.rpc.initWithSpace(_irrelevantForTest, {
           accounts: {
             data: newAcc.publicKey,
             systemProgram: anchor.web3.SystemProgram.programId,
    @@ -1012,7 +1013,7 @@ describe("misc", () => {
         });
     
         try {
    -      await program.rpc.testInitIfNeeded(3, {
    +      await program.rpc.testInitIfNeeded(_irrelevantForTest, {
             accounts: {
               data: newAcc.publicKey,
               systemProgram: anchor.web3.SystemProgram.programId,
    diff --git a/tests/multisig/package.json b/tests/multisig/package.json
    index 4cc2b97c91..f7a64a3fbc 100644
    --- a/tests/multisig/package.json
    +++ b/tests/multisig/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "multisig",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/package.json b/tests/package.json
    index a31b05b4da..568c0bb2b4 100644
    --- a/tests/package.json
    +++ b/tests/package.json
    @@ -33,7 +33,7 @@
         "declare-id"
       ],
       "dependencies": {
    -    "@project-serum/anchor": "^0.22.0",
    +    "@project-serum/anchor": "^0.22.1",
         "@project-serum/common": "^0.0.1-beta.3",
         "@project-serum/serum": "^0.13.60",
         "@solana/spl-token": "^0.1.8"
    diff --git a/tests/pda-derivation/package.json b/tests/pda-derivation/package.json
    index b4558ec2d6..12dfc09cb0 100644
    --- a/tests/pda-derivation/package.json
    +++ b/tests/pda-derivation/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "pda-derivation",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/pyth/package.json b/tests/pyth/package.json
    index 9631a37474..1f608ec267 100644
    --- a/tests/pyth/package.json
    +++ b/tests/pyth/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "pyth",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/safety-checks/programs/account-info/Cargo.toml b/tests/safety-checks/programs/account-info/Cargo.toml
    index 56dd899ba7..d0a91cef8f 100644
    --- a/tests/safety-checks/programs/account-info/Cargo.toml
    +++ b/tests/safety-checks/programs/account-info/Cargo.toml
    @@ -16,4 +16,4 @@ cpi = ["no-entrypoint"]
     default = []
     
     [dependencies]
    -anchor-lang = "0.22.0"
    +anchor-lang = "0.22.1"
    diff --git a/tests/spl/token-proxy/package.json b/tests/spl/token-proxy/package.json
    index 1493484c32..4957a6a094 100644
    --- a/tests/spl/token-proxy/package.json
    +++ b/tests/spl/token-proxy/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "token-proxy",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/swap/package.json b/tests/swap/package.json
    index a9f43c5aa5..c9de50c4c4 100644
    --- a/tests/swap/package.json
    +++ b/tests/swap/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "swap",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/system-accounts/package.json b/tests/system-accounts/package.json
    index a9d4a5df41..9b889d726d 100644
    --- a/tests/system-accounts/package.json
    +++ b/tests/system-accounts/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "system-accounts",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/sysvars/package.json b/tests/sysvars/package.json
    index 0892a899de..c830394806 100644
    --- a/tests/sysvars/package.json
    +++ b/tests/sysvars/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "sysvars",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/sysvars/tests/sysvars.js b/tests/sysvars/tests/sysvars.js
    index a0c021fd24..b350472cba 100644
    --- a/tests/sysvars/tests/sysvars.js
    +++ b/tests/sysvars/tests/sysvars.js
    @@ -1,18 +1,39 @@
     const anchor = require("@project-serum/anchor");
    +const assert = require("assert");
     
     describe("sysvars", () => {
       // Configure the client to use the local cluster.
       anchor.setProvider(anchor.Provider.local());
    +  const program = anchor.workspace.Sysvars;
     
       it("Is initialized!", async () => {
    -    const program = anchor.workspace.Sysvars;
    -    const tx = await program.rpc.sysvars({
    -      accounts: {
    +    const tx = await program.methods
    +      .sysvars()
    +      .accounts({
             clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
             rent: anchor.web3.SYSVAR_RENT_PUBKEY,
             stakeHistory: anchor.web3.SYSVAR_STAKE_HISTORY_PUBKEY,
    -      },
    -    });
    +      })
    +      .rpc();
         console.log("Your transaction signature", tx);
       });
    +
    +  it("Fails when the wrote pubkeys are provided", async () => {
    +    try {
    +      await program.methods
    +        .sysvars()
    +        .accounts({
    +          clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
    +          rent: anchor.web3.SYSVAR_RENT_PUBKEY,
    +          stakeHistory: anchor.web3.SYSVAR_REWARDS_PUBKEY,
    +        })
    +        .rpc();
    +      assert.ok(false);
    +    } catch (err) {
    +      const errMsg = "The given public key does not match the required sysvar";
    +      assert.strictEqual(err.toString(), errMsg);
    +      assert.strictEqual(err.msg, errMsg);
    +      assert.strictEqual(err.code, 3015);
    +    }
    +  });
     });
    diff --git a/tests/tictactoe/package.json b/tests/tictactoe/package.json
    index 2ac71d4411..632d97bbc0 100644
    --- a/tests/tictactoe/package.json
    +++ b/tests/tictactoe/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "tictactoe",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/typescript/package.json b/tests/typescript/package.json
    index b35595390e..3e37ccfb6d 100644
    --- a/tests/typescript/package.json
    +++ b/tests/typescript/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "typescript-example",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/zero-copy/package.json b/tests/zero-copy/package.json
    index 81c2c32027..2568b8a35c 100644
    --- a/tests/zero-copy/package.json
    +++ b/tests/zero-copy/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "zero-copy",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/zero-copy/programs/zero-copy/src/lib.rs b/tests/zero-copy/programs/zero-copy/src/lib.rs
    index 58b1beb68a..c6076ea9ff 100644
    --- a/tests/zero-copy/programs/zero-copy/src/lib.rs
    +++ b/tests/zero-copy/programs/zero-copy/src/lib.rs
    @@ -97,7 +97,8 @@ pub struct CreateBar<'info> {
             init,
             seeds = [authority.key().as_ref(), foo.key().as_ref()],
             bump,
    -        payer = authority, owner = *program_id
    +        payer = authority, owner = *program_id,
    +        space = Bar::LEN + 8
         )]
         bar: AccountLoader<'info, Bar>,
         #[account(mut)]
    @@ -132,8 +133,8 @@ pub struct UpdateLargeAccount<'info> {
     }
     
     #[account(zero_copy)]
    -#[derive(Default)]
     #[repr(packed)]
    +#[derive(Default)]
     pub struct Foo {
         pub authority: Pubkey,
         pub data: u64,
    @@ -143,10 +144,13 @@ pub struct Foo {
     }
     
     #[account(zero_copy)]
    -#[derive(Default)]
     pub struct Bar {
    -    pub authority: Pubkey,
    -    pub data: u64,
    +    pub authority: Pubkey, // 32
    +    pub data: u64,         // 8
    +}
    +
    +impl Bar {
    +    pub const LEN: usize = 32 + 8;
     }
     
     #[account(zero_copy)]
    diff --git a/ts/package.json b/ts/package.json
    index 9622e394cb..d380d0f791 100644
    --- a/ts/package.json
    +++ b/ts/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@project-serum/anchor",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "description": "Anchor client",
       "module": "./dist/esm/index.js",
       "main": "./dist/cjs/index.js",
    diff --git a/ts/src/coder/borsh/instruction.ts b/ts/src/coder/borsh/instruction.ts
    index 224ef1937e..bcb152b647 100644
    --- a/ts/src/coder/borsh/instruction.ts
    +++ b/ts/src/coder/borsh/instruction.ts
    @@ -269,7 +269,8 @@ class InstructionFormatter {
             ? "null"
             : this.formatIdlData(
                 { name: "", type: (idlField.type).option },
    -            data
    +            data,
    +            types
               );
         }
         if (idlField.type.hasOwnProperty("defined")) {
    diff --git a/ts/src/error.ts b/ts/src/error.ts
    index a508441281..03ae9be10c 100644
    --- a/ts/src/error.ts
    +++ b/ts/src/error.ts
    @@ -111,6 +111,7 @@ const LangErrorCode = {
       AccountNotInitialized: 3012,
       AccountNotProgramData: 3013,
       AccountNotAssociatedTokenAccount: 3014,
    +  AccountSysvarMismatch: 3015,
       // State.
       StateInvalidAddress: 4000,
     
    @@ -227,6 +228,10 @@ const LangErrorMessage = new Map([
         LangErrorCode.AccountNotAssociatedTokenAccount,
         "The given account is not the associated token account",
       ],
    +  [
    +    LangErrorCode.AccountSysvarMismatch,
    +    "The given public key does not match the required sysvar",
    +  ],
     
       // State.
       [
    diff --git a/ts/src/program/accounts-resolver.ts b/ts/src/program/accounts-resolver.ts
    index 758d54a304..a2bc005bba 100644
    --- a/ts/src/program/accounts-resolver.ts
    +++ b/ts/src/program/accounts-resolver.ts
    @@ -10,6 +10,13 @@ import { coder } from "../spl/token";
     
     // Populates a given accounts context with PDAs and common missing accounts.
     export class AccountsResolver> {
    +  static readonly CONST_ACCOUNTS = {
    +    systemProgram: SystemProgram.programId,
    +    tokenProgram: TOKEN_PROGRAM_ID,
    +    associatedTokenProgram: ASSOCIATED_PROGRAM_ID,
    +    rent: SYSVAR_RENT_PUBKEY,
    +  };
    +
       private _accountStore: AccountStore;
     
       constructor(
    @@ -40,40 +47,28 @@ export class AccountsResolver> {
           const accountDescName = camelCase(accountDesc.name);
     
           // PDA derived from IDL seeds.
    -      if (accountDesc.pda && accountDesc.pda.seeds.length > 0) {
    -        if (this._accounts[accountDescName] === undefined) {
    -          await this.autoPopulatePda(accountDesc);
    -          continue;
    -        }
    +      if (
    +        accountDesc.pda &&
    +        accountDesc.pda.seeds.length > 0 &&
    +        !this._accounts[accountDescName]
    +      ) {
    +        await this.autoPopulatePda(accountDesc);
    +        continue;
           }
     
           // Signers default to the provider.
    -      if (
    -        accountDesc.isSigner &&
    -        this._accounts[accountDescName] === undefined
    -      ) {
    +      if (accountDesc.isSigner && !this._accounts[accountDescName]) {
             this._accounts[accountDescName] = this._provider.wallet.publicKey;
             continue;
           }
     
           // Common accounts are auto populated with magic names by convention.
    -      switch (accountDescName) {
    -        case "systemProgram":
    -          if (this._accounts[accountDescName] === undefined) {
    -            this._accounts[accountDescName] = SystemProgram.programId;
    -          }
    -        case "rent":
    -          if (this._accounts[accountDescName] === undefined) {
    -            this._accounts[accountDescName] = SYSVAR_RENT_PUBKEY;
    -          }
    -        case "tokenProgram":
    -          if (this._accounts[accountDescName] === undefined) {
    -            this._accounts[accountDescName] = TOKEN_PROGRAM_ID;
    -          }
    -        case "associatedTokenProgram":
    -          if (this._accounts[accountDescName] === undefined) {
    -            this._accounts[accountDescName] = ASSOCIATED_PROGRAM_ID;
    -          }
    +      if (
    +        Reflect.has(AccountsResolver.CONST_ACCOUNTS, accountDescName) &&
    +        !this._accounts[accountDescName]
    +      ) {
    +        this._accounts[accountDescName] =
    +          AccountsResolver.CONST_ACCOUNTS[accountDescName];
           }
         }
       }
    @@ -234,7 +229,7 @@ export class AccountStore {
         publicKey: PublicKey
       ): Promise {
         const address = publicKey.toString();
    -    if (this._cache.get(address) === undefined) {
    +    if (!this._cache.has(address)) {
           if (name === "TokenAccount") {
             const accountInfo = await this._provider.connection.getAccountInfo(
               publicKey
    diff --git a/ts/src/program/index.ts b/ts/src/program/index.ts
    index 7971fa396a..04c6bca041 100644
    --- a/ts/src/program/index.ts
    +++ b/ts/src/program/index.ts
    @@ -77,6 +77,7 @@ export class Program {
        *   },
        * });
        * ```
    +   * @deprecated
        */
       readonly rpc: RpcNamespace;
     
    @@ -130,6 +131,7 @@ export class Program {
        *   },
        * });
        * ```
    +   * @deprecated
        */
       readonly instruction: InstructionNamespace;
     
    @@ -161,6 +163,7 @@ export class Program {
        *   },
        * });
        * ```
    +   * @deprecated
        */
       readonly transaction: TransactionNamespace;
     
    @@ -197,6 +200,7 @@ export class Program {
        *   },
        * });
        * ```
    +   * @deprecated
        */
       readonly simulate: SimulateNamespace;
     
    diff --git a/ts/src/program/namespace/index.ts b/ts/src/program/namespace/index.ts
    index f7e994dfd7..e84695cfff 100644
    --- a/ts/src/program/namespace/index.ts
    +++ b/ts/src/program/namespace/index.ts
    @@ -10,7 +10,6 @@ import RpcFactory, { RpcNamespace } from "./rpc.js";
     import AccountFactory, { AccountNamespace } from "./account.js";
     import SimulateFactory, { SimulateNamespace } from "./simulate.js";
     import { parseIdlErrors } from "../common.js";
    -import { AllInstructions } from "./types.js";
     import { MethodsBuilderFactory, MethodsNamespace } from "./methods";
     
     // Re-exports.
    @@ -55,8 +54,8 @@ export default class NamespaceFactory {
     
         const state = StateFactory.build(idl, coder, programId, provider);
     
    -    idl.instructions.forEach(>(idlIx: I) => {
    -      const ixItem = InstructionFactory.build(
    +    idl.instructions.forEach((idlIx) => {
    +      const ixItem = InstructionFactory.build(
             idlIx,
             (ixName, ix) => coder.instruction.encode(ixName, ix),
             programId
    @@ -72,7 +71,7 @@ export default class NamespaceFactory {
             programId,
             idl
           );
    -      const methodItem = MethodsBuilderFactory.build(
    +      const methodItem = MethodsBuilderFactory.build(
             provider,
             programId,
             idlIx,
    diff --git a/ts/src/program/namespace/methods.ts b/ts/src/program/namespace/methods.ts
    index bf28812acc..d55bddeea1 100644
    --- a/ts/src/program/namespace/methods.ts
    +++ b/ts/src/program/namespace/methods.ts
    @@ -17,6 +17,7 @@ import { SimulateFn } from "./simulate.js";
     import Provider from "../../provider.js";
     import { AccountNamespace } from "./account.js";
     import { AccountsResolver } from "../accounts-resolver.js";
    +import { Accounts } from "../context.js";
     
     export type MethodsNamespace<
       IDL extends Idl = Idl,
    @@ -33,9 +34,9 @@ export class MethodsBuilderFactory {
         rpcFn: RpcFn,
         simulateFn: SimulateFn,
         accountNamespace: AccountNamespace
    -  ): MethodsFn {
    -    const request: MethodsFn = (...args) => {
    -      return new MethodsBuilder(
    +  ): MethodsFn> {
    +    return (...args) =>
    +      new MethodsBuilder(
             args,
             ixFn,
             txFn,
    @@ -46,13 +47,11 @@ export class MethodsBuilderFactory {
             idlIx,
             accountNamespace
           );
    -    };
    -    return request;
       }
     }
     
     export class MethodsBuilder> {
    -  readonly _accounts: { [name: string]: PublicKey } = {};
    +  private readonly _accounts: { [name: string]: PublicKey } = {};
       private _remainingAccounts: Array = [];
       private _signers: Array = [];
       private _preInstructions: Array = [];
    @@ -80,8 +79,9 @@ export class MethodsBuilder> {
         );
       }
     
    -  // TODO: don't use any.
    -  public accounts(accounts: any): MethodsBuilder {
    +  public accounts(
    +    accounts: Partial>
    +  ): MethodsBuilder {
         Object.assign(this._accounts, accounts);
         return this;
       }
    @@ -112,7 +112,7 @@ export class MethodsBuilder> {
         return this;
       }
     
    -  public async rpc(options: ConfirmOptions): Promise {
    +  public async rpc(options?: ConfirmOptions): Promise {
         await this._accountsResolver.resolve();
         // @ts-ignore
         return this._rpcFn(...this._args, {
    @@ -126,7 +126,7 @@ export class MethodsBuilder> {
       }
     
       public async simulate(
    -    options: ConfirmOptions
    +    options?: ConfirmOptions
       ): Promise> {
         await this._accountsResolver.resolve();
         // @ts-ignore
    diff --git a/ts/src/program/namespace/types.ts b/ts/src/program/namespace/types.ts
    index 1fe703a651..337adde69b 100644
    --- a/ts/src/program/namespace/types.ts
    +++ b/ts/src/program/namespace/types.ts
    @@ -10,6 +10,7 @@ import {
       IdlTypeDefTyStruct,
     } from "../../idl";
     import { Accounts, Context } from "../context";
    +import { MethodsBuilder } from "./methods";
     
     /**
      * All instructions for an IDL.
    @@ -66,7 +67,11 @@ export type MakeInstructionsNamespace<
     };
     
     export type MakeMethodsNamespace = {
    -  [M in keyof InstructionMap]: MethodsFn[M], any>;
    +  [M in keyof InstructionMap]: MethodsFn<
    +    IDL,
    +    InstructionMap[M],
    +    MethodsBuilder[M]>
    +  >;
     };
     
     export type InstructionContextFn<