Compare commits
190 Commits
4230dce7c0
...
e5c8fbba3f
Author | SHA1 | Date |
---|---|---|
skrrb | e5c8fbba3f | |
skrrb | 338b927edc | |
acheron | 81c8c556e8 | |
czkz | c96846fce2 | |
acheron | 10c997552e | |
Sundeep Charan Ramkumar | 827c986618 | |
acheron | fefa69519f | |
zeroc | b53bb35cf2 | |
fedoras | 7515c919f8 | |
Syed Aabis Akhtar | 8e8df76eda | |
acheron | 852fcc77be | |
acheron | f74ea64ca6 | |
acheron | 257b560109 | |
acheron | 95c4959287 | |
Bhargava Sai Macha | a18d6caa6d | |
acheron | 7356bd5afe | |
acheron | 1f0bf0ee60 | |
Bhargava Sai Macha | e3ced784ad | |
acheron | ae26fd84bb | |
acheron | 0be5b00a34 | |
acheron | c7ccbb8f62 | |
acheron | 3591ba6cb8 | |
acheron | 01839ad725 | |
acheron | cbf9b0a090 | |
acheron | da2d9a4045 | |
acheron | 2dd79da674 | |
acheron | 5f6af05519 | |
acheron | 4de70aabee | |
acheron | c138a55b72 | |
acheron | 475c694355 | |
amilz | 45c84c524f | |
Jasper | 6aba24e225 | |
acheron | 800d6557b9 | |
acheron | c66b323293 | |
dongjinlong | c2cd5a99aa | |
acheron | 0f6090950a | |
Taylor Johnson | 4393d73d3d | |
acheron | 7c424ee58a | |
Snoppy | 62dccce2ed | |
zilayo | 35142161de | |
acheron | b83d5fd64b | |
Andrei Hrs | cc15435e4d | |
acheron | 8fdc07bffb | |
acheron | d931b31c0a | |
acheron | ddcb3b8260 | |
acheron | d9a9f19394 | |
Nabeel | 23028334f3 | |
cui fliter | 3e2cd0004c | |
acheron | 2f552a17f5 | |
acheron | 216b56e26f | |
acheron | 6716c13b38 | |
Jayden Park | 253501aa89 | |
acheron | 5d5cadebdd | |
Aoi Kurokawa | 8eee184938 | |
acheron | fc8cb5234a | |
Pioua | e21210538d | |
acheron | 359e2718ba | |
Anthony | 08110e63fa | |
acheron | fde00661c1 | |
Aoi Kurokawa | 94fde24339 | |
Mike MacCana | 616dd239c3 | |
acheron | ef836852dd | |
Gabriele Picco | 169264d730 | |
acheron | ef3b149348 | |
acheron | dbb36d211c | |
chalda | bcd7e1719e | |
Ford | 66d2f073bb | |
acheron | 60b10809c0 | |
acheron | c93b33a27e | |
0xabhinav | 211982affc | |
Sabir Khan | 7cbdff657d | |
Neutron | 1a6b5066df | |
acheron | 47ff77f4df | |
acheron | 1fc92ab1e3 | |
acheron | de9901b5fd | |
Jean Marchand (Exotic Markets) | 52fbe55d52 | |
acheron | c4f14b9f6f | |
Jean Marchand (Exotic Markets) | f6a15254d1 | |
acheron | 51ae380574 | |
Joe C | 13fc0bb915 | |
cavemanloverboy | c2b5472d85 | |
Michal Nazarewicz | 250fa8cdc5 | |
Jean Marchand (Exotic Markets) | c402972bf1 | |
acheron | 4c0af6dc53 | |
chalda | 61244a86dc | |
acheron | 8bf7f251ad | |
acheron | 727e6f84cb | |
acheron | dfee9589fd | |
acheron | a423f7855b | |
acheron | 9dd1b54acd | |
Jimii | 38907fa9b2 | |
acheron | beb15cdb37 | |
puhtaytow | d91781f2ce | |
John | 227ccb22fd | |
Aoi Kurokawa | c58d2f232e | |
acheron | d28414efd4 | |
John Anthos | a9c423ef24 | |
acheron | cded9de0a4 | |
John Anthos | 870ee9a876 | |
acheron | 9cb8d0355d | |
acheron | 8f3bb8a556 | |
acheron | 167c8ecbf5 | |
__ | 88f3053645 | |
acheron | 150fc3e832 | |
Michal Nazarewicz | 7e5bdce710 | |
acheron | 5a655b0f65 | |
Jimii | b6e94dacf0 | |
Pierre | 9331908aee | |
vadorovsky | 85a5a9bdfc | |
Sean Young | 749c45a2d9 | |
acheron | e0d0df4ab5 | |
acheron | fc3905a099 | |
acheron | fc9fd6d24b | |
acheron | 88a75aff13 | |
acheron | 4f996d0a58 | |
Pierre | 5900c93310 | |
acheron | 8717364f81 | |
0xWoo | 23eeb1ec2d | |
Jean Marchand (Exotic Markets) | 0fef819e4b | |
acheron | 6cf200493a | |
Jean Marchand (Exotic Markets) | dcafb789e1 | |
Jean Marchand (Exotic Markets) | 243ab75738 | |
acheron | 721eb7a3be | |
acheron | 267c4ceab7 | |
acheron | 5e7fb44518 | |
Fernando Otero | b0e725b5ac | |
acheron | 25b24a1fd3 | |
acheron | 51578bcbc5 | |
Nick Guo | 5602244e1a | |
acheron | f18fd971fb | |
acheron | e1d5e785b8 | |
acheron | d1e32674d5 | |
Sean Young | 3e8bc76d72 | |
acheron | 28adaf2343 | |
Fernando Otero | 99b75a905b | |
acheron | 3c6fc2ba2d | |
acheron | fa9f960a0b | |
acheron | b5f4796156 | |
acheron | fdda604d41 | |
Jesserc | cec9946111 | |
acheron | 4955a92593 | |
acheron | a1e4453a0b | |
acheron | b9fa898384 | |
Will | dcf5928f3f | |
acheron | 115679e675 | |
acheron | a5e4c02de0 | |
Will | a7205af5df | |
acheron | 6f9f7d9369 | |
acheron | 6eacad4b11 | |
acheron | 454f1dd044 | |
Jimii | b5cf67f13b | |
Proph3t | 58428f858d | |
acheron | 4cf447a1c4 | |
acheron | abfdc4e88f | |
acheron | 2af9cc669b | |
Proph3t | be8764b8a8 | |
acheron | b7b8736276 | |
acheron | cad868a052 | |
acheron | 8f30f00ec3 | |
Pierre | df3e95925b | |
acheron | 5eb678a8bf | |
acheron | 4604fbea9c | |
Jean Marchand (Exotic Markets) | c548c85dff | |
Jean Marchand (Exotic Markets) | 2bb3237da6 | |
dromaz | 10eb698912 | |
acheron | 8309bb3ed5 | |
acheron | c306463432 | |
acheron | cf057acac0 | |
acheron | 4e5280be46 | |
Lucas Steuernagel | cfc6d2916b | |
acheron | 472279d10d | |
acheron | b7e91d4d0d | |
Krešimir Klas | 6ef6b79a6c | |
Noah Prince | 0225b7c0fd | |
Jean Marchand (Exotic Markets) | 9ff7dfcf6f | |
chalda | 401d526150 | |
acheron | e55cd3e646 | |
Jean Marchand (Exotic Markets) | 5624bfe0ff | |
acheron | 29b8a72800 | |
Han Yang | 8bdc1b18ea | |
acheron | 9e73317d09 | |
acheron | d41e513351 | |
acheron | b5519a6532 | |
acheron | 9d947cb26b | |
acheron | 78d48552c6 | |
acheron | c2a36f9e42 | |
acheron | e1afcbf71e | |
acheron | c7c73194d8 | |
skrrb | 704692c0e2 | |
skrrb | 34a8e59232 |
|
@ -1 +0,0 @@
|
|||
large-error-threshold = 1_000_000
|
|
@ -10,7 +10,7 @@ runs:
|
|||
path: |
|
||||
~/.cache/solana/
|
||||
~/.local/share/solana/
|
||||
key: solana-${{ runner.os }}-v0000-${{ env.SOLANA_CLI_VERSION }}
|
||||
key: solana-${{ runner.os }}-v0000-${{ env.SOLANA_CLI_VERSION }}-${{ env.SOLANG_VERSION }}
|
||||
- uses: nick-fields/retry@v2
|
||||
if: steps.cache-solana.outputs.cache-hit != 'true'
|
||||
with:
|
||||
|
@ -20,6 +20,18 @@ runs:
|
|||
retry_on: error
|
||||
shell: bash
|
||||
command: sh -c "$(curl -sSfL https://release.solana.com/v${{ env.SOLANA_CLI_VERSION }}/install)"
|
||||
- uses: nick-fields/retry@v2
|
||||
if: steps.cache-solana.outputs.cache-hit != 'true'
|
||||
with:
|
||||
retry_wait_seconds: 300
|
||||
timeout_minutes: 2
|
||||
max_attempts: 10
|
||||
retry_on: error
|
||||
shell: bash
|
||||
command: |
|
||||
curl -sSL -o /home/runner/.local/share/solana/install/active_release/bin/solang \
|
||||
https://github.com/hyperledger/solang/releases/download/v${{ env.SOLANG_VERSION }}/solang-linux-x86-64
|
||||
chmod 755 /home/runner/.local/share/solana/install/active_release/bin/solang
|
||||
- run: echo "/home/runner/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- run: solana-keygen new --no-bip39-passphrase
|
||||
|
|
|
@ -20,7 +20,7 @@ runs:
|
|||
path: |
|
||||
./ts/dist/
|
||||
key: solana-${{ runner.os }}-v0000-${{ env.NODE_VERSION }}-${{ hashFiles('./ts/**/*.ts') }}
|
||||
- run: cd ts/packages/borsh && yarn --frozen-lockfile && yarn build && cd ../../../
|
||||
- run: cd ts/packages/borsh && yarn --frozen-lockfile && yarn build && yarn link && cd ../../../
|
||||
shell: bash
|
||||
- run: cd ts/packages/anchor && yarn --frozen-lockfile && yarn build:node && yarn link && cd ../../../
|
||||
shell: bash
|
||||
|
@ -28,7 +28,7 @@ runs:
|
|||
shell: bash
|
||||
- run: cd ts/packages/spl-token && yarn --frozen-lockfile && yarn build:node && yarn link && cd ../../../
|
||||
shell: bash
|
||||
- run: cd examples/tutorial && yarn link @coral-xyz/anchor && yarn --frozen-lockfile && cd ../../
|
||||
- run: cd examples/tutorial && yarn link @coral-xyz/anchor @coral-xyz/borsh && yarn --frozen-lockfile && cd ../../
|
||||
shell: bash
|
||||
- run: cd tests && yarn link @coral-xyz/anchor && yarn link @coral-xyz/spl-associated-token-account && yarn link @coral-xyz/spl-token && yarn --frozen-lockfile && cd ..
|
||||
- run: cd tests && yarn link @coral-xyz/anchor @coral-xyz/borsh @coral-xyz/spl-associated-token-account @coral-xyz/spl-token && yarn --frozen-lockfile && cd ..
|
||||
shell: bash
|
||||
|
|
|
@ -3,9 +3,9 @@ description: "Setup"
|
|||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- run: sudo apt-get update && sudo apt-get install -y pkg-config build-essential libudev-dev
|
||||
shell: bash
|
||||
- run: echo "ANCHOR_VERSION=$(cat ./VERSION)" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
- run: git submodule update --init --recursive --depth 1
|
||||
shell: bash
|
||||
- run: sudo apt-get update && sudo apt-get install -y pkg-config build-essential libudev-dev
|
||||
shell: bash
|
||||
- run: echo "ANCHOR_VERSION=$(cat ./VERSION)" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
- run: git submodule update --init --recursive --depth 1
|
||||
shell: bash
|
||||
|
|
|
@ -11,7 +11,8 @@ jobs:
|
|||
uses: ./.github/workflows/reusable-tests.yaml
|
||||
with:
|
||||
cache: false
|
||||
solana_cli_version: 1.16.0
|
||||
node_version: 17.0.1
|
||||
solana_cli_version: 1.18.8
|
||||
solang_version: 0.3.2
|
||||
node_version: 18.18.0
|
||||
cargo_profile: release
|
||||
anchor_binary_name: anchor-binary-no-caching
|
||||
|
|
|
@ -9,6 +9,9 @@ on:
|
|||
solana_cli_version:
|
||||
required: true
|
||||
type: string
|
||||
solang_version:
|
||||
required: true
|
||||
type: string
|
||||
node_version:
|
||||
required: true
|
||||
type: string
|
||||
|
@ -21,6 +24,7 @@ on:
|
|||
env:
|
||||
CACHE: inputs.cache
|
||||
SOLANA_CLI_VERSION: ${{ inputs.solana_cli_version }}
|
||||
SOLANG_VERSION: ${{ inputs.solang_version }}
|
||||
NODE_VERSION: ${{ inputs.node_version }}
|
||||
CARGO_PROFILE: ${{ inputs.cargo_profile }}
|
||||
ANCHOR_BINARY_NAME: ${{ inputs.anchor_binary_name }}
|
||||
|
@ -332,34 +336,34 @@ jobs:
|
|||
# - run: cd tests/misc && chmod +x ci.sh && ./ci.sh
|
||||
# - run: cd tests/misc && anchor test --skip-lint
|
||||
|
||||
# TODO: Re-enable after releasing `0.28.0`. See https://github.com/coral-xyz/anchor/pull/2512
|
||||
# test-anchor-init:
|
||||
# needs: setup-anchor-cli
|
||||
# name: Test Anchor Init
|
||||
# runs-on: ubuntu-latest
|
||||
# timeout-minutes: 30
|
||||
# steps:
|
||||
# - uses: actions/checkout@v3
|
||||
# - uses: ./.github/actions/setup/
|
||||
# - uses: ./.github/actions/setup-ts/
|
||||
# - uses: ./.github/actions/setup-solana/
|
||||
test-anchor-init:
|
||||
needs: setup-anchor-cli
|
||||
name: Test Anchor Init
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/setup/
|
||||
- uses: ./.github/actions/setup-ts/
|
||||
- uses: ./.github/actions/setup-solana/
|
||||
|
||||
# - uses: actions/cache@v3
|
||||
# if: ${{ env.CACHE != 'false' }}
|
||||
# name: Cache Cargo registry + index
|
||||
# id: cache-anchor
|
||||
# with:
|
||||
# path: ${{ env.CARGO_CACHE_PATH }}
|
||||
# key: cargo-${{ runner.os }}-${{ env.CARGO_PROFILE }}-anchor-${{ hashFiles('**/Cargo.lock') }}
|
||||
- uses: actions/cache@v3
|
||||
if: ${{ env.CACHE != 'false' }}
|
||||
name: Cache Cargo registry + index
|
||||
id: cache-anchor
|
||||
with:
|
||||
path: ${{ env.CARGO_CACHE_PATH }}
|
||||
key: cargo-${{ runner.os }}-${{ env.CARGO_PROFILE }}-anchor-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# - uses: actions/download-artifact@v3
|
||||
# with:
|
||||
# name: ${{ env.ANCHOR_BINARY_NAME }}
|
||||
# path: ~/.cargo/bin/
|
||||
# - run: chmod +x ~/.cargo/bin/anchor
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ env.ANCHOR_BINARY_NAME }}
|
||||
path: ~/.cargo/bin/
|
||||
- run: chmod +x ~/.cargo/bin/anchor
|
||||
|
||||
# - run: cd "$(mktemp -d)" && anchor init hello-anchor && cd hello-anchor && yarn link @coral-xyz/anchor && yarn && anchor test && yarn lint:fix
|
||||
# - uses: ./.github/actions/git-diff/
|
||||
# TODO: Re-enable once https://github.com/solana-labs/solana/issues/33504 is resolved
|
||||
# - run: cd "$(mktemp -d)" && anchor init hello-anchor && cd hello-anchor && yarn link @coral-xyz/anchor && yarn && anchor test && yarn lint:fix
|
||||
# - uses: ./.github/actions/git-diff/
|
||||
|
||||
test-programs:
|
||||
needs: setup-anchor-cli
|
||||
|
@ -376,10 +380,16 @@ jobs:
|
|||
path: tests/composite
|
||||
- cmd: cd tests/errors && anchor test --skip-lint && npx tsc --noEmit
|
||||
path: tests/errors
|
||||
- cmd: cd tests/spl/metadata && anchor test --skip-lint
|
||||
path: spl/metadata
|
||||
- cmd: cd tests/spl/token-proxy && anchor test --skip-lint
|
||||
path: spl/token-proxy
|
||||
- cmd: cd tests/spl/token-wrapper && anchor test --skip-lint
|
||||
path: spl/token-wrapper
|
||||
- cmd: cd tests/spl/transfer-hook && anchor test --skip-lint
|
||||
path: spl/transfer-hook
|
||||
- cmd: cd tests/spl/token-extensions && anchor test --skip-lint
|
||||
path: spl/token-extensions
|
||||
- cmd: cd tests/multisig && anchor test --skip-lint
|
||||
path: tests/multisig
|
||||
# - cmd: cd tests/lockup && anchor test --skip-lint
|
||||
|
@ -404,21 +414,25 @@ jobs:
|
|||
path: tests/cashiers-check
|
||||
- cmd: cd tests/declare-id && anchor test --skip-lint && npx tsc --noEmit
|
||||
path: tests/declare-id
|
||||
- cmd: cd tests/declare-program && anchor test --skip-lint
|
||||
path: tests/declare-program
|
||||
- cmd: cd tests/typescript && anchor test --skip-lint && npx tsc --noEmit
|
||||
path: tests/typescript
|
||||
- cmd: cd tests/zero-copy && rustup toolchain install 1.66.1-x86_64-unknown-linux-gnu && anchor test --skip-lint && cd programs/zero-copy && cargo test-bpf
|
||||
path: tests/zero-copy
|
||||
# zero-copy tests cause `/usr/bin/ld: final link failed: No space left on device`
|
||||
# on GitHub runners. It is likely caused by `cargo test-sbf` since all other tests
|
||||
# don't have this problem.
|
||||
# TODO: Find a fix.
|
||||
# - cmd: cd tests/zero-copy && anchor test --skip-lint && cd programs/zero-copy && cargo test-sbf
|
||||
# path: tests/zero-copy
|
||||
- cmd: cd tests/chat && anchor test --skip-lint
|
||||
path: tests/chat
|
||||
- cmd: cd tests/ido-pool && anchor test --skip-lint
|
||||
path: tests/ido-pool
|
||||
# - cmd: cd tests/cfo && anchor run test-with-build && cd deps/stake && git checkout Cargo.lock && cd ../swap && git checkout Cargo.lock
|
||||
# path: tests/cfo
|
||||
# TODO: Remove `1.14.18` installation if/when https://github.com/solana-labs/solana/issues/31960 is solved
|
||||
# `auction-house` tests don't work with Solana `1.16.0`, downgrade to `1.14.18`
|
||||
- cmd: cd tests/auction-house && solana-install init 1.14.18 && yarn --frozen-lockfile && anchor test --skip-lint && git checkout Cargo.lock
|
||||
- cmd: cd tests/auction-house && anchor test --skip-lint
|
||||
path: tests/auction-house
|
||||
- cmd: cd tests/floats && yarn --frozen-lockfile && anchor test --skip-lint && npx tsc --noEmit
|
||||
- cmd: cd tests/floats && anchor test --skip-lint && npx tsc --noEmit
|
||||
path: tests/floats
|
||||
- cmd: cd tests/safety-checks && anchor run test
|
||||
path: tests/safety-checks
|
||||
|
@ -444,6 +458,11 @@ jobs:
|
|||
path: tests/anchor-cli-account
|
||||
- cmd: cd tests/bench && anchor test --skip-lint
|
||||
path: tests/bench
|
||||
- cmd: cd tests/idl && ./test.sh
|
||||
path: tests/idl
|
||||
# TODO: Enable when `solang` becomes compatible with the new IDL spec
|
||||
# - cmd: cd tests/solang && anchor test
|
||||
# path: tests/solang
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/setup/
|
||||
|
|
|
@ -14,7 +14,8 @@ jobs:
|
|||
uses: ./.github/workflows/reusable-tests.yaml
|
||||
with:
|
||||
cache: true
|
||||
solana_cli_version: 1.16.0
|
||||
node_version: 17.0.1
|
||||
solana_cli_version: 1.18.8
|
||||
solang_version: 0.3.2
|
||||
node_version: 18.18.0
|
||||
cargo_profile: debug
|
||||
anchor_binary_name: anchor-binary
|
||||
|
|
|
@ -12,7 +12,3 @@
|
|||
path = tests/cfo/deps/stake
|
||||
url = https://github.com/project-serum/stake.git
|
||||
branch = armani/cfo
|
||||
[submodule "tests/auction-house"]
|
||||
path = tests/auction-house
|
||||
url = https://github.com/armaniferrante/auction-house
|
||||
branch = armani/pda
|
||||
|
|
166
CHANGELOG.md
166
CHANGELOG.md
|
@ -12,6 +12,163 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
|
||||
### Features
|
||||
|
||||
- lang: Implement `Arbitrary` trait for the anchor-generated instruction module when the program is compiled with the arbitrary feature (requires the arbitrary crate) ([2518](https://github.com/coral-xyz/anchor/pull/2518)).
|
||||
- avm: Support customizing the installation location using `AVM_HOME` environment variable ([#2917](https://github.com/coral-xyz/anchor/pull/2917))
|
||||
- idl, ts: Add accounts resolution for associated token accounts ([#2927](https://github.com/coral-xyz/anchor/pull/2927))
|
||||
|
||||
### Fixes
|
||||
|
||||
- lang: Eliminate variable allocations that build up stack space for token extension code generation ([#2913](https://github.com/coral-xyz/anchor/pull/2913)).
|
||||
- ts: Fix incorrect `maxSupportedTransactionVersion` in `AnchorProvider.send*()` methods ([#2922](https://github.com/coral-xyz/anchor/pull/2922)).
|
||||
|
||||
### Breaking
|
||||
|
||||
## [0.30.0] - 2024-04-15
|
||||
|
||||
### Features
|
||||
|
||||
- cli: Allow force `init` and `new` ([#2698](https://github.com/coral-xyz/anchor/pull/2698)).
|
||||
- cli: Add verifiable option when `deploy` ([#2705](https://github.com/coral-xyz/anchor/pull/2705)).
|
||||
- cli: Add support for passing arguments to the underlying `solana program deploy` command with `anchor deploy` ([#2709](https://github.com/coral-xyz/anchor/pull/2709)).
|
||||
- lang: Add `InstructionData::write_to` implementation ([#2733](https://github.com/coral-xyz/anchor/pull/2733)).
|
||||
- lang: Add `#[interface(..)]` attribute for instruction discriminator overrides ([#2728](https://github.com/coral-xyz/anchor/pull/2728)).
|
||||
- ts: Add `.interface(..)` method for instruction discriminator overrides ([#2728](https://github.com/coral-xyz/anchor/pull/2728)).
|
||||
- cli: Check `anchor-lang` and CLI version compatibility ([#2753](https://github.com/coral-xyz/anchor/pull/2753)).
|
||||
- ts: Add missing IDL PDA seed types ([#2752](https://github.com/coral-xyz/anchor/pull/2752)).
|
||||
- cli: `idl close` accepts optional `--idl-address` parameter ([#2760](https://github.com/coral-xyz/anchor/pull/2760)).
|
||||
- cli: Add support for simple wildcard patterns in Anchor.toml's `workspace.members` and `workspace.exclude`. ([#2785](https://github.com/coral-xyz/anchor/pull/2785)).
|
||||
- cli: Add `--test-template` option for `init` command ([#2805](https://github.com/coral-xyz/anchor/pull/2805)).
|
||||
- cli: `anchor test` is able to run multiple commands ([#2799](https://github.com/coral-xyz/anchor/pull/2799)).
|
||||
- cli: Check `@coral-xyz/anchor` package and CLI version compatibility ([#2813](https://github.com/coral-xyz/anchor/pull/2813)).
|
||||
- cli: Accept package name as program name ([#2816](https://github.com/coral-xyz/anchor/pull/2816)).
|
||||
- cli: Add ability to build and test only a specified program ([#2823](https://github.com/coral-xyz/anchor/pull/2823)).
|
||||
- idl: Add new IDL spec ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl: Add support for `repr`s ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl: Add support for expression evaluation ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl: Add support for using external types when generating the IDL ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl, ts: Add unit and tuple struct support ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl, ts: Add generics support ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Add `accountsPartial` method to keep the old `accounts` method behavior ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Make `opts` parameter of `AnchorProvider` constructor optional ([#2843](https://github.com/coral-xyz/anchor/pull/2843)).
|
||||
- cli: Add `--no-idl` flag to the `build` command ([#2847](https://github.com/coral-xyz/anchor/pull/2847)).
|
||||
- cli: Add priority fees to idl commands ([#2845](https://github.com/coral-xyz/anchor/pull/2845)).
|
||||
- ts: Add `prepend` option to MethodBuilder `preInstructions` method ([#2863](https://github.com/coral-xyz/anchor/pull/2863)).
|
||||
- lang: Add `declare_program!` macro ([#2857](https://github.com/coral-xyz/anchor/pull/2857)).
|
||||
- cli: Add `deactivate_feature` flag to `solana-test-validator` config in Anchor.toml ([#2872](https://github.com/coral-xyz/anchor/pull/2872)).
|
||||
- idl: Add `docs` field for constants ([#2887](https://github.com/coral-xyz/anchor/pull/2887)).
|
||||
- idl: Store deployment addresses for other clusters ([#2892](https://github.com/coral-xyz/anchor/pull/2892)).
|
||||
- lang: Add `Event` utility type to get events from bytes ([#2897](https://github.com/coral-xyz/anchor/pull/2897)).
|
||||
- lang, spl: Add support for [token extensions](https://solana.com/solutions/token-extensions) ([#2789](https://github.com/coral-xyz/anchor/pull/2789)).
|
||||
- lang: Return overflow error from `Lamports` trait operations ([#2907](https://github.com/coral-xyz/anchor/pull/2907)).
|
||||
|
||||
### Fixes
|
||||
|
||||
- syn: Add missing `new_from_array` method to `Hash` ([#2682](https://github.com/coral-xyz/anchor/pull/2682)).
|
||||
- cli: Switch to Cargo feature resolver(`resolver = "2"`) ([#2676](https://github.com/coral-xyz/anchor/pull/2676)).
|
||||
- cli: Fix using user specific path for `provider.wallet` in `Anchor.toml` ([#2696](https://github.com/coral-xyz/anchor/pull/2696)).
|
||||
- syn: Fix IDL constant seeds parsing ([#2699](https://github.com/coral-xyz/anchor/pull/2699)).
|
||||
- cli: Display errors if toolchain override restoration fails ([#2700](https://github.com/coral-xyz/anchor/pull/2700)).
|
||||
- cli: Fix commit based `anchor_version` override ([#2704](https://github.com/coral-xyz/anchor/pull/2704)).
|
||||
- spl: Fix compilation with `shmem` feature enabled ([#2722](https://github.com/coral-xyz/anchor/pull/2722)).
|
||||
- cli: Localhost default test validator address changes from `localhost` to `127.0.0.1`, NodeJS 17 IP resolution changes for IPv6 ([#2725](https://github.com/coral-xyz/anchor/pull/2725)).
|
||||
- lang: Eliminate temporary Vec allocations when serializing data with discriminant and set the default capacity to 256 bytes ([#2691](https://github.com/coral-xyz/anchor/pull/2691)).
|
||||
- lang: Allow custom lifetime in Accounts structure ([#2741](https://github.com/coral-xyz/anchor/pull/2741)).
|
||||
- lang: Remove `try_to_vec` usage while setting the return data in order to reduce heap memory usage ([#2744](https://github.com/coral-xyz/anchor/pull/2744))
|
||||
- cli: Show installation progress if Solana tools are not installed when using toolchain overrides ([#2757](https://github.com/coral-xyz/anchor/pull/2757)).
|
||||
- ts: Fix formatting enums ([#2763](https://github.com/coral-xyz/anchor/pull/2763)).
|
||||
- cli: Fix `migrate` command not working without global `ts-node` installation ([#2767](https://github.com/coral-xyz/anchor/pull/2767)).
|
||||
- client, lang, spl, syn: Enable all features for docs.rs build ([#2774](https://github.com/coral-xyz/anchor/pull/2774)).
|
||||
- ts: Fix construction of field layouts for type aliased instruction arguments ([#2821](https://github.com/coral-xyz/anchor/pull/2821))
|
||||
- idl: Fix IDL ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl, ts: Make casing consistent ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Fix not being able to use numbers in instruction, account, or event names in some cases due to case conversion ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- cli: Fix excessive test validator requests ([#2828](https://github.com/coral-xyz/anchor/pull/2828)).
|
||||
- client: Fix `parse_logs_response` to prevent panics when more than 1 outer instruction exists in logs ([#2856](https://github.com/coral-xyz/anchor/pull/2856)).
|
||||
- avm, cli: Fix `stdsimd` feature compilation error from `ahash` when installing the CLI using newer Rust versions ([#2867](https://github.com/coral-xyz/anchor/pull/2867)).
|
||||
- spl: Fix not being able to deserialize newer token 2022 extensions ([#2876](https://github.com/coral-xyz/anchor/pull/2876)).
|
||||
- spl: Remove `solana-program` dependency ([#2900](https://github.com/coral-xyz/anchor/pull/2900)).
|
||||
- spl: Make `TokenAccount` and ` Mint` `Copy` ([#2904](https://github.com/coral-xyz/anchor/pull/2904)).
|
||||
- ts: Add missing errors ([#2906](https://github.com/coral-xyz/anchor/pull/2906)).
|
||||
|
||||
### Breaking
|
||||
|
||||
- cli: Make `cargo build-sbf` the default build command ([#2694](https://github.com/coral-xyz/anchor/pull/2694)).
|
||||
- cli: Require explicit `overflow-checks` flag ([#2716](https://github.com/coral-xyz/anchor/pull/2716)).
|
||||
- ts: Remove `anchor-deprecated-state` feature ([#2717](https://github.com/coral-xyz/anchor/pull/2717)).
|
||||
- lang: Remove `CLOSED_ACCOUNT_DISCRIMINATOR` ([#2726](https://github.com/coral-xyz/anchor/pull/2726)).
|
||||
- lang: Make bumps of optional accounts `Option<u8>` rather than `u8` ([#2730](https://github.com/coral-xyz/anchor/pull/2730)).
|
||||
- spl: Remove `shared-memory` program ([#2747](https://github.com/coral-xyz/anchor/pull/2747)).
|
||||
- ts: Remove `associated`, `account.associated` and `account.associatedAddress` methods ([#2749](https://github.com/coral-xyz/anchor/pull/2749)).
|
||||
- cli: `idl upgrade` command closes the IDL buffer account ([#2760](https://github.com/coral-xyz/anchor/pull/2760)).
|
||||
- cli: Remove `--jest` option from the `init` command ([#2805](https://github.com/coral-xyz/anchor/pull/2805)).
|
||||
- cli: Require `idl-build` feature in program `Cargo.toml` ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- cli: Rename `seeds` feature to `resolution` and make it enabled by default ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- cli: Remove `idl parse` command ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl: Change IDL spec ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- syn: Remove `idl-parse` and `seeds` features ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Change `accounts` method to no longer accept resolvable accounts ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: `Program` instances use camelCase for everything ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Remove discriminator functions ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Remove `programId` parameter of the `Program` constructor ([#2864](https://github.com/coral-xyz/anchor/pull/2864)).
|
||||
- idl, syn: Move IDL types from the `anchor-syn` crate to the new IDL crate ([#2882](https://github.com/coral-xyz/anchor/pull/2882)).
|
||||
- idl: Add `#[non_exhaustive]` to IDL enums ([#2890](https://github.com/coral-xyz/anchor/pull/2890)).
|
||||
|
||||
## [0.29.0] - 2023-10-16
|
||||
|
||||
### Features
|
||||
|
||||
- lang: Change all accounts to have a reference to `AccountInfo` ([#2656](https://github.com/coral-xyz/anchor/pull/2656)).
|
||||
- lang: Add `get_lamports`, `add_lamports` and `sub_lamports` methods for all account types ([#2552](https://github.com/coral-xyz/anchor/pull/2552)).
|
||||
- client: Add a helper struct `DynSigner` to simplify use of `Client<C> where <C: Clone + Deref<Target = impl Signer>>` with Solana clap CLI utils that loads `Signer` as `Box<dyn Signer>` ([#2550](https://github.com/coral-xyz/anchor/pull/2550)).
|
||||
- lang: Allow CPI calls matching an interface without pinning program ID ([#2559](https://github.com/coral-xyz/anchor/pull/2559)).
|
||||
- cli, lang: Add IDL generation through compilation. `anchor build` still uses parsing method to generate IDLs, use `anchor idl build` to generate IDLs with the build method ([#2011](https://github.com/coral-xyz/anchor/pull/2011)).
|
||||
- avm: Add support for the `.anchorversion` file to facilitate switching between different versions of the `anchor-cli` ([#2553](https://github.com/coral-xyz/anchor/pull/2553)).
|
||||
- ts: Add ability to access workspace programs independent of the casing used, e.g. `anchor.workspace.myProgram`, `anchor.workspace.MyProgram`... ([#2579](https://github.com/coral-xyz/anchor/pull/2579)).
|
||||
- bench: Add benchmarking for program binary size ([#2591](https://github.com/coral-xyz/anchor/pull/2591)).
|
||||
- spl: Export `mpl-token-metadata` crate ([#2583](https://github.com/coral-xyz/anchor/pull/2583)).
|
||||
- spl: Add `TokenRecordAccount` for pNFTs ([#2597](https://github.com/coral-xyz/anchor/pull/2597)).
|
||||
- ts: Add support for unnamed(tuple) enum in accounts ([#2601](https://github.com/coral-xyz/anchor/pull/2601)).
|
||||
- cli: Add program template with multiple files for instructions, state... ([#2602](https://github.com/coral-xyz/anchor/pull/2602)).
|
||||
- bench: Add benchmarking for stack memory usage ([#2617](https://github.com/coral-xyz/anchor/pull/2617)).
|
||||
- lang: `Box` the inner enums of `anchor_lang::error::Error` to optimize `anchor_lang::Result` ([#2600](https://github.com/coral-xyz/anchor/pull/2600)).
|
||||
- ts: Add strong type support for `Program.addEventListener` method ([#2627](https://github.com/coral-xyz/anchor/pull/2627)).
|
||||
- syn: Add `IdlBuild` trait to implement IDL support for custom types ([#2629](https://github.com/coral-xyz/anchor/pull/2629)).
|
||||
- spl: Add `idl-build` feature. IDL build method will not work without enabling this feature when using `anchor-spl` ([#2629](https://github.com/coral-xyz/anchor/pull/2629)).
|
||||
- lang: Add support for type aliases in IDLs ([#2637](https://github.com/coral-xyz/anchor/pull/2637)).
|
||||
- cli: Add `test.upgradeable`, `test.genesis.upgradeable` setting in `Anchor.toml` to support testing upgradeable programs ([#2642](https://github.com/coral-xyz/anchor/pull/2642)).
|
||||
- cli, client, lang, spl: Update Solana toolchain and dependencies to `1.17.0`, `1.16` remains supported ([#2645](https://github.com/coral-xyz/anchor/pull/2645)).
|
||||
- spl: Add support for memo program ([#2661](https://github.com/coral-xyz/anchor/pull/2661)).
|
||||
- avm: Add `anchor-cli` installation from commit ([#2659](https://github.com/coral-xyz/anchor/pull/2659)).
|
||||
- cli: Add `toolchain` property in `Anchor.toml` to override Anchor and Solana versions ([#2649](https://github.com/coral-xyz/anchor/pull/2649)).
|
||||
|
||||
### Fixes
|
||||
|
||||
- ts: Packages no longer depend on `assert` ([#2535](https://github.com/coral-xyz/anchor/pull/2535)).
|
||||
- lang: Support for `const` in the `InitSpace` macro ([#2555](https://github.com/coral-xyz/anchor/pull/2555)).
|
||||
- cli: Support workspace inheritance ([#2570](https://github.com/coral-xyz/anchor/pull/2570)).
|
||||
- client: Compile with Solana `1.14` ([#2572](https://github.com/coral-xyz/anchor/pull/2572)).
|
||||
- cli: Fix `anchor build --no-docs` adding docs to the IDL ([#2575](https://github.com/coral-xyz/anchor/pull/2575)).
|
||||
- ts: Load workspace programs on-demand rather than loading all of them at once ([#2579](https://github.com/coral-xyz/anchor/pull/2579)).
|
||||
- lang: Fix `associated_token::token_program` constraint ([#2603](https://github.com/coral-xyz/anchor/pull/2603)).
|
||||
- cli: Fix `anchor account` command panicking outside of workspace ([#2620](https://github.com/coral-xyz/anchor/pull/2620)).
|
||||
- lang: IDL named enum variant fields are now camelCase as opposed to snake_case, consistent with the other IDL types ([#2633](https://github.com/coral-xyz/anchor/pull/2633)).
|
||||
- avm: Remove excessive panics and handle the errors gracefully ([#2671](https://github.com/coral-xyz/anchor/pull/2671)).
|
||||
|
||||
### Breaking
|
||||
|
||||
- lang: Switch to type safe bumps in context ([#2542](https://github.com/coral-xyz/anchor/pull/2542)).
|
||||
- syn: `idl` feature has been replaced with `idl-build`, `idl-parse` and `idl-types` features ([#2011](https://github.com/coral-xyz/anchor/pull/2011)).
|
||||
- syn: IDL `parse` method now returns `Result<Idl>` instead of `Result<Option<Idl>>` ([#2582](https://github.com/coral-xyz/anchor/pull/2582)).
|
||||
- spl: Update `mpl-token-metadata` dependency to use the client SDK instead of the program crate ([#2632](https://github.com/coral-xyz/anchor/pull/2632)).
|
||||
- ts: Remove `base64-js` dependency ([#2635](https://github.com/coral-xyz/anchor/pull/2635)).
|
||||
- syn: `IdlTypeDefinitionTy` enum has a new variant `Alias` ([#2637](https://github.com/coral-xyz/anchor/pull/2637)).
|
||||
- cli, client, lang, spl: Solana `1.14` is no longer supported, minimum required Solana version is `1.16.0` ([#2645](https://github.com/coral-xyz/anchor/pull/2645)).
|
||||
- cli: `anchor_version` and `solana_version` property in `Anchor.toml` that was being used in verifiable builds are moved inside `toolchain`. They are now being used for all commands in the workspace, not just verifiable builds ([#2649](https://github.com/coral-xyz/anchor/pull/2649)).
|
||||
|
||||
## [0.28.0] - 2023-06-09
|
||||
|
||||
### Features
|
||||
|
||||
- client: Add `async` feature flag to use an asynchronous anchor-client ([#2488](https://github.com/coral-xyz/anchor/pull/2488)).
|
||||
- spl: Add metadata wrappers `approve_collection_authority`, `bubblegum_set_collection_size`, `burn_edition_nft`, `burn_nft`, `revoke_collection_authority`, `set_token_standard`, `utilize`, `unverify_sized_collection_item`, `unverify_collection` ([#2430](https://github.com/coral-xyz/anchor/pull/2430))
|
||||
- spl: Add `token_program` constraint to `Token`, `Mint`, and `AssociatedToken` accounts in order to override required `token_program` fields and use different token interface implementations in the same instruction ([#2460](https://github.com/coral-xyz/anchor/pull/2460))
|
||||
|
@ -31,6 +188,7 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
- cli: Fix incorrect `metadata.address` generation in IDL after deploying with a custom keypair ([#2485](https://github.com/coral-xyz/anchor/pull/2485))
|
||||
- cli: IDL commands no longer hang when the payer doesn't have funds to pay for the transaction fee ([#2492](https://github.com/coral-xyz/anchor/pull/2492))
|
||||
- cli: Fix `anchor new` not updating `Anchor.toml` ([#2516](https://github.com/coral-xyz/anchor/pull/2516)).
|
||||
- client, lang, spl: Allow wider range of dependency versions to reduce dependency issues ([#2524](https://github.com/coral-xyz/anchor/pull/2524)).
|
||||
|
||||
### Breaking
|
||||
|
||||
|
@ -506,7 +664,7 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
### Breaking
|
||||
|
||||
- cli: `[clusters.<network>]` Anchor.toml section has been renamed to `[programs.<network>]` ([#570](https://github.com/coral-xyz/anchor/pull/570)).
|
||||
- cli: `[workspace]` member and exclude arrays must now be filepaths relative to the workpsace root ([#570](https://github.com/coral-xyz/anchor/pull/570)).
|
||||
- cli: `[workspace]` member and exclude arrays must now be filepaths relative to the workspace root ([#570](https://github.com/coral-xyz/anchor/pull/570)).
|
||||
|
||||
## [0.12.0] - 2021-08-03
|
||||
|
||||
|
@ -606,10 +764,10 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
|
||||
### Breaking Changes
|
||||
|
||||
- ts: Retrieving deserialized accounts from the `<program>.account.<my-account>` and `<program>.state` namespaces now require explicitly invoking the `fetch` API. For example, `program.account.myAccount(<adddress>)` and `program.state()` is now `program.account.myAccount.fetch(<address>)` and `program.state.fetch()` ([#322](https://github.com/coral-xyz/anchor/pull/322)).
|
||||
- ts: Retrieving deserialized accounts from the `<program>.account.<my-account>` and `<program>.state` namespaces now require explicitly invoking the `fetch` API. For example, `program.account.myAccount(<address>)` and `program.state()` is now `program.account.myAccount.fetch(<address>)` and `program.state.fetch()` ([#322](https://github.com/coral-xyz/anchor/pull/322)).
|
||||
- lang: `#[account(associated)]` now requires `init` to be provided to create an associated account. If not provided, then the address will be assumed to exist, and a constraint will be added to ensure the correctness of the address ([#318](https://github.com/coral-xyz/anchor/pull/318)).
|
||||
- lang, ts: Change account discriminator pre-image of the `#[state]` account discriminator to be namespaced by "state:" ([#320](https://github.com/coral-xyz/anchor/pull/320)).
|
||||
- lang, ts: Change domain delimiters for the pre-image of the instruciton sighash to be a single colon `:` to be consistent with accounts ([#321](https://github.com/coral-xyz/anchor/pull/321)).
|
||||
- lang, ts: Change domain delimiters for the pre-image of the instruction sighash to be a single colon `:` to be consistent with accounts ([#321](https://github.com/coral-xyz/anchor/pull/321)).
|
||||
- lang: Associated constraints no longer automatically implement `mut` ([#341](https://github.com/coral-xyz/anchor/pull/341)).
|
||||
- lang: Associated `space` constraints must now be literal integers instead of literal strings ([#341](https://github.com/coral-xyz/anchor/pull/341)).
|
||||
|
||||
|
@ -652,7 +810,7 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
|
||||
### Features
|
||||
|
||||
- lang: Allows one to specify multiple `with` targets when creating associated acconts ([#197](https://github.com/coral-xyz/anchor/pull/197)).
|
||||
- lang: Allows one to specify multiple `with` targets when creating associated accounts ([#197](https://github.com/coral-xyz/anchor/pull/197)).
|
||||
- lang, ts: Add array support ([#202](https://github.com/coral-xyz/anchor/pull/202)).
|
||||
- lang: Zero copy deserialization for accounts ([#202](https://github.com/coral-xyz/anchor/pull/202), [#206](https://github.com/coral-xyz/anchor/pull/206)).
|
||||
- lang, spl, cli, client: Upgrade solana toolchain to 1.6.6 ([#210](https://github.com/coral-xyz/anchor/pull/210)).
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# Code of Conduct
|
||||
|
||||
The Anchor repository follows the Rust [Code of Conduct](https://www.rust-lang.org/conduct.html).
|
||||
The Anchor repository follows the Rust [Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct).
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,8 +6,10 @@ codegen-units = 1
|
|||
|
||||
[workspace]
|
||||
members = [
|
||||
"avm",
|
||||
"cli",
|
||||
"client",
|
||||
"idl",
|
||||
"lang",
|
||||
"lang/attribute/*",
|
||||
"lang/derive/*",
|
||||
|
@ -18,3 +20,4 @@ exclude = [
|
|||
"tests/swap/deps/openbook-dex",
|
||||
"tests/cfo/deps/openbook-dex",
|
||||
]
|
||||
resolver = "2"
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -187,7 +187,7 @@
|
|||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2020 Serum Foundation
|
||||
Copyright 2020 Anchor Maintainers
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
2
Makefile
2
Makefile
|
@ -15,6 +15,8 @@ publish:
|
|||
sleep 25
|
||||
cd lang/derive/accounts/ && cargo publish && cd ../../../
|
||||
sleep 25
|
||||
cd lang/derive/serde/ && cargo publish && cd ../../../
|
||||
sleep 25
|
||||
cd lang/derive/space/ && cargo publish && cd ../../../
|
||||
sleep 25
|
||||
cd lang/attribute/access-control/ && cargo publish && cd ../../../
|
||||
|
|
|
@ -34,8 +34,8 @@ To jump straight to examples, go [here](https://github.com/coral-xyz/anchor/tree
|
|||
| Package | Description | Version | Docs |
|
||||
| :---------------------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------- |
|
||||
| `anchor-lang` | Rust primitives for writing programs on Solana | [![Crates.io](https://img.shields.io/crates/v/anchor-lang?color=blue)](https://crates.io/crates/anchor-lang) | [![Docs.rs](https://docs.rs/anchor-lang/badge.svg)](https://docs.rs/anchor-lang) |
|
||||
| `anchor-spl` | CPI clients for SPL programs on Solana | ![crates](https://img.shields.io/crates/v/anchor-spl?color=blue) | [![Docs.rs](https://docs.rs/anchor-spl/badge.svg)](https://docs.rs/anchor-spl) |
|
||||
| `anchor-client` | Rust client for Anchor programs | ![crates](https://img.shields.io/crates/v/anchor-client?color=blue) | [![Docs.rs](https://docs.rs/anchor-client/badge.svg)](https://docs.rs/anchor-client) |
|
||||
| `anchor-spl` | CPI clients for SPL programs on Solana | [![crates](https://img.shields.io/crates/v/anchor-spl?color=blue)](https://crates.io/crates/anchor-spl) | [![Docs.rs](https://docs.rs/anchor-spl/badge.svg)](https://docs.rs/anchor-spl) |
|
||||
| `anchor-client` | Rust client for Anchor programs | [![crates](https://img.shields.io/crates/v/anchor-client?color=blue)](https://crates.io/crates/anchor-client) | [![Docs.rs](https://docs.rs/anchor-client/badge.svg)](https://docs.rs/anchor-client) |
|
||||
| `@coral-xyz/anchor` | TypeScript client for Anchor programs | [![npm](https://img.shields.io/npm/v/@coral-xyz/anchor.svg?color=blue)](https://www.npmjs.com/package/@coral-xyz/anchor) | [![Docs](https://img.shields.io/badge/docs-typedoc-blue)](https://coral-xyz.github.io/anchor/ts/index.html) |
|
||||
| `@coral-xyz/anchor-cli` | CLI to support building and managing an Anchor workspace | [![npm](https://img.shields.io/npm/v/@coral-xyz/anchor-cli.svg?color=blue)](https://www.npmjs.com/package/@coral-xyz/anchor-cli) | [![Docs](https://img.shields.io/badge/docs-typedoc-blue)](https://coral-xyz.github.io/anchor/cli/commands.html) |
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "avm"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
rust-version = "1.60"
|
||||
edition = "2021"
|
||||
|
||||
|
@ -13,16 +13,13 @@ name = "anchor"
|
|||
path = "src/anchor/main.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.2.4", features = ["derive"]}
|
||||
cfg-if = "1.0.0"
|
||||
anyhow = "1.0.32"
|
||||
cfg-if = "1.0.0"
|
||||
cargo_toml = "0.19.2"
|
||||
clap = { version = "4.2.4", features = ["derive"] }
|
||||
dirs = "4.0.0"
|
||||
once_cell = "1.8.0"
|
||||
reqwest = { version = "0.11.9", default-features = false, features = ["blocking", "json", "rustls-tls"] }
|
||||
semver = "1.0.4"
|
||||
serde = { version = "1.0.136", features = ["derive"] }
|
||||
serde_json = "1.0.78"
|
||||
thiserror = "1.0.30"
|
||||
once_cell = { version = "1.8.0" }
|
||||
reqwest = { version = "0.11.9", default-features = false, features = ["blocking", "json", "rustls-tls"] }
|
||||
tempfile = "3.3.0"
|
||||
|
||||
[workspace]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::{env, fs, process::Command};
|
||||
use std::{env, process::Command};
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let args = env::args().skip(1).collect::<Vec<String>>();
|
||||
|
@ -7,13 +7,14 @@ fn main() -> anyhow::Result<()> {
|
|||
.map_err(|_e| anyhow::anyhow!("Anchor version not set. Please run `avm use latest`."))?;
|
||||
|
||||
let binary_path = avm::version_binary_path(&version);
|
||||
if fs::metadata(&binary_path).is_err() {
|
||||
if !binary_path.exists() {
|
||||
anyhow::bail!(
|
||||
"anchor-cli {} not installed. Please run `avm use {}`.",
|
||||
version,
|
||||
version
|
||||
);
|
||||
}
|
||||
|
||||
let exit = Command::new(binary_path)
|
||||
.args(args)
|
||||
.spawn()?
|
||||
|
|
395
avm/src/lib.rs
395
avm/src/lib.rs
|
@ -1,54 +1,84 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use cargo_toml::Manifest;
|
||||
use once_cell::sync::Lazy;
|
||||
use reqwest::header::USER_AGENT;
|
||||
use semver::Version;
|
||||
use reqwest::StatusCode;
|
||||
use semver::{Prerelease, Version};
|
||||
use serde::{de, Deserialize};
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Stdio;
|
||||
|
||||
/// Storage directory for AVM, ~/.avm
|
||||
/// Storage directory for AVM, customizable by setting the $AVM_HOME, defaults to ~/.avm
|
||||
pub static AVM_HOME: Lazy<PathBuf> = Lazy::new(|| {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(test)] {
|
||||
let dir = tempfile::tempdir().expect("Could not create temporary directory");
|
||||
dir.path().join(".avm")
|
||||
} else {
|
||||
let mut user_home = dirs::home_dir().expect("Could not find home directory");
|
||||
user_home.push(".avm");
|
||||
user_home
|
||||
if let Ok(avm_home) = std::env::var("AVM_HOME") {
|
||||
PathBuf::from(avm_home)
|
||||
} else {
|
||||
let mut user_home = dirs::home_dir().expect("Could not find home directory");
|
||||
user_home.push(".avm");
|
||||
user_home
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/// Path to the current version file ~/.avm/.version
|
||||
pub fn current_version_file_path() -> PathBuf {
|
||||
let mut current_version_file_path = AVM_HOME.to_path_buf();
|
||||
current_version_file_path.push(".version");
|
||||
current_version_file_path
|
||||
/// Path to the current version file $AVM_HOME/.version
|
||||
fn current_version_file_path() -> PathBuf {
|
||||
AVM_HOME.join(".version")
|
||||
}
|
||||
|
||||
/// Read the current version from the version file
|
||||
pub fn current_version() -> Result<Version> {
|
||||
let v = fs::read_to_string(current_version_file_path().as_path())
|
||||
.map_err(|e| anyhow!("Could not read version file: {}", e))?;
|
||||
Version::parse(v.trim_end_matches('\n').to_string().as_str())
|
||||
.map_err(|e| anyhow!("Could not parse version file: {}", e))
|
||||
/// Path to the current version file $AVM_HOME/bin
|
||||
fn get_bin_dir_path() -> PathBuf {
|
||||
AVM_HOME.join("bin")
|
||||
}
|
||||
|
||||
/// Path to the binary for the given version
|
||||
pub fn version_binary_path(version: &Version) -> PathBuf {
|
||||
let mut version_path = AVM_HOME.join("bin");
|
||||
version_path.push(format!("anchor-{version}"));
|
||||
version_path
|
||||
get_bin_dir_path().join(format!("anchor-{version}"))
|
||||
}
|
||||
|
||||
/// Ensure the users home directory is setup with the paths required by AVM.
|
||||
pub fn ensure_paths() {
|
||||
let home_dir = AVM_HOME.to_path_buf();
|
||||
if !home_dir.exists() {
|
||||
fs::create_dir_all(&home_dir).expect("Could not create .avm directory");
|
||||
}
|
||||
|
||||
let bin_dir = get_bin_dir_path();
|
||||
if !bin_dir.exists() {
|
||||
fs::create_dir_all(bin_dir).expect("Could not create .avm/bin directory");
|
||||
}
|
||||
|
||||
if !current_version_file_path().exists() {
|
||||
fs::File::create(current_version_file_path()).expect("Could not create .version file");
|
||||
}
|
||||
}
|
||||
|
||||
/// Read the current version from the version file
|
||||
pub fn current_version() -> Result<Version> {
|
||||
fs::read_to_string(current_version_file_path())
|
||||
.map_err(|e| anyhow!("Could not read version file: {}", e))?
|
||||
.trim_end_matches('\n')
|
||||
.parse::<Version>()
|
||||
.map_err(|e| anyhow!("Could not parse version file: {}", e))
|
||||
}
|
||||
|
||||
/// Update the current version to a new version
|
||||
pub fn use_version(version: &Version) -> Result<()> {
|
||||
let installed_versions = read_installed_versions();
|
||||
pub fn use_version(opt_version: Option<Version>) -> Result<()> {
|
||||
let version = match opt_version {
|
||||
Some(version) => version,
|
||||
None => read_anchorversion_file()?,
|
||||
};
|
||||
|
||||
// Make sure the requested version is installed
|
||||
if !installed_versions.contains(version) {
|
||||
let installed_versions = read_installed_versions()?;
|
||||
if !installed_versions.contains(&version) {
|
||||
if let Ok(current) = current_version() {
|
||||
println!("Version {version} is not installed, staying on version {current}.");
|
||||
} else {
|
||||
|
@ -61,104 +91,167 @@ pub fn use_version(version: &Version) -> Result<()> {
|
|||
));
|
||||
}
|
||||
|
||||
let mut current_version_file = fs::File::create(current_version_file_path().as_path())?;
|
||||
let mut current_version_file = fs::File::create(current_version_file_path())?;
|
||||
current_version_file.write_all(version.to_string().as_bytes())?;
|
||||
println!("Now using anchor version {}.", current_version()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum InstallTarget {
|
||||
Version(Version),
|
||||
Commit(String),
|
||||
}
|
||||
|
||||
/// Update to the latest version
|
||||
pub fn update() -> Result<()> {
|
||||
// Find last stable version
|
||||
let version = &get_latest_version();
|
||||
let latest_version = get_latest_version()?;
|
||||
install_version(InstallTarget::Version(latest_version), false)
|
||||
}
|
||||
|
||||
install_version(version, false)
|
||||
/// The commit sha provided can be shortened,
|
||||
///
|
||||
/// returns the full commit sha3 for unique versioning downstream
|
||||
pub fn check_and_get_full_commit(commit: &str) -> Result<String> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let response = client
|
||||
.get(format!(
|
||||
"https://api.github.com/repos/coral-xyz/anchor/commits/{commit}"
|
||||
))
|
||||
.header(USER_AGENT, "avm https://github.com/coral-xyz/anchor")
|
||||
.send()?;
|
||||
|
||||
if response.status() != StatusCode::OK {
|
||||
return Err(anyhow!(
|
||||
"Error checking commit {commit}: {}",
|
||||
response.text()?
|
||||
));
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct GetCommitResponse {
|
||||
sha: String,
|
||||
}
|
||||
|
||||
response
|
||||
.json::<GetCommitResponse>()
|
||||
.map(|resp| resp.sha)
|
||||
.map_err(|err| anyhow!("Failed to parse the response to JSON: {err:?}"))
|
||||
}
|
||||
|
||||
fn get_anchor_version_from_commit(commit: &str) -> Result<Version> {
|
||||
// We read the version from cli/Cargo.toml since there is no simpler way to do so
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let response = client
|
||||
.get(format!(
|
||||
"https://raw.githubusercontent.com/coral-xyz/anchor/{commit}/cli/Cargo.toml"
|
||||
))
|
||||
.header(USER_AGENT, "avm https://github.com/coral-xyz/anchor")
|
||||
.send()?;
|
||||
|
||||
if response.status() != StatusCode::OK {
|
||||
return Err(anyhow!(
|
||||
"Could not find anchor-cli version for commit: {response:?}"
|
||||
));
|
||||
};
|
||||
|
||||
let anchor_cli_cargo_toml = response.text()?;
|
||||
let anchor_cli_manifest = Manifest::from_str(&anchor_cli_cargo_toml)?;
|
||||
let mut version = anchor_cli_manifest.package().version().parse::<Version>()?;
|
||||
version.pre = Prerelease::new(commit)?;
|
||||
|
||||
Ok(version)
|
||||
}
|
||||
|
||||
/// Install a version of anchor-cli
|
||||
pub fn install_version(version: &Version, force: bool) -> Result<()> {
|
||||
pub fn install_version(install_target: InstallTarget, force: bool) -> Result<()> {
|
||||
let mut args: Vec<String> = vec![
|
||||
"install".into(),
|
||||
"--git".into(),
|
||||
"https://github.com/coral-xyz/anchor".into(),
|
||||
"anchor-cli".into(),
|
||||
"--locked".into(),
|
||||
"--root".into(),
|
||||
AVM_HOME.to_str().unwrap().into(),
|
||||
];
|
||||
let version = match install_target {
|
||||
InstallTarget::Version(version) => {
|
||||
args.extend(["--tag".into(), format!("v{}", version), "anchor-cli".into()]);
|
||||
version
|
||||
}
|
||||
InstallTarget::Commit(commit) => {
|
||||
args.extend(["--rev".into(), commit.clone()]);
|
||||
get_anchor_version_from_commit(&commit)?
|
||||
}
|
||||
};
|
||||
|
||||
// If version is already installed we ignore the request.
|
||||
let installed_versions = read_installed_versions();
|
||||
if installed_versions.contains(version) && !force {
|
||||
let installed_versions = read_installed_versions()?;
|
||||
if installed_versions.contains(&version) && !force {
|
||||
println!("Version {version} is already installed");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let exit = std::process::Command::new("cargo")
|
||||
.args([
|
||||
"install",
|
||||
"--git",
|
||||
"https://github.com/coral-xyz/anchor",
|
||||
"--tag",
|
||||
&format!("v{}", &version),
|
||||
"anchor-cli",
|
||||
"--locked",
|
||||
"--root",
|
||||
AVM_HOME.to_str().unwrap(),
|
||||
])
|
||||
.args(args)
|
||||
.stdout(Stdio::inherit())
|
||||
.stderr(Stdio::inherit())
|
||||
.output()
|
||||
.map_err(|e| {
|
||||
anyhow::format_err!("Cargo install for {} failed: {}", version, e.to_string())
|
||||
})?;
|
||||
.map_err(|e| anyhow!("Cargo install for {} failed: {}", version, e.to_string()))?;
|
||||
if !exit.status.success() {
|
||||
return Err(anyhow!(
|
||||
"Failed to install {}, is it a valid version?",
|
||||
version
|
||||
));
|
||||
}
|
||||
|
||||
let bin_dir = get_bin_dir_path();
|
||||
fs::rename(
|
||||
AVM_HOME.join("bin").join("anchor"),
|
||||
AVM_HOME.join("bin").join(format!("anchor-{version}")),
|
||||
bin_dir.join("anchor"),
|
||||
bin_dir.join(format!("anchor-{version}")),
|
||||
)?;
|
||||
|
||||
// If .version file is empty or not parseable, write the newly installed version to it
|
||||
if current_version().is_err() {
|
||||
let mut current_version_file = fs::File::create(current_version_file_path().as_path())?;
|
||||
let mut current_version_file = fs::File::create(current_version_file_path())?;
|
||||
current_version_file.write_all(version.to_string().as_bytes())?;
|
||||
}
|
||||
|
||||
use_version(version)
|
||||
use_version(Some(version))
|
||||
}
|
||||
|
||||
/// Remove an installed version of anchor-cli
|
||||
pub fn uninstall_version(version: &Version) -> Result<()> {
|
||||
let version_path = AVM_HOME.join("bin").join(format!("anchor-{version}"));
|
||||
let version_path = get_bin_dir_path().join(format!("anchor-{version}"));
|
||||
if !version_path.exists() {
|
||||
return Err(anyhow!("anchor-cli {} is not installed", version));
|
||||
}
|
||||
if version == ¤t_version().unwrap() {
|
||||
if version == ¤t_version()? {
|
||||
return Err(anyhow!("anchor-cli {} is currently in use", version));
|
||||
}
|
||||
fs::remove_file(version_path.as_path())?;
|
||||
fs::remove_file(version_path)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Ensure the users home directory is setup with the paths required by AVM.
|
||||
pub fn ensure_paths() {
|
||||
let home_dir = AVM_HOME.to_path_buf();
|
||||
if !home_dir.as_path().exists() {
|
||||
fs::create_dir_all(home_dir.clone()).expect("Could not create .avm directory");
|
||||
}
|
||||
let bin_dir = home_dir.join("bin");
|
||||
if !bin_dir.as_path().exists() {
|
||||
fs::create_dir_all(bin_dir).expect("Could not create .avm/bin directory");
|
||||
}
|
||||
if !current_version_file_path().exists() {
|
||||
fs::File::create(current_version_file_path()).expect("Could not create .version file");
|
||||
}
|
||||
/// Read version from .anchorversion
|
||||
pub fn read_anchorversion_file() -> Result<Version> {
|
||||
fs::read_to_string(".anchorversion")
|
||||
.map_err(|e| anyhow!(".anchorversion file not found: {e}"))
|
||||
.map(|content| Version::parse(content.trim()))?
|
||||
.map_err(|e| anyhow!("Unable to parse version: {e}"))
|
||||
}
|
||||
|
||||
/// Retrieve a list of installable versions of anchor-cli using the GitHub API and tags on the Anchor
|
||||
/// repository.
|
||||
pub fn fetch_versions() -> Vec<semver::Version> {
|
||||
pub fn fetch_versions() -> Result<Vec<Version>> {
|
||||
#[derive(Deserialize)]
|
||||
struct Release {
|
||||
#[serde(rename = "name", deserialize_with = "version_deserializer")]
|
||||
version: semver::Version,
|
||||
version: Version,
|
||||
}
|
||||
|
||||
fn version_deserializer<'de, D>(deserializer: D) -> Result<semver::Version, D::Error>
|
||||
fn version_deserializer<'de, D>(deserializer: D) -> Result<Version, D::Error>
|
||||
where
|
||||
D: de::Deserializer<'de>,
|
||||
{
|
||||
|
@ -166,71 +259,73 @@ pub fn fetch_versions() -> Vec<semver::Version> {
|
|||
Version::parse(s.trim_start_matches('v')).map_err(de::Error::custom)
|
||||
}
|
||||
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let versions: Vec<Release> = client
|
||||
let versions = reqwest::blocking::Client::new()
|
||||
.get("https://api.github.com/repos/coral-xyz/anchor/tags")
|
||||
.header(USER_AGENT, "avm https://github.com/coral-xyz/anchor")
|
||||
.send()
|
||||
.unwrap()
|
||||
.json()
|
||||
.unwrap();
|
||||
versions.into_iter().map(|r| r.version).collect()
|
||||
.send()?
|
||||
.json::<Vec<Release>>()?
|
||||
.into_iter()
|
||||
.map(|release| release.version)
|
||||
.collect();
|
||||
|
||||
Ok(versions)
|
||||
}
|
||||
|
||||
/// Print available versions and flags indicating installed, current and latest
|
||||
pub fn list_versions() -> Result<()> {
|
||||
let installed_versions = read_installed_versions();
|
||||
let mut installed_versions = read_installed_versions()?;
|
||||
|
||||
let mut available_versions = fetch_versions();
|
||||
let mut available_versions = fetch_versions()?;
|
||||
// Reverse version list so latest versions are printed last
|
||||
available_versions.reverse();
|
||||
|
||||
available_versions.iter().enumerate().for_each(|(i, v)| {
|
||||
print!("{v}");
|
||||
let mut flags = vec![];
|
||||
if i == available_versions.len() - 1 {
|
||||
flags.push("latest");
|
||||
}
|
||||
if installed_versions.contains(v) {
|
||||
flags.push("installed");
|
||||
}
|
||||
if current_version().is_ok() && current_version().unwrap() == v.clone() {
|
||||
flags.push("current");
|
||||
}
|
||||
if flags.is_empty() {
|
||||
println!();
|
||||
} else {
|
||||
println!("\t({})", flags.join(", "));
|
||||
}
|
||||
});
|
||||
let print_versions =
|
||||
|versions: Vec<Version>, installed_versions: &mut Vec<Version>, show_latest: bool| {
|
||||
versions.iter().enumerate().for_each(|(i, v)| {
|
||||
print!("{v}");
|
||||
let mut flags = vec![];
|
||||
if i == versions.len() - 1 && show_latest {
|
||||
flags.push("latest");
|
||||
}
|
||||
if let Some(position) = installed_versions.iter().position(|iv| iv == v) {
|
||||
flags.push("installed");
|
||||
installed_versions.remove(position);
|
||||
}
|
||||
if current_version().map(|cv| &cv == v).unwrap_or_default() {
|
||||
flags.push("current");
|
||||
}
|
||||
|
||||
if flags.is_empty() {
|
||||
println!();
|
||||
} else {
|
||||
println!("\t({})", flags.join(", "));
|
||||
}
|
||||
})
|
||||
};
|
||||
print_versions(available_versions, &mut installed_versions, true);
|
||||
print_versions(installed_versions.clone(), &mut installed_versions, false);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_latest_version() -> semver::Version {
|
||||
let available_versions = fetch_versions();
|
||||
available_versions.first().unwrap().clone()
|
||||
pub fn get_latest_version() -> Result<Version> {
|
||||
fetch_versions()?
|
||||
.into_iter()
|
||||
.next()
|
||||
.ok_or_else(|| anyhow!("First version not found"))
|
||||
}
|
||||
|
||||
/// Read the installed anchor-cli versions by reading the binaries in the AVM_HOME/bin directory.
|
||||
pub fn read_installed_versions() -> Vec<semver::Version> {
|
||||
let home_dir = AVM_HOME.to_path_buf();
|
||||
let mut versions = vec![];
|
||||
for file in fs::read_dir(home_dir.join("bin")).unwrap() {
|
||||
let file_name = file.unwrap().file_name();
|
||||
// Match only things that look like anchor-*
|
||||
if file_name.to_str().unwrap().starts_with("anchor-") {
|
||||
let version = file_name
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.trim_start_matches("anchor-")
|
||||
.parse::<semver::Version>()
|
||||
.unwrap();
|
||||
versions.push(version);
|
||||
}
|
||||
}
|
||||
pub fn read_installed_versions() -> Result<Vec<Version>> {
|
||||
const PREFIX: &str = "anchor-";
|
||||
let versions = fs::read_dir(get_bin_dir_path())?
|
||||
.filter_map(|entry_result| entry_result.ok())
|
||||
.filter_map(|entry| entry.file_name().to_str().map(|f| f.to_owned()))
|
||||
.filter(|file_name| file_name.starts_with(PREFIX))
|
||||
.filter_map(|file_name| file_name.trim_start_matches(PREFIX).parse::<Version>().ok())
|
||||
.collect();
|
||||
|
||||
versions
|
||||
Ok(versions)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -239,41 +334,54 @@ mod tests {
|
|||
use semver::Version;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn test_ensure_paths() {
|
||||
ensure_paths();
|
||||
assert!(AVM_HOME.exists());
|
||||
let bin_dir = AVM_HOME.join("bin");
|
||||
let bin_dir = get_bin_dir_path();
|
||||
assert!(bin_dir.exists());
|
||||
let current_version_file = AVM_HOME.join(".version");
|
||||
let current_version_file = current_version_file_path();
|
||||
assert!(current_version_file.exists());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_current_version_file_path() {
|
||||
ensure_paths();
|
||||
assert!(current_version_file_path().exists());
|
||||
fn test_version_binary_path() {
|
||||
assert_eq!(
|
||||
version_binary_path(&Version::parse("0.18.2").unwrap()),
|
||||
get_bin_dir_path().join("anchor-0.18.2")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version_binary_path() {
|
||||
assert!(
|
||||
version_binary_path(&Version::parse("0.18.2").unwrap())
|
||||
== AVM_HOME.join("bin/anchor-0.18.2")
|
||||
);
|
||||
fn test_read_anchorversion() -> Result<()> {
|
||||
ensure_paths();
|
||||
|
||||
let anchorversion_path = Path::new(".anchorversion");
|
||||
let test_version = "0.26.0";
|
||||
fs::write(anchorversion_path, test_version)?;
|
||||
|
||||
let version = read_anchorversion_file()?;
|
||||
assert_eq!(version.to_string(), test_version);
|
||||
|
||||
fs::remove_file(anchorversion_path)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_current_version() {
|
||||
ensure_paths();
|
||||
let mut current_version_file =
|
||||
fs::File::create(current_version_file_path().as_path()).unwrap();
|
||||
let mut current_version_file = fs::File::create(current_version_file_path()).unwrap();
|
||||
current_version_file.write_all("0.18.2".as_bytes()).unwrap();
|
||||
// Sync the file to disk before the read in current_version() to
|
||||
// mitigate the read not seeing the written version bytes.
|
||||
current_version_file.sync_all().unwrap();
|
||||
assert!(current_version().unwrap() == Version::parse("0.18.2").unwrap());
|
||||
assert_eq!(
|
||||
current_version().unwrap(),
|
||||
Version::parse("0.18.2").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -287,8 +395,7 @@ mod tests {
|
|||
fn test_uninstalled_in_use_version() {
|
||||
ensure_paths();
|
||||
let version = Version::parse("0.18.2").unwrap();
|
||||
let mut current_version_file =
|
||||
fs::File::create(current_version_file_path().as_path()).unwrap();
|
||||
let mut current_version_file = fs::File::create(current_version_file_path()).unwrap();
|
||||
current_version_file.write_all("0.18.2".as_bytes()).unwrap();
|
||||
// Sync the file to disk before the read in current_version() to
|
||||
// mitigate the read not seeing the written version bytes.
|
||||
|
@ -302,12 +409,40 @@ mod tests {
|
|||
fn test_read_installed_versions() {
|
||||
ensure_paths();
|
||||
let version = Version::parse("0.18.2").unwrap();
|
||||
|
||||
// Create a fake binary for anchor-0.18.2 in the bin directory
|
||||
fs::File::create(version_binary_path(&version)).unwrap();
|
||||
let expected = vec![version];
|
||||
assert!(read_installed_versions() == expected);
|
||||
assert_eq!(read_installed_versions().unwrap(), expected);
|
||||
|
||||
// Should ignore this file because its not anchor- prefixed
|
||||
fs::File::create(AVM_HOME.join("bin").join("garbage").as_path()).unwrap();
|
||||
assert!(read_installed_versions() == expected);
|
||||
assert_eq!(read_installed_versions().unwrap(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_anchor_version_from_commit() {
|
||||
let version =
|
||||
get_anchor_version_from_commit("e1afcbf71e0f2e10fae14525934a6a68479167b9").unwrap();
|
||||
assert_eq!(
|
||||
version.to_string(),
|
||||
"0.28.0-e1afcbf71e0f2e10fae14525934a6a68479167b9"
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_check_and_get_full_commit_when_full_commit() {
|
||||
assert_eq!(
|
||||
check_and_get_full_commit("e1afcbf71e0f2e10fae14525934a6a68479167b9").unwrap(),
|
||||
"e1afcbf71e0f2e10fae14525934a6a68479167b9"
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_check_and_get_full_commit_when_partial_commit() {
|
||||
assert_eq!(
|
||||
check_and_get_full_commit("e1afcbf").unwrap(),
|
||||
"e1afcbf71e0f2e10fae14525934a6a68479167b9"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use anyhow::{Error, Result};
|
||||
use anyhow::{anyhow, Error, Result};
|
||||
use avm::InstallTarget;
|
||||
use clap::{Parser, Subcommand};
|
||||
use semver::Version;
|
||||
|
||||
|
@ -15,13 +16,14 @@ pub struct Cli {
|
|||
pub enum Commands {
|
||||
#[clap(about = "Use a specific version of Anchor")]
|
||||
Use {
|
||||
#[clap(value_parser = parse_version)]
|
||||
version: Version,
|
||||
#[clap(value_parser = parse_version, required = false)]
|
||||
version: Option<Version>,
|
||||
},
|
||||
#[clap(about = "Install a version of Anchor")]
|
||||
Install {
|
||||
#[clap(value_parser = parse_version)]
|
||||
version: Version,
|
||||
/// Anchor version or commit
|
||||
#[clap(value_parser = parse_install_target)]
|
||||
version_or_commit: InstallTarget,
|
||||
#[clap(long)]
|
||||
/// Flag to force installation even if the version
|
||||
/// is already installed
|
||||
|
@ -41,15 +43,38 @@ pub enum Commands {
|
|||
// If `latest` is passed use the latest available version.
|
||||
fn parse_version(version: &str) -> Result<Version, Error> {
|
||||
if version == "latest" {
|
||||
Ok(avm::get_latest_version())
|
||||
avm::get_latest_version()
|
||||
} else {
|
||||
Version::parse(version).map_err(|e| anyhow::anyhow!(e))
|
||||
Version::parse(version).map_err(|e| anyhow!(e))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_install_target(version_or_commit: &str) -> Result<InstallTarget, Error> {
|
||||
parse_version(version_or_commit)
|
||||
.map(|version| {
|
||||
if version.pre.is_empty() {
|
||||
InstallTarget::Version(version)
|
||||
} else {
|
||||
// Allow `avm install 0.28.0-6cf200493a307c01487c7b492b4893e0d6f6cb23`
|
||||
InstallTarget::Commit(version.pre.to_string())
|
||||
}
|
||||
})
|
||||
.or_else(|version_error| {
|
||||
avm::check_and_get_full_commit(version_or_commit)
|
||||
.map(InstallTarget::Commit)
|
||||
.map_err(|commit_error| {
|
||||
anyhow!("Not a valid version or commit: {version_error}, {commit_error}")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn entry(opts: Cli) -> Result<()> {
|
||||
match opts.command {
|
||||
Commands::Use { version } => avm::use_version(&version),
|
||||
Commands::Install { version, force } => avm::install_version(&version, force),
|
||||
Commands::Use { version } => avm::use_version(version),
|
||||
Commands::Install {
|
||||
version_or_commit,
|
||||
force,
|
||||
} => avm::install_version(version_or_commit, force),
|
||||
Commands::Uninstall { version } => avm::uninstall_version(&version),
|
||||
Commands::List {} => avm::list_versions(),
|
||||
Commands::Update {} => avm::update(),
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
# Binary Size
|
||||
|
||||
All notable changes in program binary size will be documented in this file.
|
||||
|
||||
The changes are calculated by comparing the current results with the last version's results. Increase in size is shown with 🔴 and decrease is shown with 🟢.
|
||||
|
||||
The programs and their tests are located in [/tests/bench](https://github.com/coral-xyz/anchor/tree/master/tests/bench).
|
||||
|
||||
> **Note**
|
||||
> Results documented in this file are autogenerated. Running the tests will update the current results when necessary, manually editing the results should be avoided.
|
||||
|
||||
> **Warning**
|
||||
> Results may vary depending on Solana version.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
Solana version: 1.18.8
|
||||
|
||||
| Program | Binary Size | - |
|
||||
| ------- | ----------- | --- |
|
||||
| bench | 791,008 | - |
|
||||
|
||||
### Notable changes
|
||||
|
||||
---
|
||||
|
||||
## [0.30.0]
|
||||
|
||||
Solana version: 1.18.8
|
||||
|
||||
| Program | Binary Size | - |
|
||||
| ------- | ----------- | ---------------------- |
|
||||
| bench | 791,008 | 🔴 **+47,952 (6.45%)** |
|
||||
|
||||
### Notable changes
|
||||
|
||||
- Upgrade Solana to `1.18.8` ([#2867](https://github.com/coral-xyz/anchor/pull/2867)).
|
||||
|
||||
---
|
||||
|
||||
## [0.29.0]
|
||||
|
||||
Solana version: 1.17.0
|
||||
|
||||
| Program | Binary Size | +/- |
|
||||
| ------- | ----------- | ------------------------ |
|
||||
| bench | 743,056 | 🟢 **-417,904 (36.00%)** |
|
||||
|
||||
### Notable changes
|
||||
|
||||
- `Box` the `anchor_lang::Result` error variants ([#2600](https://github.com/coral-xyz/anchor/pull/2600)).
|
||||
- Change all accounts to have a reference to `AccountInfo` instead of cloning ([#2656](https://github.com/coral-xyz/anchor/pull/2656)).
|
||||
- Reduce unnecessary cloning ([#2663](https://github.com/coral-xyz/anchor/pull/2663)).
|
||||
|
||||
---
|
||||
|
||||
## [0.28.0]
|
||||
|
||||
Solana version: 1.16.0
|
||||
|
||||
| Program | Binary Size | +/- |
|
||||
| ------- | ----------- | ---------------------- |
|
||||
| bench | 1,160,960 | 🔴 **+23,272 (2.05%)** |
|
||||
|
||||
### Notable changes
|
||||
|
||||
- Upgrading Solana to `1.16`. The difference in binary size between `0.27.0` and `0.28.0` is the direct result of upgrading Solana version(both build tools and crates) ([#2512](https://github.com/coral-xyz/anchor/pull/2512)).
|
||||
|
||||
---
|
||||
|
||||
## [0.27.0]
|
||||
|
||||
Solana version: 1.14.16
|
||||
|
||||
| Program | Binary Size | +/- |
|
||||
| ------- | ----------- | --- |
|
||||
| bench | 1,137,688 | N/A |
|
||||
|
||||
---
|
|
@ -7,194 +7,503 @@ The changes are calculated by comparing the current results with the last versio
|
|||
The programs and their tests are located in [/tests/bench](https://github.com/coral-xyz/anchor/tree/master/tests/bench).
|
||||
|
||||
> **Note**
|
||||
> The results documented in this file are autogenerated. Running the tests will update the current results when necessary, manually editing the results should be avoided.
|
||||
> Results documented in this file are autogenerated. Running the tests will update the current results when necessary, manually editing the results should be avoided.
|
||||
|
||||
> **Warning**
|
||||
> Results may vary depending on Solana version.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
| Instruction | Compute Units | +/- |
|
||||
| --------------------------- | ------------- | -------------- |
|
||||
| accountInfo1 | 1015 | 🔴 **+6.39%** |
|
||||
| accountInfo2 | 1475 | 🟢 **-5.87%** |
|
||||
| accountInfo4 | 1964 | 🟢 **-4.61%** |
|
||||
| accountInfo8 | 3856 | - |
|
||||
| accountEmptyInit1 | 5817 | 🟢 **-2.37%** |
|
||||
| accountEmpty1 | 1149 | 🔴 **+5.41%** |
|
||||
| accountEmptyInit2 | 10402 | 🟢 **-1.63%** |
|
||||
| accountEmpty2 | 1754 | 🟢 **-5.29%** |
|
||||
| accountEmptyInit4 | 19557 | - |
|
||||
| accountEmpty4 | 2540 | 🟢 **-4.01%** |
|
||||
| accountEmptyInit8 | 37541 | - |
|
||||
| accountEmpty8 | 5043 | - |
|
||||
| accountSizedInit1 | 5924 | 🟢 **-2.29%** |
|
||||
| accountSized1 | 1214 | 🔴 **+6.96%** |
|
||||
| accountSizedInit2 | 10783 | - |
|
||||
| accountSized2 | 1873 | 🟢 **-4.73%** |
|
||||
| accountSizedInit4 | 19975 | - |
|
||||
| accountSized4 | 2787 | - |
|
||||
| accountSizedInit8 | 38381 | - |
|
||||
| accountSized8 | 5359 | - |
|
||||
| accountUnsizedInit1 | 6052 | 🟢 **-2.28%** |
|
||||
| accountUnsized1 | 1338 | 🔴 **+7.64%** |
|
||||
| accountUnsizedInit2 | 10929 | 🟢 **-1.02%** |
|
||||
| accountUnsized2 | 1778 | 🟢 **-6.08%** |
|
||||
| accountUnsizedInit4 | 20495 | - |
|
||||
| accountUnsized4 | 3136 | 🔴 **+1.03%** |
|
||||
| accountUnsizedInit8 | 39419 | - |
|
||||
| accountUnsized8 | 5952 | 🟢 **-1.64%** |
|
||||
| boxedAccountEmptyInit1 | 6034 | 🟢 **-2.05%** |
|
||||
| boxedAccountEmpty1 | 888 | 🟢 **-9.02%** |
|
||||
| boxedAccountEmptyInit2 | 10633 | 🟢 **-1.40%** |
|
||||
| boxedAccountEmpty2 | 1401 | 🟢 **-6.54%** |
|
||||
| boxedAccountEmptyInit4 | 19500 | - |
|
||||
| boxedAccountEmpty4 | 2424 | 🟢 **-4.19%** |
|
||||
| boxedAccountEmptyInit8 | 37415 | - |
|
||||
| boxedAccountEmpty8 | 4659 | 🟢 **-2.53%** |
|
||||
| boxedAccountSizedInit1 | 6130 | 🟢 **-2.01%** |
|
||||
| boxedAccountSized1 | 917 | 🟢 **-8.57%** |
|
||||
| boxedAccountSizedInit2 | 10828 | 🟢 **-1.34%** |
|
||||
| boxedAccountSized2 | 1463 | 🟢 **-5.86%** |
|
||||
| boxedAccountSizedInit4 | 19884 | - |
|
||||
| boxedAccountSized4 | 2543 | 🟢 **-3.75%** |
|
||||
| boxedAccountSizedInit8 | 38182 | - |
|
||||
| boxedAccountSized8 | 4898 | 🟢 **-2.10%** |
|
||||
| boxedAccountUnsizedInit1 | 6240 | 🟢 **-2.10%** |
|
||||
| boxedAccountUnsized1 | 972 | 🟢 **-9.07%** |
|
||||
| boxedAccountUnsizedInit2 | 11048 | 🟢 **-1.45%** |
|
||||
| boxedAccountUnsized2 | 1570 | 🟢 **-6.49%** |
|
||||
| boxedAccountUnsizedInit4 | 20138 | 🟢 **-1.05%** |
|
||||
| boxedAccountUnsized4 | 2768 | 🟢 **-4.52%** |
|
||||
| boxedAccountUnsizedInit8 | 39118 | - |
|
||||
| boxedAccountUnsized8 | 5347 | 🟢 **-3.08%** |
|
||||
| boxedInterfaceAccountMint1 | 2299 | - |
|
||||
| boxedInterfaceAccountMint2 | 4129 | 🔴 **+1.88%** |
|
||||
| boxedInterfaceAccountMint4 | 7783 | 🔴 **+3.25%** |
|
||||
| boxedInterfaceAccountMint8 | 15281 | 🔴 **+3.96%** |
|
||||
| boxedInterfaceAccountToken1 | 2023 | 🔴 **+16.47%** |
|
||||
| boxedInterfaceAccountToken2 | 3582 | 🔴 **+22.34%** |
|
||||
| boxedInterfaceAccountToken4 | 6692 | 🔴 **+26.48%** |
|
||||
| boxedInterfaceAccountToken8 | 13098 | 🔴 **+28.35%** |
|
||||
| interfaceAccountMint1 | 2364 | 🟢 **-6.56%** |
|
||||
| interfaceAccountMint2 | 5030 | 🔴 **+6.43%** |
|
||||
| interfaceAccountMint4 | 9803 | 🔴 **+3.94%** |
|
||||
| interfaceAccountMint8 | 18400 | 🔴 **+3.90%** |
|
||||
| interfaceAccountToken1 | 2091 | 🔴 **+19.15%** |
|
||||
| interfaceAccountToken2 | 3948 | 🔴 **+22.95%** |
|
||||
| interfaceAccountToken4 | 7547 | 🔴 **+25.66%** |
|
||||
| interface1 | 1059 | 🔴 **+6.01%** |
|
||||
| interface2 | 1479 | 🟢 **-6.04%** |
|
||||
| interface4 | 1900 | 🟢 **-4.81%** |
|
||||
| interface8 | 3651 | - |
|
||||
| program1 | 1053 | 🔴 **+5.41%** |
|
||||
| program2 | 1467 | 🟢 **-6.74%** |
|
||||
| program4 | 1878 | 🟢 **-6.01%** |
|
||||
| program8 | 3598 | 🟢 **-1.45%** |
|
||||
| signer1 | 1018 | 🔴 **+6.26%** |
|
||||
| signer2 | 1484 | 🟢 **-5.84%** |
|
||||
| signer4 | 1984 | 🟢 **-4.57%** |
|
||||
| signer8 | 3895 | - |
|
||||
| systemAccount1 | 1072 | 🔴 **+5.82%** |
|
||||
| systemAccount2 | 1590 | 🟢 **-5.69%** |
|
||||
| systemAccount4 | 2195 | 🟢 **-4.48%** |
|
||||
| systemAccount8 | 4336 | - |
|
||||
| uncheckedAccount1 | 1014 | 🔴 **+6.40%** |
|
||||
| uncheckedAccount2 | 1475 | 🟢 **-5.87%** |
|
||||
| uncheckedAccount4 | 1965 | 🟢 **-4.61%** |
|
||||
| uncheckedAccount8 | 3855 | - |
|
||||
Solana version: 1.18.8
|
||||
|
||||
| Instruction | Compute Units | - |
|
||||
| --------------------------- | ------------- | --- |
|
||||
| accountInfo1 | 601 | - |
|
||||
| accountInfo2 | 923 | - |
|
||||
| accountInfo4 | 1,583 | - |
|
||||
| accountInfo8 | 2,975 | - |
|
||||
| accountEmptyInit1 | 5,034 | - |
|
||||
| accountEmpty1 | 652 | - |
|
||||
| accountEmptyInit2 | 9,687 | - |
|
||||
| accountEmpty2 | 1,016 | - |
|
||||
| accountEmptyInit4 | 18,501 | - |
|
||||
| accountEmpty4 | 1,737 | - |
|
||||
| accountEmptyInit8 | 36,169 | - |
|
||||
| accountEmpty8 | 3,186 | - |
|
||||
| accountSizedInit1 | 5,106 | - |
|
||||
| accountSized1 | 668 | - |
|
||||
| accountSizedInit2 | 9,828 | - |
|
||||
| accountSized2 | 1,046 | - |
|
||||
| accountSizedInit4 | 18,837 | - |
|
||||
| accountSized4 | 1,807 | - |
|
||||
| accountSizedInit8 | 36,761 | - |
|
||||
| accountSized8 | 3,326 | - |
|
||||
| accountUnsizedInit1 | 5,199 | - |
|
||||
| accountUnsized1 | 702 | - |
|
||||
| accountUnsizedInit2 | 10,078 | - |
|
||||
| accountUnsized2 | 1,116 | - |
|
||||
| accountUnsizedInit4 | 19,259 | - |
|
||||
| accountUnsized4 | 1,953 | - |
|
||||
| accountUnsizedInit8 | 37,331 | - |
|
||||
| accountUnsized8 | 3,626 | - |
|
||||
| boxedAccountEmptyInit1 | 5,064 | - |
|
||||
| boxedAccountEmpty1 | 671 | - |
|
||||
| boxedAccountEmptyInit2 | 9,721 | - |
|
||||
| boxedAccountEmpty2 | 1,052 | - |
|
||||
| boxedAccountEmptyInit4 | 18,582 | - |
|
||||
| boxedAccountEmpty4 | 1,811 | - |
|
||||
| boxedAccountEmptyInit8 | 36,329 | - |
|
||||
| boxedAccountEmpty8 | 3,357 | - |
|
||||
| boxedAccountSizedInit1 | 5,119 | - |
|
||||
| boxedAccountSized1 | 686 | - |
|
||||
| boxedAccountSizedInit2 | 9,845 | - |
|
||||
| boxedAccountSized2 | 1,085 | - |
|
||||
| boxedAccountSizedInit4 | 18,825 | - |
|
||||
| boxedAccountSized4 | 1,874 | - |
|
||||
| boxedAccountSizedInit8 | 36,824 | - |
|
||||
| boxedAccountSized8 | 3,490 | - |
|
||||
| boxedAccountUnsizedInit1 | 5,207 | - |
|
||||
| boxedAccountUnsized1 | 721 | - |
|
||||
| boxedAccountUnsizedInit2 | 10,015 | - |
|
||||
| boxedAccountUnsized2 | 1,157 | - |
|
||||
| boxedAccountUnsizedInit4 | 19,160 | - |
|
||||
| boxedAccountUnsized4 | 2,019 | - |
|
||||
| boxedAccountUnsizedInit8 | 37,496 | - |
|
||||
| boxedAccountUnsized8 | 3,776 | - |
|
||||
| boxedInterfaceAccountMint1 | 1,372 | - |
|
||||
| boxedInterfaceAccountMint2 | 2,293 | - |
|
||||
| boxedInterfaceAccountMint4 | 4,121 | - |
|
||||
| boxedInterfaceAccountMint8 | 7,811 | - |
|
||||
| boxedInterfaceAccountToken1 | 2,056 | - |
|
||||
| boxedInterfaceAccountToken2 | 3,660 | - |
|
||||
| boxedInterfaceAccountToken4 | 6,858 | - |
|
||||
| boxedInterfaceAccountToken8 | 13,284 | - |
|
||||
| interfaceAccountMint1 | 1,472 | - |
|
||||
| interfaceAccountMint2 | 2,631 | - |
|
||||
| interfaceAccountMint4 | 4,951 | - |
|
||||
| interfaceAccountMint8 | 9,588 | - |
|
||||
| interfaceAccountToken1 | 2,130 | - |
|
||||
| interfaceAccountToken2 | 3,928 | - |
|
||||
| interfaceAccountToken4 | 7,521 | - |
|
||||
| interface1 | 600 | - |
|
||||
| interface2 | 745 | - |
|
||||
| interface4 | 1,033 | - |
|
||||
| interface8 | 1,616 | - |
|
||||
| program1 | 596 | - |
|
||||
| program2 | 737 | - |
|
||||
| program4 | 1,019 | - |
|
||||
| program8 | 1,584 | - |
|
||||
| signer1 | 580 | - |
|
||||
| signer2 | 872 | - |
|
||||
| signer4 | 1,454 | - |
|
||||
| signer8 | 2,618 | - |
|
||||
| systemAccount1 | 592 | - |
|
||||
| systemAccount2 | 894 | - |
|
||||
| systemAccount4 | 1,497 | - |
|
||||
| systemAccount8 | 2,707 | - |
|
||||
| uncheckedAccount1 | 563 | - |
|
||||
| uncheckedAccount2 | 836 | - |
|
||||
| uncheckedAccount4 | 1,378 | - |
|
||||
| uncheckedAccount8 | 2,468 | - |
|
||||
|
||||
### Notable changes
|
||||
|
||||
---
|
||||
|
||||
## [0.30.0]
|
||||
|
||||
Solana version: 1.18.8
|
||||
|
||||
| Instruction | Compute Units | - |
|
||||
| --------------------------- | ------------- | ---------------------- |
|
||||
| accountInfo1 | 601 | 🟢 **-94 (13.53%)** |
|
||||
| accountInfo2 | 923 | 🟢 **-112 (10.82%)** |
|
||||
| accountInfo4 | 1,583 | 🟢 **-147 (8.50%)** |
|
||||
| accountInfo8 | 2,975 | 🟢 **-367 (10.98%)** |
|
||||
| accountEmptyInit1 | 5,034 | 🟢 **-518 (9.33%)** |
|
||||
| accountEmpty1 | 652 | 🟢 **-167 (20.39%)** |
|
||||
| accountEmptyInit2 | 9,687 | 🟢 **-734 (7.04%)** |
|
||||
| accountEmpty2 | 1,016 | 🟢 **-259 (20.31%)** |
|
||||
| accountEmptyInit4 | 18,501 | 🟢 **-1,302 (6.57%)** |
|
||||
| accountEmpty4 | 1,737 | 🟢 **-440 (20.21%)** |
|
||||
| accountEmptyInit8 | 36,169 | 🟢 **-2,440 (6.32%)** |
|
||||
| accountEmpty8 | 3,186 | 🟢 **-804 (20.15%)** |
|
||||
| accountSizedInit1 | 5,106 | 🟢 **-541 (9.58%)** |
|
||||
| accountSized1 | 668 | 🟢 **-175 (20.76%)** |
|
||||
| accountSizedInit2 | 9,828 | 🟢 **-779 (7.34%)** |
|
||||
| accountSized2 | 1,046 | 🟢 **-271 (20.58%)** |
|
||||
| accountSizedInit4 | 18,837 | 🟢 **-1,388 (6.86%)** |
|
||||
| accountSized4 | 1,807 | 🟢 **-467 (20.54%)** |
|
||||
| accountSizedInit8 | 36,761 | 🟢 **-2,615 (6.64%)** |
|
||||
| accountSized8 | 3,326 | 🟢 **-859 (20.53%)** |
|
||||
| accountUnsizedInit1 | 5,199 | 🟢 **-541 (9.43%)** |
|
||||
| accountUnsized1 | 702 | 🟢 **-168 (19.31%)** |
|
||||
| accountUnsizedInit2 | 10,078 | 🟢 **-778 (7.17%)** |
|
||||
| accountUnsized2 | 1,116 | 🟢 **-263 (19.07%)** |
|
||||
| accountUnsizedInit4 | 19,259 | 🟢 **-1,393 (6.75%)** |
|
||||
| accountUnsized4 | 1,953 | 🟢 **-458 (19.00%)** |
|
||||
| accountUnsizedInit8 | 37,331 | 🟢 **-2,638 (6.60%)** |
|
||||
| accountUnsized8 | 3,626 | 🟢 **-852 (19.03%)** |
|
||||
| boxedAccountEmptyInit1 | 5,064 | 🟢 **-541 (9.65%)** |
|
||||
| boxedAccountEmpty1 | 671 | 🟢 **-185 (21.61%)** |
|
||||
| boxedAccountEmptyInit2 | 9,721 | 🟢 **-801 (7.61%)** |
|
||||
| boxedAccountEmpty2 | 1,052 | 🟢 **-295 (21.90%)** |
|
||||
| boxedAccountEmptyInit4 | 18,582 | 🟢 **-1,420 (7.10%)** |
|
||||
| boxedAccountEmpty4 | 1,811 | 🟢 **-513 (22.07%)** |
|
||||
| boxedAccountEmptyInit8 | 36,329 | 🟢 **-2,673 (6.85%)** |
|
||||
| boxedAccountEmpty8 | 3,357 | 🟢 **-954 (22.13%)** |
|
||||
| boxedAccountSizedInit1 | 5,119 | 🟢 **-567 (9.97%)** |
|
||||
| boxedAccountSized1 | 686 | 🟢 **-192 (21.87%)** |
|
||||
| boxedAccountSizedInit2 | 9,845 | 🟢 **-845 (7.90%)** |
|
||||
| boxedAccountSized2 | 1,085 | 🟢 **-309 (22.17%)** |
|
||||
| boxedAccountSizedInit4 | 18,825 | 🟢 **-1,513 (7.44%)** |
|
||||
| boxedAccountSized4 | 1,874 | 🟢 **-539 (22.34%)** |
|
||||
| boxedAccountSizedInit8 | 36,824 | 🟢 **-2,846 (7.17%)** |
|
||||
| boxedAccountSized8 | 3,490 | 🟢 **-1,003 (22.32%)** |
|
||||
| boxedAccountUnsizedInit1 | 5,207 | 🟢 **-567 (9.82%)** |
|
||||
| boxedAccountUnsized1 | 721 | 🟢 **-187 (20.59%)** |
|
||||
| boxedAccountUnsizedInit2 | 10,015 | 🟢 **-851 (7.83%)** |
|
||||
| boxedAccountUnsized2 | 1,157 | 🟢 **-300 (20.59%)** |
|
||||
| boxedAccountUnsizedInit4 | 19,160 | 🟢 **-1,528 (7.39%)** |
|
||||
| boxedAccountUnsized4 | 2,019 | 🟢 **-527 (20.70%)** |
|
||||
| boxedAccountUnsizedInit8 | 37,496 | 🟢 **-2,879 (7.13%)** |
|
||||
| boxedAccountUnsized8 | 3,776 | 🟢 **-983 (20.66%)** |
|
||||
| boxedInterfaceAccountMint1 | 1,372 | 🟢 **-824 (37.52%)** |
|
||||
| boxedInterfaceAccountMint2 | 2,293 | 🟢 **-1,554 (40.40%)** |
|
||||
| boxedInterfaceAccountMint4 | 4,121 | 🟢 **-3,011 (42.22%)** |
|
||||
| boxedInterfaceAccountMint8 | 7,811 | 🟢 **-5,932 (43.16%)** |
|
||||
| boxedInterfaceAccountToken1 | 2,056 | 🟢 **-70 (3.29%)** |
|
||||
| boxedInterfaceAccountToken2 | 3,660 | 🟢 **-46 (1.24%)** |
|
||||
| boxedInterfaceAccountToken4 | 6,858 | 🔴 **+5 (0.07%)** |
|
||||
| boxedInterfaceAccountToken8 | 13,284 | 🔴 **+100 (0.76%)** |
|
||||
| interfaceAccountMint1 | 1,472 | 🟢 **-813 (35.58%)** |
|
||||
| interfaceAccountMint2 | 2,631 | 🟢 **-1,547 (37.03%)** |
|
||||
| interfaceAccountMint4 | 4,951 | 🟢 **-3,013 (37.83%)** |
|
||||
| interfaceAccountMint8 | 9,588 | 🟢 **-5,950 (38.29%)** |
|
||||
| interfaceAccountToken1 | 2,130 | 🟢 **-82 (3.71%)** |
|
||||
| interfaceAccountToken2 | 3,928 | 🟢 **-102 (2.53%)** |
|
||||
| interfaceAccountToken4 | 7,521 | 🟢 **-142 (1.85%)** |
|
||||
| interface1 | 600 | 🟢 **-141 (19.03%)** |
|
||||
| interface2 | 745 | 🟢 **-189 (20.24%)** |
|
||||
| interface4 | 1,033 | 🟢 **-282 (21.44%)** |
|
||||
| interface8 | 1,616 | 🟢 **-470 (22.53%)** |
|
||||
| program1 | 596 | 🟢 **-145 (19.57%)** |
|
||||
| program2 | 737 | 🟢 **-197 (21.09%)** |
|
||||
| program4 | 1,019 | 🟢 **-298 (22.63%)** |
|
||||
| program8 | 1,584 | 🟢 **-502 (24.07%)** |
|
||||
| signer1 | 580 | 🟢 **-95 (14.07%)** |
|
||||
| signer2 | 872 | 🟢 **-115 (11.65%)** |
|
||||
| signer4 | 1,454 | 🟢 **-152 (9.46%)** |
|
||||
| signer8 | 2,618 | 🟢 **-228 (8.01%)** |
|
||||
| systemAccount1 | 592 | 🟢 **-137 (18.79%)** |
|
||||
| systemAccount2 | 894 | 🟢 **-199 (18.21%)** |
|
||||
| systemAccount4 | 1,497 | 🟢 **-320 (17.61%)** |
|
||||
| systemAccount8 | 2,707 | 🟢 **-564 (17.24%)** |
|
||||
| uncheckedAccount1 | 563 | 🟢 **-94 (14.31%)** |
|
||||
| uncheckedAccount2 | 836 | 🟢 **-113 (11.91%)** |
|
||||
| uncheckedAccount4 | 1,378 | 🟢 **-148 (9.70%)** |
|
||||
| uncheckedAccount8 | 2,468 | 🟢 **-220 (8.18%)** |
|
||||
|
||||
### Notable changes
|
||||
|
||||
- Upgrade Solana to `1.18.8` ([#2867](https://github.com/coral-xyz/anchor/pull/2867)).
|
||||
|
||||
---
|
||||
|
||||
## [0.29.0]
|
||||
|
||||
Solana version: 1.17.0
|
||||
|
||||
| Instruction | Compute Units | +/- |
|
||||
| --------------------------- | ------------- | ---------------------- |
|
||||
| accountInfo1 | 695 | 🟢 **-431 (38.28%)** |
|
||||
| accountInfo2 | 1,035 | 🟢 **-651 (38.61%)** |
|
||||
| accountInfo4 | 1,730 | 🟢 **-645 (27.16%)** |
|
||||
| accountInfo8 | 3,342 | 🟢 **-1,310 (28.16%)** |
|
||||
| accountEmptyInit1 | 5,552 | 🟢 **-919 (14.20%)** |
|
||||
| accountEmpty1 | 819 | 🟢 **-441 (35.00%)** |
|
||||
| accountEmptyInit2 | 10,421 | 🟢 **-1,079 (9.38%)** |
|
||||
| accountEmpty2 | 1,275 | 🟢 **-690 (35.11%)** |
|
||||
| accountEmptyInit4 | 19,803 | 🟢 **-1,691 (7.87%)** |
|
||||
| accountEmpty4 | 2,177 | 🟢 **-774 (26.23%)** |
|
||||
| accountEmptyInit8 | 38,609 | 🟢 **-2,418 (5.89%)** |
|
||||
| accountEmpty8 | 3,990 | 🟢 **-1,837 (31.53%)** |
|
||||
| accountSizedInit1 | 5,647 | 🟢 **-937 (14.23%)** |
|
||||
| accountSized1 | 843 | 🟢 **-482 (36.38%)** |
|
||||
| accountSizedInit2 | 10,607 | 🟢 **-1,183 (10.03%)** |
|
||||
| accountSized2 | 1,317 | 🟢 **-767 (36.80%)** |
|
||||
| accountSizedInit4 | 20,225 | 🟢 **-1,755 (7.98%)** |
|
||||
| accountSized4 | 2,274 | 🟢 **-899 (28.33%)** |
|
||||
| accountSizedInit8 | 39,376 | 🟢 **-2,556 (6.10%)** |
|
||||
| accountSized8 | 4,185 | 🟢 **-1,979 (32.11%)** |
|
||||
| accountUnsizedInit1 | 5,740 | 🟢 **-978 (14.56%)** |
|
||||
| accountUnsized1 | 870 | 🟢 **-579 (39.96%)** |
|
||||
| accountUnsizedInit2 | 10,856 | 🟢 **-1,195 (9.92%)** |
|
||||
| accountUnsized2 | 1,379 | 🟢 **-610 (30.67%)** |
|
||||
| accountUnsizedInit4 | 20,652 | 🟢 **-1,721 (7.69%)** |
|
||||
| accountUnsized4 | 2,411 | 🟢 **-1,136 (32.03%)** |
|
||||
| accountUnsizedInit8 | 39,969 | 🟢 **-2,985 (6.95%)** |
|
||||
| accountUnsized8 | 4,478 | 🟢 **-2,285 (33.79%)** |
|
||||
| boxedAccountEmptyInit1 | 5,605 | 🟢 **-1,083 (16.19%)** |
|
||||
| boxedAccountEmpty1 | 856 | 🟢 **-143 (14.31%)** |
|
||||
| boxedAccountEmptyInit2 | 10,522 | 🟢 **-1,209 (10.31%)** |
|
||||
| boxedAccountEmpty2 | 1,347 | 🟢 **-265 (16.44%)** |
|
||||
| boxedAccountEmptyInit4 | 20,002 | 🟢 **-1,295 (6.08%)** |
|
||||
| boxedAccountEmpty4 | 2,324 | 🟢 **-511 (18.02%)** |
|
||||
| boxedAccountEmptyInit8 | 39,002 | 🟢 **-1,896 (4.64%)** |
|
||||
| boxedAccountEmpty8 | 4,311 | 🟢 **-1,159 (21.19%)** |
|
||||
| boxedAccountSizedInit1 | 5,686 | 🟢 **-1,104 (16.26%)** |
|
||||
| boxedAccountSized1 | 878 | 🟢 **-150 (14.59%)** |
|
||||
| boxedAccountSizedInit2 | 10,690 | 🟢 **-1,248 (10.45%)** |
|
||||
| boxedAccountSized2 | 1,394 | 🟢 **-280 (16.73%)** |
|
||||
| boxedAccountSizedInit4 | 20,338 | 🟢 **-1,375 (6.33%)** |
|
||||
| boxedAccountSized4 | 2,413 | 🟢 **-541 (18.31%)** |
|
||||
| boxedAccountSizedInit8 | 39,670 | 🟢 **-2,059 (4.93%)** |
|
||||
| boxedAccountSized8 | 4,493 | 🟢 **-1,216 (21.30%)** |
|
||||
| boxedAccountUnsizedInit1 | 5,774 | 🟢 **-1,132 (16.39%)** |
|
||||
| boxedAccountUnsized1 | 908 | 🟢 **-175 (16.16%)** |
|
||||
| boxedAccountUnsizedInit2 | 10,866 | 🟢 **-1,304 (10.71%)** |
|
||||
| boxedAccountUnsized2 | 1,457 | 🟢 **-324 (18.19%)** |
|
||||
| boxedAccountUnsizedInit4 | 20,688 | 🟢 **-1,484 (6.69%)** |
|
||||
| boxedAccountUnsized4 | 2,546 | 🟢 **-633 (19.91%)** |
|
||||
| boxedAccountUnsizedInit8 | 40,375 | 🟢 **-2,274 (5.33%)** |
|
||||
| boxedAccountUnsized8 | 4,759 | 🟢 **-1,399 (22.72%)** |
|
||||
| boxedInterfaceAccountMint1 | 2,196 | 🟢 **-211 (8.77%)** |
|
||||
| boxedInterfaceAccountMint2 | 3,847 | 🟢 **-403 (9.48%)** |
|
||||
| boxedInterfaceAccountMint4 | 7,132 | 🟢 **-792 (9.99%)** |
|
||||
| boxedInterfaceAccountMint8 | 13,743 | 🟢 **-1,719 (11.12%)** |
|
||||
| boxedInterfaceAccountToken1 | 2,126 | 🟢 **-8 (0.37%)** |
|
||||
| boxedInterfaceAccountToken2 | 3,706 | 🔴 **+3 (0.08%)** |
|
||||
| boxedInterfaceAccountToken4 | 6,853 | 🔴 **+20 (0.29%)** |
|
||||
| boxedInterfaceAccountToken8 | 13,184 | 🟢 **-95 (0.72%)** |
|
||||
| interfaceAccountMint1 | 2,285 | 🟢 **-190 (7.68%)** |
|
||||
| interfaceAccountMint2 | 4,178 | 🟢 **-973 (18.89%)** |
|
||||
| interfaceAccountMint4 | 7,964 | 🟢 **-1,980 (19.91%)** |
|
||||
| interfaceAccountMint8 | 15,538 | 🟢 **-3,043 (16.38%)** |
|
||||
| interfaceAccountToken1 | 2,212 | 🔴 **+10 (0.45%)** |
|
||||
| interfaceAccountToken2 | 4,030 | 🟢 **-39 (0.96%)** |
|
||||
| interfaceAccountToken4 | 7,663 | 🟢 **-25 (0.33%)** |
|
||||
| interface1 | 741 | 🟢 **-429 (36.67%)** |
|
||||
| interface2 | 934 | 🟢 **-666 (41.63%)** |
|
||||
| interface4 | 1,315 | 🟢 **-726 (35.57%)** |
|
||||
| interface8 | 2,086 | 🟢 **-1,741 (45.49%)** |
|
||||
| program1 | 741 | 🟢 **-423 (36.34%)** |
|
||||
| program2 | 934 | 🟢 **-654 (41.18%)** |
|
||||
| program4 | 1,317 | 🟢 **-702 (34.77%)** |
|
||||
| program8 | 2,086 | 🟢 **-1,693 (44.80%)** |
|
||||
| signer1 | 675 | 🟢 **-454 (40.21%)** |
|
||||
| signer2 | 987 | 🟢 **-708 (41.77%)** |
|
||||
| signer4 | 1,606 | 🟢 **-789 (32.94%)** |
|
||||
| signer8 | 2,846 | 🟢 **-1,845 (39.33%)** |
|
||||
| systemAccount1 | 729 | 🟢 **-454 (38.38%)** |
|
||||
| systemAccount2 | 1,093 | 🟢 **-708 (39.31%)** |
|
||||
| systemAccount4 | 1,817 | 🟢 **-789 (30.28%)** |
|
||||
| systemAccount8 | 3,271 | 🟢 **-1,845 (36.06%)** |
|
||||
| uncheckedAccount1 | 657 | 🟢 **-468 (41.60%)** |
|
||||
| uncheckedAccount2 | 949 | 🟢 **-737 (43.71%)** |
|
||||
| uncheckedAccount4 | 1,526 | 🟢 **-850 (35.77%)** |
|
||||
| uncheckedAccount8 | 2,688 | 🟢 **-1,964 (42.22%)** |
|
||||
|
||||
### Notable changes
|
||||
|
||||
- `Box` the `anchor_lang::Result` error variants ([#2600](https://github.com/coral-xyz/anchor/pull/2600)).
|
||||
- Change all accounts to have a reference to `AccountInfo` instead of cloning ([#2656](https://github.com/coral-xyz/anchor/pull/2656)).
|
||||
- Reduce unnecessary cloning ([#2663](https://github.com/coral-xyz/anchor/pull/2663)).
|
||||
|
||||
---
|
||||
|
||||
## [0.28.0]
|
||||
|
||||
Solana version: 1.16.0
|
||||
|
||||
| Instruction | Compute Units | +/- |
|
||||
| --------------------------- | ------------- | ---------------------- |
|
||||
| accountInfo1 | 1,126 | 🔴 **+63 (5.93%)** |
|
||||
| accountInfo2 | 1,686 | 🟢 **-88 (4.96%)** |
|
||||
| accountInfo4 | 2,375 | 🟢 **-87 (3.53%)** |
|
||||
| accountInfo8 | 4,652 | 🔴 **+1 (0.02%)** |
|
||||
| accountEmptyInit1 | 6,471 | 🟢 **-177 (2.66%)** |
|
||||
| accountEmpty1 | 1,260 | 🔴 **+61 (5.09%)** |
|
||||
| accountEmptyInit2 | 11,500 | 🟢 **-247 (2.10%)** |
|
||||
| accountEmpty2 | 1,965 | 🟢 **-94 (4.57%)** |
|
||||
| accountEmptyInit4 | 21,494 | 🟢 **-202 (0.93%)** |
|
||||
| accountEmpty4 | 2,951 | 🟢 **-98 (3.21%)** |
|
||||
| accountEmptyInit8 | 41,027 | 🟢 **-585 (1.41%)** |
|
||||
| accountEmpty8 | 5,827 | 🟢 **-11 (0.19%)** |
|
||||
| accountSizedInit1 | 6,584 | 🟢 **-175 (2.59%)** |
|
||||
| accountSized1 | 1,325 | 🔴 **+81 (6.51%)** |
|
||||
| accountSizedInit2 | 11,790 | 🟢 **-178 (1.49%)** |
|
||||
| accountSized2 | 2,084 | 🟢 **-89 (4.10%)** |
|
||||
| accountSizedInit4 | 21,980 | 🟢 **-158 (0.71%)** |
|
||||
| accountSized4 | 3,173 | 🟢 **-17 (0.53%)** |
|
||||
| accountSizedInit8 | 41,932 | 🟢 **-568 (1.34%)** |
|
||||
| accountSized8 | 6,164 | 🔴 **+10 (0.16%)** |
|
||||
| accountUnsizedInit1 | 6,718 | 🟢 **-177 (2.57%)** |
|
||||
| accountUnsized1 | 1,449 | 🔴 **+97 (7.17%)** |
|
||||
| accountUnsizedInit2 | 12,051 | 🟢 **-188 (1.54%)** |
|
||||
| accountUnsized2 | 1,989 | 🟢 **-111 (5.29%)** |
|
||||
| accountUnsizedInit4 | 22,373 | 🟢 **-309 (1.36%)** |
|
||||
| accountUnsized4 | 3,547 | 🔴 **+40 (1.14%)** |
|
||||
| accountUnsizedInit8 | 42,954 | 🟢 **-632 (1.45%)** |
|
||||
| accountUnsized8 | 6,763 | 🟢 **-83 (1.21%)** |
|
||||
| boxedAccountEmptyInit1 | 6,688 | 🟢 **-162 (2.36%)** |
|
||||
| boxedAccountEmpty1 | 999 | 🟢 **-86 (7.93%)** |
|
||||
| boxedAccountEmptyInit2 | 11,731 | 🟢 **-226 (1.89%)** |
|
||||
| boxedAccountEmpty2 | 1,612 | 🟢 **-94 (5.51%)** |
|
||||
| boxedAccountEmptyInit4 | 21,297 | 🟢 **-342 (1.58%)** |
|
||||
| boxedAccountEmpty4 | 2,835 | 🟢 **-98 (3.34%)** |
|
||||
| boxedAccountEmptyInit8 | 40,898 | 🟢 **-588 (1.42%)** |
|
||||
| boxedAccountEmpty8 | 5,470 | 🟢 **-105 (1.88%)** |
|
||||
| boxedAccountSizedInit1 | 6,790 | 🟢 **-162 (2.33%)** |
|
||||
| boxedAccountSized1 | 1,028 | 🟢 **-84 (7.55%)** |
|
||||
| boxedAccountSizedInit2 | 11,938 | 🟢 **-222 (1.83%)** |
|
||||
| boxedAccountSized2 | 1,674 | 🟢 **-87 (4.94%)** |
|
||||
| boxedAccountSizedInit4 | 21,713 | 🟢 **-334 (1.51%)** |
|
||||
| boxedAccountSized4 | 2,954 | 🟢 **-91 (2.99%)** |
|
||||
| boxedAccountSizedInit8 | 41,729 | 🟢 **-572 (1.35%)** |
|
||||
| boxedAccountSized8 | 5,709 | 🟢 **-89 (1.54%)** |
|
||||
| boxedAccountUnsizedInit1 | 6,906 | 🟢 **-170 (2.40%)** |
|
||||
| boxedAccountUnsized1 | 1,083 | 🟢 **-95 (8.06%)** |
|
||||
| boxedAccountUnsizedInit2 | 12,170 | 🟢 **-238 (1.92%)** |
|
||||
| boxedAccountUnsized2 | 1,781 | 🟢 **-105 (5.57%)** |
|
||||
| boxedAccountUnsizedInit4 | 22,172 | 🟢 **-366 (1.62%)** |
|
||||
| boxedAccountUnsized4 | 3,179 | 🟢 **-123 (3.73%)** |
|
||||
| boxedAccountUnsizedInit8 | 42,649 | 🟢 **-636 (1.47%)** |
|
||||
| boxedAccountUnsized8 | 6,158 | 🟢 **-154 (2.44%)** |
|
||||
| boxedInterfaceAccountMint1 | 2,407 | 🟢 **-1 (0.04%)** |
|
||||
| boxedInterfaceAccountMint2 | 4,250 | 🔴 **+74 (1.77%)** |
|
||||
| boxedInterfaceAccountMint4 | 7,924 | 🔴 **+235 (3.06%)** |
|
||||
| boxedInterfaceAccountMint8 | 15,462 | 🔴 **+556 (3.73%)** |
|
||||
| boxedInterfaceAccountToken1 | 2,134 | 🔴 **+288 (15.60%)** |
|
||||
| boxedInterfaceAccountToken2 | 3,703 | 🔴 **+652 (21.37%)** |
|
||||
| boxedInterfaceAccountToken4 | 6,833 | 🔴 **+1,391 (25.56%)** |
|
||||
| boxedInterfaceAccountToken8 | 13,279 | 🔴 **+2,867 (27.54%)** |
|
||||
| interfaceAccountMint1 | 2,475 | 🟢 **-164 (6.21%)** |
|
||||
| interfaceAccountMint2 | 5,151 | 🔴 **+302 (6.23%)** |
|
||||
| interfaceAccountMint4 | 9,944 | 🔴 **+362 (3.78%)** |
|
||||
| interfaceAccountMint8 | 18,581 | 🔴 **+665 (3.71%)** |
|
||||
| interfaceAccountToken1 | 2,202 | 🔴 **+338 (18.13%)** |
|
||||
| interfaceAccountToken2 | 4,069 | 🔴 **+735 (22.05%)** |
|
||||
| interfaceAccountToken4 | 7,688 | 🔴 **+1,531 (24.87%)** |
|
||||
| interface1 | 1,170 | 🔴 **+62 (5.60%)** |
|
||||
| interface2 | 1,600 | 🟢 **-97 (5.72%)** |
|
||||
| interface4 | 2,041 | 🟢 **-106 (4.94%)** |
|
||||
| interface8 | 3,827 | 🟢 **-31 (0.80%)** |
|
||||
| program1 | 1,164 | 🔴 **+56 (5.05%)** |
|
||||
| program2 | 1,588 | 🟢 **-108 (6.37%)** |
|
||||
| program4 | 2,019 | 🟢 **-130 (6.05%)** |
|
||||
| program8 | 3,779 | 🟢 **-79 (2.05%)** |
|
||||
| signer1 | 1,129 | 🔴 **+62 (5.81%)** |
|
||||
| signer2 | 1,695 | 🟢 **-88 (4.94%)** |
|
||||
| signer4 | 2,395 | 🟢 **-87 (3.51%)** |
|
||||
| signer8 | 4,691 | 🔴 **+1 (0.02%)** |
|
||||
| systemAccount1 | 1,183 | 🔴 **+61 (5.44%)** |
|
||||
| systemAccount2 | 1,801 | 🟢 **-92 (4.86%)** |
|
||||
| systemAccount4 | 2,606 | 🟢 **-95 (3.52%)** |
|
||||
| systemAccount8 | 5,116 | 🟢 **-15 (0.29%)** |
|
||||
| uncheckedAccount1 | 1,125 | 🔴 **+63 (5.93%)** |
|
||||
| uncheckedAccount2 | 1,686 | 🟢 **-88 (4.96%)** |
|
||||
| uncheckedAccount4 | 2,376 | 🟢 **-87 (3.53%)** |
|
||||
| uncheckedAccount8 | 4,652 | 🔴 **+2 (0.04%)** |
|
||||
|
||||
### Notable changes
|
||||
|
||||
- Upgrading Solana to `1.16`. The difference in compute units usage between `0.27.0` and `0.28.0` is the direct result of upgrading Solana version(both build tools and crates) ([#2512](https://github.com/coral-xyz/anchor/pull/2512)).
|
||||
|
||||
---
|
||||
|
||||
## [0.27.0]
|
||||
|
||||
Solana version: 1.14.16
|
||||
|
||||
| Instruction | Compute Units | +/- |
|
||||
| --------------------------- | ------------- | --- |
|
||||
| accountInfo1 | 954 | N/A |
|
||||
| accountInfo2 | 1567 | N/A |
|
||||
| accountInfo4 | 2059 | N/A |
|
||||
| accountInfo8 | 3856 | N/A |
|
||||
| accountEmptyInit1 | 5958 | N/A |
|
||||
| accountEmpty1 | 1090 | N/A |
|
||||
| accountEmptyInit2 | 10574 | N/A |
|
||||
| accountEmpty2 | 1852 | N/A |
|
||||
| accountEmptyInit4 | 19557 | N/A |
|
||||
| accountEmpty4 | 2646 | N/A |
|
||||
| accountEmptyInit8 | 37541 | N/A |
|
||||
| accountEmpty8 | 5043 | N/A |
|
||||
| accountSizedInit1 | 6063 | N/A |
|
||||
| accountSized1 | 1135 | N/A |
|
||||
| accountSizedInit2 | 10783 | N/A |
|
||||
| accountSized2 | 1966 | N/A |
|
||||
| accountSizedInit4 | 19975 | N/A |
|
||||
| accountSized4 | 2787 | N/A |
|
||||
| accountSizedInit8 | 38381 | N/A |
|
||||
| accountSized8 | 5359 | N/A |
|
||||
| accountUnsizedInit1 | 6193 | N/A |
|
||||
| accountUnsized1 | 1243 | N/A |
|
||||
| accountUnsizedInit2 | 11042 | N/A |
|
||||
| accountUnsized2 | 1893 | N/A |
|
||||
| accountUnsizedInit4 | 20495 | N/A |
|
||||
| accountUnsized4 | 3104 | N/A |
|
||||
| accountUnsizedInit8 | 39419 | N/A |
|
||||
| accountUnsized8 | 6051 | N/A |
|
||||
| boxedAccountEmptyInit1 | 6160 | N/A |
|
||||
| boxedAccountEmpty1 | 976 | N/A |
|
||||
| boxedAccountEmptyInit2 | 10784 | N/A |
|
||||
| boxedAccountEmpty2 | 1499 | N/A |
|
||||
| boxedAccountEmptyInit4 | 19500 | N/A |
|
||||
| boxedAccountEmpty4 | 2530 | N/A |
|
||||
| boxedAccountEmptyInit8 | 37415 | N/A |
|
||||
| boxedAccountEmpty8 | 4780 | N/A |
|
||||
| boxedAccountSizedInit1 | 6256 | N/A |
|
||||
| boxedAccountSized1 | 1003 | N/A |
|
||||
| boxedAccountSizedInit2 | 10975 | N/A |
|
||||
| boxedAccountSized2 | 1554 | N/A |
|
||||
| boxedAccountSizedInit4 | 19884 | N/A |
|
||||
| boxedAccountSized4 | 2642 | N/A |
|
||||
| boxedAccountSizedInit8 | 38182 | N/A |
|
||||
| boxedAccountSized8 | 5003 | N/A |
|
||||
| boxedAccountUnsizedInit1 | 6374 | N/A |
|
||||
| boxedAccountUnsized1 | 1069 | N/A |
|
||||
| boxedAccountUnsizedInit2 | 11211 | N/A |
|
||||
| boxedAccountUnsized2 | 1679 | N/A |
|
||||
| boxedAccountUnsizedInit4 | 20351 | N/A |
|
||||
| boxedAccountUnsized4 | 2899 | N/A |
|
||||
| boxedAccountUnsizedInit8 | 39118 | N/A |
|
||||
| boxedAccountUnsized8 | 5517 | N/A |
|
||||
| boxedInterfaceAccountMint1 | 2299 | N/A |
|
||||
| boxedInterfaceAccountMint2 | 4053 | N/A |
|
||||
| boxedInterfaceAccountMint4 | 7538 | N/A |
|
||||
| boxedInterfaceAccountMint8 | 14699 | N/A |
|
||||
| boxedInterfaceAccountToken1 | 1737 | N/A |
|
||||
| boxedInterfaceAccountToken2 | 2928 | N/A |
|
||||
| boxedInterfaceAccountToken4 | 5291 | N/A |
|
||||
| boxedInterfaceAccountToken8 | 10205 | N/A |
|
||||
| interfaceAccountMint1 | 2530 | N/A |
|
||||
| interfaceAccountMint2 | 4726 | N/A |
|
||||
| interfaceAccountMint4 | 9431 | N/A |
|
||||
| interfaceAccountMint8 | 17709 | N/A |
|
||||
| interfaceAccountToken1 | 1755 | N/A |
|
||||
| interfaceAccountToken2 | 3211 | N/A |
|
||||
| interfaceAccountToken4 | 6006 | N/A |
|
||||
| interface1 | 999 | N/A |
|
||||
| interface2 | 1574 | N/A |
|
||||
| interface4 | 1996 | N/A |
|
||||
| interface8 | 3651 | N/A |
|
||||
| program1 | 999 | N/A |
|
||||
| program2 | 1573 | N/A |
|
||||
| program4 | 1998 | N/A |
|
||||
| program8 | 3651 | N/A |
|
||||
| signer1 | 958 | N/A |
|
||||
| signer2 | 1576 | N/A |
|
||||
| signer4 | 2079 | N/A |
|
||||
| signer8 | 3895 | N/A |
|
||||
| systemAccount1 | 1013 | N/A |
|
||||
| systemAccount2 | 1686 | N/A |
|
||||
| systemAccount4 | 2298 | N/A |
|
||||
| systemAccount8 | 4336 | N/A |
|
||||
| uncheckedAccount1 | 953 | N/A |
|
||||
| uncheckedAccount2 | 1567 | N/A |
|
||||
| uncheckedAccount4 | 2060 | N/A |
|
||||
| uncheckedAccount8 | 3855 | N/A |
|
||||
| accountInfo1 | 1,063 | N/A |
|
||||
| accountInfo2 | 1,774 | N/A |
|
||||
| accountInfo4 | 2,462 | N/A |
|
||||
| accountInfo8 | 4,651 | N/A |
|
||||
| accountEmptyInit1 | 6,648 | N/A |
|
||||
| accountEmpty1 | 1,199 | N/A |
|
||||
| accountEmptyInit2 | 11,747 | N/A |
|
||||
| accountEmpty2 | 2,059 | N/A |
|
||||
| accountEmptyInit4 | 21,696 | N/A |
|
||||
| accountEmpty4 | 3,049 | N/A |
|
||||
| accountEmptyInit8 | 41,612 | N/A |
|
||||
| accountEmpty8 | 5,838 | N/A |
|
||||
| accountSizedInit1 | 6,759 | N/A |
|
||||
| accountSized1 | 1,244 | N/A |
|
||||
| accountSizedInit2 | 11,968 | N/A |
|
||||
| accountSized2 | 2,173 | N/A |
|
||||
| accountSizedInit4 | 22,138 | N/A |
|
||||
| accountSized4 | 3,190 | N/A |
|
||||
| accountSizedInit8 | 42,500 | N/A |
|
||||
| accountSized8 | 6,154 | N/A |
|
||||
| accountUnsizedInit1 | 6,895 | N/A |
|
||||
| accountUnsized1 | 1,352 | N/A |
|
||||
| accountUnsizedInit2 | 12,239 | N/A |
|
||||
| accountUnsized2 | 2,100 | N/A |
|
||||
| accountUnsizedInit4 | 22,682 | N/A |
|
||||
| accountUnsized4 | 3,507 | N/A |
|
||||
| accountUnsizedInit8 | 43,586 | N/A |
|
||||
| accountUnsized8 | 6,846 | N/A |
|
||||
| boxedAccountEmptyInit1 | 6,850 | N/A |
|
||||
| boxedAccountEmpty1 | 1,085 | N/A |
|
||||
| boxedAccountEmptyInit2 | 11,957 | N/A |
|
||||
| boxedAccountEmpty2 | 1,706 | N/A |
|
||||
| boxedAccountEmptyInit4 | 21,639 | N/A |
|
||||
| boxedAccountEmpty4 | 2,933 | N/A |
|
||||
| boxedAccountEmptyInit8 | 41,486 | N/A |
|
||||
| boxedAccountEmpty8 | 5,575 | N/A |
|
||||
| boxedAccountSizedInit1 | 6,952 | N/A |
|
||||
| boxedAccountSized1 | 1,112 | N/A |
|
||||
| boxedAccountSizedInit2 | 12,160 | N/A |
|
||||
| boxedAccountSized2 | 1,761 | N/A |
|
||||
| boxedAccountSizedInit4 | 22,047 | N/A |
|
||||
| boxedAccountSized4 | 3,045 | N/A |
|
||||
| boxedAccountSizedInit8 | 42,301 | N/A |
|
||||
| boxedAccountSized8 | 5,798 | N/A |
|
||||
| boxedAccountUnsizedInit1 | 7,076 | N/A |
|
||||
| boxedAccountUnsized1 | 1,178 | N/A |
|
||||
| boxedAccountUnsizedInit2 | 12,408 | N/A |
|
||||
| boxedAccountUnsized2 | 1,886 | N/A |
|
||||
| boxedAccountUnsizedInit4 | 22,538 | N/A |
|
||||
| boxedAccountUnsized4 | 3,302 | N/A |
|
||||
| boxedAccountUnsizedInit8 | 43,285 | N/A |
|
||||
| boxedAccountUnsized8 | 6,312 | N/A |
|
||||
| boxedInterfaceAccountMint1 | 2,408 | N/A |
|
||||
| boxedInterfaceAccountMint2 | 4,176 | N/A |
|
||||
| boxedInterfaceAccountMint4 | 7,689 | N/A |
|
||||
| boxedInterfaceAccountMint8 | 14,906 | N/A |
|
||||
| boxedInterfaceAccountToken1 | 1,846 | N/A |
|
||||
| boxedInterfaceAccountToken2 | 3,051 | N/A |
|
||||
| boxedInterfaceAccountToken4 | 5,442 | N/A |
|
||||
| boxedInterfaceAccountToken8 | 10,412 | N/A |
|
||||
| interfaceAccountMint1 | 2,639 | N/A |
|
||||
| interfaceAccountMint2 | 4,849 | N/A |
|
||||
| interfaceAccountMint4 | 9,582 | N/A |
|
||||
| interfaceAccountMint8 | 17,916 | N/A |
|
||||
| interfaceAccountToken1 | 1,864 | N/A |
|
||||
| interfaceAccountToken2 | 3,334 | N/A |
|
||||
| interfaceAccountToken4 | 6,157 | N/A |
|
||||
| interface1 | 1,108 | N/A |
|
||||
| interface2 | 1,697 | N/A |
|
||||
| interface4 | 2,147 | N/A |
|
||||
| interface8 | 3,858 | N/A |
|
||||
| program1 | 1,108 | N/A |
|
||||
| program2 | 1,696 | N/A |
|
||||
| program4 | 2,149 | N/A |
|
||||
| program8 | 3,858 | N/A |
|
||||
| signer1 | 1,067 | N/A |
|
||||
| signer2 | 1,783 | N/A |
|
||||
| signer4 | 2,482 | N/A |
|
||||
| signer8 | 4,690 | N/A |
|
||||
| systemAccount1 | 1,122 | N/A |
|
||||
| systemAccount2 | 1,893 | N/A |
|
||||
| systemAccount4 | 2,701 | N/A |
|
||||
| systemAccount8 | 5,131 | N/A |
|
||||
| uncheckedAccount1 | 1,062 | N/A |
|
||||
| uncheckedAccount2 | 1,774 | N/A |
|
||||
| uncheckedAccount4 | 2,463 | N/A |
|
||||
| uncheckedAccount8 | 4,650 | N/A |
|
||||
|
||||
---
|
||||
|
|
|
@ -0,0 +1,508 @@
|
|||
# Stack Memory
|
||||
|
||||
All notable changes in stack memory usage will be documented in this file.
|
||||
|
||||
The changes are calculated by comparing the current results with the last version's results. Increase in usage is shown with 🔴 and decrease is shown with 🟢.
|
||||
|
||||
The programs and their tests are located in [/tests/bench](https://github.com/coral-xyz/anchor/tree/master/tests/bench).
|
||||
|
||||
> **Note**
|
||||
> Results documented in this file are autogenerated. Running the tests will update the current results when necessary, manually editing the results should be avoided.
|
||||
|
||||
> **Warning**
|
||||
> Results may vary depending on Solana version.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
Solana version: 1.18.8
|
||||
|
||||
| Instruction | Stack Memory | - |
|
||||
| ------------------------------ | ------------ | --- |
|
||||
| account_info1 | 144 | - |
|
||||
| account_info2 | 144 | - |
|
||||
| account_info4 | 144 | - |
|
||||
| account_info8 | 144 | - |
|
||||
| account_empty_init1 | 144 | - |
|
||||
| account_empty_init2 | 144 | - |
|
||||
| account_empty_init4 | 192 | - |
|
||||
| account_empty_init8 | 224 | - |
|
||||
| account_empty1 | 144 | - |
|
||||
| account_empty2 | 144 | - |
|
||||
| account_empty4 | 144 | - |
|
||||
| account_empty8 | 144 | - |
|
||||
| account_sized_init1 | 176 | - |
|
||||
| account_sized_init2 | 192 | - |
|
||||
| account_sized_init4 | 224 | - |
|
||||
| account_sized_init8 | 288 | - |
|
||||
| account_sized1 | 144 | - |
|
||||
| account_sized2 | 144 | - |
|
||||
| account_sized4 | 144 | - |
|
||||
| account_sized8 | 144 | - |
|
||||
| account_unsized_init1 | 192 | - |
|
||||
| account_unsized_init2 | 224 | - |
|
||||
| account_unsized_init4 | 288 | - |
|
||||
| account_unsized_init8 | 416 | - |
|
||||
| account_unsized1 | 144 | - |
|
||||
| account_unsized2 | 144 | - |
|
||||
| account_unsized4 | 144 | - |
|
||||
| account_unsized8 | 144 | - |
|
||||
| boxed_account_empty_init1 | 144 | - |
|
||||
| boxed_account_empty_init2 | 144 | - |
|
||||
| boxed_account_empty_init4 | 192 | - |
|
||||
| boxed_account_empty_init8 | 224 | - |
|
||||
| boxed_account_empty1 | 144 | - |
|
||||
| boxed_account_empty2 | 144 | - |
|
||||
| boxed_account_empty4 | 144 | - |
|
||||
| boxed_account_empty8 | 144 | - |
|
||||
| boxed_account_sized_init1 | 144 | - |
|
||||
| boxed_account_sized_init2 | 144 | - |
|
||||
| boxed_account_sized_init4 | 192 | - |
|
||||
| boxed_account_sized_init8 | 224 | - |
|
||||
| boxed_account_sized1 | 144 | - |
|
||||
| boxed_account_sized2 | 144 | - |
|
||||
| boxed_account_sized4 | 144 | - |
|
||||
| boxed_account_sized8 | 144 | - |
|
||||
| boxed_account_unsized_init1 | 144 | - |
|
||||
| boxed_account_unsized_init2 | 144 | - |
|
||||
| boxed_account_unsized_init4 | 192 | - |
|
||||
| boxed_account_unsized_init8 | 224 | - |
|
||||
| boxed_account_unsized1 | 144 | - |
|
||||
| boxed_account_unsized2 | 144 | - |
|
||||
| boxed_account_unsized4 | 144 | - |
|
||||
| boxed_account_unsized8 | 144 | - |
|
||||
| boxed_interface_account_mint1 | 144 | - |
|
||||
| boxed_interface_account_mint2 | 144 | - |
|
||||
| boxed_interface_account_mint4 | 144 | - |
|
||||
| boxed_interface_account_mint8 | 144 | - |
|
||||
| boxed_interface_account_token1 | 144 | - |
|
||||
| boxed_interface_account_token2 | 144 | - |
|
||||
| boxed_interface_account_token4 | 144 | - |
|
||||
| boxed_interface_account_token8 | 144 | - |
|
||||
| interface_account_mint1 | 144 | - |
|
||||
| interface_account_mint2 | 144 | - |
|
||||
| interface_account_mint4 | 144 | - |
|
||||
| interface_account_mint8 | 144 | - |
|
||||
| interface_account_token1 | 144 | - |
|
||||
| interface_account_token2 | 144 | - |
|
||||
| interface_account_token4 | 144 | - |
|
||||
| interface1 | 144 | - |
|
||||
| interface2 | 144 | - |
|
||||
| interface4 | 144 | - |
|
||||
| interface8 | 144 | - |
|
||||
| program1 | 144 | - |
|
||||
| program2 | 144 | - |
|
||||
| program4 | 144 | - |
|
||||
| program8 | 144 | - |
|
||||
| signer1 | 144 | - |
|
||||
| signer2 | 144 | - |
|
||||
| signer4 | 144 | - |
|
||||
| signer8 | 144 | - |
|
||||
| system_account1 | 144 | - |
|
||||
| system_account2 | 144 | - |
|
||||
| system_account4 | 144 | - |
|
||||
| system_account8 | 144 | - |
|
||||
| unchecked_account1 | 144 | - |
|
||||
| unchecked_account2 | 144 | - |
|
||||
| unchecked_account4 | 144 | - |
|
||||
| unchecked_account8 | 144 | - |
|
||||
|
||||
### Notable changes
|
||||
|
||||
---
|
||||
|
||||
## [0.30.0]
|
||||
|
||||
Solana version: 1.18.8
|
||||
|
||||
| Instruction | Stack Memory | - |
|
||||
| ------------------------------ | ------------ | ------------------- |
|
||||
| account_info1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_info2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_info4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_info8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_empty_init1 | 144 | 🟢 **-32 (18.18%)** |
|
||||
| account_empty_init2 | 144 | 🟢 **-64 (30.77%)** |
|
||||
| account_empty_init4 | 192 | 🟢 **-16 (7.69%)** |
|
||||
| account_empty_init8 | 224 | 🟢 **-16 (6.67%)** |
|
||||
| account_empty1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_empty2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_empty4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_empty8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_sized_init1 | 176 | 🟢 **-32 (15.38%)** |
|
||||
| account_sized_init2 | 192 | 🟢 **-64 (25.00%)** |
|
||||
| account_sized_init4 | 224 | 🟢 **-16 (6.67%)** |
|
||||
| account_sized_init8 | 288 | 🟢 **-16 (5.26%)** |
|
||||
| account_sized1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_sized2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_sized4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_sized8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_unsized_init1 | 192 | 🟢 **-32 (14.29%)** |
|
||||
| account_unsized_init2 | 224 | 🟢 **-72 (24.32%)** |
|
||||
| account_unsized_init4 | 288 | 🟢 **-16 (5.26%)** |
|
||||
| account_unsized_init8 | 416 | 🟢 **-16 (3.70%)** |
|
||||
| account_unsized1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_unsized2 | 144 | - |
|
||||
| account_unsized4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| account_unsized8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_account_empty_init1 | 144 | 🟢 **-32 (18.18%)** |
|
||||
| boxed_account_empty_init2 | 144 | 🟢 **-64 (30.77%)** |
|
||||
| boxed_account_empty_init4 | 192 | 🟢 **-16 (7.69%)** |
|
||||
| boxed_account_empty_init8 | 224 | 🟢 **-16 (6.67%)** |
|
||||
| boxed_account_empty1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_account_empty2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_account_empty4 | 144 | - |
|
||||
| boxed_account_empty8 | 144 | - |
|
||||
| boxed_account_sized_init1 | 144 | 🟢 **-32 (18.18%)** |
|
||||
| boxed_account_sized_init2 | 144 | 🟢 **-64 (30.77%)** |
|
||||
| boxed_account_sized_init4 | 192 | 🟢 **-16 (7.69%)** |
|
||||
| boxed_account_sized_init8 | 224 | 🟢 **-16 (6.67%)** |
|
||||
| boxed_account_sized1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_account_sized2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_account_sized4 | 144 | - |
|
||||
| boxed_account_sized8 | 144 | - |
|
||||
| boxed_account_unsized_init1 | 144 | 🟢 **-32 (18.18%)** |
|
||||
| boxed_account_unsized_init2 | 144 | 🟢 **-64 (30.77%)** |
|
||||
| boxed_account_unsized_init4 | 192 | 🟢 **-16 (7.69%)** |
|
||||
| boxed_account_unsized_init8 | 224 | 🟢 **-16 (6.67%)** |
|
||||
| boxed_account_unsized1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_account_unsized2 | 144 | - |
|
||||
| boxed_account_unsized4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_account_unsized8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_interface_account_mint1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_interface_account_mint2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_interface_account_mint4 | 144 | - |
|
||||
| boxed_interface_account_mint8 | 144 | - |
|
||||
| boxed_interface_account_token1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_interface_account_token2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| boxed_interface_account_token4 | 144 | - |
|
||||
| boxed_interface_account_token8 | 144 | - |
|
||||
| interface_account_mint1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| interface_account_mint2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| interface_account_mint4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| interface_account_mint8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| interface_account_token1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| interface_account_token2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| interface_account_token4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| interface1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| interface2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| interface4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| interface8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| program1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| program2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| program4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| program8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| signer1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| signer2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| signer4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| signer8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| system_account1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| system_account2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| system_account4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| system_account8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| unchecked_account1 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| unchecked_account2 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| unchecked_account4 | 144 | 🔴 **+16 (12.50%)** |
|
||||
| unchecked_account8 | 144 | 🔴 **+16 (12.50%)** |
|
||||
|
||||
### Notable changes
|
||||
|
||||
- Upgrade Solana to `1.18.8` ([#2867](https://github.com/coral-xyz/anchor/pull/2867)).
|
||||
|
||||
---
|
||||
|
||||
## [0.29.0]
|
||||
|
||||
Solana version: 1.17.0
|
||||
|
||||
| Instruction | Stack Memory | +/- |
|
||||
| ------------------------------ | ------------ | ---------------------- |
|
||||
| account_info1 | 128 | 🟢 **-200 (60.98%)** |
|
||||
| account_info2 | 128 | 🟢 **-248 (65.96%)** |
|
||||
| account_info4 | 128 | 🟢 **-432 (77.14%)** |
|
||||
| account_info8 | 128 | 🟢 **-600 (82.42%)** |
|
||||
| account_empty_init1 | 176 | 🟢 **-416 (70.27%)** |
|
||||
| account_empty_init2 | 208 | 🟢 **-352 (62.86%)** |
|
||||
| account_empty_init4 | 208 | 🟢 **-424 (67.09%)** |
|
||||
| account_empty_init8 | 240 | 🟢 **-584 (70.87%)** |
|
||||
| account_empty1 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| account_empty2 | 128 | 🟢 **-240 (65.22%)** |
|
||||
| account_empty4 | 128 | 🟢 **-424 (76.81%)** |
|
||||
| account_empty8 | 128 | 🟢 **-600 (82.42%)** |
|
||||
| account_sized_init1 | 208 | 🟢 **-392 (65.33%)** |
|
||||
| account_sized_init2 | 256 | 🟢 **-296 (53.62%)** |
|
||||
| account_sized_init4 | 240 | 🟢 **-424 (63.86%)** |
|
||||
| account_sized_init8 | 304 | 🟢 **-584 (65.77%)** |
|
||||
| account_sized1 | 128 | 🟢 **-200 (60.98%)** |
|
||||
| account_sized2 | 128 | 🟢 **-264 (67.35%)** |
|
||||
| account_sized4 | 128 | 🟢 **-440 (77.46%)** |
|
||||
| account_sized8 | 128 | 🟢 **-664 (83.84%)** |
|
||||
| account_unsized_init1 | 224 | 🟢 **-400 (64.10%)** |
|
||||
| account_unsized_init2 | 296 | 🟢 **-288 (49.32%)** |
|
||||
| account_unsized_init4 | 304 | 🟢 **-424 (58.24%)** |
|
||||
| account_unsized_init8 | 432 | 🟢 **-584 (57.48%)** |
|
||||
| account_unsized1 | 128 | 🟢 **-216 (62.79%)** |
|
||||
| account_unsized2 | 144 | 🟢 **-312 (68.42%)** |
|
||||
| account_unsized4 | 128 | 🟢 **-504 (79.75%)** |
|
||||
| account_unsized8 | 128 | 🟢 **-792 (86.09%)** |
|
||||
| boxed_account_empty_init1 | 176 | 🟢 **-376 (68.12%)** |
|
||||
| boxed_account_empty_init2 | 208 | 🟢 **-192 (48.00%)** |
|
||||
| boxed_account_empty_init4 | 208 | 🟢 **-224 (51.85%)** |
|
||||
| boxed_account_empty_init8 | 240 | 🟢 **-256 (51.61%)** |
|
||||
| boxed_account_empty1 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| boxed_account_empty2 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| boxed_account_empty4 | 144 | 🟢 **-176 (55.00%)** |
|
||||
| boxed_account_empty8 | 144 | 🟢 **-192 (57.14%)** |
|
||||
| boxed_account_sized_init1 | 176 | 🟢 **-376 (68.12%)** |
|
||||
| boxed_account_sized_init2 | 208 | 🟢 **-192 (48.00%)** |
|
||||
| boxed_account_sized_init4 | 208 | 🟢 **-224 (51.85%)** |
|
||||
| boxed_account_sized_init8 | 240 | 🟢 **-256 (51.61%)** |
|
||||
| boxed_account_sized1 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| boxed_account_sized2 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| boxed_account_sized4 | 144 | 🟢 **-176 (55.00%)** |
|
||||
| boxed_account_sized8 | 144 | 🟢 **-192 (57.14%)** |
|
||||
| boxed_account_unsized_init1 | 176 | 🟢 **-376 (68.12%)** |
|
||||
| boxed_account_unsized_init2 | 208 | 🟢 **-192 (48.00%)** |
|
||||
| boxed_account_unsized_init4 | 208 | 🟢 **-224 (51.85%)** |
|
||||
| boxed_account_unsized_init8 | 240 | 🟢 **-256 (51.61%)** |
|
||||
| boxed_account_unsized1 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| boxed_account_unsized2 | 144 | 🟢 **-176 (55.00%)** |
|
||||
| boxed_account_unsized4 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| boxed_account_unsized8 | 128 | 🟢 **-208 (61.90%)** |
|
||||
| boxed_interface_account_mint1 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| boxed_interface_account_mint2 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| boxed_interface_account_mint4 | 144 | 🟢 **-176 (55.00%)** |
|
||||
| boxed_interface_account_mint8 | 144 | 🟢 **-192 (57.14%)** |
|
||||
| boxed_interface_account_token1 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| boxed_interface_account_token2 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| boxed_interface_account_token4 | 144 | 🟢 **-176 (55.00%)** |
|
||||
| boxed_interface_account_token8 | 144 | 🟢 **-192 (57.14%)** |
|
||||
| interface_account_mint1 | 128 | 🟢 **-376 (74.60%)** |
|
||||
| interface_account_mint2 | 128 | 🟢 **-552 (81.18%)** |
|
||||
| interface_account_mint4 | 128 | 🟢 **-888 (87.40%)** |
|
||||
| interface_account_mint8 | 128 | 🟢 **-1,560 (92.42%)** |
|
||||
| interface_account_token1 | 128 | 🟢 **-552 (81.18%)** |
|
||||
| interface_account_token2 | 128 | 🟢 **-728 (85.05%)** |
|
||||
| interface_account_token4 | 128 | 🟢 **-1,240 (90.64%)** |
|
||||
| interface1 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| interface2 | 128 | 🟢 **-240 (65.22%)** |
|
||||
| interface4 | 128 | 🟢 **-424 (76.81%)** |
|
||||
| interface8 | 128 | 🟢 **-600 (82.42%)** |
|
||||
| program1 | 128 | 🟢 **-192 (60.00%)** |
|
||||
| program2 | 128 | 🟢 **-240 (65.22%)** |
|
||||
| program4 | 128 | 🟢 **-424 (76.81%)** |
|
||||
| program8 | 128 | 🟢 **-600 (82.42%)** |
|
||||
| signer1 | 128 | 🟢 **-200 (60.98%)** |
|
||||
| signer2 | 128 | 🟢 **-248 (65.96%)** |
|
||||
| signer4 | 128 | 🟢 **-432 (77.14%)** |
|
||||
| signer8 | 128 | 🟢 **-600 (82.42%)** |
|
||||
| system_account1 | 128 | 🟢 **-200 (60.98%)** |
|
||||
| system_account2 | 128 | 🟢 **-248 (65.96%)** |
|
||||
| system_account4 | 128 | 🟢 **-432 (77.14%)** |
|
||||
| system_account8 | 128 | 🟢 **-600 (82.42%)** |
|
||||
| unchecked_account1 | 128 | 🟢 **-200 (60.98%)** |
|
||||
| unchecked_account2 | 128 | 🟢 **-248 (65.96%)** |
|
||||
| unchecked_account4 | 128 | 🟢 **-432 (77.14%)** |
|
||||
| unchecked_account8 | 128 | 🟢 **-600 (82.42%)** |
|
||||
|
||||
### Notable changes
|
||||
|
||||
- `Box` the `anchor_lang::Result` error variants ([#2600](https://github.com/coral-xyz/anchor/pull/2600)).
|
||||
|
||||
---
|
||||
|
||||
## [0.28.0]
|
||||
|
||||
Solana version: 1.16.0
|
||||
|
||||
| Instruction | Stack Memory | +/- |
|
||||
| ------------------------------ | ------------ | ---------------------- |
|
||||
| account_info1 | 328 | 🔴 **+80 (32.26%)** |
|
||||
| account_info2 | 376 | 🟢 **-16 (4.08%)** |
|
||||
| account_info4 | 560 | 🔴 **+48 (9.38%)** |
|
||||
| account_info8 | 728 | 🟢 **-168 (18.75%)** |
|
||||
| account_empty_init1 | 592 | 🔴 **+8 (1.37%)** |
|
||||
| account_empty_init2 | 560 | 🔴 **+48 (9.38%)** |
|
||||
| account_empty_init4 | 632 | 🟢 **-72 (10.23%)** |
|
||||
| account_empty_init8 | 824 | 🟢 **-264 (24.26%)** |
|
||||
| account_empty1 | 320 | 🔴 **+120 (60.00%)** |
|
||||
| account_empty2 | 368 | 🔴 **+24 (6.98%)** |
|
||||
| account_empty4 | 552 | 🔴 **+88 (18.97%)** |
|
||||
| account_empty8 | 728 | 🟢 **-120 (14.15%)** |
|
||||
| account_sized_init1 | 600 | 🔴 **+8 (1.35%)** |
|
||||
| account_sized_init2 | 552 | 🔴 **+8 (1.47%)** |
|
||||
| account_sized_init4 | 664 | 🟢 **-104 (13.54%)** |
|
||||
| account_sized_init8 | 888 | 🟢 **-328 (26.97%)** |
|
||||
| account_sized1 | 328 | 🔴 **+128 (64.00%)** |
|
||||
| account_sized2 | 392 | 🔴 **+32 (8.89%)** |
|
||||
| account_sized4 | 568 | 🔴 **+40 (7.58%)** |
|
||||
| account_sized8 | 792 | 🟢 **-184 (18.85%)** |
|
||||
| account_unsized_init1 | 624 | 🔴 **+16 (2.63%)** |
|
||||
| account_unsized_init2 | 584 | 🟢 **-24 (3.95%)** |
|
||||
| account_unsized_init4 | 728 | 🟢 **-168 (18.75%)** |
|
||||
| account_unsized_init8 | 1,016 | 🟢 **-456 (30.98%)** |
|
||||
| account_unsized1 | 344 | 🔴 **+168 (95.45%)** |
|
||||
| account_unsized2 | 456 | 🔴 **+64 (16.33%)** |
|
||||
| account_unsized4 | 632 | 🟢 **-24 (3.66%)** |
|
||||
| account_unsized8 | 920 | 🟢 **-312 (25.32%)** |
|
||||
| boxed_account_empty_init1 | 552 | 🔴 **+8 (1.47%)** |
|
||||
| boxed_account_empty_init2 | 400 | 🟢 **-8 (1.96%)** |
|
||||
| boxed_account_empty_init4 | 432 | 🔴 **+8 (1.89%)** |
|
||||
| boxed_account_empty_init8 | 496 | 🔴 **+40 (8.77%)** |
|
||||
| boxed_account_empty1 | 320 | 🔴 **+80 (33.33%)** |
|
||||
| boxed_account_empty2 | 320 | 🔴 **+72 (29.03%)** |
|
||||
| boxed_account_empty4 | 320 | 🔴 **+40 (14.29%)** |
|
||||
| boxed_account_empty8 | 336 | 🔴 **+24 (7.69%)** |
|
||||
| boxed_account_sized_init1 | 552 | 🔴 **+8 (1.47%)** |
|
||||
| boxed_account_sized_init2 | 400 | 🟢 **-8 (1.96%)** |
|
||||
| boxed_account_sized_init4 | 432 | 🔴 **+8 (1.89%)** |
|
||||
| boxed_account_sized_init8 | 496 | 🔴 **+40 (8.77%)** |
|
||||
| boxed_account_sized1 | 320 | 🔴 **+80 (33.33%)** |
|
||||
| boxed_account_sized2 | 320 | 🔴 **+72 (29.03%)** |
|
||||
| boxed_account_sized4 | 320 | 🔴 **+40 (14.29%)** |
|
||||
| boxed_account_sized8 | 336 | 🔴 **+24 (7.69%)** |
|
||||
| boxed_account_unsized_init1 | 552 | 🔴 **+8 (1.47%)** |
|
||||
| boxed_account_unsized_init2 | 400 | 🟢 **-8 (1.96%)** |
|
||||
| boxed_account_unsized_init4 | 432 | 🔴 **+8 (1.89%)** |
|
||||
| boxed_account_unsized_init8 | 496 | 🔴 **+40 (8.77%)** |
|
||||
| boxed_account_unsized1 | 320 | 🔴 **+72 (29.03%)** |
|
||||
| boxed_account_unsized2 | 320 | 🔴 **+72 (29.03%)** |
|
||||
| boxed_account_unsized4 | 320 | 🔴 **+40 (14.29%)** |
|
||||
| boxed_account_unsized8 | 336 | 🔴 **+24 (7.69%)** |
|
||||
| boxed_interface_account_mint1 | 320 | 🔴 **+80 (33.33%)** |
|
||||
| boxed_interface_account_mint2 | 320 | 🔴 **+72 (29.03%)** |
|
||||
| boxed_interface_account_mint4 | 320 | 🔴 **+40 (14.29%)** |
|
||||
| boxed_interface_account_mint8 | 336 | 🔴 **+24 (7.69%)** |
|
||||
| boxed_interface_account_token1 | 320 | 🔴 **+80 (33.33%)** |
|
||||
| boxed_interface_account_token2 | 320 | 🔴 **+72 (29.03%)** |
|
||||
| boxed_interface_account_token4 | 320 | 🔴 **+40 (14.29%)** |
|
||||
| boxed_interface_account_token8 | 336 | 🔴 **+24 (7.69%)** |
|
||||
| interface_account_mint1 | 504 | 🔴 **+296 (142.31%)** |
|
||||
| interface_account_mint2 | 680 | 🟢 **-72 (9.57%)** |
|
||||
| interface_account_mint4 | 1,016 | 🟢 **-408 (28.65%)** |
|
||||
| interface_account_mint8 | 1,688 | 🟢 **-1,080 (39.02%)** |
|
||||
| interface_account_token1 | 680 | 🔴 **+416 (157.58%)** |
|
||||
| interface_account_token2 | 856 | 🟢 **-248 (22.46%)** |
|
||||
| interface_account_token4 | 1,368 | 🟢 **-760 (35.71%)** |
|
||||
| interface1 | 320 | 🔴 **+120 (60.00%)** |
|
||||
| interface2 | 368 | 🔴 **+24 (6.98%)** |
|
||||
| interface4 | 552 | 🔴 **+88 (18.97%)** |
|
||||
| interface8 | 728 | 🟢 **-120 (14.15%)** |
|
||||
| program1 | 320 | 🔴 **+120 (60.00%)** |
|
||||
| program2 | 368 | 🔴 **+24 (6.98%)** |
|
||||
| program4 | 552 | 🔴 **+88 (18.97%)** |
|
||||
| program8 | 728 | 🟢 **-120 (14.15%)** |
|
||||
| signer1 | 328 | 🔴 **+80 (32.26%)** |
|
||||
| signer2 | 376 | 🟢 **-16 (4.08%)** |
|
||||
| signer4 | 560 | 🔴 **+48 (9.38%)** |
|
||||
| signer8 | 728 | 🟢 **-168 (18.75%)** |
|
||||
| system_account1 | 328 | 🔴 **+80 (32.26%)** |
|
||||
| system_account2 | 376 | 🟢 **-16 (4.08%)** |
|
||||
| system_account4 | 560 | 🔴 **+48 (9.38%)** |
|
||||
| system_account8 | 728 | 🟢 **-168 (18.75%)** |
|
||||
| unchecked_account1 | 328 | 🔴 **+80 (32.26%)** |
|
||||
| unchecked_account2 | 376 | 🟢 **-16 (4.08%)** |
|
||||
| unchecked_account4 | 560 | 🔴 **+48 (9.38%)** |
|
||||
| unchecked_account8 | 728 | 🟢 **-168 (18.75%)** |
|
||||
|
||||
### Notable changes
|
||||
|
||||
- Upgrading Solana to `1.16`. The difference in stack memory usage between `0.27.0` and `0.28.0` is the direct result of upgrading Solana version(both build tools and crates) ([#2512](https://github.com/coral-xyz/anchor/pull/2512)).
|
||||
- Change all accounts to have a reference to `AccountInfo` instead of cloning ([#2656](https://github.com/coral-xyz/anchor/pull/2656)).
|
||||
|
||||
---
|
||||
|
||||
## [0.27.0]
|
||||
|
||||
Solana version: 1.14.16
|
||||
|
||||
| Instruction | Stack Memory | +/- |
|
||||
| ------------------------------ | ------------ | --- |
|
||||
| account_info1 | 248 | N/A |
|
||||
| account_info2 | 392 | N/A |
|
||||
| account_info4 | 512 | N/A |
|
||||
| account_info8 | 896 | N/A |
|
||||
| account_empty_init1 | 584 | N/A |
|
||||
| account_empty_init2 | 512 | N/A |
|
||||
| account_empty_init4 | 704 | N/A |
|
||||
| account_empty_init8 | 1,088 | N/A |
|
||||
| account_empty1 | 200 | N/A |
|
||||
| account_empty2 | 344 | N/A |
|
||||
| account_empty4 | 464 | N/A |
|
||||
| account_empty8 | 848 | N/A |
|
||||
| account_sized_init1 | 592 | N/A |
|
||||
| account_sized_init2 | 544 | N/A |
|
||||
| account_sized_init4 | 768 | N/A |
|
||||
| account_sized_init8 | 1,216 | N/A |
|
||||
| account_sized1 | 200 | N/A |
|
||||
| account_sized2 | 360 | N/A |
|
||||
| account_sized4 | 528 | N/A |
|
||||
| account_sized8 | 976 | N/A |
|
||||
| account_unsized_init1 | 608 | N/A |
|
||||
| account_unsized_init2 | 608 | N/A |
|
||||
| account_unsized_init4 | 896 | N/A |
|
||||
| account_unsized_init8 | 1,472 | N/A |
|
||||
| account_unsized1 | 176 | N/A |
|
||||
| account_unsized2 | 392 | N/A |
|
||||
| account_unsized4 | 656 | N/A |
|
||||
| account_unsized8 | 1,232 | N/A |
|
||||
| boxed_account_empty_init1 | 544 | N/A |
|
||||
| boxed_account_empty_init2 | 408 | N/A |
|
||||
| boxed_account_empty_init4 | 424 | N/A |
|
||||
| boxed_account_empty_init8 | 456 | N/A |
|
||||
| boxed_account_empty1 | 240 | N/A |
|
||||
| boxed_account_empty2 | 248 | N/A |
|
||||
| boxed_account_empty4 | 280 | N/A |
|
||||
| boxed_account_empty8 | 312 | N/A |
|
||||
| boxed_account_sized_init1 | 544 | N/A |
|
||||
| boxed_account_sized_init2 | 408 | N/A |
|
||||
| boxed_account_sized_init4 | 424 | N/A |
|
||||
| boxed_account_sized_init8 | 456 | N/A |
|
||||
| boxed_account_sized1 | 240 | N/A |
|
||||
| boxed_account_sized2 | 248 | N/A |
|
||||
| boxed_account_sized4 | 280 | N/A |
|
||||
| boxed_account_sized8 | 312 | N/A |
|
||||
| boxed_account_unsized_init1 | 544 | N/A |
|
||||
| boxed_account_unsized_init2 | 408 | N/A |
|
||||
| boxed_account_unsized_init4 | 424 | N/A |
|
||||
| boxed_account_unsized_init8 | 456 | N/A |
|
||||
| boxed_account_unsized1 | 248 | N/A |
|
||||
| boxed_account_unsized2 | 248 | N/A |
|
||||
| boxed_account_unsized4 | 280 | N/A |
|
||||
| boxed_account_unsized8 | 312 | N/A |
|
||||
| boxed_interface_account_mint1 | 240 | N/A |
|
||||
| boxed_interface_account_mint2 | 248 | N/A |
|
||||
| boxed_interface_account_mint4 | 280 | N/A |
|
||||
| boxed_interface_account_mint8 | 312 | N/A |
|
||||
| boxed_interface_account_token1 | 240 | N/A |
|
||||
| boxed_interface_account_token2 | 248 | N/A |
|
||||
| boxed_interface_account_token4 | 280 | N/A |
|
||||
| boxed_interface_account_token8 | 312 | N/A |
|
||||
| interface_account_mint1 | 208 | N/A |
|
||||
| interface_account_mint2 | 752 | N/A |
|
||||
| interface_account_mint4 | 1,424 | N/A |
|
||||
| interface_account_mint8 | 2,768 | N/A |
|
||||
| interface_account_token1 | 264 | N/A |
|
||||
| interface_account_token2 | 1,104 | N/A |
|
||||
| interface_account_token4 | 2,128 | N/A |
|
||||
| interface1 | 200 | N/A |
|
||||
| interface2 | 344 | N/A |
|
||||
| interface4 | 464 | N/A |
|
||||
| interface8 | 848 | N/A |
|
||||
| program1 | 200 | N/A |
|
||||
| program2 | 344 | N/A |
|
||||
| program4 | 464 | N/A |
|
||||
| program8 | 848 | N/A |
|
||||
| signer1 | 248 | N/A |
|
||||
| signer2 | 392 | N/A |
|
||||
| signer4 | 512 | N/A |
|
||||
| signer8 | 896 | N/A |
|
||||
| system_account1 | 248 | N/A |
|
||||
| system_account2 | 392 | N/A |
|
||||
| system_account4 | 512 | N/A |
|
||||
| system_account8 | 896 | N/A |
|
||||
| unchecked_account1 | 248 | N/A |
|
||||
| unchecked_account2 | 392 | N/A |
|
||||
| unchecked_account4 | 512 | N/A |
|
||||
| unchecked_account8 | 896 | N/A |
|
||||
|
||||
---
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "anchor-cli"
|
||||
version = "0.27.0"
|
||||
authors = ["armaniferrante <armaniferrante@gmail.com>"]
|
||||
version = "0.30.0"
|
||||
authors = ["Anchor Maintainers <accounts@200ms.io>"]
|
||||
rust-version = "1.60"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/coral-xyz/anchor"
|
||||
|
@ -14,37 +14,36 @@ path = "src/bin/main.rs"
|
|||
|
||||
[features]
|
||||
dev = []
|
||||
default = []
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.2.4", features = ["derive"] }
|
||||
anchor-client = { path = "../client", version = "0.30.0" }
|
||||
anchor-lang-idl = { path = "../idl", features = ["build"], version = "0.1.0" }
|
||||
anchor-lang = { path = "../lang", version = "0.30.0" }
|
||||
anyhow = "1.0.32"
|
||||
base64 = "0.13.1"
|
||||
base64 = "0.21"
|
||||
bincode = "1.3.3"
|
||||
syn = { version = "1.0.60", features = ["full", "extra-traits"] }
|
||||
anchor-lang = { path = "../lang", version = "0.27.0" }
|
||||
anchor-client = { path = "../client", version = "0.27.0" }
|
||||
anchor-syn = { path = "../lang/syn", features = ["event-cpi", "idl", "init-if-needed"], version = "0.27.0" }
|
||||
serde_json = "1.0"
|
||||
shellexpand = "2.1.0"
|
||||
toml = "0.5.8"
|
||||
solang-parser = "=0.2.3"
|
||||
semver = "1.0.4"
|
||||
serde = { version = "1.0.122", features = ["derive"] }
|
||||
solana-sdk = "<1.17.0"
|
||||
solana-program = "<1.17.0"
|
||||
solana-client = "<1.17.0"
|
||||
solana-cli-config = "<1.17.0"
|
||||
solana-faucet = "<1.17.0"
|
||||
cargo_toml = "0.19.2"
|
||||
chrono = "0.4.19"
|
||||
clap = { version = "4.2.4", features = ["derive"] }
|
||||
dirs = "4.0"
|
||||
heck = "0.4.0"
|
||||
flate2 = "1.0.19"
|
||||
tar = "0.4.35"
|
||||
heck = "0.4.0"
|
||||
pathdiff = "0.2.0"
|
||||
portpicker = "0.1.1"
|
||||
regex = "1.8.3"
|
||||
reqwest = { version = "0.11.4", default-features = false, features = ["multipart", "blocking", "rustls-tls"] }
|
||||
tokio = "~1.14.1"
|
||||
pathdiff = "0.2.0"
|
||||
cargo_toml = "0.13.0"
|
||||
semver = "1.0.4"
|
||||
serde = { version = "1.0.122", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
shellexpand = "2.1.0"
|
||||
solana-client = "1.16"
|
||||
solana-cli-config = "1.16"
|
||||
solana-faucet = "1.16"
|
||||
solana-program = "1.16"
|
||||
solana-sdk = "1.16"
|
||||
# Pin solang-parser because it may break in a backwards incompatible way in minor versions
|
||||
solang-parser = "=0.3.3"
|
||||
syn = { version = "1.0.60", features = ["full", "extra-traits"] }
|
||||
tar = "0.4.35"
|
||||
toml = "0.7.6"
|
||||
walkdir = "2.3.2"
|
||||
chrono = "0.4.19"
|
||||
portpicker = "0.1.1"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@coral-xyz/anchor-cli",
|
||||
"version": "0.27.0",
|
||||
"version": "0.30.0",
|
||||
"description": "Anchor CLI tool",
|
||||
"homepage": "https://github.com/coral-xyz/anchor#readme",
|
||||
"bugs": {
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
use std::{fs, path::Path};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use semver::{Version, VersionReq};
|
||||
|
||||
use crate::{
|
||||
config::{Config, Manifest, WithPath},
|
||||
VERSION,
|
||||
};
|
||||
|
||||
/// Check whether `overflow-checks` codegen option is enabled.
|
||||
///
|
||||
/// https://doc.rust-lang.org/rustc/codegen-options/index.html#overflow-checks
|
||||
pub fn check_overflow(cargo_toml_path: impl AsRef<Path>) -> Result<bool> {
|
||||
Manifest::from_path(cargo_toml_path)?
|
||||
.profile
|
||||
.release
|
||||
.as_ref()
|
||||
.and_then(|profile| profile.overflow_checks)
|
||||
.ok_or(anyhow!(
|
||||
"`overflow-checks` is not enabled. To enable, add:\n\n\
|
||||
[profile.release]\n\
|
||||
overflow-checks = true\n\n\
|
||||
in workspace root Cargo.toml",
|
||||
))
|
||||
}
|
||||
|
||||
/// Check whether there is a mismatch between the current CLI version and:
|
||||
///
|
||||
/// - `anchor-lang` crate version
|
||||
/// - `@coral-xyz/anchor` package version
|
||||
///
|
||||
/// This function logs warnings in the case of a mismatch.
|
||||
pub fn check_anchor_version(cfg: &WithPath<Config>) -> Result<()> {
|
||||
let cli_version = Version::parse(VERSION)?;
|
||||
|
||||
// Check lang crate
|
||||
let mismatched_lang_version = cfg
|
||||
.get_rust_program_list()?
|
||||
.into_iter()
|
||||
.map(|path| path.join("Cargo.toml"))
|
||||
.map(cargo_toml::Manifest::from_path)
|
||||
.filter_map(|man| man.ok())
|
||||
.filter_map(|man| man.dependencies.get("anchor-lang").map(|d| d.to_owned()))
|
||||
.filter_map(|dep| Version::parse(dep.req()).ok())
|
||||
.find(|ver| ver != &cli_version); // Only log the warning once
|
||||
|
||||
if let Some(ver) = mismatched_lang_version {
|
||||
eprintln!(
|
||||
"WARNING: `anchor-lang` version({ver}) and the current CLI version({cli_version}) \
|
||||
don't match.\n\n\t\
|
||||
This can lead to unwanted behavior. To use the same CLI version, add:\n\n\t\
|
||||
[toolchain]\n\t\
|
||||
anchor_version = \"{ver}\"\n\n\t\
|
||||
to Anchor.toml\n"
|
||||
);
|
||||
}
|
||||
|
||||
// Check TS package
|
||||
let package_json = {
|
||||
let package_json_path = cfg.path().parent().unwrap().join("package.json");
|
||||
let package_json_content = fs::read_to_string(package_json_path)?;
|
||||
serde_json::from_str::<serde_json::Value>(&package_json_content)?
|
||||
};
|
||||
let mismatched_ts_version = package_json
|
||||
.get("dependencies")
|
||||
.and_then(|deps| deps.get("@coral-xyz/anchor"))
|
||||
.and_then(|ver| ver.as_str())
|
||||
.and_then(|ver| VersionReq::parse(ver).ok())
|
||||
.filter(|ver| !ver.matches(&cli_version));
|
||||
|
||||
if let Some(ver) = mismatched_ts_version {
|
||||
eprintln!(
|
||||
"WARNING: `@coral-xyz/anchor` version({ver}) and the current CLI version\
|
||||
({cli_version}) don't match.\n\n\t\
|
||||
This can lead to unwanted behavior. To fix, upgrade the package by running:\n\n\t\
|
||||
yarn upgrade @coral-xyz/anchor@{cli_version}\n"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
use crate::is_hidden;
|
||||
use anchor_client::Cluster;
|
||||
use anchor_syn::idl::Idl;
|
||||
use anchor_lang_idl::types::Idl;
|
||||
use anyhow::{anyhow, bail, Context, Error, Result};
|
||||
use clap::{Parser, ValueEnum};
|
||||
use dirs::home_dir;
|
||||
use heck::ToSnakeCase;
|
||||
use reqwest::Url;
|
||||
use serde::de::{self, MapAccess, Visitor};
|
||||
|
@ -114,6 +115,8 @@ impl Manifest {
|
|||
let mut cwd_opt = Some(start_from.as_path());
|
||||
|
||||
while let Some(cwd) = cwd_opt {
|
||||
let mut anchor_toml = false;
|
||||
|
||||
for f in fs::read_dir(cwd).with_context(|| {
|
||||
format!("Error reading the directory with path: {}", cwd.display())
|
||||
})? {
|
||||
|
@ -122,15 +125,21 @@ impl Manifest {
|
|||
format!("Error reading the directory with path: {}", cwd.display())
|
||||
})?
|
||||
.path();
|
||||
if let Some(filename) = p.file_name() {
|
||||
if filename.to_str() == Some("Cargo.toml") {
|
||||
let m = WithPath::new(Manifest::from_path(&p)?, p);
|
||||
return Ok(Some(m));
|
||||
if let Some(filename) = p.file_name().and_then(|name| name.to_str()) {
|
||||
if filename == "Cargo.toml" {
|
||||
return Ok(Some(WithPath::new(Manifest::from_path(&p)?, p)));
|
||||
}
|
||||
if filename == "Anchor.toml" {
|
||||
anchor_toml = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not found. Go up a directory level.
|
||||
// Not found. Go up a directory level, but don't go up from Anchor.toml
|
||||
if anchor_toml {
|
||||
break;
|
||||
}
|
||||
|
||||
cwd_opt = cwd.parent();
|
||||
}
|
||||
|
||||
|
@ -291,38 +300,44 @@ impl WithPath<Config> {
|
|||
}
|
||||
|
||||
pub fn canonicalize_workspace(&self) -> Result<(Vec<PathBuf>, Vec<PathBuf>)> {
|
||||
let members = self
|
||||
.workspace
|
||||
.members
|
||||
.iter()
|
||||
.map(|m| {
|
||||
self.path()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join(m)
|
||||
.canonicalize()
|
||||
.unwrap_or_else(|_| {
|
||||
panic!("Error reading workspace.members. File {:?} does not exist at path {:?}.", m, self.path)
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let exclude = self
|
||||
.workspace
|
||||
.exclude
|
||||
.iter()
|
||||
.map(|m| {
|
||||
self.path()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join(m)
|
||||
.canonicalize()
|
||||
.unwrap_or_else(|_| {
|
||||
panic!("Error reading workspace.exclude. File {:?} does not exist at path {:?}.", m, self.path)
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let members = self.process_paths(&self.workspace.members)?;
|
||||
let exclude = self.process_paths(&self.workspace.exclude)?;
|
||||
Ok((members, exclude))
|
||||
}
|
||||
|
||||
fn process_paths(&self, paths: &[String]) -> Result<Vec<PathBuf>, Error> {
|
||||
let base_path = self.path().parent().unwrap();
|
||||
paths
|
||||
.iter()
|
||||
.flat_map(|m| {
|
||||
let path = base_path.join(m);
|
||||
if m.ends_with("/*") {
|
||||
let dir = path.parent().unwrap();
|
||||
match fs::read_dir(dir) {
|
||||
Ok(entries) => entries
|
||||
.filter_map(|entry| entry.ok())
|
||||
.map(|entry| self.process_single_path(&entry.path()))
|
||||
.collect(),
|
||||
Err(e) => vec![Err(Error::new(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Error reading directory {:?}: {}", dir, e),
|
||||
)))],
|
||||
}
|
||||
} else {
|
||||
vec![self.process_single_path(&path)]
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn process_single_path(&self, path: &PathBuf) -> Result<PathBuf, Error> {
|
||||
path.canonicalize().map_err(|e| {
|
||||
Error::new(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Error canonicalizing path {:?}: {}", path, e),
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::ops::Deref for WithPath<T> {
|
||||
|
@ -340,8 +355,7 @@ impl<T> std::ops::DerefMut for WithPath<T> {
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Config {
|
||||
pub anchor_version: Option<String>,
|
||||
pub solana_version: Option<String>,
|
||||
pub toolchain: ToolchainConfig,
|
||||
pub features: FeaturesConfig,
|
||||
pub registry: RegistryConfig,
|
||||
pub provider: ProviderConfig,
|
||||
|
@ -356,13 +370,38 @@ pub struct Config {
|
|||
}
|
||||
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ToolchainConfig {
|
||||
pub anchor_version: Option<String>,
|
||||
pub solana_version: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct FeaturesConfig {
|
||||
#[serde(default)]
|
||||
pub seeds: bool,
|
||||
/// Enable account resolution.
|
||||
///
|
||||
/// Not able to specify default bool value: https://github.com/serde-rs/serde/issues/368
|
||||
#[serde(default = "FeaturesConfig::get_default_resolution")]
|
||||
pub resolution: bool,
|
||||
/// Disable safety comment checks
|
||||
#[serde(default, rename = "skip-lint")]
|
||||
pub skip_lint: bool,
|
||||
}
|
||||
|
||||
impl FeaturesConfig {
|
||||
fn get_default_resolution() -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FeaturesConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
resolution: Self::get_default_resolution(),
|
||||
skip_lint: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct RegistryConfig {
|
||||
pub url: String,
|
||||
|
@ -435,11 +474,12 @@ impl Config {
|
|||
}
|
||||
|
||||
pub fn docker(&self) -> String {
|
||||
let ver = self
|
||||
let version = self
|
||||
.toolchain
|
||||
.anchor_version
|
||||
.clone()
|
||||
.unwrap_or_else(|| crate::DOCKER_BUILDER_VERSION.to_string());
|
||||
format!("projectserum/build:v{ver}")
|
||||
.as_deref()
|
||||
.unwrap_or(crate::DOCKER_BUILDER_VERSION);
|
||||
format!("backpackapp/build:v{version}")
|
||||
}
|
||||
|
||||
pub fn discover(cfg_override: &ConfigOverride) -> Result<Option<WithPath<Config>>> {
|
||||
|
@ -498,8 +538,7 @@ impl Config {
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct _Config {
|
||||
anchor_version: Option<String>,
|
||||
solana_version: Option<String>,
|
||||
toolchain: Option<ToolchainConfig>,
|
||||
features: Option<FeaturesConfig>,
|
||||
programs: Option<BTreeMap<String, BTreeMap<String, serde_json::Value>>>,
|
||||
registry: Option<RegistryConfig>,
|
||||
|
@ -574,13 +613,12 @@ impl ToString for Config {
|
|||
}
|
||||
};
|
||||
let cfg = _Config {
|
||||
anchor_version: self.anchor_version.clone(),
|
||||
solana_version: self.solana_version.clone(),
|
||||
toolchain: Some(self.toolchain.clone()),
|
||||
features: Some(self.features.clone()),
|
||||
registry: Some(self.registry.clone()),
|
||||
provider: Provider {
|
||||
cluster: self.provider.cluster.clone(),
|
||||
wallet: self.provider.wallet.to_string(),
|
||||
wallet: self.provider.wallet.stringify_with_tilde(),
|
||||
},
|
||||
test: self.test_validator.clone().map(Into::into),
|
||||
scripts: match self.scripts.is_empty() {
|
||||
|
@ -600,11 +638,10 @@ impl FromStr for Config {
|
|||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let cfg: _Config = toml::from_str(s)
|
||||
.map_err(|e| anyhow::format_err!("Unable to deserialize config: {}", e.to_string()))?;
|
||||
let cfg: _Config =
|
||||
toml::from_str(s).map_err(|e| anyhow!("Unable to deserialize config: {e}"))?;
|
||||
Ok(Config {
|
||||
anchor_version: cfg.anchor_version,
|
||||
solana_version: cfg.solana_version,
|
||||
toolchain: cfg.toolchain.unwrap_or_default(),
|
||||
features: cfg.features.unwrap_or_default(),
|
||||
registry: cfg.registry.unwrap_or_default(),
|
||||
provider: ProviderConfig {
|
||||
|
@ -697,6 +734,7 @@ pub struct TestValidator {
|
|||
pub validator: Option<Validator>,
|
||||
pub startup_wait: i32,
|
||||
pub shutdown_wait: i32,
|
||||
pub upgradeable: bool,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
|
@ -709,6 +747,8 @@ pub struct _TestValidator {
|
|||
pub startup_wait: Option<i32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub shutdown_wait: Option<i32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub upgradeable: Option<bool>,
|
||||
}
|
||||
|
||||
pub const STARTUP_WAIT: i32 = 5000;
|
||||
|
@ -721,6 +761,7 @@ impl From<_TestValidator> for TestValidator {
|
|||
startup_wait: _test_validator.startup_wait.unwrap_or(STARTUP_WAIT),
|
||||
genesis: _test_validator.genesis,
|
||||
validator: _test_validator.validator.map(Into::into),
|
||||
upgradeable: _test_validator.upgradeable.unwrap_or(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -732,6 +773,7 @@ impl From<TestValidator> for _TestValidator {
|
|||
startup_wait: Some(test_validator.startup_wait),
|
||||
genesis: test_validator.genesis,
|
||||
validator: test_validator.validator.map(Into::into),
|
||||
upgradeable: Some(test_validator.upgradeable),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -940,6 +982,8 @@ pub struct GenesisEntry {
|
|||
pub address: String,
|
||||
// Filepath to the compiled program to embed into the genesis.
|
||||
pub program: String,
|
||||
// Whether the genesis program is upgradeable.
|
||||
pub upgradeable: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
@ -1015,6 +1059,9 @@ pub struct _Validator {
|
|||
// Warp the ledger to WARP_SLOT after starting the validator.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub warp_slot: Option<String>,
|
||||
// Deactivate one or more features.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub deactivate_feature: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
|
@ -1050,6 +1097,8 @@ pub struct Validator {
|
|||
pub ticks_per_slot: Option<u16>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub warp_slot: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub deactivate_feature: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl From<_Validator> for Validator {
|
||||
|
@ -1078,6 +1127,7 @@ impl From<_Validator> for Validator {
|
|||
slots_per_epoch: _validator.slots_per_epoch,
|
||||
ticks_per_slot: _validator.ticks_per_slot,
|
||||
warp_slot: _validator.warp_slot,
|
||||
deactivate_feature: _validator.deactivate_feature,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1102,11 +1152,12 @@ impl From<Validator> for _Validator {
|
|||
slots_per_epoch: validator.slots_per_epoch,
|
||||
ticks_per_slot: validator.ticks_per_slot,
|
||||
warp_slot: validator.warp_slot,
|
||||
deactivate_feature: validator.deactivate_feature,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_LEDGER_PATH: &str = ".anchor/test-ledger";
|
||||
pub const DEFAULT_LEDGER_PATH: &str = ".anchor/test-ledger";
|
||||
const DEFAULT_BIND_ADDRESS: &str = "0.0.0.0";
|
||||
|
||||
impl Merge for _Validator {
|
||||
|
@ -1191,6 +1242,9 @@ impl Merge for _Validator {
|
|||
.or_else(|| self.slots_per_epoch.take()),
|
||||
ticks_per_slot: other.ticks_per_slot.or_else(|| self.ticks_per_slot.take()),
|
||||
warp_slot: other.warp_slot.or_else(|| self.warp_slot.take()),
|
||||
deactivate_feature: other
|
||||
.deactivate_feature
|
||||
.or_else(|| self.deactivate_feature.take()),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1237,10 +1291,16 @@ impl Program {
|
|||
Ok(WithPath::new(file, path))
|
||||
}
|
||||
|
||||
pub fn binary_path(&self) -> PathBuf {
|
||||
pub fn binary_path(&self, verifiable: bool) -> PathBuf {
|
||||
let path = if verifiable {
|
||||
format!("target/verifiable/{}.so", self.lib_name)
|
||||
} else {
|
||||
format!("target/deploy/{}.so", self.lib_name)
|
||||
};
|
||||
|
||||
std::env::current_dir()
|
||||
.expect("Must have current dir")
|
||||
.join(format!("target/deploy/{}.so", self.lib_name))
|
||||
.join(path)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1310,7 +1370,42 @@ impl AnchorPackage {
|
|||
}
|
||||
}
|
||||
|
||||
crate::home_path!(WalletPath, ".config/solana/id.json");
|
||||
#[macro_export]
|
||||
macro_rules! home_path {
|
||||
($my_struct:ident, $path:literal) => {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct $my_struct(String);
|
||||
|
||||
impl Default for $my_struct {
|
||||
fn default() -> Self {
|
||||
$my_struct(home_dir().unwrap().join($path).display().to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl $my_struct {
|
||||
fn stringify_with_tilde(&self) -> String {
|
||||
self.0
|
||||
.replacen(home_dir().unwrap().to_str().unwrap(), "~", 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for $my_struct {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(Self(s.to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for $my_struct {
|
||||
fn to_string(&self) -> String {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
home_path!(WalletPath, ".config/solana/id.json");
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
1457
cli/src/lib.rs
1457
cli/src/lib.rs
File diff suppressed because it is too large
Load Diff
|
@ -1,36 +0,0 @@
|
|||
#[macro_export]
|
||||
macro_rules! home_path {
|
||||
($my_struct:ident, $path:literal) => {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct $my_struct(String);
|
||||
|
||||
impl Default for $my_struct {
|
||||
fn default() -> Self {
|
||||
match dirs::home_dir() {
|
||||
None => {
|
||||
println!("$HOME doesn't exist. This probably won't do what you want.");
|
||||
$my_struct(".".to_string())
|
||||
}
|
||||
Some(mut path) => {
|
||||
path.push($path);
|
||||
$my_struct(path.as_path().display().to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for $my_struct {
|
||||
fn to_string(&self) -> String {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for $my_struct {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(Self(s.to_string()))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,14 +1,211 @@
|
|||
use crate::config::ProgramWorkspace;
|
||||
use crate::VERSION;
|
||||
use anchor_syn::idl::Idl;
|
||||
use crate::{
|
||||
config::ProgramWorkspace, create_files, override_or_create_files, solidity_template, Files,
|
||||
VERSION,
|
||||
};
|
||||
use anchor_lang_idl::types::Idl;
|
||||
use anyhow::Result;
|
||||
use heck::{ToLowerCamelCase, ToSnakeCase, ToUpperCamelCase};
|
||||
use clap::{Parser, ValueEnum};
|
||||
use heck::{ToLowerCamelCase, ToPascalCase, ToSnakeCase};
|
||||
use regex::Regex;
|
||||
use solana_sdk::{
|
||||
pubkey::Pubkey,
|
||||
signature::{read_keypair_file, write_keypair_file, Keypair},
|
||||
signer::Signer,
|
||||
};
|
||||
use std::{fmt::Write, path::Path};
|
||||
use std::{
|
||||
fmt::Write as _,
|
||||
fs::{self, File},
|
||||
io::Write as _,
|
||||
path::Path,
|
||||
process::Stdio,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
/// Program initialization template
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Parser, ValueEnum)]
|
||||
pub enum ProgramTemplate {
|
||||
/// Program with a single `lib.rs` file
|
||||
#[default]
|
||||
Single,
|
||||
/// Program with multiple files for instructions, state...
|
||||
Multiple,
|
||||
}
|
||||
|
||||
/// Create a program from the given name and template.
|
||||
pub fn create_program(name: &str, template: ProgramTemplate) -> Result<()> {
|
||||
let program_path = Path::new("programs").join(name);
|
||||
let common_files = vec![
|
||||
("Cargo.toml".into(), workspace_manifest().into()),
|
||||
(program_path.join("Cargo.toml"), cargo_toml(name)),
|
||||
(program_path.join("Xargo.toml"), xargo_toml().into()),
|
||||
];
|
||||
|
||||
let template_files = match template {
|
||||
ProgramTemplate::Single => create_program_template_single(name, &program_path),
|
||||
ProgramTemplate::Multiple => create_program_template_multiple(name, &program_path),
|
||||
};
|
||||
|
||||
create_files(&[common_files, template_files].concat())
|
||||
}
|
||||
|
||||
/// Create a program with a single `lib.rs` file.
|
||||
fn create_program_template_single(name: &str, program_path: &Path) -> Files {
|
||||
vec![(
|
||||
program_path.join("src").join("lib.rs"),
|
||||
format!(
|
||||
r#"use anchor_lang::prelude::*;
|
||||
|
||||
declare_id!("{}");
|
||||
|
||||
#[program]
|
||||
pub mod {} {{
|
||||
use super::*;
|
||||
|
||||
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {{
|
||||
Ok(())
|
||||
}}
|
||||
}}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize {{}}
|
||||
"#,
|
||||
get_or_create_program_id(name),
|
||||
name.to_snake_case(),
|
||||
),
|
||||
)]
|
||||
}
|
||||
|
||||
/// Create a program with multiple files for instructions, state...
|
||||
fn create_program_template_multiple(name: &str, program_path: &Path) -> Files {
|
||||
let src_path = program_path.join("src");
|
||||
vec![
|
||||
(
|
||||
src_path.join("lib.rs"),
|
||||
format!(
|
||||
r#"pub mod constants;
|
||||
pub mod error;
|
||||
pub mod instructions;
|
||||
pub mod state;
|
||||
|
||||
use anchor_lang::prelude::*;
|
||||
|
||||
pub use constants::*;
|
||||
pub use instructions::*;
|
||||
pub use state::*;
|
||||
|
||||
declare_id!("{}");
|
||||
|
||||
#[program]
|
||||
pub mod {} {{
|
||||
use super::*;
|
||||
|
||||
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {{
|
||||
initialize::handler(ctx)
|
||||
}}
|
||||
}}
|
||||
"#,
|
||||
get_or_create_program_id(name),
|
||||
name.to_snake_case(),
|
||||
),
|
||||
),
|
||||
(
|
||||
src_path.join("constants.rs"),
|
||||
r#"use anchor_lang::prelude::*;
|
||||
|
||||
#[constant]
|
||||
pub const SEED: &str = "anchor";
|
||||
"#
|
||||
.into(),
|
||||
),
|
||||
(
|
||||
src_path.join("error.rs"),
|
||||
r#"use anchor_lang::prelude::*;
|
||||
|
||||
#[error_code]
|
||||
pub enum ErrorCode {
|
||||
#[msg("Custom error message")]
|
||||
CustomError,
|
||||
}
|
||||
"#
|
||||
.into(),
|
||||
),
|
||||
(
|
||||
src_path.join("instructions").join("mod.rs"),
|
||||
r#"pub mod initialize;
|
||||
|
||||
pub use initialize::*;
|
||||
"#
|
||||
.into(),
|
||||
),
|
||||
(
|
||||
src_path.join("instructions").join("initialize.rs"),
|
||||
r#"use anchor_lang::prelude::*;
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize {}
|
||||
|
||||
pub fn handler(ctx: Context<Initialize>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
"#
|
||||
.into(),
|
||||
),
|
||||
(src_path.join("state").join("mod.rs"), r#""#.into()),
|
||||
]
|
||||
}
|
||||
|
||||
const fn workspace_manifest() -> &'static str {
|
||||
r#"[workspace]
|
||||
members = [
|
||||
"programs/*"
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
[profile.release]
|
||||
overflow-checks = true
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
[profile.release.build-override]
|
||||
opt-level = 3
|
||||
incremental = false
|
||||
codegen-units = 1
|
||||
"#
|
||||
}
|
||||
|
||||
fn cargo_toml(name: &str) -> String {
|
||||
format!(
|
||||
r#"[package]
|
||||
name = "{0}"
|
||||
version = "0.1.0"
|
||||
description = "Created with Anchor"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "lib"]
|
||||
name = "{1}"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
cpi = ["no-entrypoint"]
|
||||
no-entrypoint = []
|
||||
no-idl = []
|
||||
no-log-ix-name = []
|
||||
idl-build = ["anchor-lang/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = "{2}"
|
||||
"#,
|
||||
name,
|
||||
name.to_snake_case(),
|
||||
VERSION,
|
||||
)
|
||||
}
|
||||
|
||||
fn xargo_toml() -> &'static str {
|
||||
r#"[target.bpfel-unknown-unknown.dependencies.std]
|
||||
features = []
|
||||
"#
|
||||
}
|
||||
|
||||
/// Read the program keypair file or create a new one if it doesn't exist.
|
||||
pub fn get_or_create_program_id(name: &str) -> Pubkey {
|
||||
|
@ -25,23 +222,6 @@ pub fn get_or_create_program_id(name: &str) -> Pubkey {
|
|||
.pubkey()
|
||||
}
|
||||
|
||||
pub fn virtual_manifest() -> &'static str {
|
||||
r#"[workspace]
|
||||
members = [
|
||||
"programs/*"
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
overflow-checks = true
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
[profile.release.build-override]
|
||||
opt-level = 3
|
||||
incremental = false
|
||||
codegen-units = 1
|
||||
"#
|
||||
}
|
||||
|
||||
pub fn credentials(token: &str) -> String {
|
||||
format!(
|
||||
r#"[registry]
|
||||
|
@ -51,51 +231,40 @@ token = "{token}"
|
|||
}
|
||||
|
||||
pub fn idl_ts(idl: &Idl) -> Result<String> {
|
||||
let mut idl = idl.clone();
|
||||
for acc in idl.accounts.iter_mut() {
|
||||
acc.name = acc.name.to_lower_camel_case();
|
||||
}
|
||||
let idl_json = serde_json::to_string_pretty(&idl)?;
|
||||
let idl_name = &idl.metadata.name;
|
||||
let type_name = idl_name.to_pascal_case();
|
||||
let idl = serde_json::to_string(idl)?;
|
||||
|
||||
// Convert every field of the IDL to camelCase
|
||||
let camel_idl = Regex::new(r#""\w+":"([\w\d]+)""#)?
|
||||
.captures_iter(&idl)
|
||||
.fold(idl.clone(), |acc, cur| {
|
||||
let name = cur.get(1).unwrap().as_str();
|
||||
|
||||
// Do not modify pubkeys
|
||||
if Pubkey::from_str(name).is_ok() {
|
||||
return acc;
|
||||
}
|
||||
|
||||
let camel_name = name.to_lower_camel_case();
|
||||
acc.replace(&format!(r#""{name}""#), &format!(r#""{camel_name}""#))
|
||||
});
|
||||
|
||||
// Pretty format
|
||||
let camel_idl = serde_json::to_string_pretty(&serde_json::from_str::<Idl>(&camel_idl)?)?;
|
||||
|
||||
Ok(format!(
|
||||
r#"export type {} = {};
|
||||
|
||||
export const IDL: {} = {};
|
||||
"#,
|
||||
idl.name.to_upper_camel_case(),
|
||||
idl_json,
|
||||
idl.name.to_upper_camel_case(),
|
||||
idl_json
|
||||
r#"/**
|
||||
* Program IDL in camelCase format in order to be used in JS/TS.
|
||||
*
|
||||
* Note that this is only a type helper and is not the actual IDL. The original
|
||||
* IDL can be found at `target/idl/{idl_name}.json`.
|
||||
*/
|
||||
export type {type_name} = {camel_idl};
|
||||
"#
|
||||
))
|
||||
}
|
||||
|
||||
pub fn cargo_toml(name: &str) -> String {
|
||||
format!(
|
||||
r#"[package]
|
||||
name = "{0}"
|
||||
version = "0.1.0"
|
||||
description = "Created with Anchor"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "lib"]
|
||||
name = "{1}"
|
||||
|
||||
[features]
|
||||
no-entrypoint = []
|
||||
no-idl = []
|
||||
no-log-ix-name = []
|
||||
cpi = ["no-entrypoint"]
|
||||
default = []
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = "{2}"
|
||||
"#,
|
||||
name,
|
||||
name.to_snake_case(),
|
||||
VERSION,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn deploy_js_script_host(cluster_url: &str, script_path: &str) -> String {
|
||||
format!(
|
||||
r#"
|
||||
|
@ -181,35 +350,6 @@ module.exports = async function (provider) {
|
|||
"#
|
||||
}
|
||||
|
||||
pub fn xargo_toml() -> &'static str {
|
||||
r#"[target.bpfel-unknown-unknown.dependencies.std]
|
||||
features = []
|
||||
"#
|
||||
}
|
||||
|
||||
pub fn lib_rs(name: &str) -> String {
|
||||
format!(
|
||||
r#"use anchor_lang::prelude::*;
|
||||
|
||||
declare_id!("{}");
|
||||
|
||||
#[program]
|
||||
pub mod {} {{
|
||||
use super::*;
|
||||
|
||||
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {{
|
||||
Ok(())
|
||||
}}
|
||||
}}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize {{}}
|
||||
"#,
|
||||
get_or_create_program_id(name),
|
||||
name.to_snake_case(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn mocha(name: &str) -> String {
|
||||
format!(
|
||||
r#"const anchor = require("@coral-xyz/anchor");
|
||||
|
@ -227,7 +367,7 @@ describe("{}", () => {{
|
|||
}});
|
||||
"#,
|
||||
name,
|
||||
name.to_upper_camel_case(),
|
||||
name.to_pascal_case(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -248,7 +388,7 @@ describe("{}", () => {{
|
|||
}});
|
||||
"#,
|
||||
name,
|
||||
name.to_upper_camel_case(),
|
||||
name.to_pascal_case(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -256,35 +396,35 @@ pub fn package_json(jest: bool) -> String {
|
|||
if jest {
|
||||
format!(
|
||||
r#"{{
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"jest": "^29.0.3",
|
||||
"prettier": "^2.6.2"
|
||||
}}
|
||||
}}
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"jest": "^29.0.3",
|
||||
"prettier": "^2.6.2"
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
r#"{{
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"chai": "^4.3.4",
|
||||
"mocha": "^9.0.3",
|
||||
"prettier": "^2.6.2"
|
||||
}}
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"chai": "^4.3.4",
|
||||
"mocha": "^9.0.3",
|
||||
"prettier": "^2.6.2"
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
)
|
||||
|
@ -295,44 +435,44 @@ pub fn ts_package_json(jest: bool) -> String {
|
|||
if jest {
|
||||
format!(
|
||||
r#"{{
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"@types/bn.js": "^5.1.0",
|
||||
"@types/jest": "^29.0.3",
|
||||
"jest": "^29.0.3",
|
||||
"prettier": "^2.6.2",
|
||||
"ts-jest": "^29.0.2",
|
||||
"typescript": "^4.3.5"
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"@types/bn.js": "^5.1.0",
|
||||
"@types/jest": "^29.0.3",
|
||||
"jest": "^29.0.3",
|
||||
"prettier": "^2.6.2",
|
||||
"ts-jest": "^29.0.2",
|
||||
"typescript": "^4.3.5"
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
r#"{{
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"chai": "^4.3.4",
|
||||
"mocha": "^9.0.3",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"@types/bn.js": "^5.1.0",
|
||||
"@types/chai": "^4.3.0",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"typescript": "^4.3.5",
|
||||
"prettier": "^2.6.2"
|
||||
}}
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"chai": "^4.3.4",
|
||||
"mocha": "^9.0.3",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"@types/bn.js": "^5.1.0",
|
||||
"@types/chai": "^4.3.0",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"typescript": "^4.3.5",
|
||||
"prettier": "^2.6.2"
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
)
|
||||
|
@ -358,11 +498,11 @@ describe("{}", () => {{
|
|||
}});
|
||||
}});
|
||||
"#,
|
||||
name.to_upper_camel_case(),
|
||||
name.to_pascal_case(),
|
||||
name.to_snake_case(),
|
||||
name,
|
||||
name.to_upper_camel_case(),
|
||||
name.to_upper_camel_case(),
|
||||
name.to_pascal_case(),
|
||||
name.to_pascal_case(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -385,45 +525,44 @@ describe("{}", () => {{
|
|||
}});
|
||||
}});
|
||||
"#,
|
||||
name.to_upper_camel_case(),
|
||||
name.to_pascal_case(),
|
||||
name.to_snake_case(),
|
||||
name,
|
||||
name.to_upper_camel_case(),
|
||||
name.to_upper_camel_case(),
|
||||
name.to_pascal_case(),
|
||||
name.to_pascal_case(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn ts_config(jest: bool) -> &'static str {
|
||||
if jest {
|
||||
r#"{
|
||||
"compilerOptions": {
|
||||
"types": ["jest"],
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"lib": ["es2015"],
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
"#
|
||||
"compilerOptions": {
|
||||
"types": ["jest"],
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"lib": ["es2015"],
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
"#
|
||||
} else {
|
||||
r#"{
|
||||
"compilerOptions": {
|
||||
"types": ["mocha", "chai"],
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"lib": ["es2015"],
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
"#
|
||||
"compilerOptions": {
|
||||
"types": ["mocha", "chai"],
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"lib": ["es2015"],
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
"#
|
||||
}
|
||||
}
|
||||
|
||||
pub fn git_ignore() -> &'static str {
|
||||
r#"
|
||||
.anchor
|
||||
r#".anchor
|
||||
.DS_Store
|
||||
target
|
||||
**/*.rs.bk
|
||||
|
@ -434,8 +573,7 @@ test-ledger
|
|||
}
|
||||
|
||||
pub fn prettier_ignore() -> &'static str {
|
||||
r#"
|
||||
.anchor
|
||||
r#".anchor
|
||||
.DS_Store
|
||||
target
|
||||
node_modules
|
||||
|
@ -486,7 +624,7 @@ anchor.setProvider(provider);
|
|||
r#"
|
||||
anchor.workspace.{} = new anchor.Program({}, new PublicKey("{}"), provider);
|
||||
"#,
|
||||
program.name.to_upper_camel_case(),
|
||||
program.name.to_pascal_case(),
|
||||
serde_json::to_string(&program.idl)?,
|
||||
program.program_id
|
||||
)?;
|
||||
|
@ -494,3 +632,176 @@ anchor.workspace.{} = new anchor.Program({}, new PublicKey("{}"), provider);
|
|||
|
||||
Ok(eval_string)
|
||||
}
|
||||
|
||||
/// Test initialization template
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Parser, ValueEnum)]
|
||||
pub enum TestTemplate {
|
||||
/// Generate template for Mocha unit-test
|
||||
#[default]
|
||||
Mocha,
|
||||
/// Generate template for Jest unit-test
|
||||
Jest,
|
||||
/// Generate template for Rust unit-test
|
||||
Rust,
|
||||
}
|
||||
|
||||
impl TestTemplate {
|
||||
pub fn get_test_script(&self, js: bool) -> &str {
|
||||
match &self {
|
||||
Self::Mocha => {
|
||||
if js {
|
||||
"yarn run mocha -t 1000000 tests/"
|
||||
} else {
|
||||
"yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
|
||||
}
|
||||
}
|
||||
Self::Jest => {
|
||||
if js {
|
||||
"yarn run jest"
|
||||
} else {
|
||||
"yarn run jest --preset ts-jest"
|
||||
}
|
||||
}
|
||||
Self::Rust => "cargo test",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_test_files(
|
||||
&self,
|
||||
project_name: &str,
|
||||
js: bool,
|
||||
solidity: bool,
|
||||
program_id: &str,
|
||||
) -> Result<()> {
|
||||
match self {
|
||||
Self::Mocha => {
|
||||
// Build the test suite.
|
||||
fs::create_dir_all("tests")?;
|
||||
|
||||
if js {
|
||||
let mut test = File::create(format!("tests/{}.js", &project_name))?;
|
||||
if solidity {
|
||||
test.write_all(solidity_template::mocha(project_name).as_bytes())?;
|
||||
} else {
|
||||
test.write_all(mocha(project_name).as_bytes())?;
|
||||
}
|
||||
} else {
|
||||
let mut mocha = File::create(format!("tests/{}.ts", &project_name))?;
|
||||
if solidity {
|
||||
mocha.write_all(solidity_template::ts_mocha(project_name).as_bytes())?;
|
||||
} else {
|
||||
mocha.write_all(ts_mocha(project_name).as_bytes())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Self::Jest => {
|
||||
// Build the test suite.
|
||||
fs::create_dir_all("tests")?;
|
||||
|
||||
let mut test = File::create(format!("tests/{}.test.js", &project_name))?;
|
||||
if solidity {
|
||||
test.write_all(solidity_template::jest(project_name).as_bytes())?;
|
||||
} else {
|
||||
test.write_all(jest(project_name).as_bytes())?;
|
||||
}
|
||||
}
|
||||
Self::Rust => {
|
||||
// Do not initilize git repo
|
||||
let exit = std::process::Command::new("cargo")
|
||||
.arg("new")
|
||||
.arg("--vcs")
|
||||
.arg("none")
|
||||
.arg("--lib")
|
||||
.arg("tests")
|
||||
.stderr(Stdio::inherit())
|
||||
.output()
|
||||
.map_err(|e| anyhow::format_err!("{}", e.to_string()))?;
|
||||
if !exit.status.success() {
|
||||
eprintln!("'cargo new --lib tests' failed");
|
||||
std::process::exit(exit.status.code().unwrap_or(1));
|
||||
}
|
||||
|
||||
let mut files = Vec::new();
|
||||
let tests_path = Path::new("tests");
|
||||
files.extend(vec![(
|
||||
tests_path.join("Cargo.toml"),
|
||||
tests_cargo_toml(project_name),
|
||||
)]);
|
||||
files.extend(create_program_template_rust_test(
|
||||
project_name,
|
||||
tests_path,
|
||||
program_id,
|
||||
));
|
||||
override_or_create_files(&files)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tests_cargo_toml(name: &str) -> String {
|
||||
format!(
|
||||
r#"[package]
|
||||
name = "tests"
|
||||
version = "0.1.0"
|
||||
description = "Created with Anchor"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anchor-client = "{0}"
|
||||
{1} = {{ version = "0.1.0", path = "../programs/{1}" }}
|
||||
"#,
|
||||
VERSION, name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate template for Rust unit-test
|
||||
fn create_program_template_rust_test(name: &str, tests_path: &Path, program_id: &str) -> Files {
|
||||
let src_path = tests_path.join("src");
|
||||
vec![
|
||||
(
|
||||
src_path.join("lib.rs"),
|
||||
r#"#[cfg(test)]
|
||||
mod test_initialize;
|
||||
"#
|
||||
.into(),
|
||||
),
|
||||
(
|
||||
src_path.join("test_initialize.rs"),
|
||||
format!(
|
||||
r#"use std::str::FromStr;
|
||||
|
||||
use anchor_client::{{
|
||||
solana_sdk::{{
|
||||
commitment_config::CommitmentConfig, pubkey::Pubkey, signature::read_keypair_file,
|
||||
}},
|
||||
Client, Cluster,
|
||||
}};
|
||||
|
||||
#[test]
|
||||
fn test_initialize() {{
|
||||
let program_id = "{0}";
|
||||
let anchor_wallet = std::env::var("ANCHOR_WALLET").unwrap();
|
||||
let payer = read_keypair_file(&anchor_wallet).unwrap();
|
||||
|
||||
let client = Client::new_with_options(Cluster::Localnet, &payer, CommitmentConfig::confirmed());
|
||||
let program_id = Pubkey::from_str(program_id).unwrap();
|
||||
let program = client.program(program_id).unwrap();
|
||||
|
||||
let tx = program
|
||||
.request()
|
||||
.accounts({1}::accounts::Initialize {{}})
|
||||
.args({1}::instruction::Initialize {{}})
|
||||
.send()
|
||||
.expect("");
|
||||
|
||||
println!("Your transaction signature {{}}", tx);
|
||||
}}
|
||||
"#,
|
||||
program_id,
|
||||
name.to_snake_case(),
|
||||
),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,129 +1,25 @@
|
|||
use crate::config::ProgramWorkspace;
|
||||
use crate::VERSION;
|
||||
use anchor_syn::idl::Idl;
|
||||
use crate::create_files;
|
||||
use anyhow::Result;
|
||||
use heck::{ToLowerCamelCase, ToSnakeCase, ToUpperCamelCase};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use std::fmt::Write;
|
||||
use heck::{ToSnakeCase, ToUpperCamelCase};
|
||||
use std::path::Path;
|
||||
|
||||
pub fn default_program_id() -> Pubkey {
|
||||
"F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC"
|
||||
.parse()
|
||||
.unwrap()
|
||||
/// Create a solidity program.
|
||||
pub fn create_program(name: &str) -> Result<()> {
|
||||
let files = vec![(
|
||||
Path::new("solidity").join(name).with_extension("sol"),
|
||||
solidity(name),
|
||||
)];
|
||||
create_files(&files)
|
||||
}
|
||||
|
||||
pub fn idl_ts(idl: &Idl) -> Result<String> {
|
||||
let mut idl = idl.clone();
|
||||
for acc in idl.accounts.iter_mut() {
|
||||
acc.name = acc.name.to_lower_camel_case();
|
||||
}
|
||||
let idl_json = serde_json::to_string_pretty(&idl)?;
|
||||
Ok(format!(
|
||||
r#"export type {} = {};
|
||||
|
||||
export const IDL: {} = {};
|
||||
"#,
|
||||
idl.name.to_upper_camel_case(),
|
||||
idl_json,
|
||||
idl.name.to_upper_camel_case(),
|
||||
idl_json
|
||||
))
|
||||
}
|
||||
|
||||
pub fn deploy_js_script_host(cluster_url: &str, script_path: &str) -> String {
|
||||
fn solidity(name: &str) -> String {
|
||||
format!(
|
||||
r#"
|
||||
const anchor = require('@coral-xyz/anchor');
|
||||
|
||||
// Deploy script defined by the user.
|
||||
const userScript = require("{script_path}");
|
||||
|
||||
async function main() {{
|
||||
const url = "{cluster_url}";
|
||||
const preflightCommitment = 'recent';
|
||||
const connection = new anchor.web3.Connection(url, preflightCommitment);
|
||||
const wallet = anchor.Wallet.local();
|
||||
|
||||
const provider = new anchor.AnchorProvider(connection, wallet, {{
|
||||
preflightCommitment,
|
||||
commitment: 'recent',
|
||||
}});
|
||||
|
||||
// Run the user's deploy script.
|
||||
userScript(provider);
|
||||
}}
|
||||
main();
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
pub fn deploy_ts_script_host(cluster_url: &str, script_path: &str) -> String {
|
||||
format!(
|
||||
r#"import * as anchor from '@coral-xyz/anchor';
|
||||
|
||||
// Deploy script defined by the user.
|
||||
const userScript = require("{script_path}");
|
||||
|
||||
async function main() {{
|
||||
const url = "{cluster_url}";
|
||||
const preflightCommitment = 'recent';
|
||||
const connection = new anchor.web3.Connection(url, preflightCommitment);
|
||||
const wallet = anchor.Wallet.local();
|
||||
|
||||
const provider = new anchor.AnchorProvider(connection, wallet, {{
|
||||
preflightCommitment,
|
||||
commitment: 'recent',
|
||||
}});
|
||||
|
||||
// Run the user's deploy script.
|
||||
userScript(provider);
|
||||
}}
|
||||
main();
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
pub fn deploy_script() -> &'static str {
|
||||
r#"// Migrations are an early feature. Currently, they're nothing more than this
|
||||
// single deploy script that's invoked from the CLI, injecting a provider
|
||||
// configured from the workspace's Anchor.toml.
|
||||
|
||||
const anchor = require("@coral-xyz/anchor");
|
||||
|
||||
module.exports = async function (provider) {
|
||||
// Configure client to use the provider.
|
||||
anchor.setProvider(provider);
|
||||
|
||||
// Add your deploy script here.
|
||||
};
|
||||
"#
|
||||
}
|
||||
|
||||
pub fn ts_deploy_script() -> &'static str {
|
||||
r#"// Migrations are an early feature. Currently, they're nothing more than this
|
||||
// single deploy script that's invoked from the CLI, injecting a provider
|
||||
// configured from the workspace's Anchor.toml.
|
||||
|
||||
const anchor = require("@coral-xyz/anchor");
|
||||
|
||||
module.exports = async function (provider) {
|
||||
// Configure client to use the provider.
|
||||
anchor.setProvider(provider);
|
||||
|
||||
// Add your deploy script here.
|
||||
};
|
||||
"#
|
||||
}
|
||||
|
||||
pub fn solidity(name: &str) -> String {
|
||||
format!(
|
||||
r#"
|
||||
@program_id("{}")
|
||||
contract {} {{
|
||||
bool private value = true;
|
||||
|
||||
@payer(payer)
|
||||
constructor(address payer) {{
|
||||
constructor() {{
|
||||
print("Hello, World!");
|
||||
}}
|
||||
|
||||
|
@ -140,7 +36,6 @@ contract {} {{
|
|||
}}
|
||||
}}
|
||||
"#,
|
||||
default_program_id(),
|
||||
name.to_snake_case(),
|
||||
)
|
||||
}
|
||||
|
@ -156,20 +51,30 @@ describe("{}", () => {{
|
|||
it("Is initialized!", async () => {{
|
||||
// Add your test here.
|
||||
const program = anchor.workspace.{};
|
||||
const tx = await program.methods.initialize().rpc();
|
||||
const dataAccount = anchor.web3.Keypair.generate();
|
||||
|
||||
const tx = await program.methods
|
||||
.new()
|
||||
.accounts({{ dataAccount: dataAccount.publicKey }})
|
||||
.signers([dataAccount])
|
||||
.rpc();
|
||||
|
||||
console.log("Your transaction signature", tx);
|
||||
|
||||
const val1 = await program.methods.get()
|
||||
const val1 = await program.methods
|
||||
.get()
|
||||
.accounts({{ dataAccount: dataAccount.publicKey }})
|
||||
.view();
|
||||
|
||||
console.log("state", val1);
|
||||
|
||||
await program.methods.flip()
|
||||
await program.methods
|
||||
.flip()
|
||||
.accounts({{ dataAccount: dataAccount.publicKey }})
|
||||
.rpc();
|
||||
|
||||
const val2 = await program.methods.get()
|
||||
const val2 = await program.methods
|
||||
.get()
|
||||
.accounts({{ dataAccount: dataAccount.publicKey }})
|
||||
.view();
|
||||
|
||||
|
@ -203,93 +108,6 @@ describe("{}", () => {{
|
|||
)
|
||||
}
|
||||
|
||||
pub fn package_json(jest: bool) -> String {
|
||||
if jest {
|
||||
format!(
|
||||
r#"{{
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"jest": "^29.0.3",
|
||||
"prettier": "^2.6.2"
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
r#"{{
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"chai": "^4.3.4",
|
||||
"mocha": "^9.0.3",
|
||||
"prettier": "^2.6.2"
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ts_package_json(jest: bool) -> String {
|
||||
if jest {
|
||||
format!(
|
||||
r#"{{
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"@types/bn.js": "^5.1.0",
|
||||
"@types/jest": "^29.0.3",
|
||||
"jest": "^29.0.3",
|
||||
"prettier": "^2.6.2",
|
||||
"ts-jest": "^29.0.2",
|
||||
"typescript": "^4.3.5"
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
r#"{{
|
||||
"scripts": {{
|
||||
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
|
||||
}},
|
||||
"dependencies": {{
|
||||
"@coral-xyz/anchor": "^{VERSION}"
|
||||
}},
|
||||
"devDependencies": {{
|
||||
"chai": "^4.3.4",
|
||||
"mocha": "^9.0.3",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"@types/bn.js": "^5.1.0",
|
||||
"@types/chai": "^4.3.0",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"typescript": "^4.3.5",
|
||||
"prettier": "^2.6.2"
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ts_mocha(name: &str) -> String {
|
||||
format!(
|
||||
r#"import * as anchor from "@coral-xyz/anchor";
|
||||
|
@ -302,28 +120,32 @@ describe("{}", () => {{
|
|||
anchor.setProvider(provider);
|
||||
|
||||
const dataAccount = anchor.web3.Keypair.generate();
|
||||
const wallet = provider.wallet;
|
||||
|
||||
const program = anchor.workspace.{} as Program<{}>;
|
||||
|
||||
it("Is initialized!", async () => {{
|
||||
// Add your test here.
|
||||
const tx = await program.methods.new(wallet.publicKey)
|
||||
const tx = await program.methods
|
||||
.new()
|
||||
.accounts({{ dataAccount: dataAccount.publicKey }})
|
||||
.signers([dataAccount]).rpc();
|
||||
.signers([dataAccount])
|
||||
.rpc();
|
||||
console.log("Your transaction signature", tx);
|
||||
|
||||
const val1 = await program.methods.get()
|
||||
const val1 = await program.methods
|
||||
.get()
|
||||
.accounts({{ dataAccount: dataAccount.publicKey }})
|
||||
.view();
|
||||
|
||||
console.log("state", val1);
|
||||
|
||||
await program.methods.flip()
|
||||
await program.methods
|
||||
.flip()
|
||||
.accounts({{ dataAccount: dataAccount.publicKey }})
|
||||
.rpc();
|
||||
|
||||
const val2 = await program.methods.get()
|
||||
const val2 = await program.methods
|
||||
.get()
|
||||
.accounts({{ dataAccount: dataAccount.publicKey }})
|
||||
.view();
|
||||
|
||||
|
@ -337,137 +159,3 @@ describe("{}", () => {{
|
|||
name.to_upper_camel_case(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn ts_jest(name: &str) -> String {
|
||||
format!(
|
||||
r#"import * as anchor from "@coral-xyz/anchor";
|
||||
import {{ Program }} from "@coral-xyz/anchor";
|
||||
import {{ {} }} from "../target/types/{}";
|
||||
|
||||
describe("{}", () => {{
|
||||
// Configure the client to use the local cluster.
|
||||
const provider = anchor.AnchorProvider.env();
|
||||
anchor.setProvider(provider);
|
||||
|
||||
const dataAccount = anchor.web3.Keypair.generate();
|
||||
const wallet = provider.wallet;
|
||||
|
||||
const program = anchor.workspace.{} as Program<{}>;
|
||||
|
||||
it("Is initialized!", async () => {{
|
||||
// Add your test here.
|
||||
const tx = await program.methods.new(wallet.publicKey)
|
||||
.accounts({{ dataAccount: dataAccount.publicKey }})
|
||||
.signers([dataAccount]).rpc();
|
||||
console.log("Your transaction signature", tx);
|
||||
}});
|
||||
}});
|
||||
"#,
|
||||
name.to_upper_camel_case(),
|
||||
name.to_snake_case(),
|
||||
name,
|
||||
name.to_upper_camel_case(),
|
||||
name.to_upper_camel_case(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn ts_config(jest: bool) -> &'static str {
|
||||
if jest {
|
||||
r#"{
|
||||
"compilerOptions": {
|
||||
"types": ["jest"],
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"lib": ["es2015"],
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
"#
|
||||
} else {
|
||||
r#"{
|
||||
"compilerOptions": {
|
||||
"types": ["mocha", "chai"],
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"lib": ["es2015"],
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
"#
|
||||
}
|
||||
}
|
||||
|
||||
pub fn git_ignore() -> &'static str {
|
||||
r#"
|
||||
.anchor
|
||||
.DS_Store
|
||||
target
|
||||
**/*.rs.bk
|
||||
node_modules
|
||||
test-ledger
|
||||
"#
|
||||
}
|
||||
|
||||
pub fn prettier_ignore() -> &'static str {
|
||||
r#"
|
||||
.anchor
|
||||
.DS_Store
|
||||
target
|
||||
node_modules
|
||||
dist
|
||||
build
|
||||
test-ledger
|
||||
"#
|
||||
}
|
||||
|
||||
pub fn node_shell(
|
||||
cluster_url: &str,
|
||||
wallet_path: &str,
|
||||
programs: Vec<ProgramWorkspace>,
|
||||
) -> Result<String> {
|
||||
let mut eval_string = format!(
|
||||
r#"
|
||||
const anchor = require('@coral-xyz/anchor');
|
||||
const web3 = anchor.web3;
|
||||
const PublicKey = anchor.web3.PublicKey;
|
||||
const Keypair = anchor.web3.Keypair;
|
||||
|
||||
const __wallet = new anchor.Wallet(
|
||||
Keypair.fromSecretKey(
|
||||
Buffer.from(
|
||||
JSON.parse(
|
||||
require('fs').readFileSync(
|
||||
"{wallet_path}",
|
||||
{{
|
||||
encoding: "utf-8",
|
||||
}},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
const __connection = new web3.Connection("{cluster_url}", "processed");
|
||||
const provider = new anchor.AnchorProvider(__connection, __wallet, {{
|
||||
commitment: "processed",
|
||||
preflightcommitment: "processed",
|
||||
}});
|
||||
anchor.setProvider(provider);
|
||||
"#
|
||||
);
|
||||
|
||||
for program in programs {
|
||||
write!(
|
||||
&mut eval_string,
|
||||
r#"
|
||||
anchor.workspace.{} = new anchor.Program({}, new PublicKey("{}"), provider);
|
||||
"#,
|
||||
program.name.to_upper_camel_case(),
|
||||
serde_json::to_string(&program.idl)?,
|
||||
program.program_id
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(eval_string)
|
||||
}
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
[package]
|
||||
name = "anchor-client"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
authors = ["Anchor Maintainers <accounts@200ms.io>"]
|
||||
rust-version = "1.60"
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
description = "Rust client for Anchor programs"
|
||||
description = "An RPC client to interact with Anchor programs"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
debug = []
|
||||
async = []
|
||||
debug = []
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = { path = "../lang", version = "0.27.0" }
|
||||
anyhow = "1.0.32"
|
||||
regex = "1.4.5"
|
||||
serde = { version = "1.0.122", features = ["derive"] }
|
||||
solana-client = "1.14.7"
|
||||
solana-sdk = "<1.17.0"
|
||||
solana-account-decoder = "<1.17.0"
|
||||
thiserror = "1.0.20"
|
||||
url = "2.2.2"
|
||||
anchor-lang = { path = "../lang", version = "0.30.0" }
|
||||
anyhow = "1"
|
||||
futures = "0.3"
|
||||
regex = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
solana-account-decoder = "1.16"
|
||||
solana-client = "1.16"
|
||||
solana-sdk = "1.16"
|
||||
thiserror = "1"
|
||||
tokio = { version = "1", features = ["rt", "sync"] }
|
||||
futures = { version = "0.3.28" }
|
||||
url = "2"
|
||||
|
|
|
@ -17,8 +17,8 @@ basic-4 = { path = "../../examples/tutorial/basic-4/programs/basic-4", features
|
|||
composite = { path = "../../tests/composite/programs/composite", features = ["no-entrypoint"] }
|
||||
optional = { path = "../../tests/optional/programs/optional", features = ["no-entrypoint"] }
|
||||
events = { path = "../../tests/events/programs/events", features = ["no-entrypoint"] }
|
||||
shellexpand = "2.1.0"
|
||||
anyhow = "1.0.32"
|
||||
clap = { version = "4.2.4", features = ["derive"] }
|
||||
shellexpand = "2.1.0"
|
||||
solana-sdk = "1.16"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
solana-sdk = "<1.17.0"
|
||||
|
|
|
@ -87,8 +87,8 @@ impl Cluster {
|
|||
Cluster::Devnet => "wss://api.devnet.solana.com",
|
||||
Cluster::Testnet => "wss://api.testnet.solana.com",
|
||||
Cluster::Mainnet => "wss://api.mainnet-beta.solana.com",
|
||||
Cluster::Localnet => "ws://127.0.0.1:9000",
|
||||
Cluster::Debug => "ws://34.90.18.145:9000",
|
||||
Cluster::Localnet => "ws://127.0.0.1:8900",
|
||||
Cluster::Debug => "ws://34.90.18.145:8900",
|
||||
Cluster::Custom(_url, ws_url) => ws_url,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,64 @@
|
|||
//! `anchor_client` provides an RPC client to send transactions and fetch
|
||||
//! deserialized accounts from Solana programs written in `anchor_lang`.
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
|
||||
//! An RPC client to interact with Solana programs written in [`anchor_lang`].
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! A simple example that creates a client, sends a transaction and fetches an account:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! use std::rc::Rc;
|
||||
//!
|
||||
//! use anchor_client::{
|
||||
//! solana_sdk::{
|
||||
//! signature::{read_keypair_file, Keypair},
|
||||
//! signer::Signer,
|
||||
//! system_program,
|
||||
//! },
|
||||
//! Client, Cluster,
|
||||
//! };
|
||||
//! use my_program::{accounts, instruction, MyAccount};
|
||||
//!
|
||||
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // Create client
|
||||
//! let payer = read_keypair_file("keypair.json")?;
|
||||
//! let client = Client::new(Cluster::Localnet, Rc::new(payer));
|
||||
//!
|
||||
//! // Create program
|
||||
//! let program = client.program(my_program::ID)?;
|
||||
//!
|
||||
//! // Send a transaction
|
||||
//! let my_account_kp = Keypair::new();
|
||||
//! program
|
||||
//! .request()
|
||||
//! .accounts(accounts::Initialize {
|
||||
//! my_account: my_account_kp.pubkey(),
|
||||
//! payer: program.payer(),
|
||||
//! system_program: system_program::ID,
|
||||
//! })
|
||||
//! .args(instruction::Initialize { field: 42 })
|
||||
//! .signer(&my_account_kp)
|
||||
//! .send()?;
|
||||
//!
|
||||
//! // Fetch an account
|
||||
//! let my_account: MyAccount = program.account(my_account_kp.pubkey())?;
|
||||
//! assert_eq!(my_account.field, 42);
|
||||
//!
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! More examples can be found in [here].
|
||||
//!
|
||||
//! [here]: https://github.com/coral-xyz/anchor/tree/v0.30.0/client/example/src
|
||||
//!
|
||||
//! # Features
|
||||
//!
|
||||
//! The client is blocking by default. To enable asynchronous client, add `async` feature:
|
||||
//!
|
||||
//! ```toml
|
||||
//! anchor-client = { version = "0.30.0 ", features = ["async"] }
|
||||
//! ````
|
||||
|
||||
use anchor_lang::solana_program::hash::Hash;
|
||||
use anchor_lang::solana_program::instruction::{AccountMeta, Instruction};
|
||||
|
@ -98,6 +157,36 @@ impl<C: Clone + Deref<Target = impl Signer>> Client<C> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Auxiliary data structure to align the types of the Solana CLI utils with Anchor client.
|
||||
/// Client<C> implementation requires <C: Clone + Deref<Target = impl Signer>> which does not comply with Box<dyn Signer>
|
||||
/// that's used when loaded Signer from keypair file. This struct is used to wrap the usage.
|
||||
pub struct DynSigner(pub Arc<dyn Signer>);
|
||||
|
||||
impl Signer for DynSigner {
|
||||
fn pubkey(&self) -> Pubkey {
|
||||
self.0.pubkey()
|
||||
}
|
||||
|
||||
fn try_pubkey(&self) -> Result<Pubkey, solana_sdk::signer::SignerError> {
|
||||
self.0.try_pubkey()
|
||||
}
|
||||
|
||||
fn sign_message(&self, message: &[u8]) -> solana_sdk::signature::Signature {
|
||||
self.0.sign_message(message)
|
||||
}
|
||||
|
||||
fn try_sign_message(
|
||||
&self,
|
||||
message: &[u8],
|
||||
) -> Result<solana_sdk::signature::Signature, solana_sdk::signer::SignerError> {
|
||||
self.0.try_sign_message(message)
|
||||
}
|
||||
|
||||
fn is_interactive(&self) -> bool {
|
||||
self.0.is_interactive()
|
||||
}
|
||||
}
|
||||
|
||||
// Internal configuration for a client.
|
||||
#[derive(Debug)]
|
||||
pub struct Config<C> {
|
||||
|
@ -249,9 +338,10 @@ impl<C: Deref<Target = impl Signer> + Clone> Program<C> {
|
|||
client.logs_subscribe(filter, config).await?;
|
||||
|
||||
tx.send(unsubscribe).map_err(|e| {
|
||||
ClientError::SolanaClientPubsubError(PubsubClientError::UnexpectedMessageError(
|
||||
e.to_string(),
|
||||
))
|
||||
ClientError::SolanaClientPubsubError(PubsubClientError::RequestFailed {
|
||||
message: "Unsubscribe failed".to_string(),
|
||||
reason: e.to_string(),
|
||||
})
|
||||
})?;
|
||||
|
||||
while let Some(logs) = notifications.next().await {
|
||||
|
@ -289,16 +379,20 @@ impl<T> Iterator for ProgramAccountsIterator<T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_program_log<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>(
|
||||
pub fn handle_program_log<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>(
|
||||
self_program_str: &str,
|
||||
l: &str,
|
||||
) -> Result<(Option<T>, Option<String>, bool), ClientError> {
|
||||
use anchor_lang::__private::base64;
|
||||
use base64::engine::general_purpose::STANDARD;
|
||||
use base64::Engine;
|
||||
|
||||
// Log emitted from the current program.
|
||||
if let Some(log) = l
|
||||
.strip_prefix(PROGRAM_LOG)
|
||||
.or_else(|| l.strip_prefix(PROGRAM_DATA))
|
||||
{
|
||||
let borsh_bytes = match anchor_lang::__private::base64::decode(log) {
|
||||
let borsh_bytes = match STANDARD.decode(log) {
|
||||
Ok(borsh_bytes) => borsh_bytes,
|
||||
_ => {
|
||||
#[cfg(feature = "debug")]
|
||||
|
@ -329,10 +423,13 @@ fn handle_program_log<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>(
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_system_log(this_program_str: &str, log: &str) -> (Option<String>, bool) {
|
||||
pub fn handle_system_log(this_program_str: &str, log: &str) -> (Option<String>, bool) {
|
||||
if log.starts_with(&format!("Program {this_program_str} log:")) {
|
||||
(Some(this_program_str.to_string()), false)
|
||||
} else if log.contains("invoke") {
|
||||
|
||||
// `Invoke [1]` instructions are pushed to the stack in `parse_logs_response`,
|
||||
// so this ensures we only push CPIs to the stack at this stage
|
||||
} else if log.contains("invoke") && !log.ends_with("[1]") {
|
||||
(Some("cpi".to_string()), false) // Any string will do.
|
||||
} else {
|
||||
let re = Regex::new(r"^Program (.*) success*$").unwrap();
|
||||
|
@ -344,7 +441,7 @@ fn handle_system_log(this_program_str: &str, log: &str) -> (Option<String>, bool
|
|||
}
|
||||
}
|
||||
|
||||
struct Execution {
|
||||
pub struct Execution {
|
||||
stack: Vec<String>,
|
||||
}
|
||||
|
||||
|
@ -447,6 +544,36 @@ impl<'a, C: Deref<Target = impl Signer> + Clone> RequestBuilder<'a, C> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Set the accounts to pass to the instruction.
|
||||
///
|
||||
/// `accounts` argument can be:
|
||||
///
|
||||
/// - Any type that implements [`ToAccountMetas`] trait
|
||||
/// - A vector of [`AccountMeta`]s (for remaining accounts)
|
||||
///
|
||||
/// Note that the given accounts are appended to the previous list of accounts instead of
|
||||
/// overriding the existing ones (if any).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// program
|
||||
/// .request()
|
||||
/// // Regular accounts
|
||||
/// .accounts(accounts::Initialize {
|
||||
/// my_account: my_account_kp.pubkey(),
|
||||
/// payer: program.payer(),
|
||||
/// system_program: system_program::ID,
|
||||
/// })
|
||||
/// // Remaining accounts
|
||||
/// .accounts(vec![AccountMeta {
|
||||
/// pubkey: remaining,
|
||||
/// is_signer: true,
|
||||
/// is_writable: true,
|
||||
/// }])
|
||||
/// .args(instruction::Initialize { field: 42 })
|
||||
/// .send()?;
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn accounts(mut self, accounts: impl ToAccountMetas) -> Self {
|
||||
let mut metas = accounts.to_account_metas(None);
|
||||
|
@ -557,7 +684,10 @@ fn parse_logs_response<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>(
|
|||
let mut events: Vec<T> = Vec::new();
|
||||
if !logs.is_empty() {
|
||||
if let Ok(mut execution) = Execution::new(&mut logs) {
|
||||
for l in logs {
|
||||
// Create a new peekable iterator so that we can peek at the next log whilst iterating
|
||||
let mut logs_iter = logs.iter().peekable();
|
||||
|
||||
while let Some(l) = logs_iter.next() {
|
||||
// Parse the log.
|
||||
let (event, new_program, did_pop) = {
|
||||
if program_id_str == execution.program() {
|
||||
|
@ -581,6 +711,25 @@ fn parse_logs_response<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>(
|
|||
// Program returned.
|
||||
if did_pop {
|
||||
execution.pop();
|
||||
|
||||
// If the current iteration popped then it means there was a
|
||||
//`Program x success` log. If the next log in the iteration is
|
||||
// of depth [1] then we're not within a CPI and this is a new instruction.
|
||||
//
|
||||
// We need to ensure that the `Execution` instance is updated with
|
||||
// the next program ID, or else `execution.program()` will cause
|
||||
// a panic during the next iteration.
|
||||
if let Some(&next_log) = logs_iter.peek() {
|
||||
if next_log.ends_with("invoke [1]") {
|
||||
let re = Regex::new(r"^Program (.*) invoke.*$").unwrap();
|
||||
let next_instruction =
|
||||
re.captures(next_log).unwrap().get(1).unwrap().as_str();
|
||||
// Within this if block, there will always be a regex match.
|
||||
// Therefore it's safe to unwrap and the captured program ID
|
||||
// at index 1 can also be safely unwrapped.
|
||||
execution.push(next_instruction.to_string());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -590,6 +739,15 @@ fn parse_logs_response<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use solana_client::rpc_response::RpcResponseContext;
|
||||
|
||||
// Creating a mock struct that implements `anchor_lang::events`
|
||||
// for type inference in `test_logs`
|
||||
use anchor_lang::prelude::*;
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[event]
|
||||
pub struct MockEvent {}
|
||||
|
||||
use super::*;
|
||||
#[test]
|
||||
fn new_execution() {
|
||||
|
@ -617,4 +775,106 @@ mod tests {
|
|||
assert_eq!(program, None);
|
||||
assert!(!did_pop);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_logs_response() -> Result<()> {
|
||||
// Mock logs received within an `RpcResponse`. These are based on a Jupiter transaction.
|
||||
let logs = vec![
|
||||
"Program VeryCoolProgram invoke [1]", // Outer instruction #1 starts
|
||||
"Program log: Instruction: VeryCoolEvent",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 664387 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program VeryCoolProgram consumed 42417 of 700000 compute units",
|
||||
"Program VeryCoolProgram success", // Outer instruction #1 ends
|
||||
"Program EvenCoolerProgram invoke [1]", // Outer instruction #2 starts
|
||||
"Program log: Instruction: EvenCoolerEvent",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: TransferChecked",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 6200 of 630919 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt invoke [2]",
|
||||
"Program log: Instruction: Swap",
|
||||
"Program log: INVARIANT: SWAP",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4736 of 539321 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 531933 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt consumed 84670 of 610768 compute units",
|
||||
"Program HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt success",
|
||||
"Program EvenCoolerProgram invoke [2]",
|
||||
"Program EvenCoolerProgram consumed 2021 of 523272 compute units",
|
||||
"Program EvenCoolerProgram success",
|
||||
"Program HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt invoke [2]",
|
||||
"Program log: Instruction: Swap",
|
||||
"Program log: INVARIANT: SWAP",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4736 of 418618 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 411230 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt consumed 102212 of 507607 compute units",
|
||||
"Program HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt success",
|
||||
"Program EvenCoolerProgram invoke [2]",
|
||||
"Program EvenCoolerProgram consumed 2021 of 402569 compute units",
|
||||
"Program EvenCoolerProgram success",
|
||||
"Program 9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP invoke [2]",
|
||||
"Program log: Instruction: Swap",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4736 of 371140 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: MintTo",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4492 of 341800 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 334370 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program 9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP consumed 57610 of 386812 compute units",
|
||||
"Program 9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP success",
|
||||
"Program EvenCoolerProgram invoke [2]",
|
||||
"Program EvenCoolerProgram consumed 2021 of 326438 compute units",
|
||||
"Program EvenCoolerProgram success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: TransferChecked",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 6173 of 319725 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program EvenCoolerProgram consumed 345969 of 657583 compute units",
|
||||
"Program EvenCoolerProgram success", // Outer instruction #2 ends
|
||||
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
|
||||
"Program ComputeBudget111111111111111111111111111111 success",
|
||||
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
|
||||
"Program ComputeBudget111111111111111111111111111111 success"];
|
||||
|
||||
// Converting to Vec<String> as expected in `RpcLogsResponse`
|
||||
let logs: Vec<String> = logs.iter().map(|&l| l.to_string()).collect();
|
||||
|
||||
let program_id_str = "VeryCoolProgram";
|
||||
|
||||
// No events returned here. Just ensuring that the function doesn't panic
|
||||
// due an incorrectly emptied stack.
|
||||
let _: Vec<MockEvent> = parse_logs_response(
|
||||
RpcResponse {
|
||||
context: RpcResponseContext::new(0),
|
||||
value: RpcLogsResponse {
|
||||
signature: "".to_string(),
|
||||
err: None,
|
||||
logs: logs.to_vec(),
|
||||
},
|
||||
},
|
||||
program_id_str,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,15 +2,15 @@ WORKDIR=$(PWD)
|
|||
#
|
||||
# Anchor version.
|
||||
#
|
||||
ANCHOR_CLI=v0.27.0
|
||||
ANCHOR_CLI=v0.30.0
|
||||
#
|
||||
# Solana toolchain.
|
||||
#
|
||||
SOLANA_CLI=v1.14.16
|
||||
SOLANA_CLI=v1.18.8
|
||||
#
|
||||
# Build version should match the Anchor cli version.
|
||||
#
|
||||
IMG_ORG ?= projectserum
|
||||
IMG_ORG ?= backpackapp
|
||||
IMG_VER ?= $(ANCHOR_CLI)
|
||||
|
||||
.PHONY: build build-push build-shell publish
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# is released on GitHub.
|
||||
#
|
||||
|
||||
FROM ubuntu:18.04
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ARG SOLANA_CLI
|
||||
ARG ANCHOR_CLI
|
||||
ARG NODE_VERSION="v18.16.0"
|
||||
ARG NODE_VERSION="v18.18.0"
|
||||
|
||||
ENV HOME="/root"
|
||||
ENV PATH="${HOME}/.cargo/bin:${PATH}"
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"name": "tailwindui-documentation",
|
||||
"name": "anchor-docs",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tailwindui-documentation",
|
||||
"name": "anchor-docs",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@docsearch/react": "^3.1.1",
|
||||
|
@ -17,7 +17,7 @@
|
|||
"autoprefixer": "^10.4.7",
|
||||
"clsx": "^1.2.1",
|
||||
"focus-visible": "^5.2.0",
|
||||
"gh-pages": "^4.0.0",
|
||||
"gh-pages": "^5.0.0",
|
||||
"next": "12.2.1",
|
||||
"next-plausible": "^3.2.0",
|
||||
"postcss-focus-visible": "^6.0.4",
|
||||
|
@ -993,12 +993,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "2.6.4",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
|
||||
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.14"
|
||||
}
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
|
||||
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.4.7",
|
||||
|
@ -1398,9 +1395,9 @@
|
|||
"integrity": "sha512-lPHuHXBwpkr4RcfaZBKm6TKOWG/1N9mVggUpP4fY3l1JIUU2x4fkM8928smYdZ5lF+6KCTAxo1aK9JmqT+X71Q=="
|
||||
},
|
||||
"node_modules/email-addresses": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz",
|
||||
"integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg=="
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz",
|
||||
"integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw=="
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
|
@ -2187,13 +2184,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/gh-pages": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-4.0.0.tgz",
|
||||
"integrity": "sha512-p8S0T3aGJc68MtwOcZusul5qPSNZCalap3NWbhRUZYu1YOdp+EjZ+4kPmRM8h3NNRdqw00yuevRjlkuSzCn7iQ==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-5.0.0.tgz",
|
||||
"integrity": "sha512-Nqp1SjkPIB94Xw/3yYNTUL+G2dxlhjvv1zeN/4kMC1jfViTEqhtVz/Ba1zSXHuvXCN9ADNS1dN4r5/J/nZWEQQ==",
|
||||
"dependencies": {
|
||||
"async": "^2.6.1",
|
||||
"async": "^3.2.4",
|
||||
"commander": "^2.18.0",
|
||||
"email-addresses": "^3.0.1",
|
||||
"email-addresses": "^5.0.0",
|
||||
"filenamify": "^4.3.0",
|
||||
"find-cache-dir": "^3.3.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
|
@ -2750,11 +2747,6 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/lodash.castarray": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
|
||||
|
@ -4896,12 +4888,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"async": {
|
||||
"version": "2.6.4",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
|
||||
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.14"
|
||||
}
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
|
||||
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
|
||||
},
|
||||
"autoprefixer": {
|
||||
"version": "10.4.7",
|
||||
|
@ -5174,9 +5163,9 @@
|
|||
"integrity": "sha512-lPHuHXBwpkr4RcfaZBKm6TKOWG/1N9mVggUpP4fY3l1JIUU2x4fkM8928smYdZ5lF+6KCTAxo1aK9JmqT+X71Q=="
|
||||
},
|
||||
"email-addresses": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz",
|
||||
"integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg=="
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz",
|
||||
"integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw=="
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
|
@ -5779,13 +5768,13 @@
|
|||
}
|
||||
},
|
||||
"gh-pages": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-4.0.0.tgz",
|
||||
"integrity": "sha512-p8S0T3aGJc68MtwOcZusul5qPSNZCalap3NWbhRUZYu1YOdp+EjZ+4kPmRM8h3NNRdqw00yuevRjlkuSzCn7iQ==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-5.0.0.tgz",
|
||||
"integrity": "sha512-Nqp1SjkPIB94Xw/3yYNTUL+G2dxlhjvv1zeN/4kMC1jfViTEqhtVz/Ba1zSXHuvXCN9ADNS1dN4r5/J/nZWEQQ==",
|
||||
"requires": {
|
||||
"async": "^2.6.1",
|
||||
"async": "^3.2.4",
|
||||
"commander": "^2.18.0",
|
||||
"email-addresses": "^3.0.1",
|
||||
"email-addresses": "^5.0.0",
|
||||
"filenamify": "^4.3.0",
|
||||
"find-cache-dir": "^3.3.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
|
@ -6181,11 +6170,6 @@
|
|||
"path-exists": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"lodash.castarray": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
|
||||
|
|
|
@ -24,7 +24,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-attribute-access-control"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf7d535e1381be3de2c0716c0a1c1e32ad9df1042cddcf7bc18d743569e53319"
|
||||
dependencies = [
|
||||
|
@ -38,7 +38,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-attribute-account"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3bcd731f21048a032be27c7791701120e44f3f6371358fc4261a7f716283d29"
|
||||
dependencies = [
|
||||
|
@ -53,7 +53,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-attribute-constant"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1be64a48e395fe00b8217287f226078be2cf32dae42fdf8a885b997945c3d28"
|
||||
dependencies = [
|
||||
|
@ -64,7 +64,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-attribute-error"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38ea6713d1938c0da03656ff8a693b17dc0396da66d1ba320557f07e86eca0d4"
|
||||
dependencies = [
|
||||
|
@ -76,7 +76,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-attribute-event"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d401f11efb3644285685f8339829a9786d43ed7490bb1699f33c478d04d5a582"
|
||||
dependencies = [
|
||||
|
@ -89,7 +89,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-attribute-interface"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6700a6f5c888a9c33fe8afc0c64fd8575fa28d05446037306d0f96102ae4480"
|
||||
dependencies = [
|
||||
|
@ -103,7 +103,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-attribute-program"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ad769993b5266714e8939e47fbdede90e5c030333c7522d99a4d4748cf26712"
|
||||
dependencies = [
|
||||
|
@ -116,7 +116,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-attribute-state"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e677fae4a016a554acdd0e3b7f178d3acafaa7e7ffac6b8690cf4e171f1c116"
|
||||
dependencies = [
|
||||
|
@ -129,7 +129,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-derive-accounts"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "340beef6809d1c3fcc7ae219153d981e95a8a277ff31985bd7050e32645dc9a8"
|
||||
dependencies = [
|
||||
|
@ -142,7 +142,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-lang"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "662ceafe667448ee4199a4be2ee83b6bb76da28566eee5cea05f96ab38255af8"
|
||||
dependencies = [
|
||||
|
@ -166,7 +166,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anchor-syn"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0418bcb5daac3b8cb1b60d8fdb1d468ca36f5509f31fb51179326fae1028fdcc"
|
||||
dependencies = [
|
||||
|
|
|
@ -16,6 +16,6 @@ cpi = ["no-entrypoint"]
|
|||
default = []
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = "=0.27.0"
|
||||
anchor-lang = "=0.30.0"
|
||||
num-traits = "0.2"
|
||||
num-derive = "0.3"
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 439 KiB |
Binary file not shown.
After Width: | Height: | Size: 408 KiB |
Binary file not shown.
After Width: | Height: | Size: 257 KiB |
Binary file not shown.
After Width: | Height: | Size: 301 KiB |
Binary file not shown.
After Width: | Height: | Size: 406 KiB |
Binary file not shown.
After Width: | Height: | Size: 263 KiB |
|
@ -14,22 +14,24 @@ import 'focus-visible'
|
|||
import '@/styles/tailwind.css'
|
||||
|
||||
const navigation = [
|
||||
{
|
||||
title: 'Prologue',
|
||||
links: [
|
||||
{ title: 'Release Notes', href: '/docs/release-notes' },
|
||||
{ title: 'Contribution Guide', href: '/docs/contribution-guide' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Getting Started',
|
||||
links: [
|
||||
{ title: 'Introduction', href: '/' },
|
||||
{ title: 'Quickstart', href: '/docs/solana-playground' },
|
||||
{ title: 'Installation', href: '/docs/installation' },
|
||||
{ title: 'Hello World', href: '/docs/hello-world' },
|
||||
{ title: 'Intro to Solana', href: '/docs/intro-to-solana' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Release Notes',
|
||||
links: [
|
||||
{ title: '0.29.0', href: '/release-notes/0.29.0' },
|
||||
{ title: '0.30.0', href: '/release-notes/0.30.0' },
|
||||
{ title: 'CHANGELOG', href: '/release-notes/changelog' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Core concepts',
|
||||
links: [
|
||||
|
@ -56,6 +58,7 @@ const navigation = [
|
|||
{
|
||||
title: 'Guides',
|
||||
links: [
|
||||
{ title: 'Contribution Guide', href: '/docs/contribution-guide' },
|
||||
{ title: 'Publishing Source', href: '/docs/publishing-source' },
|
||||
{
|
||||
title: 'Verifiable Builds',
|
||||
|
@ -66,6 +69,8 @@ const navigation = [
|
|||
{
|
||||
title: 'References',
|
||||
links: [
|
||||
{ title: 'Account Constraints', href: '/docs/account-constraints' },
|
||||
{ title: 'Account Types', href: '/docs/account-types' },
|
||||
{ title: 'Anchor.toml', href: '/docs/manifest' },
|
||||
{ title: 'CLI', href: '/docs/cli' },
|
||||
{ title: 'AVM', href: '/docs/avm' },
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
---
|
||||
title: Account Constraints
|
||||
description: Anchor Account Constraint Examples
|
||||
---
|
||||
|
||||
Minimal reference examples for Anchor account [constraints](https://docs.rs/anchor-lang/latest/anchor_lang/derive.Accounts.html).
|
||||
|
||||
## Instruction Attribute
|
||||
|
||||
{% table %}
|
||||
|
||||
- Attribute
|
||||
- Example
|
||||
- Description
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[derive(Accounts)]
|
||||
#[instruction(...)]
|
||||
pub struct Initialize<'info> {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/instruction)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/instruction)
|
||||
- You can access the instruction’s arguments with the #[instruction(..)] attribute.
|
||||
You have to list them in the same order as in the instruction but you can omit all arguments after the last one you need.
|
||||
|
||||
{% /table %}
|
||||
|
||||
## Normal Constraints
|
||||
|
||||
{% table %}
|
||||
|
||||
- Attribute
|
||||
- Example
|
||||
- Description
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(signer)]
|
||||
#[account(signer @ <custom_error>)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/signer)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/signer)
|
||||
- Checks the given account signed the transaction. Custom errors are supported via @. Consider using the Signer type if you would only have this constraint on the account.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(mut)]
|
||||
#[account(mut @ <custom_error>)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/mut)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/mut)
|
||||
- Checks the given account is mutable.
|
||||
Makes anchor persist any state changes.
|
||||
Custom errors are supported via @.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(
|
||||
init,
|
||||
payer = <target_account>,
|
||||
space = <num_bytes>
|
||||
)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/init)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/init)
|
||||
- Creates the account via a CPI to the system program and initializes it (sets its account discriminator).
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(
|
||||
init_if_needed,
|
||||
payer = <target_account>
|
||||
)]
|
||||
|
||||
#[account(
|
||||
init_if_needed,
|
||||
payer = <target_account>,
|
||||
space = <num_bytes>
|
||||
)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/init_if_needed)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/init_if_needed)
|
||||
- Exact same functionality as the init constraint but only runs if the account does not exist yet.
|
||||
|
||||
This feature should be used with care and is therefore behind a feature flag. You can enable it by importing anchor-lang with the init-if-needed cargo feature.
|
||||
When using init_if_needed, you need to make sure you properly protect yourself against re-initialization attacks.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(
|
||||
seeds = <seeds>,
|
||||
bump
|
||||
)]
|
||||
|
||||
#[account(
|
||||
seeds = <seeds>,
|
||||
bump,
|
||||
seeds::program = <expr>
|
||||
)]
|
||||
|
||||
#[account(
|
||||
seeds = <seeds>,
|
||||
bump = <expr>
|
||||
)]
|
||||
|
||||
#[account(
|
||||
seeds = <seeds>,
|
||||
bump = <expr>,
|
||||
seeds::program = <expr>
|
||||
)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/seed-bump)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/seed-bump)
|
||||
- Checks that given account is a PDA derived from the currently executing program, the seeds, and if provided, the bump.
|
||||
If not provided, anchor uses the canonical bump.
|
||||
Add seeds::program = <expr> to derive the PDA from a different program than the currently executing one.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(
|
||||
has_one = <target_account>
|
||||
)]
|
||||
|
||||
#[account(
|
||||
has_one = <target_account> @ <custom_error>
|
||||
)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/has_one)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/has_one)
|
||||
- Checks the target_account field on the account matches the key of the target_account field in the Accounts struct.
|
||||
Custom errors are supported via @.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(address = <expr>)]
|
||||
#[account(address = <expr> @ <custom_error>)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/address)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/address)
|
||||
- Checks the account key matches the pubkey.
|
||||
Custom errors are supported via @.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(owner = <expr>)]
|
||||
#[account(owner = <expr> @ <custom_error>)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/owner)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/owner)
|
||||
- Checks the account owner matches expr.
|
||||
Custom errors are supported via @.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(executable)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/executable)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/executable)
|
||||
- Checks the account is executable (i.e. the account is a program).
|
||||
You may want to use the Program type instead.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(rent_exempt = skip)]
|
||||
#[account(rent_exempt = enforce)]
|
||||
```
|
||||
|
||||
- Github
|
||||
Solpg
|
||||
- Enforces rent exemption with = enforce.
|
||||
Skips rent exemption check that would normally be done through other constraints with = skip, e.g. when used with the zero constraint
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(zero)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/zero)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/zero)
|
||||
- Checks the account discriminator is zero.
|
||||
|
||||
Use this constraint if you want to create an account in a previous instruction and then initialize it in your instruction instead of using init. This is necessary for accounts that are larger than 10 Kibibyte because those accounts cannot be created via a CPI (which is what init would do).
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(close = <target_account>)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/close)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/close)
|
||||
- Closes the account by:
|
||||
|
||||
- Sending the lamports to the specified account
|
||||
- Assigning the owner to the System Program
|
||||
- Resetting the data of the account
|
||||
|
||||
Requires mut to exist on the account.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(constraint = <expr>)]
|
||||
#[account(
|
||||
constraint = <expr> @ <custom_error>
|
||||
)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/constraint)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/constraint)
|
||||
- Constraint that checks whether the given expression evaluates to true.
|
||||
Use this when no other constraint fits your use case.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(
|
||||
realloc = <space>,
|
||||
realloc::payer = <target>,
|
||||
realloc::zero = <bool>
|
||||
)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/realloc)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/realloc)
|
||||
- Used to realloc program account space at the beginning of an instruction.
|
||||
|
||||
{% /table %}
|
||||
|
||||
## SPL Constraints
|
||||
|
||||
{% table %}
|
||||
|
||||
- Attribute
|
||||
- Example
|
||||
- Description
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(
|
||||
token::mint = <target_account>,
|
||||
token::authority = <target_account>
|
||||
)]
|
||||
|
||||
#[account(
|
||||
token::mint = <target_account>,
|
||||
token::authority = <target_account>,
|
||||
token::token_program = <target_account>
|
||||
)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/token)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/token)
|
||||
- Can be used as a check or with init to create a token account with the given mint address and authority.
|
||||
When used as a check, it's possible to only specify a subset of the constraints.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(
|
||||
mint::authority = <target_account>,
|
||||
mint::decimals = <expr>
|
||||
)]
|
||||
|
||||
#[account(
|
||||
mint::authority = <target_account>,
|
||||
mint::decimals = <expr>,
|
||||
mint::freeze_authority = <target_account>
|
||||
)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/mint)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/mint)
|
||||
- Can be used as a check or with init to create a mint account with the given mint decimals and mint authority.
|
||||
The freeze authority is optional when used with init.
|
||||
When used as a check, it's possible to only specify a subset of the constraints.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(
|
||||
associated_token::mint = <target_account>,
|
||||
associated_token::authority = <target_account>
|
||||
)]
|
||||
|
||||
#[account(
|
||||
associated_token::mint = <target_account>,
|
||||
associated_token::authority = <target_account>,
|
||||
associated_token::token_program = <target_account>
|
||||
)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/associated_token)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/associated_token)
|
||||
- Can be used as a standalone as a check or with init to create an associated token account with the given mint address and authority.
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
#[account(*::token_program = <target_account>)]
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/token_program)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-constraints/token_program)
|
||||
- The token_program can optionally be overridden.
|
||||
|
||||
{% /table %}
|
|
@ -0,0 +1,135 @@
|
|||
---
|
||||
title: Account Types
|
||||
description: Anchor Account Type Examples
|
||||
---
|
||||
|
||||
Minimal reference examples for Anchor [account types](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/index.html).
|
||||
|
||||
{% table %}
|
||||
|
||||
- Type
|
||||
- Example
|
||||
- Description
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
Account<'info, T>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/Account)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/Account)
|
||||
- Account container that checks ownership on deserialization
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
AccountInfo<'info>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/AccountInfo)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/AccountInfo)
|
||||
- AccountInfo can be used as a type but Unchecked Account should be used instead
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
AccountLoader<'info, T>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/AccountLoader)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/AccountLoader)
|
||||
- Type facilitating on demand zero copy deserialization
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
Box<Account<'info, T>>
|
||||
Box<InterfaceAccount<'info, T>>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/Box)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/Box)
|
||||
- Box type to save stack space
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
Interface<'info, T>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/Interface)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/Interface)
|
||||
- Type validating that the account is one of a set of given Programs
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
InterfaceAccount<'info, T>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/InterfaceAccount)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/InterfaceAccount)
|
||||
- Account container that checks ownership on deserialization
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
Option<Account<'info, T>>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/Option)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/Option)
|
||||
- Option type for optional accounts
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
Program<'info, T>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/Program)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/Program)
|
||||
- Type validating that the account is the given Program
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
Signer<'info>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/Signer)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/Signer)
|
||||
- Type validating that the account signed the transaction
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
SystemAccount<'info>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/SystemAccount)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/SystemAccount)
|
||||
- Type validating that the account is owned by the system program
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
Sysvar<'info, T>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/Sysvar)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/Sysvar)
|
||||
- Type validating that the account is a sysvar and deserializing it
|
||||
|
||||
---
|
||||
|
||||
- ```rust
|
||||
UncheckedAccount<'info>
|
||||
```
|
||||
|
||||
- [Github](https://github.com/solana-developers/anchor-examples/tree/main/account-types/UncheckedAccount)
|
||||
[Solpg](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/account-types/UncheckedAccount)
|
||||
- Explicit wrapper for AccountInfo types to emphasize that no checks are performed
|
||||
|
||||
{% /table %}
|
|
@ -87,7 +87,6 @@ This lists cluster endpoints:
|
|||
```shell
|
||||
Cluster Endpoints:
|
||||
|
||||
* Mainnet - https://solana-api.projectserum.com
|
||||
* Mainnet - https://api.mainnet-beta.solana.com
|
||||
* Devnet - https://api.devnet.solana.com
|
||||
* Testnet - https://api.testnet.solana.com
|
||||
|
|
|
@ -61,7 +61,7 @@ pub struct Data {
|
|||
|
||||
There's nothing special happening here. It's a pretty simple program! The interesting part is how it interacts with the next program we are going to create.
|
||||
|
||||
Run
|
||||
Still inside the project, initialize a new `puppet-master` program using,
|
||||
|
||||
```shell
|
||||
anchor new puppet-master
|
||||
|
|
|
@ -16,7 +16,7 @@ custom errors which the user (you!) can return.
|
|||
- Custom Errors
|
||||
- Non-anchor errors.
|
||||
|
||||
[AnchorErrors](https://docs.rs/anchor-lang/latest/anchor_lang/error/struct.AnchorError.html) provide a range of information like the error name and number or the location in the code where the anchor was thrown, or the account that violated a constraint (e.g. a `mut` constraint). Once thrown inside the program, [you can access the error information](https://coral-xyz.github.io/anchor/ts/classes/AnchorError.html) in the anchor clients like the typescript client. The typescript client also enriches the error with additional information about which program the error was thrown in and the CPI calls (which are explained [here](./cross-program-invocations) in the book) that led to the program from which the error was thrown from. [The milestone chapter](./milestone_project_tic-tac-toe.md) explores how all of this works together in practice. For now, let's look at how different errors can be returned from inside a program.
|
||||
[AnchorErrors](https://docs.rs/anchor-lang/latest/anchor_lang/error/struct.AnchorError.html) provides a range of information like the error name and number or the location in the code where the error was thrown, or the account that violated a constraint (e.g. a `mut` constraint). Once thrown inside the program, [you can access the error information](https://coral-xyz.github.io/anchor/ts/classes/AnchorError.html) in the anchor clients like the typescript client. The typescript client also enriches the error with additional information about which program the error was thrown in and the CPI calls (which are explained [here](./cross-program-invocations) in the book) that led to the program from which the error was thrown from. [The milestone chapter](./milestone_project_tic-tac-toe.md) explores how all of this works together in practice. For now, let's look at how different errors can be returned from inside a program.
|
||||
|
||||
## Anchor Internal Errors
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ Anchor binaries are available via an NPM package [`@coral-xyz/anchor-cli`](https
|
|||
We can also use Cargo to install the CLI directly. Make sure that the `--tag` argument uses the version you want (the version here is just an example).
|
||||
|
||||
```shell
|
||||
cargo install --git https://github.com/coral-xyz/anchor --tag v0.27.0 anchor-cli --locked
|
||||
cargo install --git https://github.com/coral-xyz/anchor --tag v0.30.0 anchor-cli --locked
|
||||
```
|
||||
|
||||
On Linux systems you may need to install additional dependencies if cargo install fails. On Ubuntu,
|
||||
|
|
|
@ -3,18 +3,18 @@ title: Javascript Anchor Types Reference
|
|||
description: Anchor - Javascript Anchor Types Reference
|
||||
---
|
||||
|
||||
This reference shows you how anchor maps rust types to javascript/typescript types in the client.
|
||||
This reference shows you how Anchor maps Rust types to JavaScript/TypeScript types in the client.
|
||||
|
||||
---
|
||||
|
||||
{% table %}
|
||||
* Rust Type
|
||||
* Javascript Type
|
||||
* JavaScript Type
|
||||
* Example
|
||||
* Note
|
||||
---
|
||||
* `bool`
|
||||
* `bool`
|
||||
* `boolean`
|
||||
* ```javascript
|
||||
await program
|
||||
.methods
|
||||
|
@ -25,17 +25,17 @@ This reference shows you how anchor maps rust types to javascript/typescript typ
|
|||
* `u64/u128/i64/i128`
|
||||
* `anchor.BN`
|
||||
* ```javascript
|
||||
await program
|
||||
await program
|
||||
.methods
|
||||
.init(new anchor.BN(99))
|
||||
.rpc();
|
||||
```
|
||||
* [https://github.com/indutny/bn.js/](https://github.com/indutny/bn.js/ )
|
||||
* [https://github.com/indutny/bn.js](https://github.com/indutny/bn.js )
|
||||
---
|
||||
* `u8/u16/u32/i8/i16/i32`
|
||||
* `number`
|
||||
* ```javascript
|
||||
await program
|
||||
await program
|
||||
.methods
|
||||
.init(99)
|
||||
.rpc();
|
||||
|
@ -44,69 +44,79 @@ This reference shows you how anchor maps rust types to javascript/typescript typ
|
|||
* `f32/f64`
|
||||
* `number`
|
||||
* ```javascript
|
||||
await program
|
||||
await program
|
||||
.methods
|
||||
.init(1.0)
|
||||
.rpc();
|
||||
```
|
||||
---
|
||||
* `Enum`
|
||||
* `{ variantName: {} }`
|
||||
* ```rust
|
||||
enum MyEnum { One, Two };
|
||||
```
|
||||
```javascript
|
||||
await program
|
||||
* `object`
|
||||
* ```rust
|
||||
enum MyEnum {
|
||||
One,
|
||||
Two { val: u32 },
|
||||
Three(u8, i16),
|
||||
};
|
||||
```
|
||||
```javascript
|
||||
// Unit variant
|
||||
await program
|
||||
.methods
|
||||
.init({ one: {} })
|
||||
.rpc();
|
||||
```
|
||||
```rust
|
||||
enum MyEnum { One: { val: u64 }, Two };
|
||||
```
|
||||
```javascript
|
||||
await program
|
||||
|
||||
// Named variant
|
||||
await program
|
||||
.methods
|
||||
.init({ one: { val: 99 } })
|
||||
.init({ two: { val: 99 } })
|
||||
.rpc();
|
||||
```
|
||||
|
||||
// Unnamed (tuple) variant
|
||||
await program
|
||||
.methods
|
||||
.init({ three: [12, -34] })
|
||||
.rpc();
|
||||
```
|
||||
---
|
||||
* `Struct`
|
||||
* `{ val: {} }`
|
||||
* ```rust
|
||||
struct MyStruct { val: u64 };
|
||||
```
|
||||
struct MyStruct {
|
||||
val: u16,
|
||||
}
|
||||
```
|
||||
```javascript
|
||||
await program
|
||||
await program
|
||||
.methods
|
||||
.init({ val: 99 })
|
||||
.rpc();
|
||||
```
|
||||
```
|
||||
---
|
||||
* `[T; N]`
|
||||
* `[ T ]`
|
||||
* `Array<T>`
|
||||
* ```javascript
|
||||
await program
|
||||
await program
|
||||
.methods
|
||||
.init([1,2,3])
|
||||
.init([1, 2, 3])
|
||||
.rpc();
|
||||
```
|
||||
```
|
||||
---
|
||||
* `String`
|
||||
* `string`
|
||||
* ```javascript
|
||||
await program
|
||||
await program
|
||||
.methods
|
||||
.init("hello")
|
||||
.rpc();
|
||||
```
|
||||
```
|
||||
---
|
||||
* `Vec<T>`
|
||||
* `[ T ]`
|
||||
* `Array<T>`
|
||||
* ```javascript
|
||||
await program
|
||||
await program
|
||||
.methods
|
||||
.init([1,2,3])
|
||||
.init([1, 2, 3])
|
||||
.rpc();
|
||||
```
|
||||
```
|
||||
{% /table %}
|
||||
|
|
|
@ -34,7 +34,7 @@ Example:
|
|||
|
||||
```
|
||||
[registry]
|
||||
url = "https://anchor.projectserum.com"
|
||||
url = "https://api.apr.dev"
|
||||
```
|
||||
|
||||
## features
|
||||
|
@ -66,11 +66,11 @@ types = "app/src/idl/"
|
|||
#### members
|
||||
|
||||
Sets the paths --relative to the `Anchor.toml`--
|
||||
to all programs in the local
|
||||
workspace, i.e., the path to the `Cargo.toml` manifest associated with each
|
||||
program that can be compiled by the `anchor` CLI. For programs using the
|
||||
standard Anchor workflow, this can be omitted. For programs not written in Anchor
|
||||
but still want to publish, this should be added.
|
||||
to all programs in the local
|
||||
workspace, i.e., the path to the `Cargo.toml` manifest associated with each
|
||||
program that can be compiled by the `anchor` CLI. For programs using the
|
||||
standard Anchor workflow, this can be omitted. For programs not written in Anchor
|
||||
but still want to publish, this should be added.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -122,6 +122,20 @@ program = "dex.so"
|
|||
[[test.genesis]]
|
||||
address = "22Y43yTVxuUkoRKdm9thyRhQ3SdgQS7c7kB6UNCiaczD"
|
||||
program = "swap.so"
|
||||
upgradeable = true
|
||||
```
|
||||
|
||||
#### upgradeable
|
||||
|
||||
Deploys the program-to-test using `--upgradeable-program`. This makes it possible to test that certain instructions can only be executed by the program's upgrade authority. The initial upgrade authority will be set to `provider.wallet`.
|
||||
|
||||
If unspecified or explicitly set to false, then the test program will be deployed with `--bpf-program`, disabling upgrades to it.
|
||||
|
||||
Example:
|
||||
|
||||
```toml
|
||||
[test]
|
||||
upgradeable = true
|
||||
```
|
||||
|
||||
## test.validator
|
||||
|
@ -179,3 +193,13 @@ filename = "some_account.json"
|
|||
address = "Ev8WSPQsGb4wfjybqff5eZNcS3n6HaMsBkMk9suAiuM"
|
||||
filename = "some_other_account.json"
|
||||
```
|
||||
|
||||
## toolchain
|
||||
|
||||
Override toolchain data in the workspace similar to [`rust-toolchain.toml`](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file).
|
||||
|
||||
```toml
|
||||
[toolchain]
|
||||
anchor_version = "0.30.0" # `anchor-cli` version to use(requires `avm`)
|
||||
solana_version = "1.18.8" # Solana version to use(applies to all Solana tools)
|
||||
```
|
||||
|
|
|
@ -128,7 +128,7 @@ pub mod game {
|
|||
panic!();
|
||||
}
|
||||
user_stats.name = name;
|
||||
user_stats.bump = *ctx.bumps.get("user_stats").unwrap();
|
||||
user_stats.bump = ctx.bumps.user_stats;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ pub struct CreateUserStats<'info> {
|
|||
|
||||
In the account validation struct we use `seeds` together with `init` to create a PDA with the desired seeds.
|
||||
Additionally, we add an empty `bump` constraint to signal to anchor that it should find the canonical bump itself.
|
||||
Then, in the handler, we call `ctx.bumps.get("user_stats")` to get the bump anchor found and save it to the user stats
|
||||
Then, in the handler, we call `ctx.bumps.user_stats` to get the bump anchor found and save it to the user stats
|
||||
account as an extra property.
|
||||
|
||||
If we then want to use the created pda in a different instruction, we can add a new validation struct (This will check that the `user_stats` account is the pda created by running `hash(seeds, user_stats.bump, game_program_id)`):
|
||||
|
|
|
@ -34,7 +34,9 @@ have an `Anchor.toml` to define the build.
|
|||
An example `Anchor.toml` config looks as follows,
|
||||
|
||||
```toml
|
||||
anchor_version = "0.27.0"
|
||||
[toolchain]
|
||||
anchor_version = "0.30.0"
|
||||
solana_version = "1.18.8"
|
||||
|
||||
[workspace]
|
||||
members = ["programs/multisig"]
|
||||
|
@ -52,7 +54,7 @@ multisig = "A9HAbnCwoD6f2NkZobKFf6buJoN9gUVVvX5PoUnDHS6u"
|
|||
|
||||
Here there are four sections.
|
||||
|
||||
1. `anchor_version` (optional) - sets the anchor docker image to use. By default, the builder will use the latest version of Anchor.
|
||||
1. `[toolchain]` (optional) - sets the Anchor and Solana version to use. By default, the builder will use the current versions.
|
||||
2. `[workspace]` (optional) - sets the paths--relative to the `Anchor.toml`--
|
||||
to all programs in the local
|
||||
workspace, i.e., the path to the `Cargo.toml` manifest associated with each
|
||||
|
@ -60,13 +62,13 @@ Here there are four sections.
|
|||
standard Anchor workflow, this can be omitted. For programs not written in Anchor
|
||||
but still want to publish, this should be added.
|
||||
3. `[provider]` - configures the wallet and cluster settings. Here, `mainnet` is used because the registry only supports `mainnet` binary verification at the moment.
|
||||
4. `[programs.mainnet]` - configures each program in the workpace, providing
|
||||
4. `[programs.mainnet]` - configures each program in the workspace, providing
|
||||
the `address` of the program to verify.
|
||||
|
||||
{% callout title="Note" %}
|
||||
When defining program in `[programs.mainnet]`, make sure the name provided
|
||||
matches the **lib** name for your program, which is defined
|
||||
by your program's Cargo.toml.
|
||||
by your program's `Cargo.toml`.
|
||||
{% /callout %}
|
||||
|
||||
### Examples
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
---
|
||||
title: Quickstart
|
||||
description: Getting Started with Solana Playground
|
||||
---
|
||||
|
||||
## Solana Playground
|
||||
|
||||
Solana Playground (Solpg) is a browser based IDE that allows you to quickly develop, deploy, and test Solana programs!
|
||||
|
||||
To get started, go to [https://beta.solpg.io/](https://beta.solpg.io/).
|
||||
|
||||
### Create Playground Wallet
|
||||
|
||||
If it is your first time using Solana Playground, you'll first need to create a Playground Wallet.
|
||||
|
||||
Click on the red status indicator button labeled "Not connected" at the bottom left of the screen, (optionally) save your wallet's keypair file to your computer for backup, then click "Continue".
|
||||
|
||||
![solpg-wallet](/solpg-wallet.png)
|
||||
|
||||
After your Playground Wallet is created, you will notice the bottom of the window now states your wallet's address, your SOL balance, and the Solana cluster you are connected to (devnet by default).
|
||||
|
||||
{% callout type="warning" %}
|
||||
Your Playground Wallet will be saved in your browser's local storage. Clearing your browser cache will remove your saved wallet.
|
||||
{% /callout %}
|
||||
|
||||
To fund your Playground wallet with devnet SOL, run the following command in the Playground terminal:
|
||||
|
||||
```
|
||||
solana airdrop 5
|
||||
```
|
||||
|
||||
Alternatively, you can use this [devnet faucet](https://faucet.solana.com/).
|
||||
|
||||
### Create Anchor Project
|
||||
|
||||
Next, click the "Create a new project" button on the left-side panel.
|
||||
|
||||
Enter a project name, select Anchor as the framework, then click the "Create" button.
|
||||
|
||||
![solpg-anchor](/solpg-anchor.png)
|
||||
|
||||
This will create a basic Anchor program that can be found in the `src/lib.rs` file.
|
||||
You can learn more about the details of an Anchor program in the Core concepts section of the docs.
|
||||
|
||||
```rust
|
||||
use anchor_lang::prelude::*;
|
||||
|
||||
// This is your program's public key and it will update
|
||||
// automatically when you build the project.
|
||||
declare_id!("11111111111111111111111111111111");
|
||||
|
||||
#[program]
|
||||
mod hello_anchor {
|
||||
use super::*;
|
||||
pub fn initialize(ctx: Context<Initialize>, data: u64) -> Result<()> {
|
||||
ctx.accounts.new_account.data = data;
|
||||
msg!("Changed data to: {}!", data); // Message will show up in the tx logs
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize<'info> {
|
||||
// We must specify the space in order to initialize an account.
|
||||
// First 8 bytes are default account discriminator,
|
||||
// next 8 bytes come from NewAccount.data being type u64.
|
||||
// (u64 = 64 bits unsigned integer = 8 bytes)
|
||||
#[account(init, payer = signer, space = 8 + 8)]
|
||||
pub new_account: Account<'info, NewAccount>,
|
||||
#[account(mut)]
|
||||
pub signer: Signer<'info>,
|
||||
pub system_program: Program<'info, System>,
|
||||
}
|
||||
|
||||
#[account]
|
||||
pub struct NewAccount {
|
||||
data: u64
|
||||
}
|
||||
```
|
||||
|
||||
### Build and Deploy Program
|
||||
|
||||
To build the program, simply run `build` in the terminal. Building the program will update the program address in `declare_id!()`. This is the on-chain address of your program.
|
||||
|
||||
Once the program is built, run `deploy` in the terminal to deploy the program to the cluster (devnet by default).
|
||||
To deploy a program, SOL must be allocated to the on-chain account that stores the program. If you do not have enough SOL, you may need to first request an airdrop.
|
||||
|
||||
You can also use the `Build` and `Deploy` buttons on the left-side panel.
|
||||
|
||||
![solpg-build-deploy](/solpg-build-deploy.png)
|
||||
|
||||
### Test Program
|
||||
|
||||
Included with the starter code is a test file found in `tests/anchor.test.ts`.
|
||||
This file demonstrates how to interact with the program from the client.
|
||||
|
||||
```javascript
|
||||
// No imports needed: web3, anchor, pg and more are globally available
|
||||
|
||||
describe('Test', () => {
|
||||
it('initialize', async () => {
|
||||
// Generate keypair for the new account
|
||||
const newAccountKp = new web3.Keypair()
|
||||
|
||||
// Send transaction
|
||||
const data = new BN(42)
|
||||
const txHash = await pg.program.methods
|
||||
.initialize(data)
|
||||
.accounts({
|
||||
newAccount: newAccountKp.publicKey,
|
||||
signer: pg.wallet.publicKey,
|
||||
systemProgram: web3.SystemProgram.programId,
|
||||
})
|
||||
.signers([newAccountKp])
|
||||
.rpc()
|
||||
console.log(`Use 'solana confirm -v ${txHash}' to see the logs`)
|
||||
|
||||
// Confirm transaction
|
||||
await pg.connection.confirmTransaction(txHash)
|
||||
|
||||
// Fetch the created account
|
||||
const newAccount = await pg.program.account.newAccount.fetch(
|
||||
newAccountKp.publicKey
|
||||
)
|
||||
|
||||
console.log('On-chain data is:', newAccount.data.toString())
|
||||
|
||||
// Check whether the data on-chain is equal to local 'data'
|
||||
assert(data.eq(newAccount.data))
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
To run the test file once the program is deployed, run `test` in the terminal.
|
||||
|
||||
You can also use the `Test` button on the left-side panel.
|
||||
|
||||
![solpg-test](/solpg-test.png)
|
||||
|
||||
Lastly, the SOL allocated to the on-chain program can be fully recovered by closing the program.
|
||||
|
||||
You can close a program by running the following command and specifying the program ID found in `declare_id!()`:
|
||||
|
||||
```
|
||||
solana program close <ProgramID>
|
||||
```
|
||||
|
||||
Congratulations! You've just built and deployed your first Solana program using the Anchor framework!
|
||||
|
||||
### Import from Github
|
||||
|
||||
Solana Playground offers a convenient feature allowing you to import or view projects using their GitHub URLs.
|
||||
|
||||
Open this [Solpg link](https://beta.solpg.io/https://github.com/solana-developers/anchor-examples/tree/main/quickstart) to view the Anchor project from this [Github repo](https://github.com/solana-developers/anchor-examples/tree/main/quickstart).
|
||||
|
||||
Click the `Import` button and enter a name for the project to add it to your list of projects in Solana Playground.
|
||||
|
||||
![solpg-import](/solpg-import.png)
|
||||
|
||||
Once a project is imported, all changes are automatically saved and persisted within the Playground environment.
|
||||
|
||||
Additionally, you have the option to import projects directly by clicking the Github icon on the left-side panel.
|
||||
|
||||
![solpg-github](/solpg-github.png)
|
|
@ -170,7 +170,7 @@ pub struct Initialize<'info> {
|
|||
```
|
||||
|
||||
{% callout type="warning" title="Note" %}
|
||||
The doc comment needs to be a [line or block doc comment](https://doc.rust-lang.org/reference/comments.html#doc-comments) (/// or /\*\*) to be interepreted as doc attribute by Rust. Double slash comments (//) are not interpreted as such.
|
||||
The doc comment needs to be a [line or block doc comment](https://doc.rust-lang.org/reference/comments.html#doc-comments) (/// or /\*\*) to be interpreted as doc attribute by Rust. Double slash comments (//) are not interpreted as such.
|
||||
{% /callout %}
|
||||
|
||||
## Other Resources
|
||||
|
|
|
@ -3,7 +3,7 @@ title: Verifiable Builds
|
|||
description: Anchor - Verifiable Builds
|
||||
---
|
||||
|
||||
Building programs with the Solana CLI may embed machine specfic
|
||||
Building programs with the Solana CLI may embed machine specific
|
||||
code into the resulting binary. As a result, building the same program
|
||||
on different machines may produce different executables. To get around this
|
||||
problem, one can build inside a docker image with pinned dependencies to produce
|
||||
|
@ -37,10 +37,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.27.0` one can run
|
||||
A docker image for each version of Anchor is published on [Docker Hub](https://hub.docker.com/r/backpackapp/build). They are tagged in the form `backpackapp/build:<version>`. For example, to get the image for Anchor `v0.30.0` one can run
|
||||
|
||||
```shell
|
||||
docker pull projectserum/build:v0.27.0
|
||||
docker pull backpackapp/build:v0.30.0
|
||||
```
|
||||
|
||||
## Removing an Image
|
||||
|
|
|
@ -0,0 +1,340 @@
|
|||
---
|
||||
title: Release Notes 0.29.0
|
||||
description: Anchor - Release Notes 0.29.0
|
||||
---
|
||||
|
||||
Anchor keeps a [CHANGELOG](https://github.com/coral-xyz/anchor/blob/master/CHANGELOG.md) but it's not easy to make sense what has changed, what effect does the change have and how to migrate. This is where release notes comes in, an easy to digest and actionable view for each release.
|
||||
|
||||
---
|
||||
|
||||
## How to update
|
||||
|
||||
1. Update `avm`:
|
||||
|
||||
```sh
|
||||
cargo install --git https://github.com/coral-xyz/anchor --tag v0.29.0 avm --locked
|
||||
```
|
||||
|
||||
2. Update `anchor-cli`:
|
||||
|
||||
```sh
|
||||
avm install latest
|
||||
```
|
||||
|
||||
3. Update Anchor crate(s) to `0.29.0`. Optionally, run `cargo update` to update other dependencies to the latest compatible versions.
|
||||
|
||||
4. Update TS package(s) to `0.29.0`.
|
||||
|
||||
## Solana `1.14` is no longer supported
|
||||
|
||||
Minimum supported Solana version is now `1.16.0` because
|
||||
|
||||
- All clusters including mainnet-beta are now running `^1.16`
|
||||
- There is a [compatibility issue](https://github.com/solana-labs/solana/issues/31960) between `1.14` and `1.16`
|
||||
|
||||
If you are still on Solana `1.14`, update by running:
|
||||
|
||||
```sh
|
||||
solana-install init 1.17.0
|
||||
```
|
||||
|
||||
## Override toolchain for the workspace
|
||||
|
||||
`Anchor.toml` has a new section called `[toolchain]` that allows overriding the current toolchain versions inside the workspace.
|
||||
|
||||
```toml
|
||||
[toolchain]
|
||||
anchor_version = "0.29.0" # `anchor-cli` version to use
|
||||
solana_version = "1.17.0" # Solana version to use
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
- Fields are optional.
|
||||
- `anchor_version` requires [`avm`](https://github.com/coral-xyz/anchor/tree/master/avm) to be installed.
|
||||
- Before this release, `anchor_version` and `solana_version` keys in `Anchor.toml` were being used for Docker verifiable builds only. Now, all commands work via the `[toolchain]` section.
|
||||
|
||||
## Install CLI from commit with `avm`
|
||||
|
||||
It is possible to install CLI from commit by running:
|
||||
|
||||
```sh
|
||||
cargo install --git https://github.com/coral-xyz/anchor --rev 6cf200493a307c01487c7b492b4893e0d6f6cb23 anchor-cli --locked
|
||||
```
|
||||
|
||||
but this overrides the `anchor` binary and does not work well with `avm`.
|
||||
|
||||
In this release, `avm` supports installing and switching between commits.
|
||||
|
||||
**Install** from a commit with `avm install <VERSION>-<COMMIT>`:
|
||||
|
||||
```sh
|
||||
# <VERSION>-<COMMIT>
|
||||
avm install 0.28.0-6cf200493a307c01487c7b492b4893e0d6f6cb23
|
||||
|
||||
# Full commit hash
|
||||
avm install 6cf200493a307c01487c7b492b4893e0d6f6cb23
|
||||
|
||||
# Short commit hash
|
||||
avm install 6cf200
|
||||
```
|
||||
|
||||
**Use** a different version `avm use <VERSION>-<COMMIT>`:
|
||||
|
||||
```sh
|
||||
avm use 0.28.0-6cf200493a307c01487c7b492b4893e0d6f6cb23
|
||||
```
|
||||
|
||||
Specify `toolchain.anchor_version` as `<VERSION>-<COMMIT>`:
|
||||
|
||||
```toml
|
||||
[toolchain]
|
||||
anchor_version = "0.28.0-6cf200493a307c01487c7b492b4893e0d6f6cb23"
|
||||
```
|
||||
|
||||
## Multiple files template
|
||||
|
||||
Programs created with `anchor init` or `anchor new` have a single `lib.rs` file but not everyone prefers a single file approach for programs.
|
||||
|
||||
The most popular way of splitting the program into multiple files looks something like the following:
|
||||
|
||||
```
|
||||
├── constants.rs
|
||||
├── error.rs
|
||||
├── instructions
|
||||
│ ├── initialize.rs
|
||||
│ └── mod.rs
|
||||
├── lib.rs
|
||||
└── state
|
||||
└── mod.rs
|
||||
```
|
||||
|
||||
To initialize a workspace with this program structure, run:
|
||||
|
||||
```
|
||||
anchor init <NAME> --template multiple
|
||||
```
|
||||
|
||||
or if you have an existing workspace:
|
||||
|
||||
```
|
||||
anchor new <NAME> --template multiple
|
||||
```
|
||||
|
||||
## Upgradeable programs in tests
|
||||
|
||||
You can now configure upgradability of the programs in `anchor test`.
|
||||
|
||||
In `Anchor.toml`:
|
||||
|
||||
```toml
|
||||
[test]
|
||||
upgradeable = true
|
||||
```
|
||||
|
||||
or for an individual program:
|
||||
|
||||
```toml
|
||||
[[test.genesis]]
|
||||
address = "22Y43yTVxuUkoRKdm9thyRhQ3SdgQS7c7kB6UNCiaczD"
|
||||
program = "swap.so"
|
||||
upgradeable = true
|
||||
```
|
||||
|
||||
## Lamport utilities
|
||||
|
||||
Transferring lamports from a PDA is quite complicated due to the types that are being used.
|
||||
|
||||
Instead of
|
||||
|
||||
```rs
|
||||
**ctx.accounts.from.to_account_info().try_borrow_mut_lamports()? -= amount;
|
||||
**ctx.accounts.to.to_account_info().try_borrow_mut_lamports()? += amount;
|
||||
```
|
||||
|
||||
you can
|
||||
|
||||
```rs
|
||||
ctx.accounts.from.sub_lamports(amount)?;
|
||||
ctx.accounts.to.add_lamports(amount)?;
|
||||
```
|
||||
|
||||
Similarly for **getting** the lamports, instead of
|
||||
|
||||
```rs
|
||||
let lamports = ctx.accounts.my_account.to_account_info().lamports();
|
||||
```
|
||||
|
||||
you can
|
||||
|
||||
```rs
|
||||
let lamports = ctx.accounts.my_account.get_lamports();
|
||||
```
|
||||
|
||||
**Note:** The new methods are not only more ergonomic but they are also more performant than the previous examples. This is because `to_account_info` method clones the data internally but the new methods use a reference to the underlying data.
|
||||
|
||||
## Type safe context bumps
|
||||
|
||||
Before this release, `ctx.bumps` used to be a `BTreeMap<String, u8>` which doesn't provide type safety for the keys(account names).
|
||||
|
||||
```rs
|
||||
let bump = *ctx.bumps.get("my_account").unwrap();
|
||||
```
|
||||
|
||||
With this release, there is an auto-generated struct that holds the bump values.
|
||||
|
||||
```rs
|
||||
let bump = ctx.bumps.my_account;
|
||||
```
|
||||
|
||||
**Note**: The new way is not only more intuitive but also is more performant. This is mainly because `BTreeMap` is heap-allocated and it has to resize and grow occasionally.
|
||||
|
||||
## `idl-build` feature
|
||||
|
||||
There is a new way to generate IDLs via compilation.
|
||||
|
||||
Add `idl-build` feature to your program's `Cargo.toml` to try it out.
|
||||
|
||||
```toml
|
||||
[features]
|
||||
idl-build = ["anchor-lang/idl-build"]
|
||||
```
|
||||
|
||||
The IDL will be built automatically when you run `anchor build` but if you'd like to _only_ generate the IDL, run:
|
||||
|
||||
```sh
|
||||
anchor idl build
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
- All crates that are being used for the IDL generation needs to be added to the `idl-build` feature list.
|
||||
|
||||
```toml
|
||||
[features]
|
||||
idl-build = [
|
||||
"anchor-lang/idl-build",
|
||||
"anchor-spl/idl-build",
|
||||
"another-program/idl-build"
|
||||
]
|
||||
```
|
||||
|
||||
- Compile time checks are supported.
|
||||
- External types from other Anchor programs are supported as long as the external crate has the `idl-build` feature(see `another-program/idl-build`).
|
||||
- Conflicting type names e.g. `some_module::MyType` and `another_module::MyType` can be used together.
|
||||
- Generation time is a lot slower compared to the default method(parsing) due to Rust compile times.
|
||||
- Even though most of it works great, some parts are still rough around the edges and you may encounter parts that are not fully ironed out. Please [create an issue](https://github.com/coral-xyz/anchor/issues) if you run into a problem.
|
||||
|
||||
## Type aliases
|
||||
|
||||
Anchor IDL now supports type aliases.
|
||||
|
||||
```rs
|
||||
pub type U8Array = [u8; 8];
|
||||
|
||||
#[program]
|
||||
pub mod my_program {
|
||||
use super::*;
|
||||
|
||||
pub fn type_alias(ctx: Context<TypeAlias>, u8_array: U8Array) -> Result<()> {
|
||||
msg!("{:?}", u8_array);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct TypeAlias {}
|
||||
```
|
||||
|
||||
Generates the following IDL:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"name": "my_program",
|
||||
"instructions": [
|
||||
{
|
||||
"name": "typeAlias",
|
||||
"accounts": [],
|
||||
"args": [
|
||||
{
|
||||
"name": "u8Array",
|
||||
"type": {
|
||||
"defined": "U8Array"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"name": "U8Array",
|
||||
"type": {
|
||||
"kind": "alias",
|
||||
"value": {
|
||||
"array": ["u8", 8]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** This example only works with the default IDL generation method(parsing) for now because type aliases for default Rust types don't work properly with `idl-build`([#2640](https://github.com/coral-xyz/anchor/issues/2640)).
|
||||
|
||||
## Export `mpl-token-metadata`
|
||||
|
||||
`anchor-spl` with `metadata` feature enabled now exports the `mpl-token-metadata` crate.
|
||||
|
||||
**Note:** Consider removing the `mpl-token-metadata` dependency to reduce the possibility of having conflicting versions:
|
||||
|
||||
```diff
|
||||
[dependencies]
|
||||
anchor-spl = { version = "0.29.0", features = ["metadata"] }
|
||||
- mpl-token-metadata = "1.13.1"
|
||||
```
|
||||
|
||||
and use the exported crate from `anchor-spl`:
|
||||
|
||||
```rs
|
||||
use anchor_spl::metadata::mpl_token_metadata;
|
||||
```
|
||||
|
||||
## TypeScript SDK improvements
|
||||
|
||||
1. `Program.addEventListener` method is now strongly typed -- correct types for the event names and the event returned from the callback instead of `any`.
|
||||
|
||||
2. `anchor.workspace` now lazy loads programs on-demand. Programs that are not being used in the tests won't get loaded and therefore won't cause errors.
|
||||
|
||||
3. JavaScript convention is to use camelCase for property names but programs are accessed via PascalCase e.g. `anchor.workspace.MyProgram` which is unintuitive. Both variations work in this release.
|
||||
|
||||
```ts
|
||||
const camel = anchor.workspace.myProgram
|
||||
const pascal = anchor.workspace.MyProgram
|
||||
```
|
||||
|
||||
4. Removed `assert` and `base64-js` dependency.
|
||||
|
||||
## New docker image
|
||||
|
||||
The previous image([projectserum/build](https://hub.docker.com/r/projectserum/build)) is now deprecated, new image is [backpackapp/build](https://hub.docker.com/r/backpackapp/build).
|
||||
|
||||
To pull the latest image, run:
|
||||
|
||||
```sh
|
||||
docker pull backpackapp/build:v0.29.0
|
||||
```
|
||||
|
||||
**Note:** `anchor build --verifiable` now works with the latest image.
|
||||
|
||||
## Enhanced performance
|
||||
|
||||
`0.29.0` performance is noticeably improved in all areas, the biggest one being [binary size](https://github.com/coral-xyz/anchor/blob/master/bench/BINARY_SIZE.md#0290) which is reduced ~36% compared to `0.28.0`!
|
||||
|
||||
Similar benchmarks can be found for [compute units](https://github.com/coral-xyz/anchor/blob/master/bench/COMPUTE_UNITS.md#0290) and [stack memory](https://github.com/coral-xyz/anchor/blob/master/bench/STACK_MEMORY.md#0290).
|
||||
|
||||
**Note:** The benchmark results will vary between programs but the overall direction should be the same.
|
||||
|
||||
---
|
||||
|
||||
See the full list of changes in the [CHANGELOG](https://github.com/coral-xyz/anchor/blob/master/CHANGELOG.md#0290---2023-10-16).
|
|
@ -0,0 +1,327 @@
|
|||
---
|
||||
title: Release Notes 0.30.0
|
||||
description: Anchor - Release Notes 0.30.0
|
||||
---
|
||||
|
||||
The long-awaited v0.30.0 release is finally here!
|
||||
|
||||
We'll go over the main changes, but if you'd like to see all notable changes, check out the [CHANGELOG](https://github.com/coral-xyz/anchor/blob/v0.30.0/CHANGELOG.md#0300---2024-04-15).
|
||||
|
||||
---
|
||||
|
||||
## How to upgrade
|
||||
|
||||
1. Update `avm`:
|
||||
|
||||
```sh
|
||||
cargo install --git https://github.com/coral-xyz/anchor --tag v0.30.0 avm --locked
|
||||
```
|
||||
|
||||
2. Update `anchor-cli`:
|
||||
|
||||
```sh
|
||||
avm install latest
|
||||
```
|
||||
|
||||
3. Update Anchor crate(s) to `0.30.0`. Optionally, run `cargo update` to update other dependencies to the latest compatible versions.
|
||||
|
||||
4. Update TS package(s) to `0.30.0`.
|
||||
|
||||
## Recommended Solana Version
|
||||
|
||||
While this release supports anything above `1.16`, the recommended Solana version is `1.18.8`. You can upgrade Solana tools by running:
|
||||
|
||||
```
|
||||
solana-install init 1.18.8
|
||||
```
|
||||
|
||||
## IDL
|
||||
|
||||
The IDL type specification and generation has been rewritten. To keep the release notes short, we won't go over the changes here, but see [this](https://github.com/coral-xyz/anchor/pull/2824) if you'd like to learn more.
|
||||
|
||||
### `idl-build` feature
|
||||
|
||||
`idl-build` feature is now required in your program's `Cargo.toml` definition in order for the IDL generation to work.
|
||||
|
||||
Without this feature, `anchor build` outputs:
|
||||
|
||||
```
|
||||
Error: `idl-build` feature is missing. To solve, add
|
||||
|
||||
[features]
|
||||
idl-build = ["anchor-lang/idl-build"]
|
||||
|
||||
in `<PATH_TO_CARGO_TOML>`.
|
||||
```
|
||||
|
||||
Note that all crates that you use to generate type definitions for the IDL need to be specified in the list of `idl-build`, e.g. `anchor-spl/idl-build`, `some-program/idl-build`...
|
||||
|
||||
## Lang
|
||||
|
||||
### Dependency free program declaration
|
||||
|
||||
Depending on other crates who used different versions of Anchor is not the best experience, to say the least. To solve this problem, program clients can now be generated from their IDL using the new `declare_program!` macro:
|
||||
|
||||
```rs
|
||||
declare_program!(program_name);
|
||||
```
|
||||
|
||||
`program_name` is based on the file name of the IDL in `idls` directory, e.g. `idls/program_name.json` is required to exist in order for the above example to work.
|
||||
|
||||
This works for both on-chain (CPI) and off-chain (RPC) usage, allowing program interactions without creating a [dependency hell](https://en.wikipedia.org/wiki/Dependency_hell). Check out [this](https://github.com/coral-xyz/anchor/blob/v0.30.0/tests/declare-program/programs/declare-program/src/lib.rs) example for on-chain CPI usage.
|
||||
|
||||
For more information, see the macro's [documentation](https://docs.rs/anchor-lang/0.30.0/anchor_lang/macro.declare_program.html).
|
||||
|
||||
### Token extensions
|
||||
|
||||
#### Constraints
|
||||
|
||||
There are new account constraints for [Token Extensions (Token 2022)](https://solana.com/solutions/token-extensions):
|
||||
|
||||
- `group_pointer`:
|
||||
- `authority`
|
||||
- `group_address`
|
||||
- `group_member_pointer`:
|
||||
- `authority`
|
||||
- `member_address`
|
||||
- `metadata_pointer`:
|
||||
- `authority`
|
||||
- `metadata_address`
|
||||
- `close_authority`
|
||||
- `authority`
|
||||
- `permanent_delegate`:
|
||||
- `delegate`
|
||||
- `transfer_hook`:
|
||||
- `authority`
|
||||
- `program_id`
|
||||
|
||||
**Note:** Above values are concatinated with `::` (similar to other Anchor constraints) and have `extensions` prefix e.g. `extensions::group_pointer::authority = <EXPR>`.
|
||||
|
||||
These constraints can be used both with or without the `init` constraint.
|
||||
|
||||
[Here](https://github.com/coral-xyz/anchor/blob/v0.30.0/tests/spl/token-extensions/programs/token-extensions/src/instructions.rs) is an example program that uses these constraints.
|
||||
|
||||
#### CPI wrappers
|
||||
|
||||
`anchor-spl` now includes CPI wrappers for Token Extensions which can be accessed from `anchor_spl::token_2022_extensions`.
|
||||
|
||||
### `#[interface]` attribute
|
||||
|
||||
Transfer hooks can now be used with the new `#[interface]` macro. This argument overrides the Anchor's default instruction discriminator to use the interface instruction's discriminator.
|
||||
|
||||
Current supported values are:
|
||||
|
||||
- `spl_transfer_hook_interface::initialize_extra_account_meta_list`
|
||||
- `spl_transfer_hook_interface::execute`
|
||||
|
||||
```rs
|
||||
mod my_hook_program {
|
||||
#[interface(spl_transfer_hook_interface::initialize_extra_account_meta_list)]
|
||||
pub fn initialize(ctx: Context<Initialize>, metas: Vec<AnchorExtraAccountMeta>) -> Result<()> {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
#[interface(spl_transfer_hook_interface::execute)]
|
||||
pub fn execute(ctx: Context<Execute>, amount: u64) -> Result<()> {
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Optional bumps
|
||||
|
||||
When an optional account is not specified, instead of defaulting it to `u8::MAX`, this release changes the optional bump type to be `Option<u8>` and sets the bump field to `None`.
|
||||
|
||||
### Less heap allocations
|
||||
|
||||
[`BorshSerialize::try_to_vec`](https://github.com/near/borsh-rs/blob/79097e3c71ae469a101b4828457792bcf8be7f5f/borsh/src/ser/mod.rs#L47-L51) implementation, which is used in events, CPI, and return data, heap allocates [1024](https://github.com/near/borsh-rs/blob/79097e3c71ae469a101b4828457792bcf8be7f5f/borsh/src/ser/mod.rs#L19) bytes each time it's used, even if your data is much smaller. In this release, the default allocation is set to 256 bytes.
|
||||
|
||||
There is also a new method `InstructionData::write_to()` to write to an existing allocation rather than creating a new allocation with `InstructionData::data()`.
|
||||
|
||||
## CLI
|
||||
|
||||
### Priority fees in CLI
|
||||
|
||||
IDL commands take in `--priority-fee` argument
|
||||
As it's getting harder and harder to land transactions in mainnet-beta without using priority fees, this release supports setting `--priority-fee` argument for the IDL commands. For example:
|
||||
|
||||
```
|
||||
anchor idl erase-authority --program-id <PROGRAM_ID> --priority-fee 9000
|
||||
```
|
||||
|
||||
When the `--priortiy-fee` argument is not specified, the median fee of the last 150 confirmed slots is used.
|
||||
|
||||
### `--no-idl` flag on builds
|
||||
|
||||
IDL generation requires building of the program, but this is unnecessary if your program API doesn't change. In that case, you can use `--no-idl` flag to build your program but skip the IDL generation:
|
||||
|
||||
```
|
||||
anchor build --no-idl
|
||||
```
|
||||
|
||||
### IDL buffer is closed after `idl upgrade`
|
||||
|
||||
After an IDL upgrade, the buffer account is now closed and the lamports are returned back to the IDL authority.
|
||||
|
||||
### Pass deploy arguments to `solana-cli`
|
||||
|
||||
You can now pass arguments to `solana program deploy` from `anchor deploy`:
|
||||
|
||||
```
|
||||
anchor deploy -- --final
|
||||
```
|
||||
|
||||
### Verifiable deployments
|
||||
|
||||
Similar to verifiable builds, you can now deploy the verified build instead of the default build:
|
||||
|
||||
```
|
||||
anchor deploy --verifiable
|
||||
```
|
||||
|
||||
### Accept package name as program name
|
||||
|
||||
`--program-name` (`-p`) argument of various commands also works with package name of the program rather than lib name which is snake_case. For example:
|
||||
|
||||
```
|
||||
anchor build -p my-program
|
||||
```
|
||||
|
||||
### Deactivate test-validator features
|
||||
|
||||
You can now deactivate test-validator features from `Anchor.toml`:
|
||||
|
||||
```toml
|
||||
[test.validator]
|
||||
deactivate_feature = ["GDH5TVdbTPUpRnXaRyQqiKUa7uZAbZ28Q2N9bhbKoMLm", "zkiTNuzBKxrCLMKehzuQeKZyLtX2yvFcEKMML8nExU8"]
|
||||
```
|
||||
|
||||
### Crate and package compatibility
|
||||
|
||||
Using non-matching versions of `anchor-cli`, `anchor-lang`, and `@coral-xyz/anchor` can result in unexpected behavior. In this release, you'll get a warning if any of them don't match.
|
||||
|
||||
### Explicit `overflow-checks` flag
|
||||
|
||||
[`overflow-checks`](https://doc.rust-lang.org/cargo/reference/profiles.html#overflow-checks) flag is implicitly disabled by default. Anchor workspaces that are crated with `anchor init` have this flag enabled, however, Anchor doesn't do any checks for it after the initial workspace creation.
|
||||
|
||||
With this release, `overflow-checks` in the workspace `Cargo.toml` need to be specified. Note that "specified" does not mean enabled, as you can also disable it, but you need to be explicit in doing so.
|
||||
|
||||
### Wildcard pattern in `Anchor.toml`
|
||||
|
||||
`workspace.members` and `workspace.exclude` now supports simple wildcard pattern:
|
||||
|
||||
```toml
|
||||
[workspace]
|
||||
members = ["programs/*"]
|
||||
```
|
||||
|
||||
Note that the support is limited to this simple wildcard pattern, and more complex globs are not currently supported.
|
||||
|
||||
### `cargo build-sbf` is now the default
|
||||
|
||||
Before this release, `anchor build` used `cargo build-bpf` to build programs, however, because it is deprecated, `anchor build` now defaults to `cargo build-sbf`.
|
||||
|
||||
To preserve the old behavior, you can use:
|
||||
|
||||
```
|
||||
anchor build --arch bpf
|
||||
```
|
||||
|
||||
### Run multiple commands in scripts
|
||||
|
||||
Scripts in `Anchor.toml` now supports running multiple commands:
|
||||
|
||||
```toml
|
||||
[scripts]
|
||||
test-all = "cargo test && yarn run ts-mocha tests/**/*.ts"
|
||||
```
|
||||
|
||||
This script would run both `cargo` and `yarn` commands:
|
||||
|
||||
```
|
||||
anchor run test-all
|
||||
```
|
||||
|
||||
### Test only a specified program
|
||||
|
||||
A single program can be tested in a multi program workspace with the `--program-name` (`-p`) argument:
|
||||
|
||||
```
|
||||
anchor test --program-name example
|
||||
```
|
||||
|
||||
This builds and tests only the specified program.
|
||||
|
||||
### Rust test template
|
||||
|
||||
A wild TypeScript test won't appear if you initialize your workspace with the new Rust test template:
|
||||
|
||||
```
|
||||
anchor init --test-template rust
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
|
||||
### Account resolution
|
||||
|
||||
Account resolution refers to the ability of clients to resolve accounts without having to manually specify them when sending transactions.
|
||||
|
||||
There are too many changes to the account resolution logic in the TS library, however, we can skip a good chunk of them since they're mostly internal.
|
||||
|
||||
One change that affects everyone is the change in the `accounts` method. Even though the TS library had some support for account resolution, it had no type-level support for it — all accounts were essentially typed as partial, and there was no way to know which accounts were resolvable and which were not.
|
||||
|
||||
There are now 3 methods to specify accounts with the transaction builder:
|
||||
|
||||
- `accounts`: This method is now fully type-safe based on the resolution fields in the IDL, making it much easier to only specify the accounts that are actually needed.
|
||||
- `accountsPartial`: This method keeps the old behavior and let's you specify all accounts including the resolvable ones.
|
||||
- `accountsStrict`: If you don't want to use account resolution and specify all accounts manually (unchanged).
|
||||
|
||||
This change is likely to result in errors in your existing `.accounts()` calls. To fix, either change `accounts` to `accountsPartial`, or remove all accounts that can be resolved from the IDL. For example:
|
||||
|
||||
```diff
|
||||
- await program.methods
|
||||
- .init()
|
||||
- .accounts({
|
||||
- pda: ...,
|
||||
- signer: ...,
|
||||
- systemProgram: ...,
|
||||
- })
|
||||
- .rpc();
|
||||
+ await program.methods.init().rpc();
|
||||
```
|
||||
|
||||
### Magic account names
|
||||
|
||||
Another change that affects most projects is the removal of "magic" account names. The TS library used to autofill common program and sysvar accounts based on their name, e.g. `systemProgram`, however, this is no longer necessary with the introduction of the `address` field (in the IDL) which is used to resolve all program and sysvars by default.
|
||||
|
||||
### Case conversion
|
||||
|
||||
The internals of the TS library are filled with case conversion logic before making string comparison and this also forces other libraries who build on top of Anchor to do the same.
|
||||
|
||||
Along with making the IDL have consistent casing, TS library also has consistent casing (camelCase) in this release.
|
||||
|
||||
### No more Program ID
|
||||
|
||||
`programId` parameter of `Program` is removed since the new IDL requires to store the program id in its `address` field:
|
||||
|
||||
```diff
|
||||
- new Program(idl, programId);
|
||||
+ new Program(idl);
|
||||
```
|
||||
|
||||
### Optional provider options
|
||||
|
||||
`opts` parameter of `AnchorProvider` is now optional:
|
||||
|
||||
```diff
|
||||
- new AnchorProvider(connection, wallet, {});
|
||||
+ new AnchorProvider(connection, wallet);
|
||||
```
|
||||
|
||||
### Type changes
|
||||
|
||||
There are too many type changes to list here, especially the types that are related to the IDL. The new IDL types can be found [here](https://github.com/coral-xyz/anchor/blob/v0.30.0/ts/packages/anchor/src/idl.ts).
|
||||
|
||||
---
|
||||
|
||||
See the full list of notable changes in the [CHANGELOG](https://github.com/coral-xyz/anchor/blob/v0.30.0/CHANGELOG.md#0300---2024-04-15).
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Release Notes
|
||||
description: Anchor - Release Notes
|
||||
title: CHANGELOG
|
||||
description: Anchor - CHANGELOG
|
||||
---
|
||||
|
||||
Version 0 of Semantic Versioning is handled differently from version 1 and above.
|
||||
|
@ -8,6 +8,178 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
|
||||
---
|
||||
|
||||
## [0.30.0] - 2024-04-15
|
||||
|
||||
### Features
|
||||
|
||||
- cli: Allow force `init` and `new` ([#2698](https://github.com/coral-xyz/anchor/pull/2698)).
|
||||
- cli: Add verifiable option when `deploy` ([#2705](https://github.com/coral-xyz/anchor/pull/2705)).
|
||||
- cli: Add support for passing arguments to the underlying `solana program deploy` command with `anchor deploy` ([#2709](https://github.com/coral-xyz/anchor/pull/2709)).
|
||||
- lang: Add `InstructionData::write_to` implementation ([#2733](https://github.com/coral-xyz/anchor/pull/2733)).
|
||||
- lang: Add `#[interface(..)]` attribute for instruction discriminator overrides ([#2728](https://github.com/coral-xyz/anchor/pull/2728)).
|
||||
- ts: Add `.interface(..)` method for instruction discriminator overrides ([#2728](https://github.com/coral-xyz/anchor/pull/2728)).
|
||||
- cli: Check `anchor-lang` and CLI version compatibility ([#2753](https://github.com/coral-xyz/anchor/pull/2753)).
|
||||
- ts: Add missing IDL PDA seed types ([#2752](https://github.com/coral-xyz/anchor/pull/2752)).
|
||||
- cli: `idl close` accepts optional `--idl-address` parameter ([#2760](https://github.com/coral-xyz/anchor/pull/2760)).
|
||||
- cli: Add support for simple wildcard patterns in Anchor.toml's `workspace.members` and `workspace.exclude`. ([#2785](https://github.com/coral-xyz/anchor/pull/2785)).
|
||||
- cli: Add `--test-template` option for `init` command ([#2805](https://github.com/coral-xyz/anchor/pull/2805)).
|
||||
- cli: `anchor test` is able to run multiple commands ([#2799](https://github.com/coral-xyz/anchor/pull/2799)).
|
||||
- cli: Check `@coral-xyz/anchor` package and CLI version compatibility ([#2813](https://github.com/coral-xyz/anchor/pull/2813)).
|
||||
- cli: Accept package name as program name ([#2816](https://github.com/coral-xyz/anchor/pull/2816)).
|
||||
- cli: Add ability to build and test only a specified program ([#2823](https://github.com/coral-xyz/anchor/pull/2823)).
|
||||
- idl: Add new IDL spec ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl: Add support for `repr`s ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl: Add support for expression evaluation ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl: Add support for using external types when generating the IDL ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl, ts: Add unit and tuple struct support ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl, ts: Add generics support ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Add `accountsPartial` method to keep the old `accounts` method behavior ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Make `opts` parameter of `AnchorProvider` constructor optional ([#2843](https://github.com/coral-xyz/anchor/pull/2843)).
|
||||
- cli: Add `--no-idl` flag to the `build` command ([#2847](https://github.com/coral-xyz/anchor/pull/2847)).
|
||||
- cli: Add priority fees to idl commands ([#2845](https://github.com/coral-xyz/anchor/pull/2845)).
|
||||
- ts: Add `prepend` option to MethodBuilder `preInstructions` method ([#2863](https://github.com/coral-xyz/anchor/pull/2863)).
|
||||
- lang: Add `declare_program!` macro ([#2857](https://github.com/coral-xyz/anchor/pull/2857)).
|
||||
- cli: Add `deactivate_feature` flag to `solana-test-validator` config in Anchor.toml ([#2872](https://github.com/coral-xyz/anchor/pull/2872)).
|
||||
- idl: Add `docs` field for constants ([#2887](https://github.com/coral-xyz/anchor/pull/2887)).
|
||||
- idl: Store deployment addresses for other clusters ([#2892](https://github.com/coral-xyz/anchor/pull/2892)).
|
||||
- lang: Add `Event` utility type to get events from bytes ([#2897](https://github.com/coral-xyz/anchor/pull/2897)).
|
||||
- lang, spl: Add support for [token extensions](https://solana.com/solutions/token-extensions) ([#2789](https://github.com/coral-xyz/anchor/pull/2789)).
|
||||
- lang: Return overflow error from `Lamports` trait operations ([#2907](https://github.com/coral-xyz/anchor/pull/2907)).
|
||||
|
||||
### Fixes
|
||||
|
||||
- syn: Add missing `new_from_array` method to `Hash` ([#2682](https://github.com/coral-xyz/anchor/pull/2682)).
|
||||
- cli: Switch to Cargo feature resolver(`resolver = "2"`) ([#2676](https://github.com/coral-xyz/anchor/pull/2676)).
|
||||
- cli: Fix using user specific path for `provider.wallet` in `Anchor.toml` ([#2696](https://github.com/coral-xyz/anchor/pull/2696)).
|
||||
- syn: Fix IDL constant seeds parsing ([#2699](https://github.com/coral-xyz/anchor/pull/2699)).
|
||||
- cli: Display errors if toolchain override restoration fails ([#2700](https://github.com/coral-xyz/anchor/pull/2700)).
|
||||
- cli: Fix commit based `anchor_version` override ([#2704](https://github.com/coral-xyz/anchor/pull/2704)).
|
||||
- spl: Fix compilation with `shmem` feature enabled ([#2722](https://github.com/coral-xyz/anchor/pull/2722)).
|
||||
- cli: Localhost default test validator address changes from `localhost` to `127.0.0.1`, NodeJS 17 IP resolution changes for IPv6 ([#2725](https://github.com/coral-xyz/anchor/pull/2725)).
|
||||
- lang: Eliminate temporary Vec allocations when serializing data with discriminant and set the default capacity to 256 bytes ([#2691](https://github.com/coral-xyz/anchor/pull/2691)).
|
||||
- lang: Allow custom lifetime in Accounts structure ([#2741](https://github.com/coral-xyz/anchor/pull/2741)).
|
||||
- lang: Remove `try_to_vec` usage while setting the return data in order to reduce heap memory usage ([#2744](https://github.com/coral-xyz/anchor/pull/2744))
|
||||
- cli: Show installation progress if Solana tools are not installed when using toolchain overrides ([#2757](https://github.com/coral-xyz/anchor/pull/2757)).
|
||||
- ts: Fix formatting enums ([#2763](https://github.com/coral-xyz/anchor/pull/2763)).
|
||||
- cli: Fix `migrate` command not working without global `ts-node` installation ([#2767](https://github.com/coral-xyz/anchor/pull/2767)).
|
||||
- client, lang, spl, syn: Enable all features for docs.rs build ([#2774](https://github.com/coral-xyz/anchor/pull/2774)).
|
||||
- ts: Fix construction of field layouts for type aliased instruction arguments ([#2821](https://github.com/coral-xyz/anchor/pull/2821))
|
||||
- idl: Fix IDL ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl, ts: Make casing consistent ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Fix not being able to use numbers in instruction, account, or event names in some cases due to case conversion ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- cli: Fix excessive test validator requests ([#2828](https://github.com/coral-xyz/anchor/pull/2828)).
|
||||
- client: Fix `parse_logs_response` to prevent panics when more than 1 outer instruction exists in logs ([#2856](https://github.com/coral-xyz/anchor/pull/2856)).
|
||||
- avm, cli: Fix `stdsimd` feature compilation error from `ahash` when installing the CLI using newer Rust versions ([#2867](https://github.com/coral-xyz/anchor/pull/2867)).
|
||||
- spl: Fix not being able to deserialize newer token 2022 extensions ([#2876](https://github.com/coral-xyz/anchor/pull/2876)).
|
||||
- spl: Remove `solana-program` dependency ([#2900](https://github.com/coral-xyz/anchor/pull/2900)).
|
||||
- spl: Make `TokenAccount` and ` Mint` `Copy` ([#2904](https://github.com/coral-xyz/anchor/pull/2904)).
|
||||
- ts: Add missing errors ([#2906](https://github.com/coral-xyz/anchor/pull/2906)).
|
||||
|
||||
### Breaking
|
||||
|
||||
- cli: Make `cargo build-sbf` the default build command ([#2694](https://github.com/coral-xyz/anchor/pull/2694)).
|
||||
- cli: Require explicit `overflow-checks` flag ([#2716](https://github.com/coral-xyz/anchor/pull/2716)).
|
||||
- ts: Remove `anchor-deprecated-state` feature ([#2717](https://github.com/coral-xyz/anchor/pull/2717)).
|
||||
- lang: Remove `CLOSED_ACCOUNT_DISCRIMINATOR` ([#2726](https://github.com/coral-xyz/anchor/pull/2726)).
|
||||
- lang: Make bumps of optional accounts `Option<u8>` rather than `u8` ([#2730](https://github.com/coral-xyz/anchor/pull/2730)).
|
||||
- spl: Remove `shared-memory` program ([#2747](https://github.com/coral-xyz/anchor/pull/2747)).
|
||||
- ts: Remove `associated`, `account.associated` and `account.associatedAddress` methods ([#2749](https://github.com/coral-xyz/anchor/pull/2749)).
|
||||
- cli: `idl upgrade` command closes the IDL buffer account ([#2760](https://github.com/coral-xyz/anchor/pull/2760)).
|
||||
- cli: Remove `--jest` option from the `init` command ([#2805](https://github.com/coral-xyz/anchor/pull/2805)).
|
||||
- cli: Require `idl-build` feature in program `Cargo.toml` ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- cli: Rename `seeds` feature to `resolution` and make it enabled by default ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- cli: Remove `idl parse` command ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- idl: Change IDL spec ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- syn: Remove `idl-parse` and `seeds` features ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Change `accounts` method to no longer accept resolvable accounts ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: `Program` instances use camelCase for everything ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Remove discriminator functions ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
|
||||
- ts: Remove `programId` parameter of the `Program` constructor ([#2864](https://github.com/coral-xyz/anchor/pull/2864)).
|
||||
- idl, syn: Move IDL types from the `anchor-syn` crate to the new IDL crate ([#2882](https://github.com/coral-xyz/anchor/pull/2882)).
|
||||
- idl: Add `#[non_exhaustive]` to IDL enums ([#2890](https://github.com/coral-xyz/anchor/pull/2890)).
|
||||
|
||||
## [0.29.0] - 2023-10-16
|
||||
|
||||
### Features
|
||||
|
||||
- lang: Change all accounts to have a reference to `AccountInfo` ([#2656](https://github.com/coral-xyz/anchor/pull/2656)).
|
||||
- lang: Add `get_lamports`, `add_lamports` and `sub_lamports` methods for all account types ([#2552](https://github.com/coral-xyz/anchor/pull/2552)).
|
||||
- client: Add a helper struct `DynSigner` to simplify use of `Client<C> where <C: Clone + Deref<Target = impl Signer>>` with Solana clap CLI utils that loads `Signer` as `Box<dyn Signer>` ([#2550](https://github.com/coral-xyz/anchor/pull/2550)).
|
||||
- lang: Allow CPI calls matching an interface without pinning program ID ([#2559](https://github.com/coral-xyz/anchor/pull/2559)).
|
||||
- cli, lang: Add IDL generation through compilation. `anchor build` still uses parsing method to generate IDLs, use `anchor idl build` to generate IDLs with the build method ([#2011](https://github.com/coral-xyz/anchor/pull/2011)).
|
||||
- avm: Add support for the `.anchorversion` file to facilitate switching between different versions of the `anchor-cli` ([#2553](https://github.com/coral-xyz/anchor/pull/2553)).
|
||||
- ts: Add ability to access workspace programs independent of the casing used, e.g. `anchor.workspace.myProgram`, `anchor.workspace.MyProgram`... ([#2579](https://github.com/coral-xyz/anchor/pull/2579)).
|
||||
- bench: Add benchmarking for program binary size ([#2591](https://github.com/coral-xyz/anchor/pull/2591)).
|
||||
- spl: Export `mpl-token-metadata` crate ([#2583](https://github.com/coral-xyz/anchor/pull/2583)).
|
||||
- spl: Add `TokenRecordAccount` for pNFTs ([#2597](https://github.com/coral-xyz/anchor/pull/2597)).
|
||||
- ts: Add support for unnamed(tuple) enum in accounts ([#2601](https://github.com/coral-xyz/anchor/pull/2601)).
|
||||
- cli: Add program template with multiple files for instructions, state... ([#2602](https://github.com/coral-xyz/anchor/pull/2602)).
|
||||
- bench: Add benchmarking for stack memory usage ([#2617](https://github.com/coral-xyz/anchor/pull/2617)).
|
||||
- lang: `Box` the inner enums of `anchor_lang::error::Error` to optimize `anchor_lang::Result` ([#2600](https://github.com/coral-xyz/anchor/pull/2600)).
|
||||
- ts: Add strong type support for `Program.addEventListener` method ([#2627](https://github.com/coral-xyz/anchor/pull/2627)).
|
||||
- syn: Add `IdlBuild` trait to implement IDL support for custom types ([#2629](https://github.com/coral-xyz/anchor/pull/2629)).
|
||||
- spl: Add `idl-build` feature. IDL build method will not work without enabling this feature when using `anchor-spl` ([#2629](https://github.com/coral-xyz/anchor/pull/2629)).
|
||||
- lang: Add support for type aliases in IDLs ([#2637](https://github.com/coral-xyz/anchor/pull/2637)).
|
||||
- cli: Add `test.upgradeable`, `test.genesis.upgradeable` setting in `Anchor.toml` to support testing upgradeable programs ([#2642](https://github.com/coral-xyz/anchor/pull/2642)).
|
||||
- cli, client, lang, spl: Update Solana toolchain and dependencies to `1.17.0`, `1.16` remains supported ([#2645](https://github.com/coral-xyz/anchor/pull/2645)).
|
||||
- spl: Add support for memo program ([#2661](https://github.com/coral-xyz/anchor/pull/2661)).
|
||||
- avm: Add `anchor-cli` installation from commit ([#2659](https://github.com/coral-xyz/anchor/pull/2659)).
|
||||
- cli: Add `toolchain` property in `Anchor.toml` to override Anchor and Solana versions ([#2649](https://github.com/coral-xyz/anchor/pull/2649)).
|
||||
|
||||
### Fixes
|
||||
|
||||
- ts: Packages no longer depend on `assert` ([#2535](https://github.com/coral-xyz/anchor/pull/2535)).
|
||||
- lang: Support for `const` in the `InitSpace` macro ([#2555](https://github.com/coral-xyz/anchor/pull/2555)).
|
||||
- cli: Support workspace inheritance ([#2570](https://github.com/coral-xyz/anchor/pull/2570)).
|
||||
- client: Compile with Solana `1.14` ([#2572](https://github.com/coral-xyz/anchor/pull/2572)).
|
||||
- cli: Fix `anchor build --no-docs` adding docs to the IDL ([#2575](https://github.com/coral-xyz/anchor/pull/2575)).
|
||||
- ts: Load workspace programs on-demand rather than loading all of them at once ([#2579](https://github.com/coral-xyz/anchor/pull/2579)).
|
||||
- lang: Fix `associated_token::token_program` constraint ([#2603](https://github.com/coral-xyz/anchor/pull/2603)).
|
||||
- cli: Fix `anchor account` command panicking outside of workspace ([#2620](https://github.com/coral-xyz/anchor/pull/2620)).
|
||||
- lang: IDL named enum variant fields are now camelCase as opposed to snake_case, consistent with the other IDL types ([#2633](https://github.com/coral-xyz/anchor/pull/2633)).
|
||||
- avm: Remove excessive panics and handle the errors gracefully ([#2671](https://github.com/coral-xyz/anchor/pull/2671)).
|
||||
|
||||
### Breaking
|
||||
|
||||
- lang: Switch to type safe bumps in context ([#2542](https://github.com/coral-xyz/anchor/pull/2542)).
|
||||
- syn: `idl` feature has been replaced with `idl-build`, `idl-parse` and `idl-types` features ([#2011](https://github.com/coral-xyz/anchor/pull/2011)).
|
||||
- syn: IDL `parse` method now returns `Result<Idl>` instead of `Result<Option<Idl>>` ([#2582](https://github.com/coral-xyz/anchor/pull/2582)).
|
||||
- spl: Update `mpl-token-metadata` dependency to use the client SDK instead of the program crate ([#2632](https://github.com/coral-xyz/anchor/pull/2632)).
|
||||
- ts: Remove `base64-js` dependency ([#2635](https://github.com/coral-xyz/anchor/pull/2635)).
|
||||
- syn: `IdlTypeDefinitionTy` enum has a new variant `Alias` ([#2637](https://github.com/coral-xyz/anchor/pull/2637)).
|
||||
- cli, client, lang, spl: Solana `1.14` is no longer supported, minimum required Solana version is `1.16.0` ([#2645](https://github.com/coral-xyz/anchor/pull/2645)).
|
||||
- cli: `anchor_version` and `solana_version` property in `Anchor.toml` that was being used in verifiable builds are moved inside `toolchain`. They are now being used for all commands in the workspace, not just verifiable builds ([#2649](https://github.com/coral-xyz/anchor/pull/2649)).
|
||||
|
||||
## [0.28.0] - 2023-06-09
|
||||
|
||||
### Features
|
||||
|
||||
- client: Add `async` feature flag to use an asynchronous anchor-client ([#2488](https://github.com/coral-xyz/anchor/pull/2488)).
|
||||
- spl: Add metadata wrappers `approve_collection_authority`, `bubblegum_set_collection_size`, `burn_edition_nft`, `burn_nft`, `revoke_collection_authority`, `set_token_standard`, `utilize`, `unverify_sized_collection_item`, `unverify_collection` ([#2430](https://github.com/coral-xyz/anchor/pull/2430))
|
||||
- spl: Add `token_program` constraint to `Token`, `Mint`, and `AssociatedToken` accounts in order to override required `token_program` fields and use different token interface implementations in the same instruction ([#2460](https://github.com/coral-xyz/anchor/pull/2460))
|
||||
- cli: Add support for Solidity programs. `anchor init` and `anchor new` take an option `--solidity` which creates solidity code rather than rust. `anchor build` and `anchor test` work accordingly ([#2421](https://github.com/coral-xyz/anchor/pull/2421))
|
||||
- bench: Add benchmarking for compute units usage ([#2466](https://github.com/coral-xyz/anchor/pull/2466))
|
||||
- cli: `idl set-buffer`, `idl set-authority` and `idl close` take an option `--print-only`. which prints transaction in a base64 Borsh compatible format but not sent to the cluster. It's helpful when managing authority under a multisig, e.g., a user can create a proposal for a `Custom Instruction` in SPL Governance ([#2486](https://github.com/coral-xyz/anchor/pull/2486)).
|
||||
- lang: Add `emit_cpi!` and `#[event_cpi]` macros(behind `event-cpi` feature flag) to store event logs in transaction metadata ([#2438](https://github.com/coral-xyz/anchor/pull/2438)).
|
||||
- cli: Add `keys sync` command to sync program id declarations ([#2505](https://github.com/coral-xyz/anchor/pull/2505)).
|
||||
- cli: Create new programs with correct program ids ([#2509](https://github.com/coral-xyz/anchor/pull/2509)).
|
||||
- cli, client, lang, spl: Update Solana toolchain and dependencies to `1.16.0` and specify maximum version of `<1.17.0` ([#2512](https://github.com/coral-xyz/anchor/pull/2512)).
|
||||
- cli: `anchor deploy` command's `--program-name` argument accepts program lib names ([#2519](https://github.com/coral-xyz/anchor/pull/2519)).
|
||||
|
||||
### Fixes
|
||||
|
||||
- ts: Narrowed `AccountClient` type to it's appropriate account type ([#2440](https://github.com/coral-xyz/anchor/pull/2440))
|
||||
- lang: Fix inability to use identifiers `program_id`, `accounts`, `ix_data`, `remaining_accounts` in instruction arguments ([#2464](https://github.com/coral-xyz/anchor/pull/2464))
|
||||
- cli: Fix incorrect `metadata.address` generation in IDL after deploying with a custom keypair ([#2485](https://github.com/coral-xyz/anchor/pull/2485))
|
||||
- cli: IDL commands no longer hang when the payer doesn't have funds to pay for the transaction fee ([#2492](https://github.com/coral-xyz/anchor/pull/2492))
|
||||
- cli: Fix `anchor new` not updating `Anchor.toml` ([#2516](https://github.com/coral-xyz/anchor/pull/2516)).
|
||||
- client, lang, spl: Allow wider range of dependency versions to reduce dependency issues ([#2524](https://github.com/coral-xyz/anchor/pull/2524)).
|
||||
|
||||
### Breaking
|
||||
|
||||
- lang: Identifiers that are intended for internal usage(`program_id`, `accounts`, `ix_data`, `remaining_accounts`) have been renamed with `__` prefix ([#2464](https://github.com/coral-xyz/anchor/pull/2464))
|
||||
- spl: Remove the `metadata::create_metadata_account_v2` deprecated wrapper since it was removed from token metadata program ([#2480](https://github.com/coral-xyz/anchor/pull/2480))
|
||||
|
||||
## [0.27.0] - 2023-03-08
|
||||
|
||||
### Features
|
||||
|
@ -21,10 +193,11 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
- spl: Add `approve_checked` function ([#2401](https://github.com/coral-xyz/anchor/pull/2401)).
|
||||
- cli: Add `--skip-build` option to the verify command ([#2387](https://github.com/coral-xyz/anchor/pull/2387)).
|
||||
- client: Add support for multithreading to the rust client: use flag `--multithreaded` ([#2321](https://github.com/coral-xyz/anchor/pull/2321)).
|
||||
- client: Add `async_rpc` a method which returns a nonblocking solana rpc client ([2322](https://github.com/coral-xyz/anchor/pull/2322)).
|
||||
- client: Add `async_rpc` a method which returns a nonblocking solana rpc client ([#2322](https://github.com/coral-xyz/anchor/pull/2322)).
|
||||
- avm, cli: Use the `rustls-tls` feature of `reqwest` so that users don't need OpenSSL installed ([#2385](https://github.com/coral-xyz/anchor/pull/2385)).
|
||||
- ts: Add `VersionedTransaction` support. Methods in the `Provider` class and `Wallet` interface now use the argument `tx: Transaction | VersionedTransaction` ([2427](https://github.com/coral-xyz/anchor/pull/2427)).
|
||||
- ts: Add `VersionedTransaction` support. Methods in the `Provider` class and `Wallet` interface now use the argument `tx: Transaction | VersionedTransaction` ([#2427](https://github.com/coral-xyz/anchor/pull/2427)).
|
||||
- cli: Add `--arch sbf` option to compile programs using `cargo build-sbf` ([#2398](https://github.com/coral-xyz/anchor/pull/2398)).
|
||||
- land: Support multiple programs with the same interface using `Interface` and `InterfaceAccount` types, related to token-2022 ([#2386](https://github.com/coral-xyz/anchor/pull/2386)).
|
||||
|
||||
### Fixes
|
||||
|
||||
|
@ -101,36 +274,37 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
|
||||
### Features
|
||||
|
||||
* lang: Add `realloc`, `realloc::payer`, and `realloc::zero` as a new constraint group for program accounts ([#1986](https://github.com/coral-xyz/anchor/pull/1986)).
|
||||
* lang: Add `PartialEq` and `Eq` for `anchor_lang::Error` ([#1544](https://github.com/coral-xyz/anchor/pull/1544)).
|
||||
* cli: Add `--skip-build` to `anchor publish` ([#1786](https://github.com/coral-xyz/anchor/pull/1841)).
|
||||
* cli: Add `--program-keypair` to `anchor deploy` ([#1786](https://github.com/coral-xyz/anchor/pull/1786)).
|
||||
* cli: Add compilation optimizations to cli template ([#1807](https://github.com/coral-xyz/anchor/pull/1807)).
|
||||
* cli: `build` now adds docs to idl. This can be turned off with `--no-docs` ([#1561](https://github.com/coral-xyz/anchor/pull/1561)).
|
||||
* cli: Add `b` and `t` aliases for `build` and `test` respectively ([#1823](https://github.com/coral-xyz/anchor/pull/1823)).
|
||||
* spl: Add more derived traits to `TokenAccount` to `Mint` ([#1818](https://github.com/coral-xyz/anchor/pull/1818)).
|
||||
* spl: Add `sync_native` token program CPI wrapper function ([#1833](https://github.com/coral-xyz/anchor/pull/1833)).
|
||||
* cli: Allow passing arguments to an underlying script with `anchor run` ([#1914](https://github.com/coral-xyz/anchor/pull/1914)).
|
||||
* ts: Implement a coder for system program ([#1920](https://github.com/coral-xyz/anchor/pull/1920)).
|
||||
* ts: Add `program.coder.types` for encoding/decoding user-defined types ([#1931](https://github.com/coral-xyz/anchor/pull/1931)).
|
||||
* client: Add send_with_spinner_and_config function to RequestBuilder ([#1926](https://github.com/coral-xyz/anchor/pull/1926)).
|
||||
* ts: Implement a coder for SPL associated token program ([#1939](https://github.com/coral-xyz/anchor/pull/1939)).
|
||||
* ts: verbose error for missing `ANCHOR_WALLET` variable when using `NodeWallet.local()` ([#1958](https://github.com/coral-xyz/anchor/pull/1958)).
|
||||
* ts: Add `MethodsBuilder#accountsStrict` for strict typing on ix account input ([#2019](https://github.com/coral-xyz/anchor/pull/2019)).
|
||||
* Update solana dependencies to 1.10.29 ([#2027](https://github.com/coral-xyz/anchor/pull/2027)).
|
||||
- lang: Add `realloc`, `realloc::payer`, and `realloc::zero` as a new constraint group for program accounts ([#1986](https://github.com/coral-xyz/anchor/pull/1986)).
|
||||
- lang: Add `PartialEq` and `Eq` for `anchor_lang::Error` ([#1544](https://github.com/coral-xyz/anchor/pull/1544)).
|
||||
- cli: Add `--skip-build` to `anchor publish` ([#1786](https://github.com/coral-xyz/anchor/pull/1841)).
|
||||
- cli: Add `--program-keypair` to `anchor deploy` ([#1786](https://github.com/coral-xyz/anchor/pull/1786)).
|
||||
- cli: Add compilation optimizations to cli template ([#1807](https://github.com/coral-xyz/anchor/pull/1807)).
|
||||
- cli: `build` now adds docs to idl. This can be turned off with `--no-docs` ([#1561](https://github.com/coral-xyz/anchor/pull/1561)).
|
||||
- cli: Add `b` and `t` aliases for `build` and `test` respectively ([#1823](https://github.com/coral-xyz/anchor/pull/1823)).
|
||||
- spl: Add more derived traits to `TokenAccount` to `Mint` ([#1818](https://github.com/coral-xyz/anchor/pull/1818)).
|
||||
- spl: Add `sync_native` token program CPI wrapper function ([#1833](https://github.com/coral-xyz/anchor/pull/1833)).
|
||||
- cli: Allow passing arguments to an underlying script with `anchor run` ([#1914](https://github.com/coral-xyz/anchor/pull/1914)).
|
||||
- ts: Implement a coder for system program ([#1920](https://github.com/coral-xyz/anchor/pull/1920)).
|
||||
- ts: Add `program.coder.types` for encoding/decoding user-defined types ([#1931](https://github.com/coral-xyz/anchor/pull/1931)).
|
||||
- client: Add `send_with_spinner_and_config` function to RequestBuilder ([#1926](https://github.com/coral-xyz/anchor/pull/1926)).
|
||||
- ts: Implement a coder for SPL associated token program ([#1939](https://github.com/coral-xyz/anchor/pull/1939)).
|
||||
- ts: verbose error for missing `ANCHOR_WALLET` variable when using `NodeWallet.local()` ([#1958](https://github.com/coral-xyz/anchor/pull/1958)).
|
||||
- ts: Add `MethodsBuilder#accountsStrict` for strict typing on ix account input ([#2019](https://github.com/coral-xyz/anchor/pull/2019)).
|
||||
- Update solana dependencies to 1.10.29 ([#2027](https://github.com/coral-xyz/anchor/pull/2027)).
|
||||
|
||||
### Fixes
|
||||
|
||||
* cli: Move `overflow-checks` into workspace `Cargo.toml` so that it will not be ignored by compiler ([#1806](https://github.com/coral-xyz/anchor/pull/1806)).
|
||||
* lang: Fix missing account name information when deserialization fails when using `init` or `zero` ([#1800](https://github.com/coral-xyz/anchor/pull/1800)).
|
||||
* ts: Expose the wallet's publickey on the Provider ([#1845](https://github.com/coral-xyz/anchor/pull/1845)).
|
||||
- cli: Fix `anchor keys list` reading the `target` folder in the wrong path ([#2063](https://github.com/coral-xyz/anchor/pull/2063)).
|
||||
- cli: Move `overflow-checks` into workspace `Cargo.toml` so that it will not be ignored by compiler ([#1806](https://github.com/coral-xyz/anchor/pull/1806)).
|
||||
- lang: Fix missing account name information when deserialization fails when using `init` or `zero` ([#1800](https://github.com/coral-xyz/anchor/pull/1800)).
|
||||
- ts: Expose the wallet's publickey on the Provider ([#1845](https://github.com/coral-xyz/anchor/pull/1845)).
|
||||
|
||||
### Breaking
|
||||
|
||||
* ts: Change `BROWSER` env variable to `ANCHOR_BROWSER` ([#1233](https://github.com/coral-xyz/anchor/pull/1233)).
|
||||
* ts: Add transaction signature to `EventCallback` parameters ([#1851](https://github.com/coral-xyz/anchor/pull/1851)).
|
||||
* ts: Change `EventParser#parseLogs` implementation to be a generator instead of callback function ([#2018](https://github.com/coral-xyz/anchor/pull/2018)).
|
||||
* lang: Adds a new `&mut reallocs: BTreeSet<Pubkey>` argument to `Accounts::try_accounts` ([#1986](https://github.com/coral-xyz/anchor/pull/1986)).
|
||||
- ts: Change `BROWSER` env variable to `ANCHOR_BROWSER` ([#1233](https://github.com/coral-xyz/anchor/pull/1233)).
|
||||
- ts: Add transaction signature to `EventCallback` parameters ([#1851](https://github.com/coral-xyz/anchor/pull/1851)).
|
||||
- ts: Change `EventParser#parseLogs` implementation to be a generator instead of callback function ([#2018](https://github.com/coral-xyz/anchor/pull/2018)).
|
||||
- lang: Adds a new `&mut reallocs: BTreeSet<Pubkey>` argument to `Accounts::try_accounts` ([#1986](https://github.com/coral-xyz/anchor/pull/1986)).
|
||||
|
||||
## [0.24.2] - 2022-04-13
|
||||
|
||||
|
@ -475,7 +649,7 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
### Breaking
|
||||
|
||||
- cli: `[clusters.<network>]` Anchor.toml section has been renamed to `[programs.<network>]` ([#570](https://github.com/coral-xyz/anchor/pull/570)).
|
||||
- cli: `[workspace]` member and exclude arrays must now be filepaths relative to the workpsace root ([#570](https://github.com/coral-xyz/anchor/pull/570)).
|
||||
- cli: `[workspace]` member and exclude arrays must now be filepaths relative to the workspace root ([#570](https://github.com/coral-xyz/anchor/pull/570)).
|
||||
|
||||
## [0.12.0] - 2021-08-03
|
||||
|
||||
|
@ -575,10 +749,10 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
|
||||
### Breaking Changes
|
||||
|
||||
- ts: Retrieving deserialized accounts from the `<program>.account.<my-account>` and `<program>.state` namespaces now require explicitly invoking the `fetch` API. For example, `program.account.myAccount(<adddress>)` and `program.state()` is now `program.account.myAccount.fetch(<address>)` and `program.state.fetch()` ([#322](https://github.com/coral-xyz/anchor/pull/322)).
|
||||
- ts: Retrieving deserialized accounts from the `<program>.account.<my-account>` and `<program>.state` namespaces now require explicitly invoking the `fetch` API. For example, `program.account.myAccount(<address>)` and `program.state()` is now `program.account.myAccount.fetch(<address>)` and `program.state.fetch()` ([#322](https://github.com/coral-xyz/anchor/pull/322)).
|
||||
- lang: `#[account(associated)]` now requires `init` to be provided to create an associated account. If not provided, then the address will be assumed to exist, and a constraint will be added to ensure the correctness of the address ([#318](https://github.com/coral-xyz/anchor/pull/318)).
|
||||
- lang, ts: Change account discriminator pre-image of the `#[state]` account discriminator to be namespaced by "state:" ([#320](https://github.com/coral-xyz/anchor/pull/320)).
|
||||
- lang, ts: Change domain delimiters for the pre-image of the instruciton sighash to be a single colon `:` to be consistent with accounts ([#321](https://github.com/coral-xyz/anchor/pull/321)).
|
||||
- lang, ts: Change domain delimiters for the pre-image of the instruction sighash to be a single colon `:` to be consistent with accounts ([#321](https://github.com/coral-xyz/anchor/pull/321)).
|
||||
- lang: Associated constraints no longer automatically implement `mut` ([#341](https://github.com/coral-xyz/anchor/pull/341)).
|
||||
- lang: Associated `space` constraints must now be literal integers instead of literal strings ([#341](https://github.com/coral-xyz/anchor/pull/341)).
|
||||
|
||||
|
@ -621,7 +795,7 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
|
||||
### Features
|
||||
|
||||
- lang: Allows one to specify multiple `with` targets when creating associated acconts ([#197](https://github.com/coral-xyz/anchor/pull/197)).
|
||||
- lang: Allows one to specify multiple `with` targets when creating associated accounts ([#197](https://github.com/coral-xyz/anchor/pull/197)).
|
||||
- lang, ts: Add array support ([#202](https://github.com/coral-xyz/anchor/pull/202)).
|
||||
- lang: Zero copy deserialization for accounts ([#202](https://github.com/coral-xyz/anchor/pull/202), [#206](https://github.com/coral-xyz/anchor/pull/206)).
|
||||
- lang, spl, cli, client: Upgrade solana toolchain to 1.6.6 ([#210](https://github.com/coral-xyz/anchor/pull/210)).
|
|
@ -2,3 +2,6 @@
|
|||
members = [
|
||||
"programs/*"
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
overflow-checks = true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "basic-0",
|
||||
"version": "0.27.0",
|
||||
"version": "0.30.0",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"homepage": "https://github.com/coral-xyz/anchor#readme",
|
||||
"bugs": {
|
||||
|
@ -14,6 +14,6 @@
|
|||
"node": ">=11"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "anchor test --skip-lint"
|
||||
"test": "anchor test --skip-lint && anchor clean"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ name = "basic_0"
|
|||
[features]
|
||||
no-entrypoint = []
|
||||
cpi = ["no-entrypoint"]
|
||||
idl-build = ["anchor-lang/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = { path = "../../../../../lang" }
|
||||
|
|
|
@ -2,3 +2,6 @@
|
|||
members = [
|
||||
"programs/*"
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
overflow-checks = true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "basic-1",
|
||||
"version": "0.27.0",
|
||||
"version": "0.30.0",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"homepage": "https://github.com/coral-xyz/anchor#readme",
|
||||
"bugs": {
|
||||
|
@ -14,6 +14,6 @@
|
|||
"node": ">=11"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "anchor test --skip-lint"
|
||||
"test": "anchor test --skip-lint && anchor clean"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ name = "basic_1"
|
|||
[features]
|
||||
no-entrypoint = []
|
||||
cpi = ["no-entrypoint"]
|
||||
idl-build = ["anchor-lang/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = { path = "../../../../../lang" }
|
||||
|
|
|
@ -2,3 +2,6 @@
|
|||
members = [
|
||||
"programs/*"
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
overflow-checks = true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "basic-2",
|
||||
"version": "0.27.0",
|
||||
"version": "0.30.0",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"homepage": "https://github.com/coral-xyz/anchor#readme",
|
||||
"bugs": {
|
||||
|
@ -14,6 +14,6 @@
|
|||
"node": ">=11"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "anchor test --skip-lint"
|
||||
"test": "anchor test --skip-lint && anchor clean"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ name = "basic_2"
|
|||
[features]
|
||||
no-entrypoint = []
|
||||
cpi = ["no-entrypoint"]
|
||||
idl-build = ["anchor-lang/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = { path = "../../../../../lang" }
|
||||
|
|
|
@ -2,3 +2,6 @@
|
|||
members = [
|
||||
"programs/*"
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
overflow-checks = true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "basic-3",
|
||||
"version": "0.27.0",
|
||||
"version": "0.30.0",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"homepage": "https://github.com/coral-xyz/anchor#readme",
|
||||
"bugs": {
|
||||
|
@ -14,6 +14,6 @@
|
|||
"node": ">=11"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "anchor test --skip-lint"
|
||||
"test": "anchor test --skip-lint && anchor clean"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ name = "puppet_master"
|
|||
[features]
|
||||
no-entrypoint = []
|
||||
cpi = ["no-entrypoint"]
|
||||
idl-build = ["anchor-lang/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = { path = "../../../../../lang" }
|
||||
|
|
|
@ -12,6 +12,7 @@ name = "puppet"
|
|||
[features]
|
||||
no-entrypoint = []
|
||||
cpi = ["no-entrypoint"]
|
||||
idl-build = ["anchor-lang/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = { path = "../../../../../lang" }
|
||||
|
|
|
@ -2,3 +2,6 @@
|
|||
members = [
|
||||
"programs/*"
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
overflow-checks = true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "basic-4",
|
||||
"version": "0.27.0",
|
||||
"version": "0.30.0",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"homepage": "https://github.com/coral-xyz/anchor#readme",
|
||||
"bugs": {
|
||||
|
@ -14,6 +14,6 @@
|
|||
"node": ">=11"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "anchor test --skip-lint"
|
||||
"test": "anchor test --skip-lint && anchor clean"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ name = "basic_4"
|
|||
[features]
|
||||
no-entrypoint = []
|
||||
cpi = ["no-entrypoint"]
|
||||
idl-build = ["anchor-lang/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = { path = "../../../../../lang" }
|
||||
|
|
|
@ -9,7 +9,7 @@ pub mod basic_4 {
|
|||
|
||||
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
|
||||
let counter = ctx.accounts.counter.deref_mut();
|
||||
let bump = *ctx.bumps.get("counter").ok_or(ErrorCode::CannotGetBump)?;
|
||||
let bump = ctx.bumps.counter;
|
||||
|
||||
*counter = Counter {
|
||||
authority: *ctx.accounts.authority.key,
|
||||
|
@ -73,6 +73,4 @@ impl Counter {
|
|||
pub enum ErrorCode {
|
||||
#[msg("You are not authorized to perform this action.")]
|
||||
Unauthorized,
|
||||
#[msg("Cannot get the bump.")]
|
||||
CannotGetBump,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"programs/*"
|
||||
]
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
overflow-checks = true
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
{
|
||||
"name": "basic-5",
|
||||
"version": "0.27.0",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"homepage": "https://github.com/coral-xyz/anchor#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/coral-xyz/anchor/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/coral-xyz/anchor.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=11"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "anchor test --skip-lint"
|
||||
}
|
||||
}
|
||||
"name": "basic-5",
|
||||
"version": "0.30.0",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"homepage": "https://github.com/coral-xyz/anchor#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/coral-xyz/anchor/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/coral-xyz/anchor.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=11"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "anchor test --skip-lint && anchor clean"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ name = "basic_5"
|
|||
[features]
|
||||
no-entrypoint = []
|
||||
cpi = ["no-entrypoint"]
|
||||
idl-build = ["anchor-lang/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = { path = "../../../../../lang" }
|
|
@ -1,9 +1,4 @@
|
|||
import * as anchor from "@coral-xyz/anchor";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
TransactionMessage,
|
||||
VersionedTransaction,
|
||||
} from "@solana/web3.js";
|
||||
import { Basic5 } from "../target/types/basic_5";
|
||||
|
||||
describe("basic-5", () => {
|
||||
|
@ -64,7 +59,7 @@ describe("basic-5", () => {
|
|||
.instruction();
|
||||
|
||||
// Array of instructions
|
||||
const instructions: TransactionInstruction[] = [
|
||||
const instructions: anchor.web3.TransactionInstruction[] = [
|
||||
createInstruction,
|
||||
walkInstruction,
|
||||
runInstruction,
|
||||
|
@ -75,7 +70,9 @@ describe("basic-5", () => {
|
|||
await createAndSendV0Tx(instructions);
|
||||
});
|
||||
|
||||
async function createAndSendV0Tx(txInstructions: TransactionInstruction[]) {
|
||||
async function createAndSendV0Tx(
|
||||
txInstructions: anchor.web3.TransactionInstruction[]
|
||||
) {
|
||||
// Step 1 - Fetch the latest blockhash
|
||||
let latestBlockhash = await provider.connection.getLatestBlockhash(
|
||||
"confirmed"
|
||||
|
@ -86,13 +83,13 @@ describe("basic-5", () => {
|
|||
);
|
||||
|
||||
// Step 2 - Generate Transaction Message
|
||||
const messageV0 = new TransactionMessage({
|
||||
const messageV0 = new anchor.web3.TransactionMessage({
|
||||
payerKey: user,
|
||||
recentBlockhash: latestBlockhash.blockhash,
|
||||
instructions: txInstructions,
|
||||
}).compileToV0Message();
|
||||
console.log(" ✅ - Compiled Transaction Message");
|
||||
const transaction = new VersionedTransaction(messageV0);
|
||||
const transaction = new anchor.web3.VersionedTransaction(messageV0);
|
||||
|
||||
// Step 3 - Sign your transaction with the required `Signers`
|
||||
provider.wallet.signTransaction(transaction);
|
||||
|
@ -116,7 +113,7 @@ describe("basic-5", () => {
|
|||
);
|
||||
}
|
||||
|
||||
console.log("🎉 Transaction Succesfully Confirmed!");
|
||||
console.log("🎉 Transaction Successfully Confirmed!");
|
||||
let result = await program.account.actionState.fetch(actionState);
|
||||
console.log("Robot action state details: ", result);
|
||||
}
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
"basic-4",
|
||||
"basic-5"
|
||||
],
|
||||
"dependencies": {
|
||||
"@coral-xyz/anchor": "file:../../ts/packages/anchor"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^9.2.2",
|
||||
"prettier": "^2.5.1",
|
||||
|
@ -23,4 +20,4 @@
|
|||
"ts-mocha": "^10.0.0",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,161 +2,21 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/runtime@^7.12.5":
|
||||
version "7.16.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5"
|
||||
integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.17.2":
|
||||
version "7.20.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.6.tgz#facf4879bfed9b5326326273a64220f099b0fce3"
|
||||
integrity sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.11"
|
||||
|
||||
"@coral-xyz/anchor@file:../../ts/packages/anchor":
|
||||
version "0.27.0"
|
||||
dependencies:
|
||||
"@coral-xyz/borsh" "^0.27.0"
|
||||
"@solana/web3.js" "^1.68.0"
|
||||
base64-js "^1.5.1"
|
||||
bn.js "^5.1.2"
|
||||
bs58 "^4.0.1"
|
||||
buffer-layout "^1.2.2"
|
||||
camelcase "^6.3.0"
|
||||
cross-fetch "^3.1.5"
|
||||
crypto-hash "^1.3.0"
|
||||
eventemitter3 "^4.0.7"
|
||||
js-sha256 "^0.9.0"
|
||||
pako "^2.0.3"
|
||||
snake-case "^3.0.4"
|
||||
superstruct "^0.15.4"
|
||||
toml "^3.0.0"
|
||||
|
||||
"@coral-xyz/borsh@^0.27.0":
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.27.0.tgz#700c647ea5262b1488957ac7fb4e8acf72c72b63"
|
||||
integrity sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==
|
||||
dependencies:
|
||||
bn.js "^5.1.2"
|
||||
buffer-layout "^1.2.0"
|
||||
|
||||
"@noble/ed25519@^1.7.0":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.1.tgz#6899660f6fbb97798a6fbd227227c4589a454724"
|
||||
integrity sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw==
|
||||
|
||||
"@noble/hashes@^1.1.2":
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.4.tgz#2611ebf5764c1bf754da7c7794de4fb30512336d"
|
||||
integrity sha512-+PYsVPrTSqtVjatKt2A/Proukn2Yrz61OBThOCKErc5w2/r1Fh37vbDv0Eah7pyNltrmacjwTvdw3JoR+WE4TA==
|
||||
|
||||
"@noble/secp256k1@^1.6.3":
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.0.tgz#d15357f7c227e751d90aa06b05a0e5cf993ba8c1"
|
||||
integrity sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw==
|
||||
|
||||
"@solana/buffer-layout@^4.0.0":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15"
|
||||
integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==
|
||||
dependencies:
|
||||
buffer "~6.0.3"
|
||||
|
||||
"@solana/web3.js@^1.68.0":
|
||||
version "1.70.1"
|
||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.70.1.tgz#4a2df47cc32a0f67be5161e772b2ceb6512281fa"
|
||||
integrity sha512-AnaqCF1cJ3w7d0yhvLGAKAcRI+n5o+ursQihhoTe4cUh8/9d4gbT73SoHYElS7e67OtAgLmSfbcC5hcOAgdvnQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@noble/ed25519" "^1.7.0"
|
||||
"@noble/hashes" "^1.1.2"
|
||||
"@noble/secp256k1" "^1.6.3"
|
||||
"@solana/buffer-layout" "^4.0.0"
|
||||
bigint-buffer "^1.1.5"
|
||||
bn.js "^5.0.0"
|
||||
borsh "^0.7.0"
|
||||
bs58 "^4.0.1"
|
||||
buffer "6.0.1"
|
||||
fast-stable-stringify "^1.0.0"
|
||||
jayson "^3.4.4"
|
||||
node-fetch "2"
|
||||
rpc-websockets "^7.5.0"
|
||||
superstruct "^0.14.2"
|
||||
|
||||
"@types/connect@^3.4.33":
|
||||
version "3.4.35"
|
||||
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1"
|
||||
integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/express-serve-static-core@^4.17.9":
|
||||
version "4.17.25"
|
||||
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.25.tgz#e42f7046adc65ece2eb6059b77aecfbe9e9f82e0"
|
||||
integrity sha512-OUJIVfRMFijZukGGwTpKNFprqCCXk5WjNGvUgB/CxxBR40QWSjsNK86+yvGKlCOGc7sbwfHLaXhkG+NsytwBaQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
"@types/qs" "*"
|
||||
"@types/range-parser" "*"
|
||||
|
||||
"@types/json5@^0.0.29":
|
||||
version "0.0.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
|
||||
|
||||
"@types/lodash@^4.14.159":
|
||||
version "4.14.176"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.176.tgz#641150fc1cda36fbfa329de603bbb175d7ee20c0"
|
||||
integrity sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==
|
||||
|
||||
"@types/mocha@^9.1.1":
|
||||
version "9.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4"
|
||||
integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==
|
||||
|
||||
"@types/node@*":
|
||||
version "16.11.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.7.tgz#36820945061326978c42a01e56b61cd223dfdc42"
|
||||
integrity sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==
|
||||
|
||||
"@types/node@^12.12.54":
|
||||
version "12.20.37"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.37.tgz#abb38afa9d6e8a2f627a8cb52290b3c80fbe61ed"
|
||||
integrity sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==
|
||||
|
||||
"@types/qs@*":
|
||||
version "6.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
|
||||
integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==
|
||||
|
||||
"@types/range-parser@*":
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
|
||||
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
|
||||
|
||||
"@types/ws@^7.4.4":
|
||||
version "7.4.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702"
|
||||
integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@ungap/promise-all-settled@1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
|
||||
integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
|
||||
|
||||
JSONStream@^1.3.5:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
|
||||
integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==
|
||||
dependencies:
|
||||
jsonparse "^1.2.0"
|
||||
through ">=2.2.7 <3"
|
||||
|
||||
ansi-colors@4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
|
||||
|
@ -197,56 +57,11 @@ balanced-match@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
base-x@^3.0.2:
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320"
|
||||
integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
base64-js@^1.3.1, base64-js@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
bigint-buffer@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442"
|
||||
integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==
|
||||
dependencies:
|
||||
bindings "^1.3.0"
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||
|
||||
bindings@^1.3.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
|
||||
integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
|
||||
dependencies:
|
||||
file-uri-to-path "1.0.0"
|
||||
|
||||
bn.js@^5.0.0, bn.js@^5.1.2:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002"
|
||||
integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==
|
||||
|
||||
bn.js@^5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
|
||||
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
|
||||
|
||||
borsh@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a"
|
||||
integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==
|
||||
dependencies:
|
||||
bn.js "^5.2.0"
|
||||
bs58 "^4.0.0"
|
||||
text-encoding-utf-8 "^1.0.2"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
|
@ -267,56 +82,16 @@ browser-stdout@1.3.1:
|
|||
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
|
||||
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
|
||||
|
||||
bs58@^4.0.0, bs58@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
|
||||
integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo=
|
||||
dependencies:
|
||||
base-x "^3.0.2"
|
||||
|
||||
buffer-from@^1.0.0, buffer-from@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||
|
||||
buffer-layout@^1.2.0, buffer-layout@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5"
|
||||
integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==
|
||||
|
||||
buffer@6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2"
|
||||
integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==
|
||||
dependencies:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.2.1"
|
||||
|
||||
buffer@~6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
|
||||
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
|
||||
dependencies:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.2.1"
|
||||
|
||||
bufferutil@^4.0.1:
|
||||
version "4.0.5"
|
||||
resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.5.tgz#da9ea8166911cc276bf677b8aed2d02d31f59028"
|
||||
integrity sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==
|
||||
dependencies:
|
||||
node-gyp-build "^4.3.0"
|
||||
|
||||
camelcase@^6.0.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
|
||||
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
|
||||
|
||||
camelcase@^6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
|
||||
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
|
||||
|
||||
chalk@^4.1.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
|
@ -361,28 +136,11 @@ color-name@~1.1.4:
|
|||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
commander@^2.20.3:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
cross-fetch@^3.1.5:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
|
||||
integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
|
||||
dependencies:
|
||||
node-fetch "2.6.7"
|
||||
|
||||
crypto-hash@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/crypto-hash/-/crypto-hash-1.3.0.tgz#b402cb08f4529e9f4f09346c3e275942f845e247"
|
||||
integrity sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==
|
||||
|
||||
debug@4.3.3:
|
||||
version "4.3.3"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
|
||||
|
@ -395,11 +153,6 @@ decamelize@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
|
||||
integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
|
||||
|
||||
delay@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d"
|
||||
integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==
|
||||
|
||||
diff@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
|
||||
|
@ -410,31 +163,11 @@ diff@^3.1.0:
|
|||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
||||
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
|
||||
|
||||
dot-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
|
||||
integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==
|
||||
dependencies:
|
||||
no-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||
|
||||
es6-promise@^4.0.3:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||
|
||||
es6-promisify@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
|
||||
integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
|
||||
dependencies:
|
||||
es6-promise "^4.0.3"
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
|
@ -445,26 +178,6 @@ escape-string-regexp@4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
eventemitter3@^4.0.7:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||
|
||||
eyes@^0.1.8:
|
||||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
|
||||
integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=
|
||||
|
||||
fast-stable-stringify@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313"
|
||||
integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
|
@ -534,11 +247,6 @@ he@1.2.0:
|
|||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
ieee754@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
|
@ -596,37 +304,6 @@ isexe@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
isomorphic-ws@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc"
|
||||
integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==
|
||||
|
||||
jayson@^3.4.4:
|
||||
version "3.6.5"
|
||||
resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.6.5.tgz#e560bcad4daf098c7391f46ba8efc9d6f34a4102"
|
||||
integrity sha512-wmOjX+eQcnCDyPF4KORomaIj9wj3h0B5VEbeD0+2VHfTfErB+h1zpR7oBkgCZp36AFjp3+a4CLz6U72BYpFHAw==
|
||||
dependencies:
|
||||
"@types/connect" "^3.4.33"
|
||||
"@types/express-serve-static-core" "^4.17.9"
|
||||
"@types/lodash" "^4.14.159"
|
||||
"@types/node" "^12.12.54"
|
||||
"@types/ws" "^7.4.4"
|
||||
JSONStream "^1.3.5"
|
||||
commander "^2.20.3"
|
||||
delay "^5.0.0"
|
||||
es6-promisify "^5.0.0"
|
||||
eyes "^0.1.8"
|
||||
isomorphic-ws "^4.0.1"
|
||||
json-stringify-safe "^5.0.1"
|
||||
lodash "^4.17.20"
|
||||
uuid "^3.4.0"
|
||||
ws "^7.4.5"
|
||||
|
||||
js-sha256@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966"
|
||||
integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==
|
||||
|
||||
js-yaml@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
|
@ -634,11 +311,6 @@ js-yaml@4.1.0:
|
|||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
json-stringify-safe@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
|
||||
json5@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
|
||||
|
@ -646,11 +318,6 @@ json5@^1.0.2:
|
|||
dependencies:
|
||||
minimist "^1.2.0"
|
||||
|
||||
jsonparse@^1.2.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
|
||||
integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
|
||||
|
||||
locate-path@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
|
||||
|
@ -658,11 +325,6 @@ locate-path@^6.0.0:
|
|||
dependencies:
|
||||
p-locate "^5.0.0"
|
||||
|
||||
lodash@^4.17.20:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
log-symbols@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
|
||||
|
@ -671,13 +333,6 @@ log-symbols@4.1.0:
|
|||
chalk "^4.1.0"
|
||||
is-unicode-supported "^0.1.0"
|
||||
|
||||
lower-case@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
|
||||
integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
make-error@^1.1.1:
|
||||
version "1.3.6"
|
||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||
|
@ -754,26 +409,6 @@ nanoid@3.3.1:
|
|||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35"
|
||||
integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
|
||||
|
||||
no-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
|
||||
integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==
|
||||
dependencies:
|
||||
lower-case "^2.0.2"
|
||||
tslib "^2.0.3"
|
||||
|
||||
node-fetch@2, node-fetch@2.6.7:
|
||||
version "2.6.7"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
||||
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-gyp-build@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3"
|
||||
integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==
|
||||
|
||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
|
@ -800,11 +435,6 @@ p-locate@^5.0.0:
|
|||
dependencies:
|
||||
p-limit "^3.0.2"
|
||||
|
||||
pako@^2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d"
|
||||
integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg==
|
||||
|
||||
path-exists@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||
|
@ -839,35 +469,12 @@ readdirp@~3.6.0:
|
|||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
regenerator-runtime@^0.13.11:
|
||||
version "0.13.11"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
|
||||
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
|
||||
|
||||
regenerator-runtime@^0.13.4:
|
||||
version "0.13.9"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
|
||||
rpc-websockets@^7.5.0:
|
||||
version "7.5.0"
|
||||
resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.0.tgz#bbeb87572e66703ff151e50af1658f98098e2748"
|
||||
integrity sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
eventemitter3 "^4.0.7"
|
||||
uuid "^8.3.2"
|
||||
ws "^8.5.0"
|
||||
optionalDependencies:
|
||||
bufferutil "^4.0.1"
|
||||
utf-8-validate "^5.0.2"
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.0:
|
||||
safe-buffer@^5.1.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
@ -879,14 +486,6 @@ serialize-javascript@6.0.0:
|
|||
dependencies:
|
||||
randombytes "^2.1.0"
|
||||
|
||||
snake-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c"
|
||||
integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==
|
||||
dependencies:
|
||||
dot-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
source-map-support@^0.5.6:
|
||||
version "0.5.21"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
|
||||
|
@ -926,16 +525,6 @@ strip-json-comments@3.1.1:
|
|||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
||||
superstruct@^0.14.2:
|
||||
version "0.14.2"
|
||||
resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b"
|
||||
integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==
|
||||
|
||||
superstruct@^0.15.4:
|
||||
version "0.15.5"
|
||||
resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.15.5.tgz#0f0a8d3ce31313f0d84c6096cd4fa1bfdedc9dab"
|
||||
integrity sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==
|
||||
|
||||
supports-color@8.1.1:
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
|
||||
|
@ -950,16 +539,6 @@ supports-color@^7.1.0:
|
|||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
text-encoding-utf-8@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13"
|
||||
integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==
|
||||
|
||||
"through@>=2.2.7 <3":
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
|
@ -967,16 +546,6 @@ to-regex-range@^5.0.1:
|
|||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
toml@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee"
|
||||
integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==
|
||||
|
||||
tr46@~0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
||||
|
||||
ts-mocha@^10.0.0:
|
||||
version "10.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9"
|
||||
|
@ -1010,46 +579,11 @@ tsconfig-paths@^3.5.0:
|
|||
minimist "^1.2.6"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
tslib@^2.0.3:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
||||
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
||||
|
||||
typescript@^4.9.5:
|
||||
version "4.9.5"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
|
||||
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
|
||||
|
||||
utf-8-validate@^5.0.2:
|
||||
version "5.0.7"
|
||||
resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.7.tgz#c15a19a6af1f7ad9ec7ddc425747ca28c3644922"
|
||||
integrity sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==
|
||||
dependencies:
|
||||
node-gyp-build "^4.3.0"
|
||||
|
||||
uuid@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
|
||||
uuid@^8.3.2:
|
||||
version "8.3.2"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
||||
webidl-conversions@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
|
||||
|
||||
whatwg-url@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
|
||||
dependencies:
|
||||
tr46 "~0.0.3"
|
||||
webidl-conversions "^3.0.0"
|
||||
|
||||
which@2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||
|
@ -1076,16 +610,6 @@ wrappy@1:
|
|||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
ws@^7.4.5:
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881"
|
||||
integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==
|
||||
|
||||
ws@^8.5.0:
|
||||
version "8.11.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143"
|
||||
integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
[package]
|
||||
name = "anchor-lang-idl"
|
||||
version = "0.1.0"
|
||||
authors = ["Anchor Maintainers <accounts@200ms.io>"]
|
||||
repository = "https://github.com/coral-xyz/anchor"
|
||||
rust-version = "1.60"
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
description = "Anchor framework IDL"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
build = ["anchor-syn", "regex"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
# `build` feature only
|
||||
anchor-syn = { path = "../lang/syn", version = "0.30.0", optional = true }
|
||||
regex = { version = "1", optional = true }
|
|
@ -0,0 +1,275 @@
|
|||
use std::{
|
||||
collections::BTreeMap,
|
||||
env, mem,
|
||||
path::Path,
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
use anchor_syn::parser::context::CrateContext;
|
||||
use anyhow::{anyhow, Result};
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::types::{Idl, IdlEvent, IdlTypeDef};
|
||||
|
||||
/// A trait that types must implement in order to include the type in the IDL definition.
|
||||
///
|
||||
/// This trait is automatically implemented for Anchor all types that use the `AnchorSerialize`
|
||||
/// proc macro. Note that manually implementing the `AnchorSerialize` trait does **NOT** have the
|
||||
/// same effect.
|
||||
///
|
||||
/// Types that don't implement this trait will cause a compile error during the IDL generation.
|
||||
///
|
||||
/// The default implementation of the trait allows the program to compile but the type does **NOT**
|
||||
/// get included in the IDL.
|
||||
pub trait IdlBuild {
|
||||
/// Create an IDL type definition for the type.
|
||||
///
|
||||
/// The type is only included in the IDL if this method returns `Some`.
|
||||
fn create_type() -> Option<IdlTypeDef> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Insert all types that are included in the current type definition to the given map.
|
||||
fn insert_types(_types: &mut BTreeMap<String, IdlTypeDef>) {}
|
||||
|
||||
/// Get the full module path of the type.
|
||||
///
|
||||
/// The full path will be used in the case of a conflicting type definition, e.g. when there
|
||||
/// are multiple structs with the same name.
|
||||
///
|
||||
/// The default implementation covers most cases.
|
||||
fn get_full_path() -> String {
|
||||
std::any::type_name::<Self>().into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate IDL via compilation.
|
||||
pub fn build_idl(
|
||||
program_path: impl AsRef<Path>,
|
||||
resolution: bool,
|
||||
skip_lint: bool,
|
||||
no_docs: bool,
|
||||
) -> Result<Idl> {
|
||||
// Check safety comments
|
||||
let program_path = program_path.as_ref();
|
||||
let lib_path = program_path.join("src").join("lib.rs");
|
||||
let ctx = CrateContext::parse(lib_path)?;
|
||||
if !skip_lint {
|
||||
ctx.safety_checks()?;
|
||||
}
|
||||
|
||||
let idl = build(program_path, resolution, no_docs)?;
|
||||
let idl = convert_module_paths(idl);
|
||||
let idl = sort(idl);
|
||||
verify(&idl)?;
|
||||
|
||||
Ok(idl)
|
||||
}
|
||||
|
||||
/// Build IDL.
|
||||
fn build(program_path: &Path, resolution: bool, no_docs: bool) -> Result<Idl> {
|
||||
// `nightly` toolchain is currently required for building the IDL.
|
||||
const TOOLCHAIN: &str = "+nightly";
|
||||
install_toolchain_if_needed(TOOLCHAIN)?;
|
||||
|
||||
let output = Command::new("cargo")
|
||||
.args([
|
||||
TOOLCHAIN,
|
||||
"test",
|
||||
"__anchor_private_print_idl",
|
||||
"--features",
|
||||
"idl-build",
|
||||
"--",
|
||||
"--show-output",
|
||||
"--quiet",
|
||||
])
|
||||
.env(
|
||||
"ANCHOR_IDL_BUILD_NO_DOCS",
|
||||
if no_docs { "TRUE" } else { "FALSE" },
|
||||
)
|
||||
.env(
|
||||
"ANCHOR_IDL_BUILD_RESOLUTION",
|
||||
if resolution { "TRUE" } else { "FALSE" },
|
||||
)
|
||||
.env("RUSTFLAGS", "--cfg procmacro2_semver_exempt")
|
||||
.current_dir(program_path)
|
||||
.stderr(Stdio::inherit())
|
||||
.output()?;
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!("Building IDL failed"));
|
||||
}
|
||||
|
||||
enum State {
|
||||
Pass,
|
||||
Address,
|
||||
Constants(Vec<String>),
|
||||
Events(Vec<String>),
|
||||
Errors(Vec<String>),
|
||||
Program(Vec<String>),
|
||||
}
|
||||
|
||||
let mut address = String::new();
|
||||
let mut events = vec![];
|
||||
let mut error_codes = vec![];
|
||||
let mut constants = vec![];
|
||||
let mut types = BTreeMap::new();
|
||||
let mut idl: Option<Idl> = None;
|
||||
|
||||
let output = String::from_utf8_lossy(&output.stdout);
|
||||
if env::var("ANCHOR_LOG").is_ok() {
|
||||
println!("{}", output);
|
||||
}
|
||||
|
||||
let mut state = State::Pass;
|
||||
for line in output.lines() {
|
||||
match &mut state {
|
||||
State::Pass => match line {
|
||||
"--- IDL begin address ---" => state = State::Address,
|
||||
"--- IDL begin const ---" => state = State::Constants(vec![]),
|
||||
"--- IDL begin event ---" => state = State::Events(vec![]),
|
||||
"--- IDL begin errors ---" => state = State::Errors(vec![]),
|
||||
"--- IDL begin program ---" => state = State::Program(vec![]),
|
||||
_ => {
|
||||
if line.starts_with("test result: ok") {
|
||||
if let Some(idl) = idl.as_mut() {
|
||||
idl.address = mem::take(&mut address);
|
||||
idl.constants = mem::take(&mut constants);
|
||||
idl.events = mem::take(&mut events);
|
||||
idl.errors = mem::take(&mut error_codes);
|
||||
idl.types = {
|
||||
let prog_ty = mem::take(&mut idl.types);
|
||||
let mut types = mem::take(&mut types);
|
||||
types.extend(prog_ty.into_iter().map(|ty| (ty.name.clone(), ty)));
|
||||
types.into_values().collect()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
State::Address => {
|
||||
address = line.replace(|c: char| !c.is_alphanumeric(), "");
|
||||
state = State::Pass;
|
||||
continue;
|
||||
}
|
||||
State::Constants(lines) => {
|
||||
if line == "--- IDL end const ---" {
|
||||
let constant = serde_json::from_str(&lines.join("\n"))?;
|
||||
constants.push(constant);
|
||||
state = State::Pass;
|
||||
continue;
|
||||
}
|
||||
|
||||
lines.push(line.to_owned());
|
||||
}
|
||||
State::Events(lines) => {
|
||||
if line == "--- IDL end event ---" {
|
||||
#[derive(Deserialize)]
|
||||
struct IdlBuildEventPrint {
|
||||
event: IdlEvent,
|
||||
types: Vec<IdlTypeDef>,
|
||||
}
|
||||
|
||||
let event = serde_json::from_str::<IdlBuildEventPrint>(&lines.join("\n"))?;
|
||||
events.push(event.event);
|
||||
types.extend(event.types.into_iter().map(|ty| (ty.name.clone(), ty)));
|
||||
state = State::Pass;
|
||||
continue;
|
||||
}
|
||||
|
||||
lines.push(line.to_owned());
|
||||
}
|
||||
State::Errors(lines) => {
|
||||
if line == "--- IDL end errors ---" {
|
||||
error_codes = serde_json::from_str(&lines.join("\n"))?;
|
||||
state = State::Pass;
|
||||
continue;
|
||||
}
|
||||
|
||||
lines.push(line.to_owned());
|
||||
}
|
||||
State::Program(lines) => {
|
||||
if line == "--- IDL end program ---" {
|
||||
idl = Some(serde_json::from_str(&lines.join("\n"))?);
|
||||
state = State::Pass;
|
||||
continue;
|
||||
}
|
||||
|
||||
lines.push(line.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
idl.ok_or_else(|| anyhow!("IDL doesn't exist"))
|
||||
}
|
||||
|
||||
/// Install the given toolchain if it's not already installed.
|
||||
fn install_toolchain_if_needed(toolchain: &str) -> Result<()> {
|
||||
let is_installed = Command::new("cargo")
|
||||
.arg(toolchain)
|
||||
.output()?
|
||||
.status
|
||||
.success();
|
||||
if !is_installed {
|
||||
Command::new("rustup")
|
||||
.args(["toolchain", "install", toolchain.trim_start_matches('+')])
|
||||
.spawn()?
|
||||
.wait()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Convert paths to name if there are no conflicts.
|
||||
fn convert_module_paths(idl: Idl) -> Idl {
|
||||
let idl = serde_json::to_string(&idl).unwrap();
|
||||
let idl = Regex::new(r#""((\w+::)+)(\w+)""#)
|
||||
.unwrap()
|
||||
.captures_iter(&idl.clone())
|
||||
.fold(idl, |acc, cur| {
|
||||
let path = cur.get(0).unwrap().as_str();
|
||||
let name = cur.get(3).unwrap().as_str();
|
||||
|
||||
// Replace path with name
|
||||
let replaced_idl = acc.replace(path, &format!(r#""{name}""#));
|
||||
|
||||
// Check whether there is a conflict
|
||||
let has_conflict = replaced_idl.contains(&format!(r#"::{name}""#));
|
||||
if has_conflict {
|
||||
acc
|
||||
} else {
|
||||
replaced_idl
|
||||
}
|
||||
});
|
||||
|
||||
serde_json::from_str(&idl).expect("Invalid IDL")
|
||||
}
|
||||
|
||||
/// Alphabetically sort fields for consistency.
|
||||
fn sort(mut idl: Idl) -> Idl {
|
||||
idl.accounts.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
idl.constants.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
idl.events.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
idl.instructions.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
idl.types.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
|
||||
idl
|
||||
}
|
||||
|
||||
/// Verify IDL is valid.
|
||||
fn verify(idl: &Idl) -> Result<()> {
|
||||
// Check full path accounts
|
||||
if let Some(account) = idl
|
||||
.accounts
|
||||
.iter()
|
||||
.find(|account| account.name.contains("::"))
|
||||
{
|
||||
return Err(anyhow!(
|
||||
"Conflicting accounts names are not allowed.\nProgram: `{}`\nAccount: `{}`",
|
||||
idl.metadata.name,
|
||||
account.name
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
//! Anchor IDL.
|
||||
|
||||
pub mod types;
|
||||
|
||||
#[cfg(feature = "build")]
|
||||
pub mod build;
|
||||
|
||||
#[cfg(feature = "build")]
|
||||
pub use serde_json;
|
|
@ -0,0 +1,501 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// IDL specification Semantic Version
|
||||
pub const IDL_SPEC: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct Idl {
|
||||
pub address: String,
|
||||
pub metadata: IdlMetadata,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub docs: Vec<String>,
|
||||
pub instructions: Vec<IdlInstruction>,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub accounts: Vec<IdlAccount>,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub events: Vec<IdlEvent>,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub errors: Vec<IdlErrorCode>,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub types: Vec<IdlTypeDef>,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub constants: Vec<IdlConst>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlMetadata {
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
pub spec: String,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub description: Option<String>,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub repository: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub dependencies: Vec<IdlDependency>,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub contact: Option<String>,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub deployments: Option<IdlDeployments>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlDependency {
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlDeployments {
|
||||
pub mainnet: Option<String>,
|
||||
pub testnet: Option<String>,
|
||||
pub devnet: Option<String>,
|
||||
pub localnet: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlInstruction {
|
||||
pub name: String,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub docs: Vec<String>,
|
||||
pub discriminator: IdlDiscriminator,
|
||||
pub accounts: Vec<IdlInstructionAccountItem>,
|
||||
pub args: Vec<IdlField>,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub returns: Option<IdlType>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(untagged)]
|
||||
pub enum IdlInstructionAccountItem {
|
||||
Composite(IdlInstructionAccounts),
|
||||
Single(IdlInstructionAccount),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlInstructionAccount {
|
||||
pub name: String,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub docs: Vec<String>,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub writable: bool,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub signer: bool,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub optional: bool,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub address: Option<String>,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub pda: Option<IdlPda>,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub relations: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlInstructionAccounts {
|
||||
pub name: String,
|
||||
pub accounts: Vec<IdlInstructionAccountItem>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlPda {
|
||||
pub seeds: Vec<IdlSeed>,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub program: Option<IdlSeed>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(tag = "kind", rename_all = "lowercase")]
|
||||
pub enum IdlSeed {
|
||||
Const(IdlSeedConst),
|
||||
Arg(IdlSeedArg),
|
||||
Account(IdlSeedAccount),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlSeedConst {
|
||||
pub value: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlSeedArg {
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlSeedAccount {
|
||||
pub path: String,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub account: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlAccount {
|
||||
pub name: String,
|
||||
pub discriminator: IdlDiscriminator,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlEvent {
|
||||
pub name: String,
|
||||
pub discriminator: IdlDiscriminator,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlConst {
|
||||
pub name: String,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub docs: Vec<String>,
|
||||
#[serde(rename = "type")]
|
||||
pub ty: IdlType,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct IdlErrorCode {
|
||||
pub code: u32,
|
||||
pub name: String,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub msg: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlField {
|
||||
pub name: String,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub docs: Vec<String>,
|
||||
#[serde(rename = "type")]
|
||||
pub ty: IdlType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlTypeDef {
|
||||
pub name: String,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub docs: Vec<String>,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub serialization: IdlSerialization,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub repr: Option<IdlRepr>,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub generics: Vec<IdlTypeDefGeneric>,
|
||||
#[serde(rename = "type")]
|
||||
pub ty: IdlTypeDefTy,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[non_exhaustive]
|
||||
pub enum IdlSerialization {
|
||||
#[default]
|
||||
Borsh,
|
||||
Bytemuck,
|
||||
BytemuckUnsafe,
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(tag = "kind", rename_all = "lowercase")]
|
||||
#[non_exhaustive]
|
||||
pub enum IdlRepr {
|
||||
Rust(IdlReprModifier),
|
||||
C(IdlReprModifier),
|
||||
Transparent,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlReprModifier {
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
pub packed: bool,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub align: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(tag = "kind", rename_all = "lowercase")]
|
||||
pub enum IdlTypeDefGeneric {
|
||||
Type {
|
||||
name: String,
|
||||
},
|
||||
Const {
|
||||
name: String,
|
||||
#[serde(rename = "type")]
|
||||
ty: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(tag = "kind", rename_all = "lowercase")]
|
||||
pub enum IdlTypeDefTy {
|
||||
Struct {
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
fields: Option<IdlDefinedFields>,
|
||||
},
|
||||
Enum {
|
||||
variants: Vec<IdlEnumVariant>,
|
||||
},
|
||||
Type {
|
||||
alias: IdlType,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IdlEnumVariant {
|
||||
pub name: String,
|
||||
#[serde(skip_serializing_if = "is_default")]
|
||||
pub fields: Option<IdlDefinedFields>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(untagged)]
|
||||
pub enum IdlDefinedFields {
|
||||
Named(Vec<IdlField>),
|
||||
Tuple(Vec<IdlType>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum IdlArrayLen {
|
||||
Generic(String),
|
||||
#[serde(untagged)]
|
||||
Value(usize),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(tag = "kind", rename_all = "lowercase")]
|
||||
pub enum IdlGenericArg {
|
||||
Type {
|
||||
#[serde(rename = "type")]
|
||||
ty: IdlType,
|
||||
},
|
||||
Const {
|
||||
value: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[non_exhaustive]
|
||||
pub enum IdlType {
|
||||
Bool,
|
||||
U8,
|
||||
I8,
|
||||
U16,
|
||||
I16,
|
||||
U32,
|
||||
I32,
|
||||
F32,
|
||||
U64,
|
||||
I64,
|
||||
F64,
|
||||
U128,
|
||||
I128,
|
||||
U256,
|
||||
I256,
|
||||
Bytes,
|
||||
String,
|
||||
Pubkey,
|
||||
Option(Box<IdlType>),
|
||||
Vec(Box<IdlType>),
|
||||
Array(Box<IdlType>, IdlArrayLen),
|
||||
Defined {
|
||||
name: String,
|
||||
#[serde(default, skip_serializing_if = "is_default")]
|
||||
generics: Vec<IdlGenericArg>,
|
||||
},
|
||||
Generic(String),
|
||||
}
|
||||
|
||||
impl FromStr for IdlType {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut s = s.to_owned();
|
||||
s.retain(|c| !c.is_whitespace());
|
||||
|
||||
let r = match s.as_str() {
|
||||
"bool" => IdlType::Bool,
|
||||
"u8" => IdlType::U8,
|
||||
"i8" => IdlType::I8,
|
||||
"u16" => IdlType::U16,
|
||||
"i16" => IdlType::I16,
|
||||
"u32" => IdlType::U32,
|
||||
"i32" => IdlType::I32,
|
||||
"f32" => IdlType::F32,
|
||||
"u64" => IdlType::U64,
|
||||
"i64" => IdlType::I64,
|
||||
"f64" => IdlType::F64,
|
||||
"u128" => IdlType::U128,
|
||||
"i128" => IdlType::I128,
|
||||
"u256" => IdlType::U256,
|
||||
"i256" => IdlType::I256,
|
||||
"Vec<u8>" => IdlType::Bytes,
|
||||
"String" | "&str" | "&'staticstr" => IdlType::String,
|
||||
"Pubkey" => IdlType::Pubkey,
|
||||
_ => {
|
||||
if let Some(inner) = s.strip_prefix("Option<") {
|
||||
let inner_ty = Self::from_str(
|
||||
inner
|
||||
.strip_suffix('>')
|
||||
.ok_or_else(|| anyhow!("Invalid Option"))?,
|
||||
)?;
|
||||
return Ok(IdlType::Option(Box::new(inner_ty)));
|
||||
}
|
||||
|
||||
if let Some(inner) = s.strip_prefix("Vec<") {
|
||||
let inner_ty = Self::from_str(
|
||||
inner
|
||||
.strip_suffix('>')
|
||||
.ok_or_else(|| anyhow!("Invalid Vec"))?,
|
||||
)?;
|
||||
return Ok(IdlType::Vec(Box::new(inner_ty)));
|
||||
}
|
||||
|
||||
if s.starts_with('[') {
|
||||
fn array_from_str(inner: &str) -> IdlType {
|
||||
match inner.strip_suffix(']') {
|
||||
Some(nested_inner) => array_from_str(&nested_inner[1..]),
|
||||
None => {
|
||||
let (raw_type, raw_length) = inner.rsplit_once(';').unwrap();
|
||||
let ty = IdlType::from_str(raw_type).unwrap();
|
||||
let len = match raw_length.replace('_', "").parse::<usize>() {
|
||||
Ok(len) => IdlArrayLen::Value(len),
|
||||
Err(_) => IdlArrayLen::Generic(raw_length.to_owned()),
|
||||
};
|
||||
IdlType::Array(Box::new(ty), len)
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ok(array_from_str(&s));
|
||||
}
|
||||
|
||||
// Defined
|
||||
let (name, generics) = if let Some(i) = s.find('<') {
|
||||
(
|
||||
s.get(..i).unwrap().to_owned(),
|
||||
s.get(i + 1..)
|
||||
.unwrap()
|
||||
.strip_suffix('>')
|
||||
.unwrap()
|
||||
.split(',')
|
||||
.map(|g| g.trim().to_owned())
|
||||
.map(|g| {
|
||||
if g.parse::<bool>().is_ok()
|
||||
|| g.parse::<u128>().is_ok()
|
||||
|| g.parse::<i128>().is_ok()
|
||||
|| g.parse::<char>().is_ok()
|
||||
{
|
||||
Ok(IdlGenericArg::Const { value: g })
|
||||
} else {
|
||||
Self::from_str(&g).map(|ty| IdlGenericArg::Type { ty })
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
)
|
||||
} else {
|
||||
(s.to_owned(), vec![])
|
||||
};
|
||||
|
||||
IdlType::Defined { name, generics }
|
||||
}
|
||||
};
|
||||
Ok(r)
|
||||
}
|
||||
}
|
||||
|
||||
pub type IdlDiscriminator = Vec<u8>;
|
||||
|
||||
/// Get whether the given data is the default of its type.
|
||||
fn is_default<T: Default + PartialEq>(it: &T) -> bool {
|
||||
*it == T::default()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn option() {
|
||||
assert_eq!(
|
||||
IdlType::from_str("Option<bool>").unwrap(),
|
||||
IdlType::Option(Box::new(IdlType::Bool))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector() {
|
||||
assert_eq!(
|
||||
IdlType::from_str("Vec<bool>").unwrap(),
|
||||
IdlType::Vec(Box::new(IdlType::Bool))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array() {
|
||||
assert_eq!(
|
||||
IdlType::from_str("[Pubkey; 16]").unwrap(),
|
||||
IdlType::Array(Box::new(IdlType::Pubkey), IdlArrayLen::Value(16))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array_with_underscored_length() {
|
||||
assert_eq!(
|
||||
IdlType::from_str("[u8; 50_000]").unwrap(),
|
||||
IdlType::Array(Box::new(IdlType::U8), IdlArrayLen::Value(50000))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multidimensional_array() {
|
||||
assert_eq!(
|
||||
IdlType::from_str("[[u8; 16]; 32]").unwrap(),
|
||||
IdlType::Array(
|
||||
Box::new(IdlType::Array(
|
||||
Box::new(IdlType::U8),
|
||||
IdlArrayLen::Value(16)
|
||||
)),
|
||||
IdlArrayLen::Value(32)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generic_array() {
|
||||
assert_eq!(
|
||||
IdlType::from_str("[u64; T]").unwrap(),
|
||||
IdlType::Array(Box::new(IdlType::U64), IdlArrayLen::Generic("T".into()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defined() {
|
||||
assert_eq!(
|
||||
IdlType::from_str("MyStruct").unwrap(),
|
||||
IdlType::Defined {
|
||||
name: "MyStruct".into(),
|
||||
generics: vec![]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn defined_with_generics() {
|
||||
assert_eq!(
|
||||
IdlType::from_str("MyStruct<Pubkey, u64, 8>").unwrap(),
|
||||
IdlType::Defined {
|
||||
name: "MyStruct".into(),
|
||||
generics: vec![
|
||||
IdlGenericArg::Type {
|
||||
ty: IdlType::Pubkey
|
||||
},
|
||||
IdlGenericArg::Type { ty: IdlType::U64 },
|
||||
IdlGenericArg::Const { value: "8".into() },
|
||||
],
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "anchor-lang"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
authors = ["Anchor Maintainers <accounts@200ms.io>"]
|
||||
repository = "https://github.com/coral-xyz/anchor"
|
||||
rust-version = "1.60"
|
||||
|
@ -8,12 +8,12 @@ edition = "2021"
|
|||
license = "Apache-2.0"
|
||||
description = "Solana Sealevel eDSL"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
allow-missing-optionals = ["anchor-derive-accounts/allow-missing-optionals"]
|
||||
init-if-needed = ["anchor-derive-accounts/init-if-needed"]
|
||||
derive = []
|
||||
default = []
|
||||
event-cpi = ["anchor-attribute-event/event-cpi"]
|
||||
anchor-debug = [
|
||||
"anchor-attribute-access-control/anchor-debug",
|
||||
"anchor-attribute-account/anchor-debug",
|
||||
|
@ -21,24 +21,43 @@ anchor-debug = [
|
|||
"anchor-attribute-error/anchor-debug",
|
||||
"anchor-attribute-event/anchor-debug",
|
||||
"anchor-attribute-program/anchor-debug",
|
||||
"anchor-attribute-program/anchor-debug",
|
||||
"anchor-derive-accounts/anchor-debug"
|
||||
]
|
||||
derive = []
|
||||
event-cpi = ["anchor-attribute-event/event-cpi"]
|
||||
idl-build = [
|
||||
"anchor-attribute-account/idl-build",
|
||||
"anchor-attribute-constant/idl-build",
|
||||
"anchor-attribute-event/idl-build",
|
||||
"anchor-attribute-error/idl-build",
|
||||
"anchor-attribute-program/idl-build",
|
||||
"anchor-derive-accounts/idl-build",
|
||||
"anchor-derive-serde/idl-build",
|
||||
"anchor-lang-idl/build",
|
||||
]
|
||||
init-if-needed = ["anchor-derive-accounts/init-if-needed"]
|
||||
interface-instructions = ["anchor-attribute-program/interface-instructions"]
|
||||
|
||||
[dependencies]
|
||||
anchor-attribute-access-control = { path = "./attribute/access-control", version = "0.27.0" }
|
||||
anchor-attribute-account = { path = "./attribute/account", version = "0.27.0" }
|
||||
anchor-attribute-constant = { path = "./attribute/constant", version = "0.27.0" }
|
||||
anchor-attribute-error = { path = "./attribute/error", version = "0.27.0" }
|
||||
anchor-attribute-event = { path = "./attribute/event", version = "0.27.0" }
|
||||
anchor-attribute-program = { path = "./attribute/program", version = "0.27.0" }
|
||||
anchor-derive-accounts = { path = "./derive/accounts", version = "0.27.0" }
|
||||
anchor-derive-space = { path = "./derive/space", version = "0.27.0" }
|
||||
arrayref = "0.3.6"
|
||||
base64 = "0.13.0"
|
||||
bincode = "1.3.3"
|
||||
borsh = "<0.11.0"
|
||||
bytemuck = "1.4.0"
|
||||
anchor-attribute-access-control = { path = "./attribute/access-control", version = "0.30.0" }
|
||||
anchor-attribute-account = { path = "./attribute/account", version = "0.30.0" }
|
||||
anchor-attribute-constant = { path = "./attribute/constant", version = "0.30.0" }
|
||||
anchor-attribute-error = { path = "./attribute/error", version = "0.30.0" }
|
||||
anchor-attribute-event = { path = "./attribute/event", version = "0.30.0" }
|
||||
anchor-attribute-program = { path = "./attribute/program", version = "0.30.0" }
|
||||
anchor-derive-accounts = { path = "./derive/accounts", version = "0.30.0" }
|
||||
anchor-derive-serde = { path = "./derive/serde", version = "0.30.0" }
|
||||
anchor-derive-space = { path = "./derive/space", version = "0.30.0" }
|
||||
|
||||
# `anchor-lang-idl` should only be included with `idl-build` feature
|
||||
anchor-lang-idl = { path = "../idl", version = "0.1.0", optional = true }
|
||||
|
||||
arrayref = "0.3"
|
||||
base64 = "0.21"
|
||||
bincode = "1"
|
||||
borsh = ">=0.9, <0.11"
|
||||
bytemuck = "1"
|
||||
solana-program = "1.16"
|
||||
thiserror = "1"
|
||||
# TODO: Remove. This crate has been added to fix a build error with the 1.16.0 release.
|
||||
getrandom = { version = "0.2", features = ["custom"] }
|
||||
solana-program = "<1.17.0"
|
||||
thiserror = "1.0.20"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "anchor-attribute-access-control"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
authors = ["Anchor Maintainers <accounts@200ms.io>"]
|
||||
repository = "https://github.com/coral-xyz/anchor"
|
||||
license = "Apache-2.0"
|
||||
|
@ -15,9 +15,7 @@ proc-macro = true
|
|||
anchor-debug = ["anchor-syn/anchor-debug"]
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0.60", features = ["full"] }
|
||||
anyhow = "1.0.32"
|
||||
anchor-syn = { path = "../../syn", version = "0.27.0" }
|
||||
regex = "1.0"
|
||||
anchor-syn = { path = "../../syn", version = "0.30.0" }
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = { version = "1", features = ["full"] }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "anchor-attribute-account"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
authors = ["Anchor Maintainers <accounts@200ms.io>"]
|
||||
repository = "https://github.com/coral-xyz/anchor"
|
||||
license = "Apache-2.0"
|
||||
|
@ -13,12 +13,11 @@ proc-macro = true
|
|||
|
||||
[features]
|
||||
anchor-debug = ["anchor-syn/anchor-debug"]
|
||||
idl-build = ["anchor-syn/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0.60", features = ["full"] }
|
||||
anyhow = "1.0.32"
|
||||
anchor-syn = { path = "../../syn", version = "0.27.0", features = ["hash"] }
|
||||
rustversion = "1.0.3"
|
||||
bs58 = "0.4.0"
|
||||
anchor-syn = { path = "../../syn", version = "0.30.0", features = ["hash"] }
|
||||
bs58 = "0.5"
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = { version = "1", features = ["full"] }
|
||||
|
|
|
@ -10,7 +10,6 @@ extern crate proc_macro;
|
|||
|
||||
use proc_macro2::{Delimiter, Span, TokenTree};
|
||||
use quote::{quote, ToTokens};
|
||||
use std::convert::TryFrom;
|
||||
use syn::{
|
||||
bracketed,
|
||||
parse::{Parse, ParseStream, Result},
|
||||
|
|
|
@ -392,19 +392,57 @@ pub fn zero_copy(
|
|||
quote! {#[derive(::bytemuck::Zeroable)]}
|
||||
};
|
||||
|
||||
proc_macro::TokenStream::from(quote! {
|
||||
let ret = quote! {
|
||||
#[derive(anchor_lang::__private::ZeroCopyAccessor, Copy, Clone)]
|
||||
#repr
|
||||
#pod
|
||||
#zeroable
|
||||
#account_strct
|
||||
})
|
||||
};
|
||||
|
||||
#[cfg(feature = "idl-build")]
|
||||
{
|
||||
let derive_unsafe = if is_unsafe {
|
||||
// Not a real proc-macro but exists in order to pass the serialization info
|
||||
quote! { #[derive(bytemuck::Unsafe)] }
|
||||
} else {
|
||||
quote! {}
|
||||
};
|
||||
let zc_struct = syn::parse2(quote! {
|
||||
#derive_unsafe
|
||||
#ret
|
||||
})
|
||||
.unwrap();
|
||||
let idl_build_impl = anchor_syn::idl::impl_idl_build_struct(&zc_struct);
|
||||
return proc_macro::TokenStream::from(quote! {
|
||||
#ret
|
||||
#idl_build_impl
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
proc_macro::TokenStream::from(ret)
|
||||
}
|
||||
|
||||
/// Defines the program's ID. This should be used at the root of all Anchor
|
||||
/// based programs.
|
||||
#[proc_macro]
|
||||
pub fn declare_id(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
#[cfg(feature = "idl-build")]
|
||||
let address = input.clone().to_string();
|
||||
|
||||
let id = parse_macro_input!(input as id::Id);
|
||||
proc_macro::TokenStream::from(quote! {#id})
|
||||
let ret = quote! { #id };
|
||||
|
||||
#[cfg(feature = "idl-build")]
|
||||
{
|
||||
let idl_print = anchor_syn::idl::gen_idl_print_fn_address(address);
|
||||
return proc_macro::TokenStream::from(quote! {
|
||||
#ret
|
||||
#idl_print
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
proc_macro::TokenStream::from(ret)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "anchor-attribute-constant"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
authors = ["Anchor Maintainers <accounts@200ms.io>"]
|
||||
repository = "https://github.com/coral-xyz/anchor"
|
||||
license = "Apache-2.0"
|
||||
|
@ -13,8 +13,9 @@ proc-macro = true
|
|||
|
||||
[features]
|
||||
anchor-debug = ["anchor-syn/anchor-debug"]
|
||||
idl-build = ["anchor-syn/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
syn = { version = "1.0.60", features = ["full"] }
|
||||
anchor-syn = { path = "../../syn", version = "0.27.0" }
|
||||
anchor-syn = { path = "../../syn", version = "0.30.0" }
|
||||
quote = "1"
|
||||
syn = { version = "1", features = ["full"] }
|
||||
|
|
|
@ -7,5 +7,26 @@ pub fn constant(
|
|||
_attr: proc_macro::TokenStream,
|
||||
input: proc_macro::TokenStream,
|
||||
) -> proc_macro::TokenStream {
|
||||
#[cfg(feature = "idl-build")]
|
||||
{
|
||||
use quote::quote;
|
||||
|
||||
let ts = match syn::parse(input).unwrap() {
|
||||
syn::Item::Const(item) => {
|
||||
let idl_print = anchor_syn::idl::gen_idl_print_fn_constant(&item);
|
||||
quote! {
|
||||
#item
|
||||
#idl_print
|
||||
}
|
||||
}
|
||||
item => quote! {#item},
|
||||
};
|
||||
|
||||
return proc_macro::TokenStream::from(quote! {
|
||||
#ts
|
||||
});
|
||||
};
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
input
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "anchor-attribute-error"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
authors = ["Anchor Maintainers <accounts@200ms.io>"]
|
||||
repository = "https://github.com/coral-xyz/anchor"
|
||||
license = "Apache-2.0"
|
||||
|
@ -13,9 +13,9 @@ proc-macro = true
|
|||
|
||||
[features]
|
||||
anchor-debug = ["anchor-syn/anchor-debug"]
|
||||
idl-build = ["anchor-syn/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0.60", features = ["full"] }
|
||||
anchor-syn = { path = "../../syn", version = "0.27.0" }
|
||||
anchor-syn = { path = "../../syn", version = "0.30.0" }
|
||||
quote = "1"
|
||||
syn = { version = "1", features = ["full"] }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "anchor-attribute-event"
|
||||
version = "0.27.0"
|
||||
version = "0.30.0"
|
||||
authors = ["Anchor Maintainers <accounts@200ms.io>"]
|
||||
repository = "https://github.com/coral-xyz/anchor"
|
||||
license = "Apache-2.0"
|
||||
|
@ -14,10 +14,10 @@ proc-macro = true
|
|||
[features]
|
||||
anchor-debug = ["anchor-syn/anchor-debug"]
|
||||
event-cpi = ["anchor-syn/event-cpi"]
|
||||
idl-build = ["anchor-syn/idl-build"]
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0.60", features = ["full"] }
|
||||
anyhow = "1.0.32"
|
||||
anchor-syn = { path = "../../syn", version = "0.27.0", features = ["hash"] }
|
||||
anchor-syn = { path = "../../syn", version = "0.30.0", features = ["hash"] }
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = { version = "1", features = ["full"] }
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue