Rise In Logo





Build on Circle

You have two options to send tokens.

  • You can send tokens to the same wallet. If so, you can understand the transaction was successful by looking at the transaction log or by checking the change in the native currency which will be used for gas fees.
  • Otherwise you can create a new wallet.
  • Open the User-Controlled-Wallet project.
  • Get the necessary variables from each section.
  • App Id: Same as before
  • User Id: To create a separate user, you can generate a new one, to use the same user, keep it the same as before.
  • User Session and Encryption Key: Generate new ones.
  • Challenge Id: Create a new one by initializing the user.
  • Create a new wallet.

Remember that you need to update the .env.local file for each new variable you have retrieved.

After you have a sender and a receiver wallet, it is time for your first transaction.

Javascript Code to Send 1 USDC Token

import dotenv from "dotenv";

import fetch from "node-fetch";

import { acquire_session_token } from "../helpers/acquire_session_token.js";

import { v4 as uuidv4 } from "uuid";

dotenv.config();

const userCredentials = await acquire_session_token();

const userToken = userCredentials.userToken;

const encryptionKey = userCredentials.encryptionKey;

const idempotencyKey = uuidv4();

const url = "<https://api.circle.com/v1/w3s/user/transactions/transfer>";

const options = {

  method: "POST",

  headers: {

    "Content-Type": "application/json",

    Authorization: `Bearer ${process.env.API_KEY}`,

    "X-User-Token": userToken,

  },

  body: JSON.stringify({

    idempotencyKey: idempotencyKey,

    userId: `${process.env.USER_ID}`,

    destinationAddress: `${process.env.ADDRESS_R}`,

    refId: "",

    amounts: \["1"\],

    feeLevel: "HIGH",

    tokenId: `${process.env.USDC_TOKEN_ID}`,

    walletId: `${process.env.WALLET_ID}`,

  }),

};

fetch(url, options)

  .then((res) =&gt; res.json())

  .then((json) =&gt; {

    console.log("user token:", userToken);

    console.log("encryption key:", encryptionKey);

    console.log("idempotency key:", idempotencyKey);

    console.log(json);

  })

  .catch((err) =&gt; console.error("error:" + err));

Now, let's break down this code to understand it better.

import dotenv from "dotenv";

import fetch from "node-fetch";

import { acquire_session_token } from "../helpers/acquire_session_token.js";

import { v4 as uuidv4 } from "uuid";

Here you import the necessary libraries and codes.

  • dotenv and fetch have the same purpose as in the previous examples to use the .env file and to be able to make fetch calls to the api.
  • acquire_session_token this is the same function as you used in the user-controlled wallet project. Now, this code returns an object that has a userToken and encryption key.
  • uuid: to create the idempotency key with a unique identifier.
const url = "<https://api.circle.com/v1/w3s/user/transactions/transfer>";

const options = {

  method: "POST",

  headers: {

    "Content-Type": "application/json",

    Authorization: `Bearer ${process.env.API_KEY}`,

    "X-User-Token": userToken,

  },

  body: JSON.stringify({

    idempotencyKey: idempotencyKey,

    userId: `${process.env.USER_ID}`,

    destinationAddress: `${process.env.ADDRESS_R}`,

    refId: "",

    amounts: \["1"\],

    feeLevel: "HIGH",

    tokenId: `${process.env.USDC_TOKEN_ID}`,

    walletId: `${process.env.WALLET_ID}`,

  }),

};
  • url is where you send the POST request.
  • headers include necessary information for the call including API_KEY and userToken.
  • body: this contains the information for your transaction.
  • idempotency key: This uniquely identifies the transaction.
  • userId: This is the id of the user who makes the transaction.
  • destinationAddress: This is the address of the wallet that receives the funds.
  • amounts: Amount of token to be transferred.
  • feeLevel: This indicates the amount of fee to be used for the transaction.
  • tokenId: The id of the token to be sent (in this case the id of the USDC token that you have retrieved in the previous lesson).
  • walletId: Id of the wallet that sends the funds
fetch(url, options)

  .then((res) =&gt; res.json())

  .then((json) =&gt; {

    console.log("user token:", userToken);

    console.log("encryption key:", encryptionKey);

    console.log("idempotency key:", idempotencyKey);

    console.log(json);

  })

  .catch((err) =&gt; console.error("error:" + err));
  • This part works the same as the previous examples. Differently, you are printing some information (user token, encryption key and idempotency key) before returning the json object.
  • The reason that code logs this information is because you are going to need it in the next part.

This code returns a challengeId inside a json object. You are going to use this challenge id as you used before when you played the part of the end user and created a wallet by setting up a pin code and a recovery question. Since this is a user controlled wallet, you need the authorization from the end user. This is true for wallet creation and this is also true for transaction. For that, reason, please save this challenge id for the next part.

Completing the Challenge

Now that you have the user token (session token), encryption key and Challenge ID, you can again play the role of the end user and complete the challenge for your transaction to be successful.

  • Open the user-controlled-wallet project, where you have created the user controlled wallet.
  • Click on the wallet icon in the homepage that will take you to the wallet creation page.

You have used that page before to create a wallet. This time, you are going to use this for completing a transaction. The reason you can use the same structure is because of the challenge. In the user controlled wallet, after you have done your part, you will require the authorization of the user. In Circle, you do this with a challenge. That is why in both creating a user controlled wallet, and creating a transaction, at the end, you have acquired a challenge id. You will use the same parameters as before: APP ID. USER ID, USER(SESSION) TOKEN, ENCRYPTION KEY and CHALLENGE ID. You have acquired these values if you followed the previous steps.

  • Now, put the values and click on the button to verify the challenge.
  • It will ask for your pin code and that is it. Now you have successfully sent a 1 USDC token to another wallet!

Summary

Creating a transaction has two main parts:

1.Part of the developer:

  • Developer acquires the session token, encryption key and challenge id. Putting the necessary parameters makes the api call.

2. Part of the user:

  • User completes this transaction by completing the challenge by putting the pin code.
Rise In Logo

Rise together in web3