Skip to main content
This guide covers how to integrate Range’s SigVerify pattern into a Solana program. SigVerify is a lightweight alternative to the Onchain Risk Verifier, instead of relying on oracle networks, your backend calls the Range API, signs an attestation, and your onchain program verifies the signature directly using Ed25519.
Prerequisites: You need a Risk API key, a Solana development environment (Anchor), and a backend service that holds an Ed25519 keypair.

How It Works

Your backend screens the user’s wallet via the Range API, then signs a time-stamped attestation message. The user submits this attestation in a Solana transaction, and the onchain program verifies the signature, signer identity, and freshness, all without any oracle dependency.

How It Compares to the Oracle Approach

Security Model

  • Ed25519 signature verification: The onchain program verifies the backend’s signature using Ed25519. This example uses the brine-ed25519 crate for in-program verification. Alternatively, you can use Solana’s native Ed25519 SigVerify precompile , this requires an additional instruction and onchain introspection to validate the signature (similar to what Switchboard does under the hood), but avoids depending on a third-party crate. Either way, forged attestations are rejected.
  • Signer binding: The message embeds the user’s pubkey. The program verifies it matches the transaction signer, preventing replay attacks.
  • Freshness check: Attestations expire after 60 seconds (configurable). The program compares the message timestamp against the onchain clock.
  • Audit trail: Each attestation includes a unique riskCallId that links the onchain verification to the original API call.
  • API keys stay off-chain: The Range API key is only used by your backend, it never appears in transaction data.

Use Cases


Step 1: Screen the Wallet (TypeScript)

Your backend calls the Range API to get the wallet’s risk score and generates a unique riskCallId for audit tracking.
The riskCallId is generated client-side as a random 16-byte hex string. This ties the onchain attestation to a specific screening event for auditability.

Step 2: Sign the Attestation (TypeScript)

After screening, your backend signs a message that binds the risk result to the user’s wallet and a specific point in time.
The message format is {timestamp}_{pubkey}_{riskCallId} where:
  • timestamp: Unix timestamp in seconds (used for freshness check onchain)
  • pubkey: The user’s Solana wallet address (base58)
  • riskCallId: Unique identifier linking to the API screening result
The backend secret key must be kept secure. If compromised, an attacker could forge attestations. Rotate the backend keypair and update the onchain program’s BACKEND_PUBKEY constant if a key is ever leaked.

Step 3: Build and Send the Transaction (TypeScript)

The user submits the backend’s attestation in a Solana transaction. The SDK’s buildVerifyRiskInstruction constructs the instruction with the Anchor discriminator, signature, and message, see the full implementation in the example repo.

Step 4: Verify Onchain (Rust)

The Anchor program verifies the Ed25519 signature, checks that the message signer matches the transaction signer, and enforces a freshness window.

Program Entry Point

Verification Logic

Signature Verification and Message Parsing


Step 5: Run the Example

Clone the example repository and set up your own keys.
Update BACKEND_PUBKEY in programs/sigverify/src/constants.rs with your backend’s public key:
Since you’re deploying your own copy of the program, you’ll also need to generate a new program keypair and update the program ID:
Update the program ID in both programs/sigverify/src/lib.rs (declare_id!) and Anchor.toml ([programs.devnet]) with the output, and update PROGRAM_ID in app/sdk.ts to match.
Expected output:
For local development, you can use Surfpool to run a local Solana validator that auto-deploys your program on file changes.

Customizing for Your Program

Adjusting the Risk Threshold

Modify the screening threshold in your backend to match your risk policy:

Adjusting the Attestation Lifetime

Update the constant in your onchain program:
Longer lifetimes reduce the number of API calls but increase the window for stale risk data. For high-value operations, keep the lifetime short (60 seconds or less).

Adding the Risk Score Onchain

You can extend the message format to include the risk score itself, allowing your program to enforce thresholds onchain:

Production Considerations

  • Rotate backend keys: Have a key rotation strategy. Update BACKEND_PUBKEY in your program via an upgrade or a config PDA.
  • Use HTTPS everywhere: Ensure your backend-to-Range-API communication uses TLS.
  • Log riskCallId: Store the mapping between riskCallId and screening results for compliance audits.

What’s Next

Address Risk Score

Full endpoint reference for the Risk API used in the screening step.

Onchain Risk Verifier

Oracle-based alternative using Switchboard On-Demand for fully decentralized verification.

Example Repository

Complete working implementation with Anchor program and TypeScript SDK.

Wallet Integration

For off-chain risk screening in wallets and dApps.
Last modified on June 17, 2026