Skip to content

Latest commit

 

History

History
217 lines (164 loc) · 7.11 KB

code-snippets.md

File metadata and controls

217 lines (164 loc) · 7.11 KB

Code Snippets for Common Patterns

This guide documents the QuorumProof Code Snippet Library, designed to accelerate development, eliminate repetitive boilerplate, and enforce best practices across Soroban smart contracts and client SDK integrations.


Overview

When developing smart contracts and decentralized services on Stellar/Soroban, certain patterns repeat constantly:

  • Setting up a #![no_std] contract skeleton with storage keys.
  • Enforcing caller authorization with require_auth().
  • Safe storage retrieval with custom error handling.
  • Writing to persistent storage with automatic TTL extension (extend_ttl).
  • Emitting typed events with topics.
  • Validating quorum slice weights against threshold limits.
  • Verifying verifiable credentials off-chain.
  • Invoking smart contracts via the Stellar SDK.

The QuorumProof snippet library encapsulates these patterns into standardized triggers available in popular IDEs.


Quick Reference Table

Rust & Soroban Smart Contracts

Prefix Name Description Key Elements
qp-contract Soroban Contract Boilerplate Scaffold struct, initialize, and contractimpl #[contract], #[contractimpl], Env, DataKey
qp-error-enum Contract Error Enum Typed contract errors with error codes #[contracterror], #[repr(u32)]
qp-require-auth Require Auth Authentication verification caller.require_auth()
qp-storage-get Instance Storage Get Read instance storage with error handling env.storage().instance().get(), ok_or
qp-storage-set Persistent Storage Set Write persistent storage and extend TTL env.storage().persistent().extend_ttl()
qp-event-publish Publish Event Emit typed Soroban event with topics env.events().publish()
qp-contract-test Contract Unit Test Scaffold test module with mock environment Env::default(), mock_all_auths(), register_contract
qp-quorum-slice Quorum Slice Validation Sum attestor weights and check threshold iter().map(|a| a.weight).sum(), InvalidThreshold
qp-zk-verify ZK Proof Verification Cross-contract call to ZK verifier zk_verifier::Client::new(), verify_proof()

TypeScript & Client SDK

Prefix Name Description Key Elements
qp-invoke-contract Contract Invocation Stellar SDK contract call Contract, TransactionBuilder, submitTransaction
qp-verify-credential Credential Verification Off-chain credential validation Timestamp expiration, signature validation
qp-ws-subscribe WebSocket Event Stream Real-time event listener with reconnect WebSocket, credentials topic, auto-reconnect

IDE Setup & Integration

1. Visual Studio Code & Cursor (Default / Recommended)

The repository includes workspace-level snippets in .vscode/quorumproof.code-snippets.

When you open the QuorumProof workspace in VS Code or Cursor:

  1. Open any .rs, .ts, or .js file.
  2. Type any prefix (e.g., qp-contract or qp-invoke-contract).
  3. Press Tab or Enter to expand the snippet.
  4. Press Tab to navigate between placeholders and tab stops.

Recommended Editor Setting

In .vscode/settings.json, ensure snippet suggestions appear at the top:

{
  "editor.snippetSuggestions": "top",
  "editor.tabCompletion": "on"
}

2. JetBrains IDEs (RustRover, CLion, WebStorm, IntelliJ)

The repository provides ready-to-import Live Templates in snippets/jetbrains/QuorumProof.xml.

Installation:

  1. Open Settings / Preferences (Cmd + , on macOS, Ctrl + Alt + S on Linux/Windows).
  2. Navigate to Editor > Live Templates.
  3. Click the gear icon (Manage) or + and choose Import Templates.
  4. Select snippets/jetbrains/QuorumProof.xml from the repository root.
  5. Click Apply and OK.

Triggers will now auto-complete in Rust and TypeScript files.


3. Neovim & Vim (LuaSnip & UltiSnips)

UltiSnips format snippets are provided in:

  • snippets/ultisnips/rust.snippets
  • snippets/ultisnips/typescript.snippets

UltiSnips Setup:

Add the snippet directory to your ~/.vimrc or init.vim:

let g:UltiSnipsSnippetDirectories=["UltiSnips", "/path/to/QuorumProof/snippets/ultisnips"]

LuaSnip Setup:

If using LuaSnip with friendly-snippets:

require("luasnip.loaders.from_vscode").lazy_load({
    paths = { "./.vscode" }
})

Common Patterns & Snippet Walkthroughs

Pattern 1: Authoring a New Soroban Attestation Contract

  1. In a new .rs file, type qp-contract and press Tab. Enter your contract name:
#![no_std]
use soroban_sdk::{contract, contractimpl, contracttype, symbol_short, Address, Env, String, Symbol, Vec};

#[contract]
pub struct ComplianceRegistry;
  1. Add custom error codes by typing qp-error-enum:
use soroban_sdk::contracterror;

#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[repr(u32)]
pub enum RegistryError {
    NotInitialized = 1,
    AlreadyInitialized = 2,
    Unauthorized = 3,
    InvalidThreshold = 4,
}
  1. Inside your method, enforce authentication by typing qp-require-auth:
admin.require_auth();
  1. Retrieve stored parameters using qp-storage-get:
let threshold: u32 = env
    .storage()
    .instance()
    .get(&DataKey::Threshold)
    .ok_or(RegistryError::NotInitialized)?;
  1. Validate quorum weight using qp-quorum-slice:
let total_weight: u32 = attestations
    .iter()
    .map(|a| a.weight)
    .sum();

if total_weight < threshold {
    return Err(RegistryError::InvalidThreshold);
}
  1. Persist results and emit an on-chain event using qp-storage-set and qp-event-publish:
env.storage().persistent().set(&key, &total_weight);
env.storage().persistent().extend_ttl(&key, 100_000, 200_000);

env.events().publish(
    (symbol_short!("attest"), subject),
    total_weight
);

Pattern 2: Writing a Soroban Contract Test

Type qp-contract-test to scaffold a complete test harness:

#[cfg(test)]
mod test {
    use super::*;
    use soroban_sdk::{testutils::Address as _, Address, Env};

    #[test]
    fn test_initialize_and_verify() {
        let env = Env::default();
        env.mock_all_auths();

        let contract_id = env.register_contract(None, ComplianceRegistry);
        let client = ComplianceRegistryClient::new(&env, &contract_id);

        let admin = Address::generate(&env);
        client.initialize(&admin);

        assert!(client.is_initialized());
    }
}

Working Examples

Full runnable examples showing how all snippets integrate together are located in examples/snippets/:


Validating Snippets

To verify all snippet files conform to standard schema and naming rules, run the test script:

python3 scripts/test_snippets.py