-
Notifications
You must be signed in to change notification settings - Fork 61
refactor: update Solana example #287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughThe Solana example shifts configuration from localnet to devnet, upgrades Anchor and related dependencies, integrates a gateway CPI, and extends the connected program with new functions (on_revert, trigger_deposit), caller validation via sysvar instruction inspection, expanded PDA state, and corresponding account-context changes. Several setup scripts and embedded keys were removed; an initialize script was added. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Connected as Connected Program
participant Gateway as Gateway Program
participant Sysvar as Instructions Sysvar
participant System as System Program
rect rgb(230,245,255)
Note over Connected: on_call flow (caller validation + funds)
Client->>Connected: on_call(amount, data, accounts...)
activate Connected
Connected->>Sysvar: get_instruction_relative(...)
Sysvar-->>Connected: caller instruction
alt invalid caller
Connected-->>Client: Error(InvalidCaller)
else valid caller
Connected->>Connected: compute distribution (50% to remaining_accounts)
Connected->>Connected: update PDA (shares, last_revert_*)
alt data contains "revert"
Connected-->>Client: Error(RevertMessage)
else
Connected-->>Client: Success / logs
end
end
deactivate Connected
end
rect rgb(245,230,255)
Note over Connected: on_revert flow
Client->>Connected: on_revert(amount, sender, data)
activate Connected
Connected->>Connected: store last_revert_sender & message
alt data contains "revert"
Connected-->>Client: Error(RevertMessage)
else
Connected-->>Client: Success / logs
end
deactivate Connected
end
rect rgb(235,255,230)
Note over Connected: trigger_deposit CPI to Gateway
Client->>Connected: trigger_deposit(amount, receiver, revert_options)
activate Connected
Connected->>Gateway: CPI deposit(amount, receiver, revert_options)
activate Gateway
Gateway->>System: Transfer funds
System-->>Gateway: Confirm
Gateway-->>Connected: Confirm
Connected-->>Client: Deposit triggered
deactivate Gateway
deactivate Connected
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
examples/call/solana/programs/connected/src/lib.rs (1)
145-147: Allocate sufficient PDA space for the expanded state.
size_of::<Pda>() + 32no longer covers bothlast_messageand the newlast_revert_message. Once the combined payloads exceed the tiny slack, Anchor will throwAccountDidNotSerializeand the instruction will revert. Please reserve concrete space for both strings (including discriminator and prefixes) and reference sharedMAX_*constants.- #[account(init, payer = signer, space = size_of::<Pda>() + 32, seeds = [b"connected"], bump)] + #[account( + init, + payer = signer, + space = 8 + + 20 + + 4 + MAX_MESSAGE_LEN + + 32 + + 4 + MAX_REVERT_MESSAGE_LEN, + seeds = [b"connected"], + bump + )]const MAX_MESSAGE_LEN: usize = 128; const MAX_REVERT_MESSAGE_LEN: usize = 128;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (2)
examples/call/solana/Cargo.lockis excluded by!**/*.lockexamples/call/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (10)
examples/call/.gitignore(1 hunks)examples/call/package.json(1 hunks)examples/call/solana/Anchor.toml(1 hunks)examples/call/solana/programs/connected/Cargo.toml(1 hunks)examples/call/solana/programs/connected/src/lib.rs(5 hunks)examples/call/solana/scripts/initialize.ts(1 hunks)examples/call/solana/setup/connected-keypair.json(0 hunks)examples/call/solana/setup/constants.ts(0 hunks)examples/call/solana/setup/encodeCallArgs.ts(0 hunks)examples/call/solana/setup/main.ts(0 hunks)
💤 Files with no reviewable changes (4)
- examples/call/solana/setup/encodeCallArgs.ts
- examples/call/solana/setup/constants.ts
- examples/call/solana/setup/main.ts
- examples/call/solana/setup/connected-keypair.json
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/App.tsx:8-9
Timestamp: 2025-09-17T20:09:36.410Z
Learning: In the zeta-chain/example-contracts repository, commit c9e419c6c8d6f045b06b2ba94c3c9f9b4ab05d0f addressed a runtime issue by splitting AppContent.tsx into DynamicAppContent.tsx and Eip6963AppContent.tsx components, providing better separation of concerns between dynamic wallet and EIP-6963 wallet implementations.
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/utils/ethersHelpers.ts:1-6
Timestamp: 2025-09-18T17:59:04.889Z
Learning: Commit 1c6cffd3d29499bf0544987a9116c7c6571ff895 in zeta-chain/example-contracts resolves the noble/hashes esbuild build failure by adding resolutions for "noble/hashes": "1.8.0" and "noble/curves": "1.9.7" to examples/hello/frontend/package.json.
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/ConnectedContent.tsx:3-10
Timestamp: 2025-09-18T18:00:10.177Z
Learning: Commit 1c6cffd3d29499bf0544987a9116c7c6571ff895 in zeta-chain/example-contracts#280 successfully resolved the noble/hashes "anumber" export error by adding resolutions in examples/hello/frontend/package.json to pin noble/hashes to 1.8.0 and noble/curves to 1.9.7, eliminating the version conflicts that were causing esbuild build failures.
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 296
File: examples/hello/frontend/src/hooks/useHandleCall.ts:158-164
Timestamp: 2025-10-08T17:47:55.635Z
Learning: In Solana integration for ZetaChain universal contracts, `revert_address` should be a Solana Pubkey (native Solana address), while `abort_address` should be a 20-byte Ethereum-style address as per the Rust struct definition: `pub struct RevertOptions { pub revert_address: Pubkey, pub abort_address: [u8; 20], ... }`.
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/DisconnectedContent.tsx:7-7
Timestamp: 2025-09-17T20:18:16.669Z
Learning: In the zeta-chain/example-contracts repository, example applications like the Hello frontend are designed specifically for local development use by developers to demonstrate the technology. For these demo applications, simpler patterns like hardcoded constants (e.g., USE_DYNAMIC_WALLET) are preferred over environment variable configuration to keep the setup straightforward for learning purposes.
🧬 Code graph analysis (2)
examples/call/solana/scripts/initialize.ts (1)
examples/call/solana/programs/connected/src/lib.rs (1)
initialize(12-14)
examples/call/solana/programs/connected/src/lib.rs (1)
examples/messaging/commands/message.ts (1)
message(100-124)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: slither (examples/hello, hello.sarif)
- GitHub Check: slither (examples/call, call.sarif)
- GitHub Check: slither (examples/swap, swap.sarif)
🔇 Additional comments (3)
examples/call/package.json (1)
48-48: Valid test dependency addition, but test infrastructure appears incomplete.The
ts-mochadevDependency is appropriate for TypeScript test execution. However, the test script at line 7 remains a placeholder that exits with an error, suggesting the test infrastructure is not yet operational.Verify that test files and a functional test script will be added to complete the test setup, or document if tests are deferred to a future PR.
examples/call/.gitignore (1)
22-22: Appropriate exclusion of Solana test artifacts.Ignoring the
test-ledgerdirectory is correct, as it contains generated Solana ledger data from local testing and should not be committed to version control.examples/call/solana/scripts/initialize.ts (1)
1-12: Well-structured initialization script with environment dependencies.The script follows Anchor best practices with proper provider setup, IDL-based program instantiation, and error handling. The initialize RPC call will correctly infer required accounts from the IDL.
Ensure the following prerequisites are met for successful execution:
- Environment variables:
ANCHOR_PROVIDER_URLandANCHOR_WALLETmust be configured forAnchorProvider.env()to function correctly.- IDL availability: The IDL file at
../target/idl/connected.jsonmust exist (typically generated viaanchor build).- Configuration alignment: The critical Anchor.toml configuration mismatch identified in the previous file must be resolved before this script can successfully interact with the deployed program.
| anchor-lang = { version = "=0.31.1" } | ||
| anchor-spl = { version = "=0.31.1" } | ||
| spl-associated-token-account = { version = "6.0.0", features = ["no-entrypoint"] } | ||
| gateway = { git = "https://github.com/zeta-chain/protocol-contracts-solana/", version = "0.1.0", features = ["cpi", "no-entrypoint"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove incompatible version field from git dependency.
Cargo rejects dependencies that specify both git and version; this manifest will not parse, so the program cannot even compile. Drop the version key (or switch to a tag/rev) so the build succeeds.
-gateway = { git = "https://github.com/zeta-chain/protocol-contracts-solana/", version = "0.1.0", features = ["cpi", "no-entrypoint"] }
+gateway = { git = "https://github.com/zeta-chain/protocol-contracts-solana/", features = ["cpi", "no-entrypoint"] }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| gateway = { git = "https://github.com/zeta-chain/protocol-contracts-solana/", version = "0.1.0", features = ["cpi", "no-entrypoint"] } | |
| gateway = { git = "https://github.com/zeta-chain/protocol-contracts-solana/", features = ["cpi", "no-entrypoint"] } |
🤖 Prompt for AI Agents
In examples/call/solana/programs/connected/Cargo.toml around line 23, the
dependency entry mixes git and version fields which Cargo rejects; remove the
version field (or replace it with an explicit tag/rev) so the dependency uses
only git (or git + tag/rev). Update the gateway line to drop version = "0.1.0"
and, if you need a specific commit/tag, replace version with tag = "<tag>" or
rev = "<rev>" accordingly so the manifest parses and the program can build.
| let message = String::from_utf8(data).map_err(|_| ErrorCode::InvalidDataFormat)?; | ||
| pda.last_message = message; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard message lengths to match the PDA allocation.
Even after resizing the account, arbitrary payloads can exceed the reserved capacity, again triggering AccountDidNotSerialize. Add explicit require! checks before persisting both the call and revert messages, and introduce an error code so callers get a clear signal instead of a cryptic serialization failure.
let message = String::from_utf8(data).map_err(|_| ErrorCode::InvalidDataFormat)?;
+ require!(message.len() <= MAX_MESSAGE_LEN, ErrorCode::MessageTooLong); let message = String::from_utf8(data).map_err(|_| ErrorCode::InvalidDataFormat)?;
+ require!(message.len() <= MAX_REVERT_MESSAGE_LEN, ErrorCode::MessageTooLong); #[msg("Caller is not the gateway program.")]
InvalidCaller,
+ #[msg("Message exceeds the maximum length reserved in the PDA.")]
+ MessageTooLong,Also applies to: 94-95, 205-209
|
|
||
| [programs.localnet] | ||
| connected = "9BjVGjn28E58LgSi547JYEpqpgRoo1TErkbyXiRSNDQy" | ||
| [programs.devnet] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want to point directly to devnet here or keep localnet as default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only got it working on devnet now, so this is what I'm defaulting to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll need to update Localnet with the newer version of the Gateway and make sure this example works there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
examples/call/package.json (1)
48-48: Consider clarifying the ts-mocha addition and testing strategy across examples.The addition of ts-mocha to devDependencies here differs from other examples in the PR. Verify that:
- The mocha test runner is explicitly configured and needed (existing @types/mocha suggests mocha may already be present as a transitive dependency).
- The ts-mocha ^11.1.0 version is compatible with ts-node (>=8.0.0) in the project.
- If ts-mocha is necessary for this example's testing needs, consider whether it should be added to other examples as well for consistency.
The zetachain version pinning to 7.4.0 (exact version, no caret) is appropriate and aligns with the refactor's intent to lock to a known-good version. Ensure all examples have been tested against this version.
Also applies to: 66-66
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (6)
examples/call/yarn.lockis excluded by!**/yarn.lock,!**/*.lockexamples/hello/yarn.lockis excluded by!**/yarn.lock,!**/*.lockexamples/messaging/yarn.lockis excluded by!**/yarn.lock,!**/*.lockexamples/nft/yarn.lockis excluded by!**/yarn.lock,!**/*.lockexamples/swap/yarn.lockis excluded by!**/yarn.lock,!**/*.lockexamples/token/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (7)
examples/call/package.json(2 hunks)examples/call/solana/Anchor.toml(1 hunks)examples/hello/package.json(1 hunks)examples/messaging/package.json(1 hunks)examples/nft/package.json(1 hunks)examples/swap/package.json(1 hunks)examples/token/package.json(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- examples/token/package.json
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/App.tsx:8-9
Timestamp: 2025-09-17T20:09:36.410Z
Learning: In the zeta-chain/example-contracts repository, commit c9e419c6c8d6f045b06b2ba94c3c9f9b4ab05d0f addressed a runtime issue by splitting AppContent.tsx into DynamicAppContent.tsx and Eip6963AppContent.tsx components, providing better separation of concerns between dynamic wallet and EIP-6963 wallet implementations.
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/utils/ethersHelpers.ts:1-6
Timestamp: 2025-09-18T17:59:04.889Z
Learning: Commit 1c6cffd3d29499bf0544987a9116c7c6571ff895 in zeta-chain/example-contracts resolves the noble/hashes esbuild build failure by adding resolutions for "noble/hashes": "1.8.0" and "noble/curves": "1.9.7" to examples/hello/frontend/package.json.
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/ConnectedContent.tsx:3-10
Timestamp: 2025-09-18T18:00:10.177Z
Learning: Commit 1c6cffd3d29499bf0544987a9116c7c6571ff895 in zeta-chain/example-contracts#280 successfully resolved the noble/hashes "anumber" export error by adding resolutions in examples/hello/frontend/package.json to pin noble/hashes to 1.8.0 and noble/curves to 1.9.7, eliminating the version conflicts that were causing esbuild build failures.
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 296
File: examples/hello/frontend/src/hooks/useHandleCall.ts:158-164
Timestamp: 2025-10-08T17:47:55.635Z
Learning: In Solana integration for ZetaChain universal contracts, `revert_address` should be a Solana Pubkey (native Solana address), while `abort_address` should be a 20-byte Ethereum-style address as per the Rust struct definition: `pub struct RevertOptions { pub revert_address: Pubkey, pub abort_address: [u8; 20], ... }`.
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/DisconnectedContent.tsx:7-7
Timestamp: 2025-09-17T20:18:16.669Z
Learning: In the zeta-chain/example-contracts repository, example applications like the Hello frontend are designed specifically for local development use by developers to demonstrate the technology. For these demo applications, simpler patterns like hardcoded constants (e.g., USE_DYNAMIC_WALLET) are preferred over environment variable configuration to keep the setup straightforward for learning purposes.
📚 Learning: 2025-09-18T17:59:04.889Z
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/utils/ethersHelpers.ts:1-6
Timestamp: 2025-09-18T17:59:04.889Z
Learning: Commit 1c6cffd3d29499bf0544987a9116c7c6571ff895 in zeta-chain/example-contracts resolves the noble/hashes esbuild build failure by adding resolutions for "noble/hashes": "1.8.0" and "noble/curves": "1.9.7" to examples/hello/frontend/package.json.
Applied to files:
examples/hello/package.jsonexamples/messaging/package.jsonexamples/swap/package.jsonexamples/call/package.jsonexamples/nft/package.json
📚 Learning: 2025-09-18T18:00:10.177Z
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/ConnectedContent.tsx:3-10
Timestamp: 2025-09-18T18:00:10.177Z
Learning: Commit 1c6cffd3d29499bf0544987a9116c7c6571ff895 in zeta-chain/example-contracts#280 successfully resolved the noble/hashes "anumber" export error by adding resolutions in examples/hello/frontend/package.json to pin noble/hashes to 1.8.0 and noble/curves to 1.9.7, eliminating the version conflicts that were causing esbuild build failures.
Applied to files:
examples/hello/package.jsonexamples/messaging/package.jsonexamples/swap/package.jsonexamples/call/package.jsonexamples/nft/package.json
📚 Learning: 2025-09-17T21:47:04.873Z
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/AppContent.tsx:6-6
Timestamp: 2025-09-17T21:47:04.873Z
Learning: The noble/hashes version conflict issue in zeta-chain/example-contracts should be resolved at the zetachain/wallet library level by adding resolutions to force compatible versions, protecting all consumers from this transitive dependency issue.
Applied to files:
examples/hello/package.jsonexamples/messaging/package.jsonexamples/swap/package.jsonexamples/call/package.jsonexamples/nft/package.json
📚 Learning: 2025-09-17T21:47:04.873Z
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/AppContent.tsx:6-6
Timestamp: 2025-09-17T21:47:04.873Z
Learning: zetachain/wallet brings in viem and dynamic-labs packages that cause noble/hashes version conflicts. The library should add resolutions for noble/hashes and noble/curves to protect all consumers from this transitive dependency issue.
Applied to files:
examples/hello/package.jsonexamples/messaging/package.jsonexamples/swap/package.jsonexamples/call/package.jsonexamples/nft/package.json
📚 Learning: 2025-09-17T20:09:36.410Z
Learnt from: hernan-clich
Repo: zeta-chain/example-contracts PR: 280
File: examples/hello/frontend/src/App.tsx:8-9
Timestamp: 2025-09-17T20:09:36.410Z
Learning: In the zeta-chain/example-contracts repository, commit c9e419c6c8d6f045b06b2ba94c3c9f9b4ab05d0f addressed a runtime issue by splitting AppContent.tsx into DynamicAppContent.tsx and Eip6963AppContent.tsx components, providing better separation of concerns between dynamic wallet and EIP-6963 wallet implementations.
Applied to files:
examples/hello/package.jsonexamples/messaging/package.jsonexamples/swap/package.jsonexamples/call/package.jsonexamples/nft/package.json
🔇 Additional comments (5)
examples/call/solana/Anchor.toml (1)
7-15: Configuration now properly aligned for devnet deployment.The program declaration
[programs.devnet]is now consistent with the providercluster = "devnet"configuration. This resolves the prior critical cluster mismatch that would have caused runtime failures. The program address and wallet configuration are in place.Note that while the configuration is now correct, the PR objectives indicate ongoing transaction failures on devnet (withdraw-and-call and call commands failing). These appear to be functional/logic issues rather than configuration concerns, and may warrant investigation in the connected program implementation or transaction payload construction.
examples/hello/package.json (1)
60-60: Version pinning strategy change: zetachain now locked to 7.4.0.The zetachain dependency has been pinned to exact version 7.4.0 (removing the caret ^). This prevents automatic minor/patch updates and requires manual intervention for future upgrades. Verify that this deliberate locking aligns with your version management strategy and that all functionality has been validated against 7.4.0.
Also applies to: 61-61
examples/nft/package.json (1)
64-64: Version pinning: zetachain locked to 7.4.0 across the NFT example.The dependency update is consistent with other examples in this PR. Ensure 7.4.0 has been validated in the context of the NFT example's functionality.
Also applies to: 65-65
examples/swap/package.json (1)
62-62: Version pinning: zetachain locked to 7.4.0 in the swap example.Consistent with the broader refactor. Verify that swap functionality works correctly with the new zetachain version.
Also applies to: 63-63
examples/messaging/package.json (1)
66-66: Version pinning: zetachain locked to 7.4.0 in the messaging example.Consistent with the refactor across all examples. Verify that messaging contracts and their CLI operations function correctly with 7.4.0.
Also applies to: 67-67
Follow the docs: zeta-chain/docs#685
Summary by CodeRabbit
New Features
Bug Fixes
Chores