From 43643d93fab3f7850f55cb9100b184a7013431ca Mon Sep 17 00:00:00 2001 From: Sergey Timoshin Date: Fri, 30 May 2025 13:58:46 +0100 Subject: [PATCH] Configure Docker image with proper proving keys (#1766) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add proving key files to Docker image instead of using empty directory. Change run mode to RPC and update documentation for Docker usage. fix: indexer get_compressed_account return type (#1765) * fix: rpc return types * fix: discriminator serialization is le bytes in photon * fix: pr feedback chore: bump versions, add batched Merkle tree placeholder bytes (#1767) * chore: bump light-batched-merkle-tree -> 0.2.0, light-merkle-tree-metadata -> 0.2.0, light-concurrent-merkle-tree -> 2.0.0, light-merkle-tree-reference 2.0.0 * chore: add batched-merkle-tree placeholder bytes * regenerate accounts * fix: make concurrent mt *mut fields private * chore: bump light-hash-set version -> 2.0.0 * bump: light-bloom-filter version -> 0.2.0 * fix: light-test-utils usage of concurrent-merkle-tree * chore: bump concurrent-merkle-tree version -> 2.0.1 * chore: bump light-indexed-merkle-tree version -> 2.0.0 feat: add next nullifier index (#1604) * feat: add next_nullifier_index * chore: regenerated accounts * fix: tests refactor: nullifiers in BatchPublicTransactionEvent (#1606) * refactor: nullifiers in BatchPublicTransactionEvent * fix: e2e test fix: precision in js rpc client (#1588) * fix precision in js rpc client when coercing tokenData responses * fix lint * fix toCamelCase for nested objects + BN conversion for BiggNumbers * exclude winston from rollup * simplify stringification * add for u64::max * rename coercer * fix lint * release to npm * bump, rm winston * bump * switch toCamelCas * add tests for safe-conversion * rm comments * rm logger feat: add selection helpers and idempotent variants (#1600) * fix precision in js rpc client when coercing tokenData responses fix lint fix toCamelCase for nested objects + BN conversion for BiggNumbers exclude winston from rollup simplify stringification add for u64::max rename coercer fix lint release to npm bump, rm winston bump switch toCamelCas add tests for safe-conversion rm comments add selection helpers, idempotent, meaningfful error messages. add tests add tests to ci fmt bump CHANGELOG.md * rm logger * better error messages * bump to 0.20.5 * add docstring * bump CHANGELOG.md * bump and update expected error message in tests chore: rename token selectors in js (#1612) * rename * bump Update verify.rs (#1605) fix: parse event from transaction (#1614) * wip * cleanup and refactor into event dir * fix: ci * chore: add photon test data generation for 4 cpi events fix: proof by index by fixing get_num_inserted_elements() (#1611) * wip * cleanup and refactor into event dir * fix: ci * chore: add photon test data generation for 4 cpi events * fix: proof by index by fixing get_num_inserted_elements() * fix: run program ci tests on program libs changes * remove legacy comment * fix: system test * fix: sytem test fix: add registered program ownership check fix: add signer check for batched address tree fix: migrate state output queue signer check build(deps): bump tabled from 0.17.0 to 0.18.0 (#1607) Bumps [tabled](https://github.com/zhiburt/tabled) from 0.17.0 to 0.18.0. - [Changelog](https://github.com/zhiburt/tabled/blob/master/CHANGELOG.md) - [Commits](https://github.com/zhiburt/tabled/commits) --- updated-dependencies: - dependency-name: tabled dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps-dev): bump nx from 20.3.0 to 20.4.6 (#1610) Bumps [nx](https://github.com/nrwl/nx/tree/HEAD/packages/nx) from 20.3.0 to 20.4.6. - [Release notes](https://github.com/nrwl/nx/releases) - [Commits](https://github.com/nrwl/nx/commits/20.4.6/packages/nx) --- updated-dependencies: - dependency-name: nx dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps-dev): bump eslint from 9.19.0 to 9.21.0 (#1609) Bumps [eslint](https://github.com/eslint/eslint) from 9.19.0 to 9.21.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.19.0...v9.21.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps): bump zerocopy from 0.8.14 to 0.8.20 (#1608) Bumps [zerocopy](https://github.com/google/zerocopy) from 0.8.14 to 0.8.20. - [Release notes](https://github.com/google/zerocopy/releases) - [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/zerocopy/compare/v0.8.14...v0.8.20) --- updated-dependencies: - dependency-name: zerocopy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps): bump pnpm/action-setup from 4.0.0 to 4.1.0 (#1565) Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](https://github.com/pnpm/action-setup/compare/v4.0.0...v4.1.0) --- updated-dependencies: - dependency-name: pnpm/action-setup dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps-dev): bump husky from 9.1.5 to 9.1.7 (#1574) Bumps [husky](https://github.com/typicode/husky) from 9.1.5 to 9.1.7. - [Release notes](https://github.com/typicode/husky/releases) - [Commits](https://github.com/typicode/husky/compare/v9.1.5...v9.1.7) --- updated-dependencies: - dependency-name: husky dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> test: e2e forester (#1615) build(deps-dev): bump chai from 5.1.2 to 5.2.0 (#1620) Bumps [chai](https://github.com/chaijs/chai) from 5.1.2 to 5.2.0. - [Release notes](https://github.com/chaijs/chai/releases) - [Changelog](https://github.com/chaijs/chai/blob/main/History.md) - [Commits](https://github.com/chaijs/chai/compare/v5.1.2...v5.2.0) --- updated-dependencies: - dependency-name: chai dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps-dev): bump @types/react-dom from 19.0.3 to 19.0.4 (#1623) Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 19.0.3 to 19.0.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom) --- updated-dependencies: - dependency-name: "@types/react-dom" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> fix: install rust 1.83 via install.sh (#1628) build(deps-dev): bump ts-mocha from 10.0.0 to 11.1.0 (#1621) Bumps [ts-mocha](https://github.com/piotrwitek/ts-mocha) from 10.0.0 to 11.1.0. - [Release notes](https://github.com/piotrwitek/ts-mocha/releases) - [Commits](https://github.com/piotrwitek/ts-mocha/compare/v10.0.0...v11.1.0) --- updated-dependencies: - dependency-name: ts-mocha dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps): bump thiserror from 2.0.11 to 2.0.12 (#1622) Bumps [thiserror](https://github.com/dtolnay/thiserror) from 2.0.11 to 2.0.12. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/2.0.11...2.0.12) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps): bump log from 0.4.25 to 0.4.26 (#1624) Bumps [log](https://github.com/rust-lang/log) from 0.4.25 to 0.4.26. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.25...0.4.26) --- updated-dependencies: - dependency-name: log dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps): bump syn from 2.0.96 to 2.0.99 (#1625) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.96 to 2.0.99. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/2.0.96...2.0.99) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> refactor: forester(send_transaction): add timeout checks (#1631) feat: add testnet init xtask command (#1632) * feat: add testnet init xtask command * fix tests * fix lint * fix: registry program test perf: indexed array remove next index (#1629) * created separate indexed array crate, updated MockBatchedAddressForester, created indexed tree in test mt * refactor: remove next_index from non-inclusion circuit * chore: debugged tests: batched merkle tree, light-prover-client, added new reference indexed array and Merkle tree * stash, empty_address_queue_test v1 wip * more fixes, e2e tests work * fix: e2e, registry tests * fix: concurrent tree tests * chore: clean up light-indexed-array * cleanup and regenerate batched address tree account * chore: updated proving keys download url * Update GitHub Actions to use 8vCPU runner for prover tests * remove warnings * Update prover/server/prover/proving_keys_utils.go * chore: add comma for ,input Co-authored-by: Sergey Timoshin * chore: remove leftover * remove unwrap * remove legacy tests --------- Co-authored-by: Sergey Timoshin chore: update photon api (#1634) * chore: update photon api * fix: context * fix: install script * Update sdk-libs/client/src/indexer/photon_indexer.rs * chore: trigger forester ci on program and photon api changes * switch to warp-vms for forester ci workflow * add retry logic for `get_validity_proof_v2` --------- Co-authored-by: Sergey Timoshin feat: optimize forester by parallelizing zkp proof generation for batch append and nullify (#1633) * wip * parallel batch proof gen * Remove debug logs * remove unnecessary init_logger calls from tests * cleanup * cleanup * Add delays to stabilize async indexer batch tests * test_indexer: get_queue_elements with 0 offset * fix * Group transactions into chunks for batch processing. * Remove sleep delay in transaction processing. * Refactor chunking logic with a constant for chunk size. * add batch_ixs_per_tx configuration for transaction batching Replaces the fixed CHUNK_SIZE with a configurable batch_ixs_per_tx parameter, allowing dynamic control over instructions per transaction. * Change batch_ixs_per_tx to 1 in test configurations * format * switch to warp-ubuntu-latest-x64-4x for forester ci workflow chore: fix and rename sdk test to anchor sdk test (#1645) * chore: fix and rename sdk test to anchor sdk test * fix: pnpm lockfile * chore: renamed anchor-sdk-test -> sdk-anchor-test * fix: pnpm lock * remove warnings * cleanup sdk-anchor-test fix: allow export for batch* circuits (#1653) fix: hashing be for batched trees for TokenData and CompressedAccount… (#1652) * fix: hashing be for batched trees for TokenData and CompressedAccount amount * refactor: indexed element hashing to use 32 byte inputs * test: add more tests CompressedAccount hash * test: randomized legacy, hash vs z hash test * test: token data legacy random test * test: circuit account hash and token data hash equivalence refactor: LightHasher and AsByteVec -> ToByteArray (#1650) refactor: hasher and ToByteArray -> ToByteArray refactor: hash_to_bn254_field_size_be return Option<[u8;32]> -> [u8;32] rename: Truncate -> HashToFieldSize refactor: move bigint -> light-hasher, hash to field size return Result refactor: data hasher into file, add macros to implement data hasher and to bytes for arrays refactor: rename bytes.rs -> to_byte_array.rs refactor: replace light_merkle_tree_metadata::TreeType with light_compressed_account::TreeType (#1655) refactor: add queue_pubkey & tree_type to MerkleTreeSequenceNumber (#1660) * refactor: add queue_pubkey & tree_type to MerkleTreeSequenceNumber * format * fix: update photon to sergey/merkle-tree-seq-plus * update program layout in typescript bindings, fix tests * cleanup * fix test * fix: update photon dependency to latest commit refactor: light-sdk, Light Account and LightAccountInfo (#1662) * refactor: sdk verify * refactor: LightAccount, LightAccountInfo and tests * fixed: sdk test feat: Formal Verification for updated circuits (#1644) * bump lean version * update circuits with input hashing * checkpoint on rangetrees * no indices * remove next index * progress on address tree * extract all circuits * checkpoint * bring back some tests * catch-up old mains * batch append circuit * add proofs for BatchUpdate * soundness and completeness for address append * clean up sorries * state main props for address append * fix change * fix tags * correct tree depths refactor: light-sdk file structure (#1663) fix: rent exemption check (#1668) * fix: relax rent exemption check from strict equal to greater than * remove dead code * Update program-libs/account-checks/src/checks.rs Co-authored-by: ananas-block <58553958+ananas-block@users.noreply.github.com> --------- Co-authored-by: Swen Schäferjohann <42959314+SwenSchaeferjohann@users.noreply.github.com> fix: queue type usage in from account info (#1669) * fix: use queue type consistently in from_account_info * chore: fix lint chore: unify queue and tree types (#1670) * fix: use queue type consistently in from_account_info * chore: fix lint * chore: unify queue and tree type constants in light-compressed-account chore: add metadata length and current index checks to vec and cyclic vec from_bytes_at (#1671) chore: feature gate try_into_array, to_vec behind std feature, make std non default (#1672) chore: light-batched-merkle-tree feature gate test-utils test-only (#1673) * chore: light-batched-merkle-tree feature gate test-utils test-only chore: update github workflow to test with test-only feature * fix: account compression program test imports refactor: system program anchor -> pinocchio (#1664) * feat: created anchor system program feat: account checks with pinoccio and anchor feat: program_check, signer_check, pda_check * fix: cli, replace light_system_program with light_system_program_pinocchio * fix: rust tests feat: batch address updates support (#1651) * feat: batch address updates support * refactor: remove debug prints and improve PhotonIndexer initialization * add light-concurrent-merkle-tree dep to sdk-libs/program-test * refactor: reduce batch size for transaction configuration in e2e forester test chore: bump groth16 solana v0.1.0 (#1680) feat: feat: add queue_index to NewAddress and implement handling logic (#1683) feat: extend PackedAccounts with pre and system accounts (#1679) * feat: extend PackedAccounts with pre and system accounts * Update sdk-libs/sdk/src/instruction/pack_accounts.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * format * feat: return offsets from packed accounts * Update sdk-libs/sdk/Cargo.toml Co-authored-by: Swen Schäferjohann <42959314+SwenSchaeferjohann@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Swen Schäferjohann <42959314+SwenSchaeferjohann@users.noreply.github.com> refactor: light hasher, add fuzzing (#1684) * chore: remove flatten attribute, rename truncate code -> hash_to_field_size_code refactor: into hasher dir refactor: field processor refactor: input validation remove reconstructed struct refactor: add context struct refactor: move context struct into field_processor format feat: add basic fuzzing move tests refined fuzzing strategy implemented review feedback removed to_bytes_arrays fix LightHasher unit tests cleanup fix: tests * test: add Pubkey and borsh #[hash] tests, add debug print to DataHasher::hash * Update program-libs/hasher/src/hash_to_field_size.rs Co-authored-by: Swen Schäferjohann <42959314+SwenSchaeferjohann@users.noreply.github.com> * Update program-libs/hasher/src/errors.rs Co-authored-by: Swen Schäferjohann <42959314+SwenSchaeferjohann@users.noreply.github.com> --------- Co-authored-by: Swen Schäferjohann <42959314+SwenSchaeferjohann@users.noreply.github.com> refactor: discriminator sdk macro, light-hasher remove Discriminator, light-account-checks remove constant from Discriminator (#1685) refactor: sdk use compressed account info from light-compressed-account (#1686) * refactor: sdk use compressed account info from light-compressed-account * chore: resolve merge conflict refactore: rename tree and queue types with v1, v2 suffixes (#1687) refactor: MerkleContext nullifier_queue_pubkey -> queue_pubkey (#1688) refactor: counter example (#1690) * fixed counter test program * feat: counter program added close instruction * add to ci tests, format * refactor: rename CBorshAccount -> LightAccount feat: cli: update commands for checking compressed SOL and token balances (#1694) * feat: cli: update commands for checking compressed SOL and token balances * fix: update token balance command to handle multiple accounts feat: assign addresses (#1695) * feat: assign addresses to compressed accounts * feat: make tx hash optional * chore: bump photon commit hash perf: extend registered program pda account (#1698) * perf: replaced signer derivation check with comparison * feat: add resize instruction with tests * regenerated accounts chore: rename instruction data traits (#1699) fix: add account is zeroed check to init cpi context account (#1700) * fix: add account is zeroed check to init cpi context account refactor: improve epoch_manager error handling and logging (#1697) 1. Increases log verbosity for key operations in `process_queue` (finding slots, waiting, sending txs) by changing several `trace!` calls to `info!`. 2. Modifies error handling within the main loop: - Errors encountered during the rollover check (`check_for_epoch_rollover`) are now logged as errors but no longer cause the `process_queue` function to return immediately. - Failures during `send_batched_transactions` are also logged as errors, but the function now continues processing the epoch instead of returning the error. This makes the forester more resilient to transient transaction send issues. 3. Removes a redundant `TODO` comment. test: add new instruction integration test (#1703) * test: add rnd test for zero copy ix data & traits, restore cpi tests, add account checks unit tests add tests for invoke_cpi_with_account_info bump anchor to 0.31.0, and solana versions to 2.2.1 chore: added tests, refactored cpi context validation * update ci setup and build * fix setup and build * chore: bump RPC methods to solana v2 (#1704) --------- Co-authored-by: Swen Schäferjohann <42959314+SwenSchaeferjohann@users.noreply.github.com> refactor: instruction data field is_decompress -> is_compress refactor: use check_data_is_zeroed set_discriminator test: restore verify signer test test: restore cpi context unit tests fix: typos in filenames chore: remove obsolete combine logic and tests refactor: use account_info_init instead of manually setting the discriminator feat: add xtask to create serialized protocol config update instruction feat: address v2 test with multiple addresses, add async yields (#1719) * feat: address v2 test with multiple addresses, add async yields * enhance address creation logic to support multiple addresses * add `tokio::task::yield_now()` in async loops to improve responsiveness * refactor: remove commented debug print statements from test_indexer chore: included `pkgconf` and `libssl-dev` to support building with OpenSSL (#1721) fix: forester do not retry failing tx (#1724) * fix: forester do not retry failing tx * cleanup feat: add retry mechanism to rate-limited requests in Photon indexer (#1722) * feat: add retry mechanism to rate-limited requests in Photon indexer Replaced `rate_limited_request` with `rate_limited_request_with_retry` to include a retry mechanism for handling transient errors. * format * Reduced initial retry delay to 100ms and capped exponential backoff at 4000ms to improve responsiveness and mitigate excessive delays. * refactor: simplify retry logic in get_validity_proof_v2 request fix: check_account_balance_is_rent_exempt return rent_exemption (#1715) * fix: check_account_balance_is_rent_exempt return rent_exemption * test: test rollover fee is correct * Update program-tests/account-compression-test/tests/batched_merkle_tree_test.rs feat: add batch compress tokens (#1718) * feat: add batch compress tokens fix ctoken js test: mint-to with wrong authority now throws inside spl program test and optimize batch compress test: add failing tests and fix mint to failing tests fix: token22 compression feat: add single amount to batch compress * fix: comments * perf: remove unnecessary seed check * perf: remove unused input data * perf: switch ctoken system program cpi to with_readonly * feat: add with tx hash to transfer ix * chore: add transfer2 to ensure transfer backwards compatibility * stash pre claude * feat: stateless.js add decodeInstructionDataInvokeCpiWithReadOnly * stash * stash * remove transaction2 * cleanup * chore: review 1718 (#1725) * chore: expect index in batch compress * chore: is_valid_token_pool_pda return Result * test: add randomized test for BatchCompressInstructionData * fix: mint lookup --------- Co-authored-by: Swen Schäferjohann <42959314+SwenSchaeferjohann@users.noreply.github.com> chore: fix token escrow idl (#1729) build(deps-dev): bump eslint from 9.21.0 to 9.26.0 (#1726) Bumps [eslint](https://github.com/eslint/eslint) from 9.21.0 to 9.26.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.21.0...v9.26.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 9.26.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> CI: migrate workflows to cache v4 (#1716) Co-authored-by: David Klank build(deps): bump serde_json from 1.0.139 to 1.0.140 (#1639) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.139 to 1.0.140. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.139...v1.0.140) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps-dev): bump syncpack from 13.0.1 to 13.0.4 (#1713) Bumps [syncpack](https://github.com/JamieMason/syncpack) from 13.0.1 to 13.0.4. - [Release notes](https://github.com/JamieMason/syncpack/releases) - [Changelog](https://github.com/JamieMason/syncpack/blob/13.0.4/CHANGELOG.md) - [Commits](https://github.com/JamieMason/syncpack/compare/13.0.1...13.0.4) --- updated-dependencies: - dependency-name: syncpack dependency-version: 13.0.4 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps): bump serde_with from 2.3.3 to 3.12.0 (#1649) Bumps [serde_with](https://github.com/jonasbb/serde_with) from 2.3.3 to 3.12.0. - [Release notes](https://github.com/jonasbb/serde_with/releases) - [Commits](https://github.com/jonasbb/serde_with/compare/v2.3.3...v3.12.0) --- updated-dependencies: - dependency-name: serde_with dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps): bump react and @types/react (#1738) Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) and [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react). These dependencies needed to be updated together. Updates `react` from 19.0.0 to 19.1.0 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v19.1.0/packages/react) Updates `@types/react` from 19.0.8 to 19.1.3 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: react dependency-version: 19.1.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: "@types/react" dependency-version: 19.1.3 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> refactor: forester improvements (#1723) * feat: add retry mechanism to rate-limited requests in Photon indexer Replaced `rate_limited_request` with `rate_limited_request_with_retry` to include a retry mechanism for handling transient errors. * Reduced initial retry delay to 100ms and capped exponential backoff at 4000ms to improve responsiveness and mitigate excessive delays. * refactor: enhance error handling and return types in tree scheduling functions * update transaction batching configuration for improved performance * refactor: update light slot calculation and add tests for phase start scenarios * refactor: implement rate-limited request for get_indexer_slot method * refactor: adjust indexer wait logic and enhance error handling in transaction processing * refactor: add hash cache into transaction processing * Replace `debug` logs with `trace` and remove unused dependencies * Increase sleep duration in utils.rs from 400ms to 500ms * Add `#[serial]` attribute to test_transfer_with_transaction_hash --------- Co-authored-by: ananas-block <58553958+ananas-block@users.noreply.github.com> build(deps): bump react-dom and @types/react-dom (#1737) Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) and [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom). These dependencies needed to be updated together. Updates `react-dom` from 19.0.0 to 19.1.0 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v19.1.0/packages/react-dom) Updates `@types/react-dom` from 19.0.4 to 19.1.3 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom) --- updated-dependencies: - dependency-name: react-dom dependency-version: 19.1.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: "@types/react-dom" dependency-version: 19.1.3 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> build(deps-dev): bump eslint-config-next from 15.1.4 to 15.3.2 (#1739) Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 15.1.4 to 15.3.2. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/commits/v15.3.2/packages/eslint-config-next) --- updated-dependencies: - dependency-name: eslint-config-next dependency-version: 15.3.2 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Refactor Dockerfile and update README for key management (#1743) chore: pnpm update (#1744) chore: cleanup light client and light-program-test (#1720) * refactored dependencies in light-client * refactor program-test * chore: split up system-cpi-test into v1 and v2 * fix test_state_indexer_async_batched * ignore flaky forester test refactor: counter program 2 (#1710) fix: zero copy num traits (#1750) * chore: feature flag num traits * chore: removed redundant light verifier tests refactor: RPC pool configuration and connection handling (#1745) * Refactor RPC pool configuration and connection handling - Introduced `RpcPoolConfig` struct for better organization of RPC pool settings. - Updated CLI arguments to include new RPC pool parameters: connection timeout, idle timeout, max retries, and retry delays. - Replaced direct usage of `SolanaRpcPool` with a builder pattern for improved configurability. - Enhanced connection retrieval with retry logic and exponential backoff. - Removed unused `log` dependency from `sdk-libs/client/Cargo.toml`. * rebase * fix after rebase feat: regenerate photon-api crate & v2 proof handling (#1753) * feat: regenerate photon-api crate * refactor: remove debug print statement from get_validity_proof_v2 * feat: enable indexer in LightValidatorConfig for address tree initialization * refactor: disable adjust address root index calculation in types.rs * feat: update photon dependency to a newer commit * rename AddressSeq to AddressQueueIndex and update related references * refactor: implement Display trait for AccountState and update formatting * rename: change AddressSeq to AddressQueueIndex and update module references * refactor: change nullifier_queue_index and tree_type to u16 in AccountContext chore: update rust to 1.86 (#1759) * chore: update rust to 1.86 * chore: simplify get_output_account (#1760) --------- Co-authored-by: ananas-block <58553958+ananas-block@users.noreply.github.com> add light-compressed-token-sdk crate lint add tree and queue add account_info rename to decompress proof option fix lint rebased to main add c-token rust client helpers wip wip wip add test dir wip rev. transfersdk wip wip wip wip wip wip wip wip wip wip wip wip aadd lengthbuffer to cpi wuip --- js/stateless.js/src/rpc-interface.ts | 1 - .../examples/basic_usage.rs | 135 ----------- .../src/instructions.rs | 135 ++++++----- .../tests/integration_test.rs | 225 ++++++++++++++++++ .../src/cpi/account_info.rs | 2 +- .../src/cpi/instruction.rs | 20 +- sdk-libs/compressed-token-sdk/src/state.rs | 20 +- 7 files changed, 329 insertions(+), 209 deletions(-) delete mode 100644 sdk-libs/compressed-token-client/examples/basic_usage.rs create mode 100644 sdk-libs/compressed-token-client/tests/integration_test.rs diff --git a/js/stateless.js/src/rpc-interface.ts b/js/stateless.js/src/rpc-interface.ts index f5312d3a63..c6963bc132 100644 --- a/js/stateless.js/src/rpc-interface.ts +++ b/js/stateless.js/src/rpc-interface.ts @@ -114,7 +114,6 @@ export interface HexInputsForProver { leaf: string; } -// TODO: Rename Compressed -> ValidityProof export type CompressedProofWithContext = { compressedProof: CompressedProof; roots: BN[]; diff --git a/sdk-libs/compressed-token-client/examples/basic_usage.rs b/sdk-libs/compressed-token-client/examples/basic_usage.rs deleted file mode 100644 index 6e31e33686..0000000000 --- a/sdk-libs/compressed-token-client/examples/basic_usage.rs +++ /dev/null @@ -1,135 +0,0 @@ -//! Example demonstrating basic usage of the compressed-token-client library - -use light_compressed_token_client::{ - batch_compress, compress, create_decompress_instruction, AccountState, CompressedAccount, - DecompressParams, MerkleContext, TokenData, TreeType, -}; -use solana_sdk::pubkey::Pubkey; - -fn main() { - // Example 1: Simple compression - simple_compress_example(); - - // Example 2: Batch compression - batch_compress_example(); - - // Example 3: Decompression - decompress_example(); -} - -fn simple_compress_example() { - println!("=== Simple Compress Example ==="); - - let payer = Pubkey::new_unique(); - let owner = Pubkey::new_unique(); - let source_token_account = Pubkey::new_unique(); - let mint = Pubkey::new_unique(); - let recipient = Pubkey::new_unique(); - let output_state_tree = Pubkey::new_unique(); - - let instruction = compress( - payer, - owner, - source_token_account, - mint, - 1000, // amount - recipient, - output_state_tree, - ) - .expect("Failed to create compress instruction"); - - println!("Created compress instruction:"); - println!(" Program ID: {}", instruction.program_id); - println!(" Accounts: {} total", instruction.accounts.len()); - println!(); -} - -fn batch_compress_example() { - println!("=== Batch Compress Example ==="); - - let payer = Pubkey::new_unique(); - let owner = Pubkey::new_unique(); - let source_token_account = Pubkey::new_unique(); - let mint = Pubkey::new_unique(); - let output_state_tree = Pubkey::new_unique(); - - let recipients = vec![ - (Pubkey::new_unique(), 500), - (Pubkey::new_unique(), 300), - (Pubkey::new_unique(), 200), - ]; - - let _instruction = batch_compress( - payer, - owner, - source_token_account, - mint, - recipients.clone(), - output_state_tree, - ) - .expect("Failed to create batch compress instruction"); - - println!( - "Created batch compress instruction for {} recipients:", - recipients.len() - ); - for (recipient, amount) in recipients { - println!(" {} -> {} tokens", recipient, amount); - } - println!(); -} - -fn decompress_example() { - println!("=== Decompress Example ==="); - - let payer = Pubkey::new_unique(); - let owner = Pubkey::new_unique(); - let mint = Pubkey::new_unique(); - let destination_token_account = Pubkey::new_unique(); - let merkle_tree = Pubkey::new_unique(); - let queue = Pubkey::new_unique(); - - // Create mock compressed account data - let compressed_account = CompressedAccount { - owner: light_compressed_token_client::PROGRAM_ID, - lamports: 0, - data: None, - address: None, - }; - - let token_data = TokenData { - mint, - owner, - amount: 1000, - delegate: None, - state: AccountState::Initialized, - tlv: None, - }; - - let merkle_context = MerkleContext { - merkle_tree_pubkey: merkle_tree, - queue_pubkey: queue, - leaf_index: 0, - prove_by_index: false, - tree_type: TreeType::StateV2, - }; - - let params = DecompressParams { - payer, - input_compressed_token_accounts: vec![(compressed_account, token_data, merkle_context)], - to_address: destination_token_account, - amount: 500, - recent_input_state_root_indices: vec![Some(0)], - recent_validity_proof: None, - output_state_tree: Some(merkle_tree), - token_program_id: None, - }; - - let instruction = - create_decompress_instruction(params).expect("Failed to create decompress instruction"); - - println!("Created decompress instruction:"); - println!(" Program ID: {}", instruction.program_id); - println!(" Decompressing 500 tokens (500 remain compressed)"); - println!(); -} diff --git a/sdk-libs/compressed-token-client/src/instructions.rs b/sdk-libs/compressed-token-client/src/instructions.rs index c50ca8ceeb..5b160962f6 100644 --- a/sdk-libs/compressed-token-client/src/instructions.rs +++ b/sdk-libs/compressed-token-client/src/instructions.rs @@ -62,19 +62,18 @@ pub struct DecompressParams { /// Create a compress instruction /// -/// This instruction transfers tokens from an SPL token account to compressed token accounts. +/// This instruction compresses tokens from an SPL token account to N recipients. pub fn create_compress_instruction( params: CompressParams, ) -> Result { let token_program = params.token_program_id.unwrap_or(anchor_spl::token::ID); - // Create output compressed accounts - let output_compressed_accounts = if let Some(batch_recipients) = params.batch_recipients { + let output_compressed_accounts = if let Some(ref batch_recipients) = params.batch_recipients { batch_recipients - .into_iter() + .iter() .map(|(recipient, amount)| TokenTransferOutputData { - owner: recipient, - amount, + owner: *recipient, + amount: *amount, lamports: None, merkle_tree: params.output_state_tree, }) @@ -87,41 +86,46 @@ pub fn create_compress_instruction( merkle_tree: params.output_state_tree, }] }; - - // Calculate total amount let total_amount: u64 = output_compressed_accounts.iter().map(|x| x.amount).sum(); - // Create the instruction using the transfer SDK - transfer_sdk::create_transfer_instruction( + // TODO: refactor. + let ix = match transfer_sdk::create_transfer_instruction( ¶ms.payer, ¶ms.owner, - &[], // empty input merkle context for compression + &[], &output_compressed_accounts, - &[], // empty root indices for compression - &None, // no proof needed for compression - &[], // empty input token data for compression - &[], // empty input compressed accounts for compression + &[], + &None, + &[], + &[], params.mint, - None, // no delegate - true, // is_compress = true - Some(total_amount), // compress_or_decompress_amount - Some(crate::get_token_pool_pda(¶ms.mint)), // token_pool_pda - Some(params.source), // compress_or_decompress_token_account - false, // don't sort outputs - None, // no delegate change account - None, // no lamports change account - token_program == spl_token_2022::ID, // is_token_22 - &[], // no additional token pools - false, // with_transaction_hash = false - ) - .map_err(|e| { - CompressedTokenError::SerializationError(format!("Failed to create instruction: {:?}", e)) - }) + None, + true, + Some(total_amount), + Some(crate::get_token_pool_pda(¶ms.mint)), + Some(params.source), + false, + None, + None, + token_program == spl_token_2022::ID, + &[], + false, + ) { + Ok(ix) => ix, + Err(e) => { + return Err(CompressedTokenError::SerializationError(format!( + "Failed to create instruction: {:?}", + e + ))) + } + }; + + Ok(ix) } /// Create a decompress instruction /// -/// This instruction transfers tokens from compressed token accounts to an SPL token account. +/// This instruction decompresses compressed tokens to an SPL token account. pub fn create_decompress_instruction( params: DecompressParams, ) -> Result { @@ -133,7 +137,6 @@ pub fn create_decompress_instruction( let token_program = params.token_program_id.unwrap_or(anchor_spl::token::ID); - // Extract components from input accounts let (compressed_accounts, token_data, merkle_contexts): (Vec<_>, Vec<_>, Vec<_>) = params .input_compressed_token_accounts .into_iter() @@ -148,13 +151,9 @@ pub fn create_decompress_instruction( }, ); - // Get mint from first token data let mint = token_data[0].mint; - - // Get owner from first token data let owner = token_data[0].owner; - // Create output state for remaining tokens (if any) let input_total: u64 = token_data.iter().map(|td| td.amount).sum(); let remaining_amount = input_total.saturating_sub(params.amount); @@ -171,7 +170,7 @@ pub fn create_decompress_instruction( vec![] }; - // Create the instruction using the transfer SDK + // TODO: refactor. transfer_sdk::create_transfer_instruction( ¶ms.payer, &owner, @@ -182,26 +181,24 @@ pub fn create_decompress_instruction( &token_data, &compressed_accounts, mint, - None, // no delegate - false, // is_compress = false - Some(params.amount), // compress_or_decompress_amount - Some(crate::get_token_pool_pda(&mint)), // token_pool_pda - Some(params.to_address), // compress_or_decompress_token_account - false, // don't sort outputs - None, // no delegate change account - None, // no lamports change account - token_program == spl_token_2022::ID, // is_token_22 - &[], // no additional token pools - false, // with_transaction_hash = false + None, + false, + Some(params.amount), + Some(crate::get_token_pool_pda(&mint)), + Some(params.to_address), + false, + None, + None, + token_program == spl_token_2022::ID, + &[], + false, ) .map_err(|e| { CompressedTokenError::SerializationError(format!("Failed to create instruction: {:?}", e)) }) } -/// Helper function to create a simple compress instruction -/// -/// This is a convenience function for the most common compress use case. +/// Create a compress instruction with a single recipient. pub fn compress( payer: Pubkey, owner: Pubkey, @@ -224,27 +221,32 @@ pub fn compress( }) } -/// Helper function to create a batch compress instruction -/// -/// Compress tokens to multiple recipients in a single transaction. +/// Creates a compress instruction to compress tokens to multiple recipients. pub fn batch_compress( payer: Pubkey, owner: Pubkey, source_token_account: Pubkey, mint: Pubkey, - recipients: Vec<(Pubkey, u64)>, + recipients: Vec, + amounts: Vec, output_state_tree: Pubkey, ) -> Result { + if recipients.len() != amounts.len() { + return Err(CompressedTokenError::InvalidParams( + "Recipients and amounts must have the same length".to_string(), + )); + } + create_compress_instruction(CompressParams { payer, owner, source: source_token_account, - to_address: Pubkey::default(), // Not used in batch mode + to_address: Pubkey::default(), mint, - amount: 0, // Not used in batch mode + amount: 0, output_state_tree, token_program_id: None, - batch_recipients: Some(recipients), + batch_recipients: Some(recipients.into_iter().zip(amounts).collect()), }) } @@ -286,12 +288,21 @@ mod tests { let output_state_tree = Pubkey::new_unique(); let recipients = vec![ - (Pubkey::new_unique(), 500), - (Pubkey::new_unique(), 300), - (Pubkey::new_unique(), 200), + Pubkey::new_unique(), + Pubkey::new_unique(), + Pubkey::new_unique(), ]; + let amounts = vec![500, 300, 200]; - let result = batch_compress(payer, owner, source, mint, recipients, output_state_tree); + let result = batch_compress( + payer, + owner, + source, + mint, + recipients, + amounts, + output_state_tree, + ); assert!(result.is_ok()); let instruction = result.unwrap(); diff --git a/sdk-libs/compressed-token-client/tests/integration_test.rs b/sdk-libs/compressed-token-client/tests/integration_test.rs new file mode 100644 index 0000000000..ab9d1695ab --- /dev/null +++ b/sdk-libs/compressed-token-client/tests/integration_test.rs @@ -0,0 +1,225 @@ +#[cfg(test)] +mod tests { + use light_compressed_token_client::{ + batch_compress, compress, create_decompress_instruction, AccountState, CompressedAccount, + DecompressParams, MerkleContext, TokenData, TreeType, + }; + use solana_sdk::pubkey::Pubkey; + + #[test] + fn test_simple_compress() { + let payer = Pubkey::new_unique(); + let owner = Pubkey::new_unique(); + let source_token_account = Pubkey::new_unique(); + let mint = Pubkey::new_unique(); + let recipient = Pubkey::new_unique(); + let output_state_tree = Pubkey::new_unique(); + + let instruction = compress( + payer, + owner, + source_token_account, + mint, + 1000, // amount + recipient, + output_state_tree, + ) + .expect("Failed to create compress instruction"); + + assert_eq!( + instruction.program_id, + light_compressed_token_client::PROGRAM_ID + ); + assert!(!instruction.accounts.is_empty()); + + let account_keys: Vec<_> = instruction.accounts.iter().map(|a| a.pubkey).collect(); + assert!(account_keys.contains(&payer)); + assert!(account_keys.contains(&owner)); + assert!(account_keys.contains(&source_token_account)); + assert!(account_keys.contains(&output_state_tree)); + } + + #[test] + fn test_batch_compress() { + let payer = Pubkey::new_unique(); + let owner = Pubkey::new_unique(); + let source_token_account = Pubkey::new_unique(); + let mint = Pubkey::new_unique(); + let output_state_tree = Pubkey::new_unique(); + + let recipients = vec![ + Pubkey::new_unique(), + Pubkey::new_unique(), + Pubkey::new_unique(), + ]; + let amounts = vec![500, 300, 200]; + + let total_amount: u64 = amounts.iter().sum(); + assert_eq!(total_amount, 1000); + + let instruction = batch_compress( + payer, + owner, + source_token_account, + mint, + recipients, + amounts, + output_state_tree, + ) + .expect("Failed to create batch compress instruction"); + + assert_eq!( + instruction.program_id, + light_compressed_token_client::PROGRAM_ID + ); + assert!(!instruction.accounts.is_empty()); + + let account_keys: Vec<_> = instruction.accounts.iter().map(|a| a.pubkey).collect(); + assert!(account_keys.contains(&payer)); + assert!(account_keys.contains(&owner)); + assert!(account_keys.contains(&source_token_account)); + + assert!(account_keys.contains(&output_state_tree)); + } + + #[test] + fn test_decompress() { + let payer = Pubkey::new_unique(); + let owner = Pubkey::new_unique(); + let mint = Pubkey::new_unique(); + let destination_token_account = Pubkey::new_unique(); + let merkle_tree = Pubkey::new_unique(); + let queue = Pubkey::new_unique(); + + let compressed_account = CompressedAccount { + owner: light_compressed_token_client::PROGRAM_ID, + lamports: 0, + data: None, + address: None, + }; + + let token_data = TokenData { + mint, + owner, + amount: 1000, + delegate: None, + state: AccountState::Initialized, + tlv: None, + }; + + let merkle_context = MerkleContext { + merkle_tree_pubkey: merkle_tree, + queue_pubkey: queue, + leaf_index: 0, + prove_by_index: false, + tree_type: TreeType::StateV2, + }; + + let params = DecompressParams { + payer, + input_compressed_token_accounts: vec![( + compressed_account.clone(), + token_data.clone(), + merkle_context.clone(), + )], + to_address: destination_token_account, + amount: 500, + recent_input_state_root_indices: vec![Some(0)], + recent_validity_proof: None, + output_state_tree: Some(merkle_tree), + token_program_id: None, + }; + + let instruction = + create_decompress_instruction(params).expect("Failed to create decompress instruction"); + + assert_eq!( + instruction.program_id, + light_compressed_token_client::PROGRAM_ID + ); + assert!(!instruction.accounts.is_empty()); + + let account_keys: Vec<_> = instruction.accounts.iter().map(|a| a.pubkey).collect(); + assert!(account_keys.contains(&payer)); + assert!(account_keys.contains(&destination_token_account)); + assert!(account_keys.contains(&merkle_tree)); + assert!(account_keys.contains(&queue)); + + assert_eq!(token_data.amount, 1000); + assert_eq!(token_data.owner, owner); + assert_eq!(token_data.mint, mint); + assert_eq!(token_data.state, AccountState::Initialized); + + assert_eq!( + compressed_account.owner, + light_compressed_token_client::PROGRAM_ID + ); + assert_eq!(compressed_account.lamports, 0); + + assert_eq!(merkle_context.merkle_tree_pubkey, merkle_tree); + assert_eq!(merkle_context.queue_pubkey, queue); + assert_eq!(merkle_context.leaf_index, 0); + assert!(!merkle_context.prove_by_index); + assert_eq!(merkle_context.tree_type, TreeType::StateV2); + } + + #[test] + fn test_decompress_partial_amount() { + let payer = Pubkey::new_unique(); + let owner = Pubkey::new_unique(); + let mint = Pubkey::new_unique(); + let destination_token_account = Pubkey::new_unique(); + let merkle_tree = Pubkey::new_unique(); + let queue = Pubkey::new_unique(); + + let total_amount = 1000u64; + let decompress_amount = 500u64; + + let compressed_account = CompressedAccount { + owner: light_compressed_token_client::PROGRAM_ID, + lamports: 0, + data: None, + address: None, + }; + + let token_data = TokenData { + mint, + owner, + amount: total_amount, + delegate: None, + state: AccountState::Initialized, + tlv: None, + }; + + let merkle_context = MerkleContext { + merkle_tree_pubkey: merkle_tree, + queue_pubkey: queue, + leaf_index: 0, + prove_by_index: false, + tree_type: TreeType::StateV2, + }; + + let params = DecompressParams { + payer, + input_compressed_token_accounts: vec![( + compressed_account, + token_data.clone(), + merkle_context, + )], + to_address: destination_token_account, + amount: decompress_amount, + recent_input_state_root_indices: vec![Some(0)], + recent_validity_proof: None, + output_state_tree: Some(merkle_tree), + token_program_id: None, + }; + + let instruction = + create_decompress_instruction(params).expect("Failed to create decompress instruction"); + + assert!(instruction.accounts.len() > 0); + assert_eq!(token_data.amount, total_amount); + assert!(decompress_amount < total_amount); + assert_eq!(total_amount - decompress_amount, 500); + } +} diff --git a/sdk-libs/compressed-token-sdk/src/cpi/account_info.rs b/sdk-libs/compressed-token-sdk/src/cpi/account_info.rs index be5526b5ff..22d6a9d128 100644 --- a/sdk-libs/compressed-token-sdk/src/cpi/account_info.rs +++ b/sdk-libs/compressed-token-sdk/src/cpi/account_info.rs @@ -1,6 +1,6 @@ +use crate::state::InputTokenDataWithContext; use light_compressed_account::compressed_account::PackedMerkleContext; -use crate::state::InputTokenDataWithContext; /// Get an existing compressed token account from token_data in optimized /// format. /// diff --git a/sdk-libs/compressed-token-sdk/src/cpi/instruction.rs b/sdk-libs/compressed-token-sdk/src/cpi/instruction.rs index c097fad72c..4bc94c6386 100644 --- a/sdk-libs/compressed-token-sdk/src/cpi/instruction.rs +++ b/sdk-libs/compressed-token-sdk/src/cpi/instruction.rs @@ -1,3 +1,4 @@ +use crate::cpi::accounts::CompressedTokenDecompressCpiAccounts; #[cfg(feature = "anchor")] use anchor_lang::AnchorSerialize; #[cfg(not(feature = "anchor"))] @@ -11,10 +12,7 @@ use solana_program::{ pubkey::Pubkey, }; -use crate::{ - cpi::accounts::CompressedTokenDecompressCpiAccounts, - state::{CompressedTokenInstructionDataTransfer, InputTokenDataWithContext}, -}; +use crate::state::{CompressedTokenInstructionDataTransfer, InputTokenDataWithContext}; /// Return Instruction to decompress compressed token accounts. /// Proof can be None if prove_by_index is used. @@ -31,7 +29,7 @@ pub fn decompress( let accounts = vec![ AccountMeta::new(*light_cpi_accounts.fee_payer.key, true), AccountMeta::new_readonly(*light_cpi_accounts.authority.key, true), - AccountMeta::new_readonly(*light_cpi_accounts.cpi_authority_pda.key, true), + AccountMeta::new_readonly(*light_cpi_accounts.cpi_authority_pda.key, false), AccountMeta::new_readonly(*light_cpi_accounts.light_system_program.key, false), AccountMeta::new_readonly(*light_cpi_accounts.registered_program_pda.key, false), AccountMeta::new_readonly(*light_cpi_accounts.noop_program.key, false), @@ -47,7 +45,7 @@ pub fn decompress( ]; Ok(Instruction { - program_id: *light_cpi_accounts.token_program.key, + program_id: *light_cpi_accounts.self_program.key, accounts, data, }) @@ -75,12 +73,20 @@ pub fn decompress_token_instruction_data( compress_or_decompress_amount: Some(amount), cpi_context: cpi_context.copied(), lamports_change_account_merkle_tree_index: None, + with_transaction_hash: false, }; let mut inputs = Vec::new(); + // transfer discriminator + inputs.extend_from_slice(&[163, 52, 200, 231, 140, 3, 69, 186]); + let mut serialized_data = Vec::new(); compressed_token_instruction_data_transfer - .serialize(&mut inputs) + .serialize(&mut serialized_data) .unwrap(); + + // Add length buffer + inputs.extend_from_slice(&(serialized_data.len() as u32).to_le_bytes()); + inputs.extend_from_slice(&serialized_data); inputs } diff --git a/sdk-libs/compressed-token-sdk/src/state.rs b/sdk-libs/compressed-token-sdk/src/state.rs index ed32b34f71..c4abdec1db 100644 --- a/sdk-libs/compressed-token-sdk/src/state.rs +++ b/sdk-libs/compressed-token-sdk/src/state.rs @@ -6,8 +6,19 @@ use light_compressed_account::{ compressed_account::{CompressedAccountWithMerkleContext, PackedMerkleContext}, instruction_data::{compressed_proof::CompressedProof, cpi_context::CompressedCpiContext}, }; + use solana_program::pubkey::Pubkey; +#[derive(Clone, Debug, PartialEq, Eq, AnchorSerialize, AnchorDeserialize)] +pub struct PackedTokenTransferOutputData { + pub owner: Pubkey, + pub amount: u64, + pub lamports: Option, + pub merkle_tree_index: u8, + /// Placeholder for TokenExtension tlv data (unimplemented) + pub tlv: Option>, +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, AnchorDeserialize, AnchorSerialize)] #[repr(u8)] pub enum AccountState { @@ -42,14 +53,17 @@ pub struct TokenDataWithMerkleContext { pub struct CompressedTokenInstructionDataTransfer { pub proof: Option, pub mint: Pubkey, - - pub delegated_transfer: Option, + /// Is required if the signer is delegate, + /// -> delegate is authority account, + /// owner = Some(owner) is the owner of the token account. + pub delegated_transfer: Option, pub input_token_data_with_context: Vec, - pub output_compressed_accounts: Vec, + pub output_compressed_accounts: Vec, pub is_compress: bool, pub compress_or_decompress_amount: Option, pub cpi_context: Option, pub lamports_change_account_merkle_tree_index: Option, + pub with_transaction_hash: bool, } #[derive(Debug, Clone, AnchorSerialize, AnchorDeserialize)]