Skip to main content

Claiming Mutations

Process claims for tokens and NFTs from drops using GraphQL mutations.

Basic Claiming

Claim Drop

Claim a specific amount from a drop.
mutation ClaimDrop($input: ClaimDropInput!) {
  claimDrop(input: $input) {
    claim {
      id
      amount
      claimedAt
      txHash
      user {
        id
        username
        displayName
      }
      drop {
        id
        title
        type
        tokenSymbol
      }
    }
    claimParams {
      amount
      nonce
      expiry
      signature
    }
    dropInfo {
      dropObjectId
      packageId
      coinType
      isRandomAmount
    }
  }
}
Variables:
{
  "input": {
    "dropId": "drop_abc123",
    "amount": "100",
    "userAddress": "0x123abc...",
    "paymentIntentId": "pi_xyz789"
  }
}
Response:
{
  "data": {
    "claimDrop": {
      "claim": {
        "id": "claim_def456",
        "amount": "100",
        "claimedAt": "2024-01-15T15:30:00Z",
        "txHash": null,
        "user": {
          "id": "user_ghi789",
          "username": "claimer123",
          "displayName": "Claimer Name"
        },
        "drop": {
          "id": "drop_abc123",
          "title": "Community Token Drop",
          "type": "TOKEN",
          "tokenSymbol": "COMM"
        }
      },
      "claimParams": {
        "amount": "100000000000",
        "nonce": "1234567890",
        "expiry": "1705334400",
        "signature": "0x123abc..."
      },
      "dropInfo": {
        "dropObjectId": "0x456def...",
        "packageId": "0x789ghi...",
        "coinType": "0xabc123::token::COMM",
        "isRandomAmount": false
      }
    }
  }
}

Claim Random Drop

Claim a random amount from a drop that supports random amounts.
mutation ClaimRandomDrop($input: ClaimRandomDropInput!) {
  claimRandomDrop(input: $input) {
    success
    message
    transactionHash
    claimedAmount
    claim {
      id
      amount
      claimedAt
      user {
        username
        displayName
      }
    }
    drop {
      id
      title
      type
      claimedAmount
      maxAmount
      remainingBalance
    }
  }
}
Variables:
{
  "input": {
    "dropId": "drop_abc123",
    "userAddress": "0x123abc...",
    "paymentIntentId": "pi_xyz789"
  }
}
Response:
{
  "data": {
    "claimRandomDrop": {
      "success": true,
      "message": "Successfully claimed random amount",
      "transactionHash": "0x456def...",
      "claimedAmount": "250",
      "claim": {
        "id": "claim_jkl012",
        "amount": "250",
        "claimedAt": "2024-01-15T15:35:00Z",
        "user": {
          "username": "claimer123",
          "displayName": "Claimer Name"
        }
      },
      "drop": {
        "id": "drop_abc123",
        "title": "Random Token Drop",
        "type": "TOKEN",
        "claimedAmount": "25250",
        "maxAmount": "100000",
        "remainingBalance": "74750"
      }
    }
  }
}

Confirm Claim

Confirm a claim after blockchain transaction completion.
mutation ConfirmClaim($input: ConfirmClaimInput!) {
  confirmClaim(input: $input) {
    success
    message
    transactionHash
    claimedAmount
    drop {
      id
      title
      claimedAmount
      maxAmount
      claimRate
      remainingBalance
    }
  }
}
Variables:
{
  "input": {
    "dropId": "drop_abc123",
    "claimId": "claim_def456",
    "transactionHash": "0x789ghi...",
    "amount": "100"
  }
}
Response:
{
  "data": {
    "confirmClaim": {
      "success": true,
      "message": "Claim confirmed successfully",
      "transactionHash": "0x789ghi...",
      "claimedAmount": "100",
      "drop": {
        "id": "drop_abc123",
        "title": "Community Token Drop",
        "claimedAmount": "25100",
        "maxAmount": "100000",
        "claimRate": 25.1,
        "remainingBalance": "74900"
      }
    }
  }
}

Input Types

ClaimDropInput

input ClaimDropInput {
  dropId: ID! # ID of the drop to claim from
  amount: String! # Amount to claim (in base units)
  userAddress: String! # User's wallet address
  paymentIntentId: ID # Optional payment intent ID for paid drops
}

ClaimRandomDropInput

input ClaimRandomDropInput {
  dropId: ID! # ID of the drop to claim from
  userAddress: String! # User's wallet address
  paymentIntentId: ID # Optional payment intent ID for paid drops
}

ConfirmClaimInput

input ConfirmClaimInput {
  dropId: ID! # ID of the drop
  claimId: ID! # ID of the claim to confirm
  transactionHash: String! # Blockchain transaction hash
  amount: String! # Amount that was claimed
}

Response Types

ClaimDropResult

type ClaimDropResult {
  claim: Claim! # The created claim record
  claimParams: ClaimParams! # Parameters for blockchain transaction
  dropInfo: DropInfo! # Drop contract information
}

ClaimParams

type ClaimParams {
  amount: String! # Amount in base units
  nonce: String! # Unique nonce for the claim
  expiry: BigInt! # Expiry timestamp
  signature: String! # Backend signature for claim
}

DropInfo

type DropInfo {
  dropObjectId: String! # On-chain drop object ID
  packageId: String! # Smart contract package ID
  coinType: String! # Token type identifier
  isRandomAmount: Boolean! # Whether the drop supports random amounts
}

ClaimResult

type ClaimResult {
  success: Boolean! # Whether the claim was successful
  message: String! # Status message
  transactionHash: String # Blockchain transaction hash
  claimedAmount: String # Amount that was claimed
  drop: Drop # Updated drop information
}

ClaimRandomDropResult

type ClaimRandomDropResult {
  success: Boolean! # Whether the claim was successful
  message: String! # Status message
  transactionHash: String # Blockchain transaction hash
  claimedAmount: String # Actual amount claimed (random)
  claim: Claim # The created claim record
  drop: Drop # Updated drop information
}

Error Handling

Drop Not Found

mutation ClaimFromNonExistentDrop {
  claimDrop(
    input: { dropId: "nonexistent", amount: "100", userAddress: "0x123..." }
  ) {
    claim {
      id
    }
  }
}
Response:
{
  "errors": [
    {
      "message": "Drop not found",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["claimDrop"]
    }
  ],
  "data": {
    "claimDrop": null
  }
}

Drop Inactive

mutation ClaimFromInactiveDrop {
  claimDrop(
    input: { dropId: "drop_inactive", amount: "100", userAddress: "0x123..." }
  ) {
    claim {
      id
    }
  }
}
Response:
{
  "errors": [
    {
      "message": "Drop is not active",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["claimDrop"]
    }
  ],
  "data": {
    "claimDrop": null
  }
}

Insufficient Balance

mutation ClaimExcessiveAmount {
  claimDrop(
    input: { dropId: "drop_abc123", amount: "1000000", userAddress: "0x123..." }
  ) {
    claim {
      id
    }
  }
}
Response:
{
  "errors": [
    {
      "message": "Insufficient balance in drop",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["claimDrop"]
    }
  ],
  "data": {
    "claimDrop": null
  }
}

Eligibility Check Failed

mutation ClaimWithoutEligibility {
  claimDrop(
    input: { dropId: "drop_gated", amount: "100", userAddress: "0x123..." }
  ) {
    claim {
      id
    }
  }
}
Response:
{
  "errors": [
    {
      "message": "User not eligible for this drop",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["claimDrop"]
    }
  ],
  "data": {
    "claimDrop": null
  }
}

Best Practices

1. Check Eligibility First

# Good: Check eligibility before claiming
query CheckEligibility($dropId: ID!, $userAddress: String!) {
  checkGatingEligibility(
    input: { dropId: $dropId, walletAddress: $userAddress }
  ) {
    eligible
    reason
    missingRequirements
  }
}

# Then claim if eligible
mutation ClaimIfEligible($input: ClaimDropInput!) {
  claimDrop(input: $input) {
    claim {
      id
      amount
    }
  }
}

2. Handle Payment Intents

# For paid drops, create payment intent first
mutation CreatePaymentIntent($input: CreatePaymentIntentInput!) {
  createPaymentIntent(input: $input) {
    id
    intentId
    status
    paymentUrl
  }
}

# Then claim with payment intent ID
mutation ClaimWithPayment($input: ClaimDropInput!) {
  claimDrop(input: $input) {
    claim {
      id
      amount
    }
    claimParams {
      signature
    }
  }
}

3. Always Confirm Claims

# After blockchain transaction
mutation ConfirmClaimTransaction($input: ConfirmClaimInput!) {
  confirmClaim(input: $input) {
    success
    message
    drop {
      claimedAmount
      remainingBalance
    }
  }
}

Common Use Cases

Free Token Claim

mutation ClaimFreeTokens {
  claimDrop(
    input: {
      dropId: "drop_free_tokens"
      amount: "100"
      userAddress: "0x123abc..."
    }
  ) {
    claim {
      id
      amount
      claimedAt
    }
    claimParams {
      amount
      nonce
      expiry
      signature
    }
    dropInfo {
      dropObjectId
      packageId
      coinType
    }
  }
}
mutation ClaimPaidNFT {
  claimDrop(
    input: {
      dropId: "drop_paid_nft"
      amount: "1"
      userAddress: "0x123abc..."
      paymentIntentId: "pi_xyz789"
    }
  ) {
    claim {
      id
      amount
      claimedAt
      drop {
        title
        type
        price
      }
    }
    claimParams {
      signature
    }
  }
}

Random Amount Claim

mutation ClaimRandomAmount {
  claimRandomDrop(
    input: { dropId: "drop_random", userAddress: "0x123abc..." }
  ) {
    success
    message
    claimedAmount
    claim {
      id
      amount
      claimedAt
    }
    drop {
      claimedAmount
      remainingBalance
    }
  }
}

Claim with Verification

# Complete claim flow with verification
mutation CompleteClaimFlow($dropId: ID!, $userAddress: String!) {
  # This would be multiple operations in practice
  claimDrop(
    input: { dropId: $dropId, amount: "100", userAddress: $userAddress }
  ) {
    claim {
      id
      amount
      claimedAt
      user {
        username
        displayName
      }
    }
    claimParams {
      amount
      nonce
      expiry
      signature
    }
    dropInfo {
      dropObjectId
      packageId
      coinType
      isRandomAmount
    }
  }
}

Batch Claim Information

mutation ClaimAndGetDropInfo($input: ClaimDropInput!) {
  claimDrop(input: $input) {
    claim {
      id
      amount
      claimedAt
      user {
        username
        displayName
      }
    }
    dropInfo {
      dropObjectId
      packageId
      coinType
      isRandomAmount
    }
  }
}

# Also get updated drop stats
query GetUpdatedDropStats($dropId: ID!) {
  drop(id: $dropId) {
    id
    title
    claimedAmount
    maxAmount
    claimRate
    remainingBalance
    claimCount
    claims(limit: 5) {
      id
      amount
      claimedAt
      user {
        username
        displayName
      }
    }
  }
}