Skip to content

[TA-4413]: verification base setup#4

Merged
AdriaCarrera merged 9 commits intomainfrom
contracts/feat/verification-contract-setup
Apr 17, 2025
Merged

[TA-4413]: verification base setup#4
AdriaCarrera merged 9 commits intomainfrom
contracts/feat/verification-contract-setup

Conversation

@GuillemGarciaDev
Copy link
Collaborator

@GuillemGarciaDev GuillemGarciaDev commented Apr 8, 2025

[TA-4413]: verification base setup

This PR includes the FastAuthGuard (FAGuard) contract, which is responsible for verifying the authenticity of a user's request. It also scaffolds the FastAuth contract without any logic.

The goal of this contract is to act as a proxy contract to abstract any verification implementation directly to the contract itself. You can add custom guards which must implement the ExternalGuard trait. The governance over this guards remains private to the FastAuthGuard contract owner in this initial version.

Changes 🛠️

contracts/fa-guard

  • Created new contract.
  • Added add_guard, get_guard and delete_guard guard governance methods.
  • Added verify and on_verify_callback methods.
  • Contract unit tests.
  • Contract integration tests.

contracts/fa

  • basic contract setup

Summary by CodeRabbit

  • New Features

    • Introduced the FastAuth Guard smart contract package, providing guard verification and management capabilities.
    • Added a mock external guard contract for testing purposes.
    • Included detailed documentation and build instructions for the new contract.
    • Added comprehensive tests for guard management and verification functionality.
  • Chores

    • Updated workspace configuration to include the new contract and remove deprecated app entries.
    • Added Rust toolchain configuration for consistent development setup.
  • Refactor

    • Renamed the "contracts" package to "fa" for improved clarity.
  • Bug Fixes

    • None.
  • Documentation

    • Updated and added README files reflecting new package names and features.
  • Tests

    • Added new test suites to ensure contract reliability.
  • Revert

    • Removed deprecated app and configuration files related to previous projects.

@GuillemGarciaDev GuillemGarciaDev added the contracts contracts app label Apr 8, 2025
@GuillemGarciaDev GuillemGarciaDev marked this pull request as ready for review April 8, 2025 13:19
@coderabbitai
Copy link

coderabbitai bot commented Apr 8, 2025

📝 Walkthrough

Walkthrough

This change removes the apps/contracts and apps/relayer projects, including all their configuration, source, and test files. In their place, it introduces a new smart contract package under contracts/fa-guard, which includes contract logic, interfaces, mocks, tests, and supporting configuration files. Additionally, the workspace configuration is updated to reflect these changes, removing the old projects and adding a new one. There are also minor updates to the contracts/fa package, including a package rename and documentation/header adjustments.

Changes

File(s) / Path(s) Change Summary
apps/contracts/package.json Removed project configuration and scripts for the contracts application.
apps/relayer/* (all files: .eslintrc.js, package.json, src/index.ts, test/index.test.ts, tsconfig.json) Removed the entire relayer application, including its configuration, source, linting, and test files.
pnpm-workspace.yaml Removed apps/relayer and apps/contracts from the workspace; added contracts/fa-verification.
contracts/fa/Cargo.toml Renamed package from contracts to fa.
contracts/fa/README.md Changed document header from # contracts to # fa.
contracts/fa/rust-toolchain.toml Added Rust toolchain configuration specifying stable channel, rustfmt component, and WASM target.
contracts/fa-guard/Cargo.toml Added new Cargo.toml for the fa-guard package, specifying metadata, dependencies, build settings, and workspace members.
contracts/fa-guard/README.md Added documentation describing the FastAuth Guard contract, build instructions, and related links.
contracts/fa-guard/package.json Added Node.js package configuration for @contracts/fa-guard, including build and test scripts.
contracts/fa-guard/src/interfaces.rs Introduced ExternalGuard trait/interface for cross-contract calls with a verify method.
contracts/fa-guard/src/lib.rs Implemented the FaGuard smart contract with guard management, verification logic, and inline tests.
contracts/fa-guard/mocks/external-guard/Cargo.toml Added Cargo.toml for a mock external guard contract, with dependencies and dev-dependencies.
contracts/fa-guard/mocks/external-guard/src/lib.rs Implemented MockExternalGuard struct with a verify method returning a static successful result.
contracts/fa-guard/tests/test_basics.rs Added test suite covering CRUD operations for guards and the verification mechanism.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant FaGuardContract
    participant ExternalGuard (Mock)
    
    Client->>FaGuardContract: add_guard(guard_id, guard_address)
    FaGuardContract->>FaGuardContract: Store guard mapping

    Client->>FaGuardContract: get_guard(guard_id)
    FaGuardContract->>Client: Return guard_address

    Client->>FaGuardContract: verify(guard_id, payload)
    FaGuardContract->>ExternalGuard (Mock): verify(payload)
    ExternalGuard (Mock)-->>FaGuardContract: (bool, user, permissions)
    FaGuardContract->>FaGuardContract: on_verify_callback(result)
    FaGuardContract->>Client: Return verification result
Loading

Possibly related PRs

  • [TA-4295]: base project #1: Introduces the original apps/contracts and apps/relayer projects and their configuration files, which this PR removes and replaces with new contract architecture.

Suggested reviewers

  • AdriaCarrera

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between de41b7f and 9a41adc.

📒 Files selected for processing (1)
  • contracts/fa-guard/mocks/external-guard/src/lib.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • contracts/fa-guard/mocks/external-guard/src/lib.rs

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (20)
contracts/fa/.github/workflows/undeploy-staging.yml (1)

1-26: Undeploy Staging Workflow: Clear and Well-Structured

The workflow script clearly constructs the staging account ID using GitHub context variables and follows the expected steps (checkout, install NEAR CLI, delete account). Consider verifying that the NEAR CLI installer version (v0.11.1) is current and, if needed, adding error handling (e.g., using set -e in the multi-line run block) to ensure a robust cleanup process.

contracts/fa/.github/workflows/deploy-production.yml (1)

10-12: Job ID Naming Consistency

The job ID used here is "deploy-staging" despite the workflow deploying to production. Renaming it to something like "deploy-production" would improve clarity and reduce potential confusion between staging and production deployments.

contracts/fa/.github/workflows/test.yml (1)

1-33: Test Workflow Configuration Looks Good

This workflow efficiently covers code formatting (via cargo fmt), linting (using cargo clippy), and testing (with cargo test). For further optimization, you might consider adding caching for cargo dependencies to reduce job run times.

contracts/fa/.github/workflows/deploy-staging.yml (2)

39-42: Remove Trailing Spaces in Comments

Static analysis has flagged trailing spaces on lines 41 and 42. Removing these extraneous spaces will help maintain compliance with YAML linting standards.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 41-41: trailing spaces

(trailing-spaces)


[error] 42-42: trailing spaces

(trailing-spaces)


52-57: Ensure GitHub CLI Availability

The step that comments on the pull request uses the GitHub CLI (gh pr comment). Please verify that the GitHub CLI is available in the runner environment or consider adding an installation step if required.

contracts/fa/Cargo.toml (1)

1-9: Repository Field Placeholder.
The package renaming to "fa" is correctly applied, and overall the configuration looks good. However, the repository field (line 9) is still using a placeholder URL. Consider updating it to a valid repository URL to improve the discoverability and integration with NEAR ecosystem tools.

contracts/fa/README.md (1)

1-38: Updated Documentation Header with Opportunities for Expansion.
Changing the header from # contracts to # fa correctly reflects the new package name. However, since the FastAuth contract scaffolding has been introduced in this PR, it would be beneficial to expand the README with a brief explanation of the FastAuth purpose and usage. This will help onboard developers and clarify its role within the overall verification system.

🧰 Tools
🪛 LanguageTool

[grammar] ~32-~32: This phrase is duplicated. You should probably use “Documentation NEAR” only once.
Context: ...hain from command line - NEAR Rust SDK Documentation - NEAR Documentation - [NEAR StackOverflow](https://stackoverflow.co...

(PHRASE_REPETITION)


[grammar] ~35-~35: Adverb repetition.
Context: ...w.com/questions/tagged/nearprotocol) - NEAR Discord - [NEAR Telegram Developers Community Group](ht...

(ADVERB_VERB_ADVERB_REPETITION)

contracts/fa-guard/package.json (1)

1-14: New FastAuthGuard Package Setup.
The new package.json for @contracts/fa-guard is set up correctly with the necessary build and test scripts. For improved metadata and clarity, consider providing values for the "description" and "author" fields.

contracts/fa-guard/README.md (1)

1-37: Well-structured documentation, consider enhancing with architectural context.

The README provides clear instructions on building and testing, along with useful resources. However, it would benefit from additional context explaining how the FastAuth Guard fits into the broader system architecture and interacts with other components like the FastAuth contract mentioned in the PR description.

🧰 Tools
🪛 LanguageTool

[grammar] ~31-~31: This phrase is duplicated. You should probably use “Documentation NEAR” only once.
Context: ...hain from command line - NEAR Rust SDK Documentation - NEAR Documentation - [NEAR StackOverflow](https://stackoverflow.co...

(PHRASE_REPETITION)


[grammar] ~34-~34: Adverb repetition.
Context: ...w.com/questions/tagged/nearprotocol) - NEAR Discord - [NEAR Telegram Developers Community Group](ht...

(ADVERB_VERB_ADVERB_REPETITION)

contracts/fa-guard/src/interfaces.rs (1)

3-7: Add more detailed documentation to the interface.

The ExternalGuard trait is minimalistic but could benefit from additional documentation explaining:

  • The expected format or structure of the payload parameter
  • What the boolean return value signifies (success/failure criteria)
  • Any security considerations for implementers
 // Validator interface, for cross-contract calls
 #[ext_contract(external_guard)]
 pub trait ExternalGuard {
+    /// Verifies the authenticity of the provided payload
+    ///
+    /// # Arguments
+    /// * `payload` - The data to verify, typically in a serialized format
+    ///
+    /// # Returns
+    /// * `bool` - Returns true if verification succeeds, false otherwise
     fn verify(&self, payload: String) -> bool;
 }
contracts/fa-guard/mocks/external-guard/src/lib.rs (2)

3-18: Consider enhancing the mock for more comprehensive testing.

The implementation is appropriate for basic testing, but could be extended to support more complex testing scenarios.

Consider adding features that would make testing more robust:

 #[near(contract_state)]
-pub struct MockExternalGuard {}
+pub struct MockExternalGuard {
+    // Store expected results for specific payloads
+    expected_results: near_sdk::collections::LookupMap<String, bool>,
+    // Default result for payloads not explicitly set
+    default_result: bool,
+}

 impl Default for MockExternalGuard {
     fn default() -> Self {
-        Self {}
+        Self {
+            expected_results: near_sdk::collections::LookupMap::new(b"e"),
+            default_result: false,
+        }
     }
 }

 #[near]
 impl MockExternalGuard {
     pub fn verify(&self, payload: String) -> bool {
-        // For testing, we'll just return true if the payload is not empty
-        !payload.is_empty()
+        // Return specific result if set, otherwise use default behavior
+        self.expected_results.get(&payload).unwrap_or_else(|| {
+            // Default implementation: true if payload is not empty
+            !payload.is_empty() && self.default_result
+        })
+    }
+
+    // Method to set expected result for specific payload
+    pub fn set_expected_result(&mut self, payload: String, result: bool) {
+        self.expected_results.insert(payload, result);
+    }
+
+    // Method to set default result
+    pub fn set_default_result(&mut self, result: bool) {
+        self.default_result = result;
+    }
 }

20-30: Tests should be updated to match the enhanced implementation.

If you implement the suggested enhancements to the MockExternalGuard struct, update the tests to verify the new functionality.

 #[cfg(test)]
 mod tests {
     use super::*;

     #[test]
     fn test_verify() {
-        let contract = MockExternalGuard::default();
+        let mut contract = MockExternalGuard::default();
+        
+        // Test default behavior
         assert!(contract.verify("test".to_string()));
         assert!(!contract.verify("".to_string()));
+        
+        // Test custom expected results
+        contract.set_expected_result("special_payload".to_string(), true);
+        assert!(contract.verify("special_payload".to_string()));
+        
+        // Test default result override
+        contract.set_default_result(true);
+        assert!(contract.verify("".to_string())); // Now empty string returns true
     }
 }
contracts/fa-guard/Cargo.toml (3)

3-3: Update the placeholder project description.

The current description "cargo-near-new-project-description" is a default placeholder and should be replaced with an accurate description of the FastAuthGuard contract's purpose.

-description = "cargo-near-new-project-description"
+description = "FastAuth Guard contract for verification of user requests"

6-9: Complete the repository field in package metadata.

The TODO comment and placeholder repository URL should be filled with the actual repository URL to ensure proper discovery by NEAR ecosystem tools and compliance with NEP-0330.

-# TODO: Fill out the repository field to help NEAR ecosystem tools to discover your project.
-# NEP-0330 is automatically implemented for all contracts built with https://github.com/near/cargo-near.
-# Link to the repository will be available via `contract_source_metadata` view-function.
-repository = "https://github.com/<xxx>/<xxx>"
+# NEP-0330 is automatically implemented for all contracts built with https://github.com/near/cargo-near.
+# Link to the repository will be available via `contract_source_metadata` view-function.
+repository = "https://github.com/Peersyst/fast-auth"

24-27: Consider implementing a more robust environment variable passing mechanism.

The passed_env array is currently empty, but you might want to consider adding environment variables that could be relevant for reproducible builds, such as RUSTFLAGS or other build-specific configurations.

# in a reproducible manner
# supported by `sourcescan/cargo-near:0.10.1-rust-1.82.0` image or later images
-passed_env = []
+passed_env = ["RUSTFLAGS", "CARGO_NET_GIT_FETCH_WITH_CLI"]
contracts/fa-guard/tests/test_basics.rs (2)

74-74: Potential hardcoded path issue for mock guard WASM.

The path to the mock guard WASM file is hardcoded, which might cause issues if the build directory structure changes or if the tests are run in a different environment.

Consider using a more dynamic approach to find the WASM file, or at least add error handling for when the file isn't found:

-let mock_guard = sandbox.dev_deploy(include_bytes!("../target/wasm32-unknown-unknown/release/external_guard.wasm")).await?;
+// Compile the mock guard directly or use a more robust path resolution
+let mock_guard_wasm = near_workspaces::compile_project("./mocks/external-guard").await?;
+let mock_guard = sandbox.dev_deploy(&mock_guard_wasm).await?;

87-100: Enhance the verification test with more payload variants.

The test only checks a successful verification case with a "test_payload" string. Consider testing with different payloads including edge cases to ensure robust verification.

// Call verify with a test payload
let verify_outcome = contract
    .call("verify")
    .args_json(json!({
        "guard_id": "mock",
        "payload": "test_payload"
    }))
    .transact()
    .await?;
assert!(verify_outcome.is_success());

+// Test with an empty payload (should fail verification but not the transaction)
+let empty_verify_outcome = contract
+    .call("verify")
+    .args_json(json!({
+        "guard_id": "mock",
+        "payload": ""
+    }))
+    .transact()
+    .await?;
+assert!(empty_verify_outcome.is_success()); // Transaction should succeed
+// The verification result should be false, which we could check via events or a view method
contracts/fa-guard/src/lib.rs (3)

47-51: Consider adding existence checks before adding guards.

The add_guard method doesn't check if the guard already exists. While overwriting is a valid behavior, you might want to add a log message if you're overwriting an existing guard.

#[private]
pub fn add_guard(&mut self, guard_id: String, guard_address: AccountId) {
-    log!("Saving guard: {guard_id}");
+    if let Some(existing_address) = self.guards.get(&guard_id) {
+        log!("Overwriting existing guard: {guard_id}, old address: {existing_address}, new address: {guard_address}");
+    } else {
+        log!("Adding new guard: {guard_id}");
+    }
    self.guards.insert(guard_id, guard_address);
}

10-13: Consider adding more detailed documentation for the contract structure.

The contract structure could benefit from more detailed documentation explaining its purpose and functionality.

// Define the contract structure
#[near(contract_state)]
+/// FaGuard contract manages external verification guards
+/// It allows adding, removing, and querying guards
+/// Each guard implements the ExternalGuard trait
+/// The contract is used to verify payloads using the specified guards
pub struct FaGuard{
    guards: HashMap<String, AccountId>,
}

53-58: Consider checking if the guard exists before removing it.

The remove_guard method doesn't check if the guard exists before attempting to remove it. Although HashMap::remove works silently when the key doesn't exist, it might be more helpful to log whether a guard was actually removed.

#[private]
pub fn remove_guard(&mut self, guard_id: String) {
-    log!("Removing guard: {guard_id}");
-    self.guards.remove(&guard_id);
+    if let Some(removed) = self.guards.remove(&guard_id) {
+        log!("Removed guard: {guard_id}, address: {removed}");
+    } else {
+        log!("Attempted to remove non-existent guard: {guard_id}");
+    }
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa6c2c8 and e537b8c.

⛔ Files ignored due to path filters (2)
  • contracts/fa-guard/Cargo.lock is excluded by !**/*.lock
  • contracts/fa/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (23)
  • apps/contracts/package.json (0 hunks)
  • apps/relayer/.eslintrc.js (0 hunks)
  • apps/relayer/package.json (0 hunks)
  • apps/relayer/src/index.ts (0 hunks)
  • apps/relayer/test/index.test.ts (0 hunks)
  • apps/relayer/tsconfig.json (0 hunks)
  • contracts/fa-guard/Cargo.toml (1 hunks)
  • contracts/fa-guard/README.md (1 hunks)
  • contracts/fa-guard/mocks/external-guard/Cargo.toml (1 hunks)
  • contracts/fa-guard/mocks/external-guard/src/lib.rs (1 hunks)
  • contracts/fa-guard/package.json (1 hunks)
  • contracts/fa-guard/src/interfaces.rs (1 hunks)
  • contracts/fa-guard/src/lib.rs (1 hunks)
  • contracts/fa-guard/tests/test_basics.rs (1 hunks)
  • contracts/fa/.github/workflows/deploy-production.yml (1 hunks)
  • contracts/fa/.github/workflows/deploy-staging.yml (1 hunks)
  • contracts/fa/.github/workflows/test.yml (1 hunks)
  • contracts/fa/.github/workflows/undeploy-staging.yml (1 hunks)
  • contracts/fa/.gitignore (1 hunks)
  • contracts/fa/Cargo.toml (1 hunks)
  • contracts/fa/README.md (1 hunks)
  • contracts/fa/rust-toolchain.toml (1 hunks)
  • pnpm-workspace.yaml (1 hunks)
💤 Files with no reviewable changes (6)
  • apps/contracts/package.json
  • apps/relayer/src/index.ts
  • apps/relayer/test/index.test.ts
  • apps/relayer/package.json
  • apps/relayer/.eslintrc.js
  • apps/relayer/tsconfig.json
🧰 Additional context used
🧬 Code Definitions (4)
contracts/fa-guard/src/interfaces.rs (1)
contracts/fa-guard/src/lib.rs (1)
  • verify (63-72)
contracts/fa-guard/src/lib.rs (2)
contracts/fa-guard/mocks/external-guard/src/lib.rs (1)
  • verify (14-17)
contracts/fa-guard/src/interfaces.rs (1)
  • verify (6-6)
contracts/fa-guard/tests/test_basics.rs (2)
contracts/fa/tests/test_basics.rs (1)
  • test_contract_is_operational (4-9)
contracts/fa-guard/mocks/external-guard/src/lib.rs (1)
  • test_verify (25-29)
contracts/fa-guard/mocks/external-guard/src/lib.rs (3)
contracts/fa/src/lib.rs (1)
  • default (12-16)
contracts/fa-guard/src/lib.rs (2)
  • default (17-21)
  • verify (63-72)
contracts/fa-guard/tests/test_basics.rs (1)
  • test_verify (69-103)
🪛 LanguageTool
contracts/fa-guard/README.md

[grammar] ~31-~31: This phrase is duplicated. You should probably use “Documentation NEAR” only once.
Context: ...hain from command line - NEAR Rust SDK Documentation - NEAR Documentation - [NEAR StackOverflow](https://stackoverflow.co...

(PHRASE_REPETITION)


[grammar] ~34-~34: Adverb repetition.
Context: ...w.com/questions/tagged/nearprotocol) - NEAR Discord - [NEAR Telegram Developers Community Group](ht...

(ADVERB_VERB_ADVERB_REPETITION)

🪛 YAMLlint (1.35.1)
contracts/fa/.github/workflows/deploy-staging.yml

[error] 41-41: trailing spaces

(trailing-spaces)


[error] 42-42: trailing spaces

(trailing-spaces)

🔇 Additional comments (9)
contracts/fa/rust-toolchain.toml (1)

1-5: Rust Toolchain Configuration Confirmation

The new file correctly sets up the Rust toolchain to use the stable channel and includes the rustfmt component. Specifying the target as "wasm32-unknown-unknown" ensures that the project is properly configured for WebAssembly compilation, which aligns well with the intended contract deployment strategies.

contracts/fa/.github/workflows/deploy-production.yml (1)

15-27: Production Deployment Steps Are Solid

The checkout, CLI installation, and deployment command steps are well-structured. Just ensure that all production environment variables (e.g., account IDs, network configurations, signing keys) are correctly configured in your repository secrets. Overall, the implementation is sound.

contracts/fa/.gitignore (1)

1-2: Appropriate Ignoring of Build Artifacts.
The addition of the /target entry ensures that compiled artifacts are not tracked by Git, which is standard practice for Rust projects.

pnpm-workspace.yaml (1)

1-5: Workspace Restructuring Verified.
The removal of the "apps/contracts" and "apps/relayer" entries—and the inclusion of "contracts/fa-verification"—aligns with the new project structure. This change reduces clutter and accurately represents the current package organization.

contracts/fa-guard/mocks/external-guard/Cargo.toml (1)

1-13: LGTM: Cargo configuration follows best practices for NEAR contracts.

The Cargo.toml is appropriately configured with the necessary dependencies and crate type for a NEAR smart contract mock. The use of specific dependency versions ensures build reproducibility.

contracts/fa-guard/Cargo.toml (1)

50-58: The release profile settings look good for a NEAR contract.

The release profile is well-configured for a NEAR smart contract with optimizations for small code size, including single codegen units, LTO, and other best practices for WASM targets.

contracts/fa-guard/tests/test_basics.rs (2)

3-9: Test structure is appropriate for contract verification.

The main test function properly sets up the contract WASM and calls the individual test functions for CRUD operations and verification, making good use of the tokio async test framework.


36-44: Test covers error case for non-existent guard.

The test properly checks the behavior when attempting to get a non-existent guard, ensuring that the contract fails as expected in this case. This is good defensive testing.

contracts/fa-guard/src/lib.rs (1)

94-106: Unit tests are thorough and well-structured.

The unit tests cover both the successful and failure cases for guard operations, which is good practice for ensuring robust contract behavior.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
contracts/fa-guard/src/lib.rs (3)

38-43: Clarify or remove the reference to "DEFAULT_GUARD" in doc comment.

The doc comment on line 38 references returning a "defaulting to DEFAULT_GUARD," but there is no definition or usage of a DEFAULT_GUARD within the code. Consider updating the comment or introducing the actual default guard logic if intended.


61-75: Consider specifying gas usage for external call.

Current external call to external_guard::ext(guard_address).verify(payload) lacks explicit gas configuration. For better control and predictability of cross-contract calls on NEAR, consider specifying a static or configurable gas amount with .with_static_gas(...) or .with_attached_deposit(...) if a deposit is needed.


100-132: Add test coverage for verification flow.

The current inline tests do not cover the happy path or error handling flow in verify and on_verify_callback. Consider adding tests to ensure:

  • The contract properly calls the external guard.
  • The callback handles success and failure as intended.
    This robust test coverage will bolster confidence in the contract’s verification logic.

Do you want me to generate example integration tests that call verify and simulate the callback?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e537b8c and e18ad70.

📒 Files selected for processing (1)
  • contracts/fa-guard/src/lib.rs (1 hunks)
🔇 Additional comments (2)
contracts/fa-guard/src/lib.rs (2)

45-50: Revisit access control for guard management methods.

Both add_guard and remove_guard are documented as “Public method” but are annotated with #[private], meaning they can only be invoked by this contract internally (or by itself via cross-contract calls). If you want external calls to manage guards (e.g., by the contract owner), consider enforcing ownership checks rather than marking them private, or update the documentation to reflect that these methods are private by design.

Would you like to ensure only the contract owner can invoke these methods, or are you intentionally restricting their access altogether? Please confirm so we can proceed with an appropriate solution.

Also applies to: 52-57


78-91: Good error logging in callback implementation.

The callback correctly distinguishes between an external guard verification failure and a rejected or successful verification result. This makes it straightforward to trace verification outcomes in logs.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
contracts/fa-guard/src/lib.rs (2)

28-37: Consider enforcing explicit ownership checks during contract initialization.
Your #[private] annotation prevents external calls from directly invoking init, and you correctly guard against re-initialization via env::state_exists(). However, if you plan to restrict contract initialization solely to a designated owner, add an ownership check here or in the deployment flow to ensure that only the intended account can initialize the contract.


80-94: Return more context upon verification failure if desired.
The contract currently returns a boolean in on_verify_callback. If you want richer feedback—such as error codes or messages—consider returning or logging additional data to prove the nature of the failure. This could help debugging or auditing verification attempts.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e18ad70 and dcea4b5.

📒 Files selected for processing (1)
  • contracts/fa-guard/src/lib.rs (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
contracts/fa-guard/src/lib.rs (3)
contracts/fa-guard/mocks/external-guard/src/lib.rs (2)
  • default (7-9)
  • verify (14-17)
contracts/fa/src/lib.rs (1)
  • default (12-16)
contracts/fa-guard/src/interfaces.rs (1)
  • verify (6-6)
🔇 Additional comments (1)
contracts/fa-guard/src/lib.rs (1)

65-78: Add negative tests for the verify method.
Currently, there is no test verifying the panic or error path when providing a non-existing guard or invalid input. Creating a test that ensures the correct behavior (e.g., panic on missing guard) will make the contract more robust and help prevent regressions.

Do you want a script or snippet to set up a dedicated unit test to cover this scenario?

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (7)
contracts/fa-guard/src/interfaces.rs (1)

4-7: Consider returning a structured type instead of a 3-tuple.
Returning (bool, String, String) may obscure semantics, making it unclear what each String represents (e.g., user, permissions). A struct would improve clarity and maintainability, especially if the contract evolves to return additional fields in the future.

- fn verify(&self, payload: String) -> (bool, String, String);
+ #[derive(Serialize, Deserialize)]
+ #[serde(crate = "near_sdk::serde")]
+ pub struct VerificationResult {
+     pub success: bool,
+     pub user: String,
+     pub permissions: String,
+ }

+ fn verify(&self, payload: String) -> VerificationResult;
contracts/fa-guard/mocks/external-guard/src/lib.rs (1)

14-17: Consider handling the empty payload case.
Currently, verify() always returns true regardless of the input. Handling empty payloads explicitly (e.g., returning (false, "", "")) can help you test both success and failure scenarios in your mock.

 pub fn verify(&self, _payload: String) -> (bool, String, String) {
-    (true, "user".to_string(), "permissions".to_string())
+    if _payload.is_empty() {
+        (false, String::new(), String::new())
+    } else {
+        (true, "user".to_string(), "permissions".to_string())
+    }
 }
contracts/fa-guard/src/lib.rs (5)

28-37: Optionally store an owner.
The init method successfully prevents re-initialization, but the PR objective mentions that guard governance should be restricted to the contract owner. Consider adding an owner field at initialization and verifying it in admin methods (e.g., add_guard, remove_guard).

 #[near(contract_state)]
 pub struct FaGuard{
     guards: HashMap<String, AccountId>,
+    owner: AccountId,
 }

 #[init]
 #[private]
 pub fn init(init_guards: HashMap<String, AccountId>) -> Self {
     if env::state_exists() {
         env::panic_str("Contract is already initialized");
     }
-    Self { guards: init_guards }
+    Self {
+        guards: init_guards,
+        owner: env::predecessor_account_id()
+    }
 }

42-46: Update the reference to “defaulting to DEFAULT_GUARD.”
The docstring references a default guard, yet the code panics if no guard is found. Either remove the mention of a default guard or implement a genuine default.

-// Public method - returns the guard saved, defaulting to DEFAULT_GUARD
+// Public method - returns the guard or panics if not found

65-78: Optionally specify gas usage for cross-contract calls.
The verify method calls external_guard::ext(...) without specifying gas, which can lead to default or insufficient gas usage. You may want to configure .with_static_gas(...) or .with_attached_deposit(...) if needed for your scenario.

 external_guard::ext(guard_address.clone())
+.with_static_gas(5_000_000_000_000)
 .verify(payload)
 .then(Self::ext(env::current_account_id())
     .on_verify_callback()
 )

81-94: Consider using a structured return type in on_verify_callback.
Returning (bool, String, String) can confuse readers and is prone to mismatch with the external trait. A named struct or an enum for different outcomes can improve maintainability.


105-134: Expand or integrate tests for verification and callback logic.
These tests check guard CRUD but do not verify the verify and on_verify_callback flow (despite references to them in your integration tests). Consider adding a unit test stub or confirm all test scenarios with your integration tests.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dcea4b5 and de41b7f.

📒 Files selected for processing (3)
  • contracts/fa-guard/mocks/external-guard/src/lib.rs (1 hunks)
  • contracts/fa-guard/src/interfaces.rs (1 hunks)
  • contracts/fa-guard/src/lib.rs (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
contracts/fa-guard/src/interfaces.rs (2)
contracts/fa-guard/mocks/external-guard/src/lib.rs (1)
  • verify (14-17)
contracts/fa-guard/src/lib.rs (1)
  • verify (65-78)
contracts/fa-guard/mocks/external-guard/src/lib.rs (3)
contracts/fa-guard/src/lib.rs (1)
  • verify (65-78)
contracts/fa-guard/src/interfaces.rs (1)
  • verify (6-6)
contracts/fa-guard/tests/test_basics.rs (1)
  • test_verify (69-103)

@GuillemGarciaDev GuillemGarciaDev added the feature Feature label Apr 14, 2025
@AdriaCarrera AdriaCarrera merged commit 2095a05 into main Apr 17, 2025
4 checks passed
@AdriaCarrera AdriaCarrera deleted the contracts/feat/verification-contract-setup branch April 17, 2025 14:11
@coderabbitai coderabbitai bot mentioned this pull request Jan 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contracts contracts app feature Feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments