Compare commits

...

190 Commits

Author SHA1 Message Date
skrrb e5c8fbba3f
Merge 338b927edc into 81c8c556e8 2024-04-25 13:42:55 +00:00
skrrb 338b927edc Merge branch 'master' into syn-derive-arbitrary 2024-04-25 22:42:27 +09:00
acheron 81c8c556e8
idl: Add accounts resolution for associated token accounts (#2927) 2024-04-24 18:02:20 +02:00
czkz c96846fce2
ts: Fix incorrect `maxSupportedTransactionVersion` in `AnchorProvider.send*()` methods (#2922) 2024-04-23 18:39:18 +02:00
acheron 10c997552e
Add `anchor-derive-serde` crate to the publish script (#2924) 2024-04-23 00:48:58 +02:00
Sundeep Charan Ramkumar 827c986618
lang: Eliminate variable allocations that build up stack space for token extension code generation (#2913) 2024-04-22 13:00:40 +02:00
acheron fefa69519f
ts: Upgrade `@babel/traverse` to 7.24.1 (#2919) 2024-04-20 19:03:16 +02:00
zeroc b53bb35cf2
avm: Support customizing the installation location (#2917) 2024-04-20 13:36:19 +02:00
fedoras 7515c919f8
lang: Fix `token_program` docs.rs documentation (#2918) 2024-04-20 00:50:00 +02:00
Syed Aabis Akhtar 8e8df76eda
docs: Fix GitHub example link of `declare_program!` in release notes (#2910)
Co-authored-by: acheron <98934430+acheroncrypto@users.noreply.github.com>
2024-04-18 15:20:53 +02:00
acheron 852fcc77be
v0.30.0 (#2909) 2024-04-15 17:20:01 +02:00
acheron f74ea64ca6
idl: Rename crate name to `anchor-lang-idl` (#2908) 2024-04-15 13:56:53 +02:00
acheron 257b560109
lang: Return overflow error from `Lamports` trait operations (#2907) 2024-04-14 23:04:51 +02:00
acheron 95c4959287
ts: Add missing errors (#2906) 2024-04-14 00:00:41 +02:00
Bhargava Sai Macha a18d6caa6d
spl: Make `TokenAccount` and `Mint` `Copy` (#2904) 2024-04-13 23:30:02 +02:00
acheron 7356bd5afe
idl: Keep crate and `spec` version the same (#2901) 2024-04-13 01:06:45 +02:00
acheron 1f0bf0ee60
spl: Remove `solana-program` dependency (#2900) 2024-04-11 23:57:41 +02:00
Bhargava Sai Macha e3ced784ad
Add support for token extensions (#2789) 2024-04-11 22:49:13 +02:00
acheron ae26fd84bb
spl: Upgrade `mpl-token-metadata` to 4.1.2 (#2899) 2024-04-10 23:58:13 +02:00
acheron 0be5b00a34
lang: Add `Event` utility type to get events from bytes (#2897) 2024-04-09 23:57:41 +02:00
acheron c7ccbb8f62
Fix `1.79.0-nightly` warnings (#2896) 2024-04-08 23:58:45 +02:00
acheron 3591ba6cb8
spl: Remove `toml_edit` version requirement (#2895) 2024-04-08 21:19:34 +02:00
acheron 01839ad725
lang: Add composite accounts support for `declare_program!` (#2894) 2024-04-07 23:41:56 +02:00
acheron cbf9b0a090
Unpin `nightly` version (#2893) 2024-04-07 13:47:50 +02:00
acheron da2d9a4045
idl: Store deployment addresses for other clusters (#2892) 2024-04-06 23:39:53 +02:00
acheron 2dd79da674
spl: Upgrade `spl-associated-token-account` to 3.0.2 (#2891) 2024-04-05 23:18:46 +02:00
acheron 5f6af05519
idl: Add `#[non_exhaustive]` to IDL enums (#2890) 2024-04-04 22:34:35 +02:00
acheron 4de70aabee
idl: Add `docs` field for constants (#2887) 2024-04-03 21:59:43 +02:00
acheron c138a55b72
idl: Move IDL types from the `anchor-syn` crate to the new IDL crate (#2882) 2024-04-02 20:01:27 +02:00
acheron 475c694355
Upgrade `spl-token-2022` to 3.0.2 (#2876) 2024-03-31 07:59:49 +02:00
amilz 45c84c524f
cli: Add `deactivate_feature` flag to `solana-test-validator` config in Anchor.toml (#2872) 2024-03-30 17:40:30 +01:00
Jasper 6aba24e225
cli: Standardize Rust templates for `anchor init` generated JSON and ignore files (#2874) 2024-03-30 17:14:30 +01:00
acheron 800d6557b9
ci: Add `declare-program` tests (#2873) 2024-03-30 17:04:43 +01:00
acheron c66b323293
Upgrade Solana to 1.18.8 (#2867) 2024-03-28 05:52:24 +01:00
dongjinlong c2cd5a99aa
Fix typos in comments (#2868) 2024-03-27 23:59:38 +01:00
acheron 0f6090950a
lang: Add `declare_program!` macro (#2857) 2024-03-25 23:14:02 +01:00
Taylor Johnson 4393d73d3d
ts: Add optional `prepend` parameter to `preInstructions` method (#2863) 2024-03-24 14:39:57 +01:00
acheron 7c424ee58a
ts: Remove `programId` parameter of the `Program` constructor (#2864) 2024-03-22 01:51:26 +01:00
Snoppy 62dccce2ed
Fix typos (#2860) 2024-03-21 22:34:21 +01:00
zilayo 35142161de
client: Fix panic in event parsing due to empty stack (#2856) 2024-03-20 13:54:13 +01:00
acheron b83d5fd64b
Upgrade `cargo_toml` to 0.19.2 (#2859) 2024-03-20 02:36:39 +01:00
Andrei Hrs cc15435e4d
cli: Add priority fees to idl commands (#2845) 2024-03-19 11:00:09 +01:00
acheron 8fdc07bffb
docs: Refactor sidebar navigation (#2852) 2024-03-18 08:26:55 +01:00
acheron d931b31c0a
cli: Add `--no-idl` flag to the `build` command (#2847) 2024-03-16 15:56:13 +01:00
acheron ddcb3b8260
ts: Make `opts` parameter of `AnchorProvider` constructor optional (#2843) 2024-03-14 23:59:39 +01:00
acheron d9a9f19394
Fix IDL (#2824)
* Rewrite IDL type spec

* Rewrite IDL generation

* Partially rewrite the TS package with the new IDL, improved account resolution and types
2024-03-10 14:22:23 +01:00
Nabeel 23028334f3
spl: Add documentation for `burn_nft` (#2819)
Co-authored-by: acheron <acheroncrypto@gmail.com>
2024-03-07 14:24:45 +01:00
cui fliter 3e2cd0004c
Fix typos in comments (#2830) 2024-03-05 22:42:14 +01:00
acheron 2f552a17f5
cli: Fix excessive test validator requests (#2828) 2024-02-29 21:42:28 +01:00
acheron 216b56e26f
cli: Add ability to build and test only a specified program (#2823) 2024-02-24 15:45:09 +01:00
acheron 6716c13b38
client: Add documentation for `RequestBuilder.accounts` method (#2822) 2024-02-20 22:38:31 +01:00
Jayden Park 253501aa89
ts: Correctly construct field layout for type aliases (#2821) 2024-02-19 20:59:48 +01:00
acheron 5d5cadebdd
cli: Accept package name as program name (#2816) 2024-02-16 16:51:56 +01:00
Aoi Kurokawa 8eee184938
cli: Add Rust test template (#2805) 2024-02-14 23:58:40 +01:00
acheron fc8cb5234a
cli: Check `@coral-xyz/anchor` package and CLI version compatibility (#2813) 2024-02-11 03:54:41 +01:00
Pioua e21210538d
docs: Fix typos (#2815) 2024-02-10 22:39:00 +01:00
acheron 359e2718ba
tests: Fix non-path `anchor-lang` dep in tests (#2811) 2024-02-07 23:59:54 +01:00
Anthony 08110e63fa
Fix broken link to Rust's code of conduct (#2810) 2024-02-06 23:41:53 +01:00
acheron fde00661c1
spl: Pin version of `toml_edit` crate to 0.21.0 (#2807) 2024-02-04 12:46:25 +01:00
Aoi Kurokawa 94fde24339
cli: Add support for multiple commands with `anchor test` (#2799) 2024-02-01 14:59:46 +01:00
Mike MacCana 616dd239c3
docs: minor fixes to JS Anchor types (#2796) 2024-01-31 12:06:30 +01:00
acheron ef836852dd
Specify `solana-program` version range to not include 1.18.0 (#2798) 2024-01-29 23:18:57 +01:00
Gabriele Picco 169264d730
cli: Add support for simple wildcard patterns in Anchor.toml's `workspace.members` and `workspace.exclude` (#2785)
Co-authored-by: acheron <98934430+acheroncrypto@users.noreply.github.com>
2024-01-25 14:37:01 +01:00
acheron ef3b149348
client: Add crate level examples and features docs (#2779) 2024-01-21 23:32:50 +01:00
acheron dbb36d211c
cli: Remove redundant Solidity code (#2778) 2024-01-18 20:15:55 +01:00
chalda bcd7e1719e
cli: Specify the address to close with `idl close` and close buffer after `idl upgrade` (#2760)
Co-authored-by: acheron <acheroncrypto@gmail.com>
2024-01-16 20:04:54 +01:00
Ford 66d2f073bb
docs: proofread the changelog (#2772) 2024-01-15 20:17:03 +01:00
acheron 60b10809c0
Enable all features for docs.rs build (#2774) 2024-01-14 19:42:58 +01:00
acheron c93b33a27e
cli: Fix `migrate` command not working without global `ts-node` installation (#2767) 2024-01-11 14:13:56 +01:00
0xabhinav 211982affc
ts: Fix formatting enums (#2763)
Co-authored-by: acheron <acheroncrypto@gmail.com>
2024-01-09 13:47:59 +01:00
Sabir Khan 7cbdff657d
cli: set I/O stream to `Stdio:null` if the given `solana_version` is already installed (#2757)
Co-authored-by: acheron <acheroncrypto@gmail.com>
2024-01-06 18:06:09 +01:00
Neutron 1a6b5066df
ts: Add IDL seed types (#2752)
Signed-off-by: Shiva953 <b22070@students.iitmandi.ac.in>
Co-authored-by: acheron <acheroncrypto@gmail.com>
2024-01-04 18:42:29 +01:00
acheron 47ff77f4df
cli: Check `anchor-lang` and CLI version compatibility (#2753) 2024-01-03 00:01:12 +01:00
acheron 1fc92ab1e3
lang: Fix `use of unstable library feature 'build_hasher_simple_hash_one'` (#2756) 2023-12-31 18:05:33 +01:00
acheron de9901b5fd
ts: Remove deprecated `associated` methods (#2749) 2023-12-27 18:35:54 +01:00
Jean Marchand (Exotic Markets) 52fbe55d52
spl: Remove shared memory program (#2747) 2023-12-26 22:21:42 +01:00
acheron c4f14b9f6f
lang: Remove `try_to_vec` usage (#2744) 2023-12-23 23:28:46 +01:00
Jean Marchand (Exotic Markets) f6a15254d1
lang: Allow custom lifetime for Accounts structure (#2741) 2023-12-21 22:59:41 +01:00
acheron 51ae380574
ci: Remove manual downgrade of `index_list` to make `solana-program-test` compile (#2739) 2023-12-19 23:59:58 +01:00
Joe C 13fc0bb915
lang: Add `#[interface]` attribute for overriding the default discriminator (#2728) 2023-12-17 23:57:57 +01:00
cavemanloverboy c2b5472d85
lang: Add `InstructionData::write_to` implementation (#2733)
Co-authored-by: acheron <98934430+acheroncrypto@users.noreply.github.com>
Co-authored-by: acheron <acheroncrypto@gmail.com>
2023-12-16 23:59:53 +01:00
Michal Nazarewicz 250fa8cdc5
lang: Avoid temporary `Vec`s when serializing objects with discriminators and set default capacity to 256 bytes (#2691) 2023-12-14 21:09:48 +01:00
Jean Marchand (Exotic Markets) c402972bf1
lang: Make bumps of optional accounts `Option<u8>` rather than `u8` (#2730) 2023-12-14 01:31:08 +01:00
acheron 4c0af6dc53
lang: Remove `CLOSED_ACCOUNT_DISCRIMINATOR` (#2726) 2023-12-12 20:55:21 +01:00
chalda 61244a86dc
Change default local test-validator address from localhost to 127.0.0.1 (#2725) 2023-12-11 23:29:01 +01:00
acheron 8bf7f251ad
spl: Fix compilation with `shmem` feature enabled (#2722) 2023-12-08 15:26:22 +01:00
acheron 727e6f84cb
cli: Fix toolchain `solana_version` override log (#2719) 2023-12-06 15:56:31 +01:00
acheron dfee9589fd
ts: Remove `anchor-deprecated-state` feature (#2717) 2023-12-03 11:24:40 +01:00
acheron a423f7855b
cli: Require explicit `overflow-checks` flag (#2716) 2023-11-30 00:55:12 +01:00
acheron 9dd1b54acd
lang: Remove the unnecessary clone in `to_account_info().clone()` (#2713) 2023-11-26 16:58:44 +01:00
Jimii 38907fa9b2
docs: explicitely state where to initialize the new anchor program (#2712) 2023-11-25 14:22:27 +01:00
acheron beb15cdb37
cli: Add support for passing arguments to `solana program deploy` (#2709) 2023-11-22 23:55:51 +01:00
puhtaytow d91781f2ce
client: expose more parts from logs parsing (#2707) 2023-11-22 02:14:52 +01:00
John 227ccb22fd
docs: Add Solana Playground quickstart page, and add examples page for anchor contraints and types (#2703) 2023-11-20 19:47:05 +01:00
Aoi Kurokawa c58d2f232e
cli: add verifiable option in deploy command (#2705) 2023-11-19 23:59:47 +01:00
acheron d28414efd4
cli: Fix commit based `anchor_version` override (#2704) 2023-11-17 15:26:44 +01:00
John Anthos a9c423ef24
syn: Fix IDL constant seeds parsing (#2699) 2023-11-15 23:59:34 +01:00
acheron cded9de0a4
cli: Improve error handling of toolchain overrides (#2700) 2023-11-13 23:58:21 +01:00
John Anthos 870ee9a876
cli: Add ability to force init and new commands via cli (#2698)
Co-authored-by: acheron <acheroncrypto@gmail.com>
2023-11-11 12:21:56 +01:00
acheron 9cb8d0355d
cli: Fix using user specific path for `provider.wallet` (#2696) 2023-11-09 21:58:08 +01:00
acheron 8f3bb8a556
cli: Make `cargo build-sbf` the default build command (#2694) 2023-11-07 00:53:26 +01:00
acheron 167c8ecbf5
syn: Fix `Hash::new_from_array` warning in non-bpf targets (#2693) 2023-11-03 15:53:46 +01:00
__ 88f3053645
client: Fix erroneous Cluster websocket ports (#2690) 2023-10-31 23:31:04 +01:00
acheron 150fc3e832
Fix workspace `resolver` warning (#2676) 2023-10-30 22:39:07 +01:00
Michal Nazarewicz 7e5bdce710
Update base64 dependency (#2686) 2023-10-28 23:00:00 +02:00
acheron 5a655b0f65
ts: Use workspace dependencies and fix tests (#2685) 2023-10-27 00:59:11 +02:00
Jimii b6e94dacf0
Make `anchor-spl` and `anchor-client` badges links to creates.io (#2684) 2023-10-26 23:58:36 +02:00
Pierre 9331908aee
tests: Add remaining accounts test (#2683) 2023-10-26 01:14:38 +02:00
vadorovsky 85a5a9bdfc
syn: Add missing `new_from_array` method to `Hash` (#2682) 2023-10-25 00:15:12 +02:00
Sean Young 749c45a2d9
Fixes for Solidity/Solang (#2677) 2023-10-24 15:59:34 +02:00
acheron e0d0df4ab5
Fix 1.73.0 clippy warnings (#2674) 2023-10-20 15:48:01 +02:00
acheron fc3905a099
ci: Re-enable `anchor init` test (#2673) 2023-10-18 11:22:54 +02:00
acheron fc9fd6d24b
v0.29.0 (#2672) 2023-10-16 18:35:17 +02:00
acheron 88a75aff13
avm: Install from version-commit and refactor (#2671) 2023-10-15 11:36:50 +02:00
acheron 4f996d0a58
cli: Add ability to override toolchain from `Anchor.toml` (#2649) 2023-10-14 21:40:26 +02:00
Pierre 5900c93310
avm: Allow install, list and use from commit (#2659) 2023-10-14 17:41:46 +02:00
acheron 8717364f81
Remove the maximum version constraint from Solana crates (#2667) 2023-10-13 23:58:51 +02:00
0xWoo 23eeb1ec2d
spl: add feature memo to support cpi to spl-memo (#2661) 2023-10-13 01:23:35 +02:00
Jean Marchand (Exotic Markets) 0fef819e4b
chore: Remove abusive cloning (#2663) 2023-10-12 23:59:21 +02:00
acheron 6cf200493a
spl: Update dependencies to their latest versions (#2657) 2023-10-12 11:13:30 +02:00
Jean Marchand (Exotic Markets) dcafb789e1
lang: Add accounts by reference (#2656) 2023-10-11 16:46:48 +02:00
Jean Marchand (Exotic Markets) 243ab75738
lang: Type safe bumps (#2542) 2023-10-10 23:48:23 +02:00
acheron 721eb7a3be
bench: Fix number formatting due to locale difference (#2655) 2023-10-10 13:16:09 +02:00
acheron 267c4ceab7
tests: Remove `auction-house` submodule and host it natively (#2654) 2023-10-09 13:50:40 +02:00
acheron 5e7fb44518
Upgrade Solana to `1.17.0` (#2645) 2023-10-07 23:53:37 +02:00
Fernando Otero b0e725b5ac
spl: Update `mpl-token-metadata` to `3.1.0` and fix `create_metadata_accounts_v3` (#2651) 2023-10-07 11:01:19 +02:00
acheron 25b24a1fd3
syn: Fix having access to `idl` module by default (#2650) 2023-10-06 14:52:50 +02:00
acheron 51578bcbc5
spl: Fix compilation error and warnings (#2647) 2023-10-05 19:19:07 +02:00
Nick Guo 5602244e1a
cli: Support upgradeable program in anchor test (#2642)
Resolves #2641
2023-10-03 22:46:40 +02:00
acheron f18fd971fb
Update Node to `18.18.0` LTS (#2643) 2023-10-03 11:49:03 +02:00
acheron e1d5e785b8
syn: Fix generic type aliases (#2644) 2023-10-01 22:53:02 +02:00
acheron d1e32674d5
Add type alias support (#2637) 2023-09-27 22:59:29 +02:00
Sean Young 3e8bc76d72
Update to solang v0.3.2 and add simple test (#2636) 2023-09-26 22:55:41 +02:00
acheron 28adaf2343
ts: Remove `base64-js` dependency (#2635) 2023-09-25 23:36:58 +02:00
Fernando Otero 99b75a905b
spl: Update to token metadata client sdk (#2632) 2023-09-25 16:19:23 +02:00
acheron 3c6fc2ba2d
syn: Fix IDL named enum variant field being snake_case (#2633) 2023-09-21 18:45:22 +02:00
acheron fa9f960a0b
docs: Add tuple enum JS client documentation (#2631) 2023-09-18 23:07:15 +02:00
acheron b5f4796156
Add `IdlBuild` trait (#2629) 2023-09-15 23:59:18 +02:00
acheron fdda604d41
ts: Add strong type support for `addEventListener` (#2627) 2023-09-13 00:12:41 +02:00
Jesserc cec9946111
docs: Fix typo and grammar in error documentation 2023-09-10 21:32:34 +02:00
acheron 4955a92593
Add byte slice(`&[u8]`) support for `idl-build` (#2622) 2023-09-08 10:01:51 +02:00
acheron a1e4453a0b
cli: Make conflicting account names a compile-time error (#2621) 2023-09-05 17:30:53 +02:00
acheron b9fa898384
cli: Fix `anchor account` command panicking outside of workspace (#2620) 2023-09-01 22:42:06 +02:00
Will dcf5928f3f
lang: `Box` the inner enums of `anchor_lang::error::Error` (#2600)
Co-authored-by: acheron <acheroncrypto@gmail.com>
2023-08-30 19:28:51 +02:00
acheron 115679e675
bench: Add benchmarking for stack memory usage (#2617) 2023-08-28 14:13:12 +02:00
acheron a5e4c02de0
ts: Bump packages to `0.28.1-beta.2` (#2616) 2023-08-27 10:21:17 +02:00
Will a7205af5df
lang: `associated_token` constraints don't work when setting `token_program` (#2603)
Co-authored-by: acheron <acheroncrypto@gmail.com>
2023-08-23 22:10:08 +02:00
acheron 6f9f7d9369
tests: Move IDL related tests in `misc` to `idl` (#2606) 2023-08-19 13:09:09 +02:00
acheron 6eacad4b11
cli: Add program template with multiple files (#2602) 2023-08-15 23:58:17 +02:00
acheron 454f1dd044
ts: Add support for unnamed(tuple) enum in accounts (#2601) 2023-08-13 16:50:28 +02:00
Jimii b5cf67f13b
spl: Add `TokenRecordAccount` for pNFTs (#2597) 2023-08-12 22:02:37 +02:00
Proph3t 58428f858d
Add `setup_tests.sh` for setting up your local machine for tests (#2594) 2023-08-11 21:48:28 +02:00
acheron 4cf447a1c4
bench: Add benchmarking for program binary size (#2591) 2023-08-08 22:03:31 +02:00
acheron abfdc4e88f
chore: Remove duplicate dependency and and alphabetize features (#2590) 2023-08-05 23:47:06 +02:00
acheron 2af9cc669b
cli: Improve converting non-conflicting paths to names in IDL (#2588) 2023-08-02 23:01:05 +02:00
Proph3t be8764b8a8
Fix typo in account.rs docs (#2587) 2023-08-01 22:23:48 +02:00
acheron b7b8736276
spl: Export `mpl-token-metadata` crate (#2583) 2023-07-31 23:41:12 +02:00
acheron cad868a052
Make the new IDL features explicit (#2582) 2023-07-29 23:49:17 +02:00
acheron 8f30f00ec3
tests: Improve IDL comparison tests (#2581) 2023-07-27 23:29:26 +02:00
Pierre df3e95925b
chore: Use @noble/hashes/sha256 rather than obscure package (#2580) 2023-07-26 23:56:12 +02:00
acheron 5eb678a8bf
ts: Lazy load workspace programs and improve program name accessor (#2579) 2023-07-25 23:52:26 +02:00
acheron 4604fbea9c
cli: Automatically decide IDL generation method (#2578) 2023-07-22 16:39:05 +02:00
Jean Marchand (Exotic Markets) c548c85dff
chore: Remove unused crates (#2577) 2023-07-22 12:43:56 +02:00
Jean Marchand (Exotic Markets) 2bb3237da6
chore: Fix clippy lints (#2576) 2023-07-21 11:04:52 +02:00
dromaz 10eb698912
avm: Add support for the `.anchorversion` file (#2553)
Co-authored-by: acheron <acheroncrypto@gmail.com>
2023-07-20 23:58:13 +02:00
acheron 8309bb3ed5
cli: Fix `anchor build --no-docs` (#2575) 2023-07-19 18:28:38 +02:00
acheron c306463432
tests: Refactor IDL tests (#2573) 2023-07-17 22:47:55 +02:00
acheron cf057acac0
client: Fix compilation with Solana `1.14` (#2572) 2023-07-16 17:08:25 +02:00
acheron 4e5280be46
cli: Fix workspace inheritence (#2570) 2023-07-14 23:17:23 +02:00
Lucas Steuernagel cfc6d2916b
cli: Bump `solang-parser` version (#2569) 2023-07-14 21:29:16 +02:00
acheron 472279d10d
cli: Add `--out` and `--out-ts` arguments for `idl build` command (#2566) 2023-07-13 22:06:12 +02:00
acheron b7e91d4d0d
Remove IDL `path` field (#2564) 2023-07-11 19:05:14 +02:00
Krešimir Klas 6ef6b79a6c
IDL generation through compilation (#2011)
Co-authored-by: acheron <acheroncrypto@gmail.com>
2023-07-08 19:59:30 +02:00
Noah Prince 0225b7c0fd
lang: Allow polymorphic CPI calls matching an interface (#2559) 2023-07-07 23:30:38 +02:00
Jean Marchand (Exotic Markets) 9ff7dfcf6f
lang: Support for `const` in the `InitSpace` macro (#2555) 2023-07-05 10:05:37 +02:00
chalda 401d526150
client: Add `DynSigner` (#2550) 2023-07-03 22:56:58 +02:00
acheron e55cd3e646
lang: Add `Lamports` trait (#2552) 2023-07-01 22:59:36 +02:00
Jean Marchand (Exotic Markets) 5624bfe0ff
lang: Fix typo in the doc (#2551) 2023-06-29 13:35:38 +02:00
acheron 29b8a72800
bench: Show change amount and add change note (#2549) 2023-06-27 20:03:51 +02:00
Han Yang 8bdc1b18ea
spl: Only allow spl-token version above 1.1 (#2546) 2023-06-26 19:04:30 +02:00
acheron 9e73317d09
bench: Show Solana version used in tests (#2543) 2023-06-24 23:28:16 +02:00
acheron d41e513351
ts: Bump packages to `0.28.1-beta.1` (#2539) 2023-06-21 23:32:14 +02:00
acheron b5519a6532
bench: Add lock files and store Solana version (#2537) 2023-06-20 20:20:22 +02:00
acheron 9d947cb26b
ts: Remove usage of `assert` (#2535) 2023-06-17 21:19:42 +02:00
acheron 78d48552c6
docker: Update org name and Ubuntu version (#2533) 2023-06-14 20:41:20 +02:00
acheron c2a36f9e42
ci: Enable `anchor init` test (#2529) 2023-06-12 20:09:14 +02:00
acheron e1afcbf71e
v0.28.0 (#2527) 2023-06-09 18:00:35 +02:00
acheron c7c73194d8
Allow wider range of dependency versions to reduce dependency issues (#2524) 2023-06-08 18:59:44 +02:00
skrrb 704692c0e2 changelog 2023-06-06 12:29:36 +02:00
skrrb 34a8e59232 syn: derive arbitrary for the instruction data 2023-06-06 11:59:06 +02:00
579 changed files with 39638 additions and 11595 deletions

View File

@ -1 +0,0 @@
large-error-threshold = 1_000_000

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

4
.gitmodules vendored
View File

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

View File

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

View File

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

3052
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -1 +1 @@
0.27.0
0.30.0

1259
avm/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -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 == &current_version().unwrap() {
if version == &current_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"
)
}
}

View File

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

79
bench/BINARY_SIZE.md Normal file
View File

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

View File

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

508
bench/STACK_MEMORY.md Normal file
View File

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

View File

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

View File

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

82
cli/src/checks.rs Normal file
View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

66
docs/package-lock.json generated
View File

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

View File

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

View File

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

BIN
docs/public/solpg-test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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)`):

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,3 +2,6 @@
members = [
"programs/*"
]
[profile.release]
overflow-checks = true

View File

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

View File

@ -12,6 +12,7 @@ name = "basic_0"
[features]
no-entrypoint = []
cpi = ["no-entrypoint"]
idl-build = ["anchor-lang/idl-build"]
[dependencies]
anchor-lang = { path = "../../../../../lang" }

View File

@ -2,3 +2,6 @@
members = [
"programs/*"
]
[profile.release]
overflow-checks = true

View File

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

View File

@ -12,6 +12,7 @@ name = "basic_1"
[features]
no-entrypoint = []
cpi = ["no-entrypoint"]
idl-build = ["anchor-lang/idl-build"]
[dependencies]
anchor-lang = { path = "../../../../../lang" }

View File

@ -2,3 +2,6 @@
members = [
"programs/*"
]
[profile.release]
overflow-checks = true

View File

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

View File

@ -12,6 +12,7 @@ name = "basic_2"
[features]
no-entrypoint = []
cpi = ["no-entrypoint"]
idl-build = ["anchor-lang/idl-build"]
[dependencies]
anchor-lang = { path = "../../../../../lang" }

View File

@ -2,3 +2,6 @@
members = [
"programs/*"
]
[profile.release]
overflow-checks = true

View File

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

View File

@ -12,6 +12,7 @@ name = "puppet_master"
[features]
no-entrypoint = []
cpi = ["no-entrypoint"]
idl-build = ["anchor-lang/idl-build"]
[dependencies]
anchor-lang = { path = "../../../../../lang" }

View File

@ -12,6 +12,7 @@ name = "puppet"
[features]
no-entrypoint = []
cpi = ["no-entrypoint"]
idl-build = ["anchor-lang/idl-build"]
[dependencies]
anchor-lang = { path = "../../../../../lang" }

View File

@ -2,3 +2,6 @@
members = [
"programs/*"
]
[profile.release]
overflow-checks = true

View File

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

View File

@ -12,6 +12,7 @@ name = "basic_4"
[features]
no-entrypoint = []
cpi = ["no-entrypoint"]
idl-build = ["anchor-lang/idl-build"]
[dependencies]
anchor-lang = { path = "../../../../../lang" }

View File

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

View File

@ -1,4 +1,7 @@
[workspace]
members = [
"programs/*"
]
]
[profile.release]
overflow-checks = true

View File

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

View File

@ -12,6 +12,7 @@ name = "basic_5"
[features]
no-entrypoint = []
cpi = ["no-entrypoint"]
idl-build = ["anchor-lang/idl-build"]
[dependencies]
anchor-lang = { path = "../../../../../lang" }

View File

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

View File

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

View File

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

25
idl/Cargo.toml Normal file
View File

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

275
idl/src/build.rs Normal file
View File

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

9
idl/src/lib.rs Normal file
View File

@ -0,0 +1,9 @@
//! Anchor IDL.
pub mod types;
#[cfg(feature = "build")]
pub mod build;
#[cfg(feature = "build")]
pub use serde_json;

501
idl/src/types.rs Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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