Merge branch 'master' into cli-workspace

This commit is contained in:
Paul Schaaf 2022-03-07 14:23:45 -05:00
commit b6b209840c
No known key found for this signature in database
GPG Key ID: 832D12D4356B4331
90 changed files with 476 additions and 320 deletions

View File

@ -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 }}

View File

@ -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

View File

@ -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).

30
Cargo.lock generated
View File

@ -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",

View File

@ -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<Initialize>, start: u64) -> ProgramResult {
pub fn initialize(ctx: Context<Initialize>, start: u64) -> Result<()> {
let counter = &mut ctx.accounts.counter;
counter.authority = *ctx.accounts.authority.key;
counter.count = start;
Ok(())
}
pub fn increment(ctx: Context<Increment>) -> ProgramResult {
pub fn increment(ctx: Context<Increment>) -> 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 ❤️

View File

@ -1 +1 @@
0.22.0
0.22.1

View File

@ -1,6 +1,6 @@
[package]
name = "avm"
version = "0.22.0"
version = "0.22.1"
edition = "2018"
[[bin]]

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-cli"
version = "0.22.0"
version = "0.22.1"
authors = ["armaniferrante <armaniferrante@gmail.com>"]
edition = "2018"

View File

@ -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": {

View File

@ -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"
}}

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-client"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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"] }

View File

@ -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,

View File

@ -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"]

View File

@ -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:<version>`. 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:<version>`. 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

View File

@ -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.

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -13,7 +13,7 @@
"basic-4"
],
"dependencies": {
"@project-serum/anchor": "^0.22.0"
"@project-serum/anchor": "^0.22.1"
},
"devDependencies": {
"mocha": "^9.1.3",

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-lang"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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"

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-attribute-access-control"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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"

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-attribute-account"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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"

View File

@ -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.

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-attribute-constant"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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" }

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-attribute-error"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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" }

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-attribute-event"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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"] }

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-attribute-interface"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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"

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-attribute-program"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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" }

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-attribute-state"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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" }

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-derive-accounts"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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" }

View File

@ -89,7 +89,6 @@ use syn::parse_macro_input;
/// </tr>
/// <tr>
/// <td>
/// <code>#[account(init, payer = &lt;target_account&gt;)]</code><br><br>
/// <code>#[account(init, payer = &lt;target_account&gt;, space = &lt;num_bytes&gt;)]</code>
/// </td>
/// <td>
@ -110,14 +109,12 @@ use syn::parse_macro_input;
/// and be called <code>system_program</code>.
/// </li>
/// <li>
/// Requires that the <code>space</code> constraint is specified
/// or, if creating an <code>Account</code> type, the <code>T</code> of <code>Account</code>
/// to implement the rust std <code>Default</code> trait.<br>
/// Requires that the <code>space</code> constraint is specified.
/// When using the <code>space</code> constraint, one must remember to add 8 to it
/// which is the size of the account discriminator.<br>
/// The given number is the size of the account in bytes, so accounts that hold
/// a variable number of items such as a <code>Vec</code> should use the <code>space</code>
/// constraint instead of using the <code>Default</code> 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.<br>
/// The given space number is the size of the account in bytes, so accounts that hold
/// a variable number of items such as a <code>Vec</code> should allocate sufficient space for all items that may
/// be added to the data structure because account size is fixed. Check out the <a href = "https://borsh.io/" target = "_blank" rel = "noopener noreferrer">borsh library</a>
/// (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:
/// <pre>
/// #[account]
/// #[derive(Default)]
/// pub struct MyData {
/// &nbsp;&nbsp;&nbsp;&nbsp;pub data: u64
/// }&#10;
/// #[account]
/// pub struct OtherData {
/// &nbsp;&nbsp;&nbsp;&nbsp;pub data: u64
/// }&#10;
/// #[derive(Accounts)]
/// pub struct Initialize<'info> {
/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(init, payer = payer)]
/// &nbsp;&nbsp;&nbsp;&nbsp;pub data_account: Account<'info, MyData>,
/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(init, payer = payer, space = 8 + 8)]
/// &nbsp;&nbsp;&nbsp;&nbsp;pub data_account_two: Account<'info, OtherData>,
/// &nbsp;&nbsp;&nbsp;&nbsp;pub data_account_two: Account<'info, MyData>,
/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(mut)]
/// &nbsp;&nbsp;&nbsp;&nbsp;pub payer: Signer<'info>,
/// &nbsp;&nbsp;&nbsp;&nbsp;pub system_program: Program<'info, System>,
@ -172,7 +162,7 @@ use syn::parse_macro_input;
/// #[instruction(bump: u8)]
/// pub struct Initialize<'info> {
/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init, payer = payer,
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init, payer = payer, space = 8 + 8
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seeds = [b"example_seed".as_ref()], bump = bump
/// &nbsp;&nbsp;&nbsp;&nbsp;)]
/// &nbsp;&nbsp;&nbsp;&nbsp;pub pda_data_account: Account<'info, MyData>,
@ -182,7 +172,7 @@ use syn::parse_macro_input;
/// &nbsp;&nbsp;&nbsp;&nbsp;)]
/// &nbsp;&nbsp;&nbsp;&nbsp;pub account_for_other_program: AccountInfo<'info>,
/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init,payer = payer, space = 8 + 8,
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init, payer = payer, space = 8 + 8,
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;owner = other_program.key(),
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seeds = [b"other_seed".as_ref()], bump
/// &nbsp;&nbsp;&nbsp;&nbsp;)]

View File

@ -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<Sysvar<'info, T>> {
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()),
}
}
}

View File

@ -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

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-syn"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
repository = "https://github.com/project-serum/anchor"
license = "Apache-2.0"

View File

@ -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!()
};

View File

@ -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!()
};

View File

@ -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.

View File

@ -353,7 +353,7 @@ fn parse_account_derives(ctx: &CrateContext) -> HashMap<String, AccountsStruct>
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));
}

View File

@ -721,7 +721,7 @@ pub enum ConstraintRentExempt {
pub struct ConstraintInitGroup {
pub if_needed: bool,
pub seeds: Option<ConstraintSeedsGroup>,
pub payer: Option<Expr>,
pub payer: Expr,
pub space: Option<Expr>,
pub kind: InitKind,
}

View File

@ -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 {

View File

@ -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(),

View File

@ -1,6 +1,6 @@
[package]
name = "anchor-spl"
version = "0.22.0"
version = "0.22.1"
authors = ["Serum Foundation <foundation@projectserum.com>"]
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 }

View File

@ -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)]

View File

@ -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>,

View File

@ -1,6 +1,6 @@
{
"dependencies": {
"@project-serum/anchor": "^0.22.0"
"@project-serum/anchor": "^0.22.1"
},
"devDependencies": {
"chai": "^4.3.4",

View File

@ -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>,

View File

@ -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": {

View File

@ -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": {

View File

@ -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<'info, Officer>>,
#[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<'info, TokenAccount>>,
#[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<'info, TokenAccount>>,
#[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<'info, TokenAccount>>,
#[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<'info, TokenAccount>>,
#[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.

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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>,
}

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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<Account<'info, IdoAccount>>,
// 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<'info, Mint>>,
#[account(constraint = watermelon_mint.key() == ido_authority_watermelon.mint)]
pub watermelon_mint: Box<Account<'info, Mint>>,
@ -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<'info, TokenAccount>>,
#[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<Account<'info, TokenAccount>>,
// 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<Account<'info, TokenAccount>>,
// 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<'info, TokenAccount>>,
#[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 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,
pub redeemable_mint: Pubkey,
pub watermelon_mint: Pubkey,
pub pool_usdc: Pubkey,
pub pool_watermelon: Pubkey,
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,
pub ido_times: IdoTimes,
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]

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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);

View File

@ -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::<DataZeroCopy>())]
#[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::<Data>())]
#[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::<Data>())]
#[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>,

View File

@ -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,

View File

@ -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": {

View File

@ -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"

View File

@ -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": {

View File

@ -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": {

View File

@ -16,4 +16,4 @@ cpi = ["no-entrypoint"]
default = []
[dependencies]
anchor-lang = "0.22.0"
anchor-lang = "0.22.1"

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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);
}
});
});

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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)]

View File

@ -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",

View File

@ -269,7 +269,8 @@ class InstructionFormatter {
? "null"
: this.formatIdlData(
{ name: "", type: (<IdlTypeOption>idlField.type).option },
data
data,
types
);
}
if (idlField.type.hasOwnProperty("defined")) {

View File

@ -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.
[

View File

@ -10,6 +10,13 @@ import { coder } from "../spl/token";
// Populates a given accounts context with PDAs and common missing accounts.
export class AccountsResolver<IDL extends Idl, I extends AllInstructions<IDL>> {
static readonly CONST_ACCOUNTS = {
systemProgram: SystemProgram.programId,
tokenProgram: TOKEN_PROGRAM_ID,
associatedTokenProgram: ASSOCIATED_PROGRAM_ID,
rent: SYSVAR_RENT_PUBKEY,
};
private _accountStore: AccountStore<IDL>;
constructor(
@ -40,40 +47,28 @@ export class AccountsResolver<IDL extends Idl, I extends AllInstructions<IDL>> {
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<IDL extends Idl> {
publicKey: PublicKey
): Promise<T> {
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

View File

@ -77,6 +77,7 @@ export class Program<IDL extends Idl = Idl> {
* },
* });
* ```
* @deprecated
*/
readonly rpc: RpcNamespace<IDL>;
@ -130,6 +131,7 @@ export class Program<IDL extends Idl = Idl> {
* },
* });
* ```
* @deprecated
*/
readonly instruction: InstructionNamespace<IDL>;
@ -161,6 +163,7 @@ export class Program<IDL extends Idl = Idl> {
* },
* });
* ```
* @deprecated
*/
readonly transaction: TransactionNamespace<IDL>;
@ -197,6 +200,7 @@ export class Program<IDL extends Idl = Idl> {
* },
* });
* ```
* @deprecated
*/
readonly simulate: SimulateNamespace<IDL>;

View File

@ -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(<I extends AllInstructions<IDL>>(idlIx: I) => {
const ixItem = InstructionFactory.build<IDL, I>(
idl.instructions.forEach((idlIx) => {
const ixItem = InstructionFactory.build<IDL, typeof idlIx>(
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<IDL, typeof idlIx>(
provider,
programId,
idlIx,

View File

@ -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<IDL>,
simulateFn: SimulateFn<IDL>,
accountNamespace: AccountNamespace<IDL>
): MethodsFn<IDL, I, any> {
const request: MethodsFn<IDL, I, any> = (...args) => {
return new MethodsBuilder(
): MethodsFn<IDL, I, MethodsBuilder<IDL, I>> {
return (...args) =>
new MethodsBuilder(
args,
ixFn,
txFn,
@ -46,13 +47,11 @@ export class MethodsBuilderFactory {
idlIx,
accountNamespace
);
};
return request;
}
}
export class MethodsBuilder<IDL extends Idl, I extends AllInstructions<IDL>> {
readonly _accounts: { [name: string]: PublicKey } = {};
private readonly _accounts: { [name: string]: PublicKey } = {};
private _remainingAccounts: Array<AccountMeta> = [];
private _signers: Array<Signer> = [];
private _preInstructions: Array<TransactionInstruction> = [];
@ -80,8 +79,9 @@ export class MethodsBuilder<IDL extends Idl, I extends AllInstructions<IDL>> {
);
}
// TODO: don't use any.
public accounts(accounts: any): MethodsBuilder<IDL, I> {
public accounts(
accounts: Partial<Accounts<I["accounts"][number]>>
): MethodsBuilder<IDL, I> {
Object.assign(this._accounts, accounts);
return this;
}
@ -112,7 +112,7 @@ export class MethodsBuilder<IDL extends Idl, I extends AllInstructions<IDL>> {
return this;
}
public async rpc(options: ConfirmOptions): Promise<TransactionSignature> {
public async rpc(options?: ConfirmOptions): Promise<TransactionSignature> {
await this._accountsResolver.resolve();
// @ts-ignore
return this._rpcFn(...this._args, {
@ -126,7 +126,7 @@ export class MethodsBuilder<IDL extends Idl, I extends AllInstructions<IDL>> {
}
public async simulate(
options: ConfirmOptions
options?: ConfirmOptions
): Promise<SimulateResponse<any, any>> {
await this._accountsResolver.resolve();
// @ts-ignore

View File

@ -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<IDL extends Idl, I extends IdlInstruction> = {
[M in keyof InstructionMap<I>]: MethodsFn<IDL, InstructionMap<I>[M], any>;
[M in keyof InstructionMap<I>]: MethodsFn<
IDL,
InstructionMap<I>[M],
MethodsBuilder<IDL, InstructionMap<I>[M]>
>;
};
export type InstructionContextFn<