We refreshed our doc site!

Bookmarked links may have changed

Read release notes

Web3 Services

Send an Outbound Transfer or Execute Contract

Learn how to send USDC or execute a contract from a user-controlled wallet with social logins or email authentication

This guide outlines how to initiate a currency transfer or execute a contract from a previously created user-controlled wallet with social logins or email authentication. To create a wallet, see Create Your First Wallet with Social Logins or Create Your First Wallet with Email.

If you’re building with Wallet Signing Service, you must manage the transaction broadcasting and indexing with your blockchain infrastructure.

Step 1. Check wallet balance and obtain token ID

Before making an outbound transfer, you must have a token ID and token balance greater than 0.

  1. Include userToken copied from the previous step in the header of a GET request to the /wallets endpoint.

  2. From the response, copy id which is your wallet ID.

    const response = await circleUserSdk.listWallets({
      userToken: '<USER_TOKEN>',
      pageSize: 10
    });
    
  3. Using id which you just copied, send a GET request to the /wallet/{id}/balances endpoint to check your wallet’s token balance.
    From the response, copy and store the tokenId that you intend to transfer.

      const response = await circleUserSdk.getWalletTokenBalance({
      userToken: '<USER_TOKEN>',
      walletId: '<WALLET_ID>'
    });
    

Step 2. Estimate the cost of transaction (optional)

To estimate the fees for the transaction to transfer tokens, send a POST request to the transactions/transfer/estimateFee endpoint.

const response = await circleUserSdk.estimateTransferFee({
  userToken: '<USER_TOKEN>',
  amount: ['.01'],
  destinationAddress: '0xEb9614D6d001391e22dDbbEA7571e9823A469c1f',
  tokenId: '36b6931a-873a-56a8-8a27-b706b17104ee',
  walletId: '01899cf2-d415-7052-a207-f9862157e546'
});

Response Body

JSON
{
  "data": {
    "low": {
      "gasLimit": "21000",
      "baseFee": "2.456220277",
      "priorityFee": "1.022783914",
      "maxFee": "5.935224468"
    },
    "medium": {
      "gasLimit": "21000",
      "baseFee": "2.456220277",
      "priorityFee": "2.655282857",
      "maxFee": "7.567723411"
    },
    "high": {
      "gasLimit": "21000",
      "baseFee": "2.456220277",
      "priorityFee": "15.986229693",
      "maxFee": "20.898670247"
    }
  }
}

Step 3. Initiate a blockchain transaction

Execute an asset transfer

To initiate a blockchain transfer from a specified wallet to a blockchain address:

  1. Include walletId and destinationAddress in a POST request to the /user/transactions/transfer endpoint.
  2. From the response, copy challengeId for the next step.

Execute a contract

To create a transaction that executes a smart contract:

  1. Include walletId and contractAddress in a POST request to the /user/transactions/contractExecution endpoint.
  2. From the response, copy challengeId and enter it in the sample app.

Step 4. Confirm execution

To authorize a transfer on the sample app's confirmation UI, ensure you have obtained an active user token and encryption key.

  • From the Execute Challenge screen in the sample app, paste the Challenge ID that you copied from the previous step and select Execute.

    The sample app displays a confirmation UI that contains transaction details for the user to confirm. You can customize confirmation UIs. For more, see Confirmation UIs .

Step 5. Check transaction status

As the transfer transaction’s state changes and ultimately completes, Circle sends webhook notifications to a subscriber endpoint. For a list of all possible states, see Asynchronous States and Statuses.

The following code sample shows an example of a webhook notification for a transfer.

JSON

JSON
{
  "subscriptionId": "d4c07d5f-f05f-4fe4-853d-4dd434806dfb",
  "notificationId": "acab8c14-92ae-481a-8335-6eb5271da014",
  "notificationType": "transactions.outbound",
  "notification": {
    "id": "ad3f40ae-9c0e-52cf-816f-91838850572a",
    "blockchain": "MATIC-AMOY",
    "tokenId": "36b6931a-873a-56a8-8a27-b706b17104ee",
    "walletId": "01899cf2-d415-7052-a207-f9862157e546",
    "sourceAddress": "0x7b777eb80e82f73f118378b15509cb48cd2c2ac3",
    "destinationAddress": "0x6e5eaf34c73d1cd0be4e24f923b97cf38e10d1f3",
    "transactionType": "OUTBOUND",
    "custodyType": "ENDUSER",
    "state": "COMPLETE",
    "amounts": [
      "0.01"
    ],
    "nfts": null,
    "txHash": "0x535ff240984f54e755d67cdc9c79c88768fe5997955f09f3a66b4d1126810900",
    "blockHash": "0xa4c5c79500240f3ae3f4e5c5f641198b7c698d83b7539ac4e8cf2d3f5f49bdfd",
    "blockHeight": 41100000,
    "networkFee": "0.07037500047405219",
    "firstConfirmDate": "2023-10-11T21:08:28Z",
    "operation": "TRANSFER",
    "userId": "c266945c-f440-4537-85cf-a16b6e33b0cc",
    "abiParameters": null,
    "createDate": "2023-10-11T21:08:13Z",
    "updateDate": "2023-10-11T21:08:37Z"
  },
  "timestamp": "2023-10-11T21:08:13Z",
  "version": 2
}

You can also include your user's userId or userToken in a GET request to the /transactions endpoint.

const response = await circleUserSdk.listTransactions({
  userToken: '<USER_TOKEN>'
});

The following code sample shows the response.

JSON

JSON
{
  "data": {
    "transactions": [
      {
        "id": "ad3f40ae-9c0e-52cf-816f-91838850572a",
        "blockchain": "MATIC-AMOY",
        "tokenId": "36b6931a-873a-56a8-8a27-b706b17104ee",
        "walletId": "01899cf2-d415-7052-a207-f9862157e546",
        "sourceAddress": "0x7b777eb80e82f73f118378b15509cb48cd2c2ac3",
        "destinationAddress": "0x6e5eaf34c73d1cd0be4e24f923b97cf38e10d1f3",
        "transactionType": "OUTBOUND",
        "custodyType": "ENDUSER",
        "state": "COMPLETE",
        "amounts": [
          "0.01"
        ],
        "nfts": null,
        "txHash": "0x535ff240984f54e755d67cdc9c79c88768fe5997955f09f3a66b4d1126810900",
        "blockHash": "0xa4c5c79500240f3ae3f4e5c5f641198b7c698d83b7539ac4e8cf2d3f5f49bdfd",
        "blockHeight": 41100000,
        "networkFee": "0.07037500047405219",
        "firstConfirmDate": "2023-10-11T21:08:28Z",
        "operation": "TRANSFER",
        "userId": "c266945c-f440-4537-85cf-a16b6e33b0cc",
        "abiParameters": null,
        "createDate": "2023-10-11T21:08:13Z",
        "updateDate": "2023-10-11T21:08:37Z"
      },
      {
        "id": "81cf790a-ed95-5d41-b7bd-c4e15390eef6",
        "blockchain": "MATIC-AMOY",
        "tokenId": "36b6931a-873a-56a8-8a27-b706b17104ee",
        "walletId": "01899cf2-d415-7052-a207-f9862157e546",
        "sourceAddress": "0x48520ff9b32d8b5bf87abf789ea7b3c394c95ebe",
        "destinationAddress": "0x7b777eb80e82f73f118378b15509cb48cd2c2ac3",
        "transactionType": "INBOUND",
        "custodyType": "ENDUSER",
        "state": "COMPLETE",
        "amounts": [
          "10"
        ],
        "nfts": null,
        "txHash": "0x5121f9efec29d4d661ffb0b777727d1f5ba7b5bc286ac4891c82f7b1b80a9485",
        "blockHash": "0xba7984dbe7423827b5fd175a636552ae85401c3f2a0c5cdda934a37d6652ac49",
        "blockHeight": 41098635,
        "networkFee": "0.001911870000955935",
        "firstConfirmDate": "2023-10-11T20:13:33Z",
        "operation": "TRANSFER",
        "userId": "c266945c-f440-4537-85cf-a16b6e33b0cc",
        "abiParameters": null,
        "createDate": "2023-10-11T20:13:33Z",
        "updateDate": "2023-10-11T20:13:45Z"
      }
    ]
  }
}
Did this page help you?
© 2023-2024 Circle Technology Services, LLC. All rights reserved.