Auto SDKAuto DrivePay with AI3

Pay with AI3 — Developer Integration

This page covers how to integrate permissionless Auto Drive credit purchasing into your own application using the AutoDriveCreditsReceiver smart contract and the credits API.

For the end-user purchase walkthrough, see the Pay with AI3 guide.

For a complete working example of Pay with AI3 in a real application, see Eulonomys — a reference app with full source code showing the payment intent flow, on-chain contract calls, and Auto Drive uploads end-to-end.


How It Works

The payment system is built around a payment intent model. Each purchase follows four steps:

  1. Your app fetches a price quote from the backend — reflects the live protocol-level DSN storage cost via a Substrate RPC connection to the Autonomys consensus chain, plus a service fee.
  2. Your app asks the Auto Drive backend to create a payment intent — a server-side record that locks the price and binds a bytes32 intent ID to the authenticated account for up to 10 minutes.
  3. Your app calls payIntent(intentId) on the AutoDriveCreditsReceiver contract on Auto-EVM, sending the exact quoted AI3 amount as msg.value.
  4. Your app submits the transaction hash to the watch endpoint; the backend polls for 6 block confirmations and then grants the credits.

Credits are available immediately after confirmation and can be used via the dashboard, the Auto SDK, or the REST API.


Smart Contract

FieldValue
ContractAutoDriveCreditsReceiver
NetworkAutonomys Auto-EVM
Chain ID870
Address0xBa5bed8325183c0807EcBC80C82D40Dc7Ac5cbf7

View on Blockscout: AutoDriveCreditsReceiver

payIntent

function payIntent(bytes32 intentId) public payable whenNotPaused;

intentId is the bytes32 value returned by POST /intents/. Send the exact quoted amount as msg.value — the transaction will fail if the value does not match.

The whenNotPaused modifier allows the protocol team to pause payments in the event of a critical issue.

Event

event IntentPaymentReceived(bytes32 indexed intentId, uint256 paymentAmount);

Emitted on successful payment. Listen for this event to confirm receipt before calling the watch endpoint.


Payment Intent State Machine

PENDING ──► CONFIRMED ──► COMPLETED

   ├──► EXPIRED   (no payment received within 10 minutes)

   └──► FAILED    (payment amount below the quoted price)

CONFIRMED ──► OVER_CAP  (account's 100 GB purchased credit limit exceeded)

Always fetch a fresh quote immediately before creating an intent. Prices reflect live protocol storage cost and can change between requests.


API Reference

Base URL: https://api.autonomys.xyz

Get a Price Quote

GET /intents/price

Returns the current AI3 cost (in Shannons) per GB. No authentication required.

Example response:

{
  "pricePerGb": "1000000000000000000",
  "currency": "AI3"
}

Create a Payment Intent

POST /intents/

Locks the current price for the authenticated account and returns an intent ID.

Authentication: Requires an Auto Drive API key (created from a Google-authenticated account).

Request body:

{
  "storageGb": 10
}

Response:

{
  "intentId": "0xabc123...",
  "amount": "10000000000000000000",
  "expiresAt": "2026-05-12T12:10:00Z"
}

Pass intentId as the argument to payIntent and amount as msg.value.


Confirm a Transaction

POST /intents/:id/watch

Submit the on-chain transaction hash. The backend polls for 6 confirmations before crediting the account.

Request body:

{
  "txHash": "0xdef456..."
}

Integration Patterns

Pattern 1 — App-managed credits

Your application holds a funded Auto-EVM wallet and purchases credits on behalf of users. Useful for apps that abstract storage costs away entirely.

import { ethers } from 'ethers'
 
const CONTRACT_ADDRESS = '0xBa5bed8325183c0807EcBC80C82D40Dc7Ac5cbf7'
const ABI = [
  'function payIntent(bytes32 intentId) payable',
  'event IntentPaymentReceived(bytes32 indexed intentId, uint256 paymentAmount)',
]
 
async function purchaseCredits(signer: ethers.Signer, authToken: string, storageGb: number) {
  // 1. Fetch fresh quote
  const quoteRes = await fetch('https://api.autonomys.xyz/intents/price')
  const { pricePerGb } = await quoteRes.json()
 
  // 2. Create intent — price locked for 10 minutes
  const intentRes = await fetch('https://api.autonomys.xyz/intents/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${authToken}`,
    },
    body: JSON.stringify({ storageGb }),
  })
  const { intentId, amount } = await intentRes.json()
 
  // 3. Call payIntent on Auto-EVM — send exact quoted amount
  const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, signer)
  const tx = await contract.payIntent(intentId, { value: amount })
  await tx.wait()
 
  // 4. Submit tx hash — backend confirms 6 blocks then grants credits
  await fetch(`https://api.autonomys.xyz/intents/${intentId}/watch`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ txHash: tx.hash }),
  })
 
  return tx.hash
}

Pattern 2 — User-managed credits

Direct users to the Auto Drive dashboard to purchase credits themselves using the Pay with AI3 guide. Your application uses the AutoSDK with the user’s API key — no on-chain interaction required in your code.

This is the lower-complexity option and is suitable for most applications.


Using Credits After Purchase

Once purchased, credits are consumed automatically when uploading via the @autonomys/auto-drive SDK. No additional configuration is needed.

import { createAutoDriveApi } from '@autonomys/auto-drive'
import { NetworkId } from '@autonomys/auto-utils'
 
const api = createAutoDriveApi({ apiKey: 'your-api-key', network: NetworkId.MAINNET })
 
// Credits are deducted automatically on upload
const cid = await api.uploadFileFromInput(file, {
  password: 'optional-encryption-password', // enable AES-256-GCM encryption
})
 
console.log('Uploaded CID:', cid)

Credits are consumed in FIFO expiry order — the soonest-to-expire credits are spent first.


Limits and Expiry

ParameterValue
Maximum purchased credits100 GB per account
Credit expiry90 days from grant date
Intent timeout10 minutes
Confirmation blocks6

Further Reading