Skip to main content

Overview

The transactions API provides gas sponsorship for all wallet operations. The backend builds transaction bytes, sponsors gas, and co-signs transactions.
Wallet endpoints are public (no authentication). Status endpoint requires API key.

Gas Sponsorship Flow

All wallet transactions follow a two-step flow:
  1. Build: Wallet sends transaction parameters to /transactions/gas-sponsor
  2. Submit: Wallet signs transaction bytes and submits via /transactions/submit
The backend acts as the gas sponsor, co-signing the transaction.

Endpoints

Build Sponsored Transaction

Build a gas-sponsored transaction and return transaction bytes for signing.
POST /api/identipay/v1/transactions/gas-sponsor

Request Body

type
string
required
Transaction type: send, settlement, settlement_no_zk, pool_deposit, or pool_withdraw
senderAddress
string
required
Sender’s Sui address

Additional Parameters by Type

Response

txBytes
string
Base64-encoded transaction bytes ready for signing

Example Request

curl -X POST https://api.identipay.com/api/identipay/v1/transactions/gas-sponsor \
  -H "Content-Type: application/json" \
  -d '{
    "type": "send",
    "senderAddress": "0xabc123...",
    "amount": "1000000000",
    "recipient": "0xdef456...",
    "coinType": "0x2::sui::SUI",
    "ephemeralPubkey": [1,2,3,...],
    "viewTag": 42
  }'

Example Response

{
  "txBytes": "AAACAAgA...(base64-encoded)..."
}

Error Responses


Submit Signed Transaction

Submit a signed transaction for co-signing and broadcasting.
POST /api/identipay/v1/transactions/submit

Request Body

txBytes
string
required
Base64-encoded transaction bytes (from /gas-sponsor)
senderSignature
string
required
Base64-encoded sender signature

Response

txDigest
string
Sui transaction digest (hash)

Example Request

curl -X POST https://api.identipay.com/api/identipay/v1/transactions/submit \
  -H "Content-Type: application/json" \
  -d '{
    "txBytes": "AAACAAgA...",
    "senderSignature": "ABC123..."
  }'

Example Response

{
  "txDigest": "9x4Kb2FgH8..."
}

Error Responses


Submit Pool Transaction

Submit a pool withdrawal transaction (backend signs as both sender and gas sponsor).
POST /api/identipay/v1/transactions/submit-pool
Used for shielded pool withdrawals where the backend controls the pool account.

Request Body

txBytes
string
required
Base64-encoded transaction bytes (from /gas-sponsor with type=pool_withdraw)

Response

txDigest
string
Sui transaction digest

Example Request

curl -X POST https://api.identipay.com/api/identipay/v1/transactions/submit-pool \
  -H "Content-Type: application/json" \
  -d '{
    "txBytes": "AAACAAgA..."
  }'

Example Response

{
  "txDigest": "7yZ3Jb1Hf9..."
}

Get Transaction Status

Check the status of a proposal/transaction (merchant endpoint).
GET /api/identipay/v1/transactions/:txId/status
Requires Authorization: Bearer {apiKey} header

Path Parameters

txId
string
required
Transaction ID (UUID)

Response

transactionId
string
Transaction UUID
status
string
Status: pending, settled, expired, or cancelled
suiTxDigest
string
Sui transaction digest (if settled)
settledAt
string
ISO 8601 timestamp when settled (if settled)

Example Request

curl https://api.identipay.com/api/identipay/v1/transactions/550e8400-.../status \
  -H "Authorization: Bearer ip_live_abc123..."

Example Response

{
  "transactionId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "settled",
  "suiTxDigest": "9x4Kb2FgH8...",
  "settledAt": "2026-03-09T20:15:32.000Z"
}

Error Responses

Implementation Details

Gas Sponsorship Architecture

The backend uses Sui’s sponsored transaction feature:
  1. Build Phase: Backend constructs a TransactionBlock with itself as the gas sponsor
  2. Sign Phase: Wallet signs as the sender
  3. Co-Sign Phase: Backend signs as the gas sponsor and submits
This allows users to transact without holding SUI for gas.

Security Model

The backend:
  • Only sponsors valid transaction types (whitelist)
  • Validates all transaction parameters
  • Never accesses user funds (users control their own keys)
  • Only pays gas fees

Settlement Flow

For a complete payment settlement:
  1. Fetch Proposal: Wallet calls /intents/:txId
  2. Verify Intent: Wallet validates merchant signature and intent hash
  3. Generate Stealth Address: Wallet creates buyer stealth address
  4. Build Settlement: Call /transactions/gas-sponsor with type=settlement
  5. Sign Transaction: Wallet signs with user’s key
  6. Submit: Call /transactions/submit
  7. Monitor: Connect to WebSocket for real-time updates
See WebSocket for monitoring settlement status.

Background Settlement Indexer

The backend polls for SettlementEvent events every 3 seconds:
async function pollSettlementEvents() {
  const result = await suiService.pollSettlementEvents(cursor);
  
  for (const event of result.events) {
    const [proposal] = await db
      .select()
      .from(proposals)
      .where(eq(proposals.intentHash, event.intentHash));
    
    if (proposal && proposal.status === "pending") {
      await db
        .update(proposals)
        .set({ status: "settled", suiTxDigest: event.txDigest });
      
      pushSettlementUpdate(proposal.transactionId, "settled", event.txDigest);
    }
  }
}
When a settlement is detected:
  1. Update proposal status to settled
  2. Store Sui transaction digest
  3. Push update to all connected WebSocket clients

Build docs developers (and LLMs) love