Quick Start

Add 2FA to your Solana dApp in 5 minutes. No program changes required.

Step 1: Install the SDK

npm install intentguard-sdk @solana/web3.js

Step 2: Compute the Intent Hash

The intent hash is a SHA-256 digest of the action name and parameters. Both the mobile app and the dApp must compute the same hash for verification to succeed.

import { computeIntentHash } from 'intentguard-sdk';

// Hash the user's intended action
const hash = computeIntentHash('swap', {
  inputMint: 'So11111111111111111111111111111111111111112',
  outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
  amount: 1_000_000_000,  // 1 SOL in lamports
  slippage: 50,           // 0.5% in bps
});

Important: The hash uses length-prefixed encoding to prevent concatenation ambiguity. Always use computeIntentHash() rather than manual hashing.

Step 3: Commit Intent (Mobile/Trusted Device)

On the trusted device (mobile app), the user confirms the action and commits the intent hash on-chain.

import { createCommitIntentInstruction } from 'intentguard-sdk';
import { Connection, Transaction } from '@solana/web3.js';

const connection = new Connection('https://api.devnet.solana.com');
const appId = new PublicKey('JUP6...'); // Target dApp program ID

const commitIx = createCommitIntentInstruction(
  user.publicKey,  // wallet
  appId,           // app identifier
  hash,            // intent hash
  300,             // TTL in seconds (5 min)
);

const tx = new Transaction().add(commitIx);
await sendAndConfirmTransaction(connection, tx, [user]);

Step 4: Verify + Execute (Browser/dApp)

The dApp detects the on-chain commit and prepends a verify instruction to the actual transaction.

import {
  createVerifyIntentInstruction,
  getIntentCommit,
} from 'intentguard-sdk';

// Check if intent has been committed
const commit = await getIntentCommit(connection, user.publicKey, appId);
if (!commit) throw new Error('No pending intent');

// Build verify instruction
const verifyIx = createVerifyIntentInstruction(user.publicKey, appId, hash);

// Build your normal swap/transfer instruction
const swapIx = buildSwapInstruction(params);

// Send atomically: verify MUST succeed for swap to execute
const tx = new Transaction().add(verifyIx).add(swapIx);
await sendAndConfirmTransaction(connection, tx, [user]);

Step 5: Handle Expiry & Revocation

If the user decides not to proceed, they can revoke the intent to reclaim rent:

import { createRevokeIntentInstruction } from 'intentguard-sdk';

const revokeIx = createRevokeIntentInstruction(user.publicKey, appId);
const tx = new Transaction().add(revokeIx);
await sendAndConfirmTransaction(connection, tx, [user]);

Expired intents (past TTL) will also fail verification automatically.

What Happens Under the Hood

StepInstructionAccountsEffect
Commitcommit_intent4 (intent PDA, config, user, system)Creates IntentCommit PDA with hash + TTL
Verifyverify_intent4 (intent PDA, config, user, system)Checks hash match, closes PDA, collects fee
Revokerevoke_intent2 (intent PDA, user)Closes PDA, refunds rent to user

Next: SDK Reference for all available functions and parameters.