Skip to main content
When an agent attempts an operation that exceeds its policy limits or requires explicit human approval, the x0-guard program generates a Blink — a Solana Action that the owner can approve from any Blink-compatible wallet or application.
Agent attempts transfer exceeding daily limit

  ├── Guard validates: amount > remaining_allowance

  ├── Guard checks: blinks_generated_this_hour < 3

  ├── Guard emits: BlinkGenerated event

  └── Agent returns Blink URL to caller

        ├── Owner opens URL in Blink-compatible wallet
        ├── Reviews details (amount, recipient, memo)
        └── Signs + submits transaction
Generated when an agent transfer exceeds policy limits.
import { generateTransferBlink } from '@x0-protocol/sdk';

const blink = generateTransferBlink({
  policyPda: agentPolicy,
  agent: agentPubkey,
  recipient: recipientPubkey,
  amount: new BN(5_000_000_000), // 5,000 USDC
  mint: usdcMint,
  memo: 'Large infrastructure payment',
});
Fields:
FieldDescription
recipientDestination wallet address
amountTransfer amount in micro-units
mintToken mint to transfer
memoHuman-readable reason for transfer

Rate Limiting

Blinks are rate-limited to prevent spam and denial-of-service:
ParameterValueDescription
MAX_BLINKS_PER_HOUR3Maximum Blinks per agent per hour
BLINK_GENERATION_COST_LAMPORTS1,000,0000.001 SOL burned per Blink
BLINK_EXPIRY_SECONDS900Blinks expire after 15 minutes
If the agent exceeds the Blink rate limit, the transfer is rejected with BlinkRateLimitExceeded (0x1130).
1

Generation

The agent SDK creates a Blink object containing action details, encodes it as a Solana Actions URL, and optionally generates a QR code.
2

Delivery

The Blink URL is surfaced to the owner via the agent’s interface — push notification, chat message, email, or QR display.
3

Review

The owner opens the Blink in any Solana Actions-compatible wallet (Phantom, Solflare, Dialect, etc.) and reviews the requested action.
4

Approval

The owner signs the transaction in-wallet. The signed transaction is submitted directly to Solana — no intermediary.
5

Expiration

If the owner does not act within 15 minutes, the Blink expires. The agent may generate a new one (subject to rate limits).

Solana Actions Metadata

The SDK produces an Actions-compliant JSON metadata response for rendering in Blink clients:
import { buildActionsMetadata } from '@x0-protocol/sdk';

const metadata = buildActionsMetadata(blink);
// Returns:
// {
//   icon: "https://x0.org/icon.png",
//   title: "Approve Transfer",
//   description: "Agent requests 5,000 USDC transfer to ...",
//   label: "Approve",
//   links: {
//     actions: [
//       { label: "Approve Transfer", href: "..." },
//     ]
//   }
// }

QR Code Generation

For mobile-first approval flows:
import { generateQRData } from '@x0-protocol/sdk';

const qrPayload = generateQRData(blink, 'https://api.x0.org/actions');
// Encode qrPayload into a QR code image

Validation

import { validateBlink, isBlinkExpiredFromBlink } from '@x0-protocol/sdk';

if (!validateBlink(data)) {
  throw new Error('Invalid blink structure');
}

if (isBlinkExpiredFromBlink(blink)) {
  throw new Error('Blink has expired');
}

Events

EventFieldsWhen
BlinkGeneratedpolicy, agent, amount, recipient, expires_at, timestampBlink created by guard
CodeNameDescription
0x1130BlinkRateLimitExceededAgent exceeded 3 Blinks/hour
0x1131BlinkExpiredBlink is past 15-minute window
0x1132InvalidBlinkSignatureSubmitted signature doesn’t match
0x1133BlinkAlreadyProcessedBlink was already approved/rejected
Last modified on February 8, 2026