> ## Documentation Index
> Fetch the complete documentation index at: https://metalayerlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# How to use the Points API

The distribution of both Blast Points and Blast Gold can be done using the offchain Points API.

The integration of the Points API is divided into 2 parts:

**Onchain**: Configuring the [operator](/airdrop/mainnet-points-api/concepts#smart-contract-operator) address for the contract during deployment.

**Offchain**: Interacting with the Points API to fetch points balances and transferring points to users.

<Steps>
  <Step stepNumber="1" title={"Configuring the points operator address for the contract"} titleSize="h3">
    Any contracts that expect to accumulate Blast points or gold should call
    `configurePointsOperator` to be compatible with the points API.

    **We recommend calling it on construction/proxy initialization.**

    Contracts can earn points by holding ETH, WETH, or USDB, or by being designated
    recipients in another contract’s interactions with the points API.

    ```solidity theme={null}
    interface IBlastPoints {
      function configurePointsOperator(address operator) external;
      function configurePointsOperatorOnBehalf(address contractAddress, address operator) external;
    }

    // EXAMPLE dAPP
    contract Dapp {
      constructor(address _pointsOperator) {
        // be sure to use the appropriate testnet/mainnet BlastPoints address
        // BlastPoints Testnet address: 0x2fc95838c71e76ec69ff817983BFf17c710F34E0
        // BlastPoints Mainnet address: 0x2536FE9ab3F511540F2f9e2eC2A805005C3Dd800

        IBlastPoints(BlastPointsAddress).configurePointsOperator(_pointsOperator);
      }
    }
    ```
  </Step>
</Steps>

That's it, the `operator` is now configured and we can move onto the offchain steps!

<Accordion title="How do I change the operator at a later stage?">
  Once the points operator has been set once, only the existing points
  operator can update it by calling `configurePointsOperatorOnBehalf`.

  ```solidity theme={null}
  interface IBlastPoints {
    function configurePointsOperator(address operator) external;
    function configurePointsOperatorOnBehalf(address contractAddress, address operator) external;
  }
  ```

  The first parameter of `configurePointsOperatorOnBehalf` is the contract you’d like to change the points operator for.

  The second parameter is the new points `operator`. The `msg.sender` must be the current points operator.

  This mechanism allows you to change your points operator at any point after your contract has been created.
</Accordion>

## Interacting with the Points API

The points API is authenticated and requires the `bearerToken` to be present in headers as `Authorization: Bearer ${bearerToken}`.

We will get the `bearerToken` from the authentication flow.

<Steps titleSize="h3">
  <Step stepNumber="1" title="Obtaining a challenge">
    Requesting a challenge and message. Message to be signed by the
    `operator` private key following the
    [ERC-191](https://eips.ethereum.org/EIPS/eip-191) standard

    <CodeGroup>
      ```bash Mainnet theme={null}
      curl --request POST \
        --url https://waitlist-api.prod.blast.io/v1/dapp-auth/challenge \
        --header 'Content-Type: application/json' \
        --data '{
          "contractAddress": "<string>",
          "operatorAddress": "<string>"
      }'
      ```

      ```bash Testnet theme={null}
      curl --request POST \
        --url https://waitlist-api.develop.testblast.io/v1/dapp-auth/challenge \
        --header 'Content-Type: application/json' \
        --data '{
          "contractAddress": "<string>",
          "operatorAddress": "<string>"
      }'
      ```
    </CodeGroup>
  </Step>

  <Step stepNumber="2" title="Obtaining a bearer token">
    Using the message signed by the `operator` private key we can now obtain a `bearerToken` which then can be used to access authenticated routes on the Points API.

    <CodeGroup>
      ```bash Mainnet theme={null}
      curl --request POST \
        --url https://waitlist-api.prod.blast.io/v1/dapp-auth/solve \
        --header 'Content-Type: application/json' \
        --data '{
        "challengeData": "<string>",
        "signature": "<string>"
      }'
      ```

      ```bash Testnet theme={null}
      curl --request POST \
        --url https://waitlist-api.develop.testblast.io/v1/dapp-auth/solve \
        --header 'Content-Type: application/json' \
        --data '{
        "challengeData": "<string>",
        "signature": "<string>"
      }'
      ```
    </CodeGroup>
  </Step>

  <Step stepNumber="3" title="Get contract's points balance">
    Get the contract's points balance to see how many points can be distributed.

    The response will contain the points balances for both `Blast Points` (`PHASE2_POINTS`) and `Blast Gold` (`PHASE2_GOLD`).

    <CodeGroup>
      ```bash Mainnet theme={null}
      curl --request GET \
        --url https://waitlist-api.prod.blast.io/v1/contracts/{contractAddress}/point-balances \
        --header 'Authorization: Bearer <token>'
      ```

      ```bash Testnet theme={null}
      curl --request GET \
        --url https://waitlist-api.develop.testblast.io/v1/contracts/{contractAddress}/point-balances \
        --header 'Authorization: Bearer <token>'
      ```
    </CodeGroup>
  </Step>

  <Step stepNumber="4" title="Submitting a batch of point transfers">
    Submit a batch with details indicating which and how many points to transfer to a user.

    Operators cannot submit a batch to transfer `PHASE2_POINTS` and `PHASE2_GOLD` points simultaneously.

    <Info>
      `secondsToFinalize` should be greater than equal to `3600` for mainnet. If not provided the default is `86400`.

      Check Points API Parameters for the respective network for more information.
    </Info>

    <Note>
      If you need idempotency you can generate your own `batchId`s and use [this](/airdrop/mainnet-points-api/api-reference/mainnet/submitting-a-batch-idempotently) API endpoint.
    </Note>

    <CodeGroup>
      ```bash Mainnet theme={null}
      curl --request POST \
        --url https://waitlist-api.prod.blast.io/v1/contracts/{contractAddress}/batches \
        --header 'Authorization: Bearer <token>' \
        --header 'Content-Type: application/json' \
        --data '{
          "pointType": "<string>",
          "transfers": [
            {
              "toAddress": "<string>",
              "points": "<string>"
            }
          ],
          "secondsToFinalize": 3600
      }'
      ```

      ```bash Testnet theme={null}
      curl --request POST \
        --url https://waitlist-api.develop.testblast.io/v1/contracts/{contractAddress}/batches \
        --header 'Authorization: Bearer <token>' \
        --header 'Content-Type: application/json' \
        --data '{
          "pointType": "<string>",
          "transfers": [
            {
              "toAddress": "<string>",
              "points": "<string>"
            }
          ],
          "secondsToFinalize": 123
      }'
      ```
    </CodeGroup>
  </Step>

  <Step stepNumber="5" title="Fetching a single batch">
    Fetching the submitted batch to check the status of the point transfers.

    <Note>
      Alternatively, you can fetch all batches associated with your `contractAddress` using [this](/airdrop/mainnet-points-api/api-reference/mainnet/fetching-batches) API endpoint.
    </Note>

    <CodeGroup>
      ```bash Mainnet theme={null}
      curl --request GET \
        --url https://waitlist-api.prod.blast.io/v1/contracts/{contractAddress}/batches/{batchId} \
        --header 'Authorization: Bearer <token>'
      ```

      ```bash Testnet theme={null}
      curl --request GET \
        --url https://waitlist-api.develop.testblast.io/v1/contracts/{contractAddress}/batches/{batchId} \
        --header 'Authorization: Bearer <token>'
      ```
    </CodeGroup>
  </Step>
</Steps>

That's all you need to successfully transfer points to the users of your smart contract!

<AccordionGroup>
  <Accordion title="How do I cancel one/some of the transfers in the batch?">
    You cannot cancel an individual transfer, you cancel the entire batch of
    transfers using
    [this](/airdrop/mainnet-points-api/api-reference/mainnet/cancelling-a-batch)
    API endpoint and submit a new batch.
  </Accordion>
</AccordionGroup>
