Skip to main content
Version: Next

Fungible Token Drop

Introduction

In this tutorial, you will learn how to create a fungible token drop from scratch. This allows you onboard users both with $NEAR and a set of FTs with the click of a link. An excellent use case can be seamlessly offering in-game currency to players.

ft claim

To learn more about the FT drop, see the concepts page


Prerequisites

For the basic tutorials, you can choose to run the scripts on your own machine. To do so, you must have the following:

  1. Node JS
  2. NEAR-API-JS
  3. Keypom JS SDK

With this tutorial, you can either create your own script by following along, or view the completed script available in the Keypom Documentation Examples repo.

Creating your Project

In this section, you're going to create your project and install the SDK to prepare for the tutorial. If you have a completed script and have installed the SDK, you can skip forward.

First, you need to give your project a home.

mkdir my-keypom-project && cd my-keypom-project

Next, you'll want to create a default package.json file using the following command. You can accept all default values.

npm init

At this point, your project structure should look like this.

/my-keypom-project
├── package.json

If you open package.json, you should see this.

Default package.json

{
"name": "my-keypom-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

The next step is to create an empty JavaScript file.

touch ft-keypom.js

Finally, the last step is to install the Keypom JS SDK.

npm install @keypom/core

After installing the SDK, your package.json file should now look slightly different.

package.json after installing the SDK

{
"name": "my-keypom-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@keypom/core": "^1.0.0"
}
}

With these steps complete, your project folder should look like this.

/my-keypom-project
├── ft-keypom.js
├── package.json
├── package-lock.json
├── node_modules
│ └── @keypom/core
│ └── ...

You are now ready to begin creating your drop!


Breaking Down the Problem

The process of creating an FT drop can be broken down into the following steps.

1) Connect to the NEAR blockchain.
2) Ensure the funder has enough FTs to fund the drop.
3) Create the drop.
4) Transfer Keypom the necessary Fungible Tokens.
5) Create linkdrops.

The following skeleton code can be used as a starting point:

// Each of the two methods to create this drop will have their own unique set of imports

// Imports used in the Keypom SDK method:
const { initKeypom, createDrop, getEnv, formatLinkdropUrl } = require("@keypom/core");
const { parseNearAmount } = require("@near-js/utils");
const { UnencryptedFileSystemKeyStore } = require("@near-js/keystores-node");
const { Near } = require("@near-js/wallet-account");
const { Account } = require("@near-js/accounts");
const { BN } = require("bn.js");
const path = require("path");
const homedir = require("os").homedir();

// Imports used in the NEAR-API-JS method:
const { parseNearAmount } = require("@near-js/utils");
const { KeyPair } = require("@near-js/crypto")
const { Near } = require("@near-js/wallet-account");
const { Account } = require("@near-js/accounts");
const { UnencryptedFileSystemKeyStore } = require("@near-js/keystores-node");
const { getRecentDropId } = require("../utils/general.js")
const { BN } = require("bn.js");
const path = require("path");
const homedir = require("os").homedir();


async function FTDropKeypom(){
// GETTING STARTED

// STEP 1 Initialize NEAR blockchain connection.

// STEP 2 Ensure the funder has enough FTs to fund the drop.

// CREATING DROP AND TRANSFERRING FTs

// STEP 3 Create the drop.

// STEP 4 Transfer Keypom the necessary Fungible Tokens.

// CREATING LINKDROPS

// STEP 5 Create Linkdrops
}

FTDropKeypom()

Steps 1 and 2 will be covered in "Getting Started" and Steps 3, 4, and 5 will be under "Creating FT drop and Transferring FTs". Step 6 will have its own section called "Creating Linkrops".


Getting Started

In this section, you'll be addressing the first two steps: connecting to NEAR and ensuring the funder has enough FTs for the drop.

Connecting to the NEAR blockchain will be done using NEAR-API-JS and consists of the following steps:

1) Create a Keystore, which stores your access keys used to sign transactions

  • select a network, either testnet or mainnet
  • choose a location where the keypairs live, either a folder on your local machine, or in-memory

2) Define a NEAR configuration using the Keystore
3) Use the configuration to initialize a connection to NEAR

More information about this process can be found here.

note

For simplicity, this tutorial will choose a file-based keystore and point to the ~/.near-credentials folder on your local machine since this is where most of your keys are stored. For more information about KeyStores, visit NEAR's official docs.

To ensure the funder has enough FTs to fund the drop, a new concept is to be defined.

info

amountToTransfer = FT per use * number of keys * uses per key.

Using NEAR-API-JS, a viewFunction to the FT contract can be made to call ft_balance_of. This will return the funder's FT balance, which can be compared with amountToTransfer to ensure the funder has enough FTs to fund the drop.

The code for setting up the NEAR connection and ensuring sufficient funder FT balance is shown below. In the skeleton code, these are steps 1 and 2.

basic-tutorials/fungible-token-drop/ft-example.js
loading...
note

In the code, you may notice the balances defined using BN. These are simply Big Numbers and is a library built to handle numbers beyond JavaScript's max safe integer.

The FTs in this example have a decimal of 24. This is the same as 1 $NEAR -> 1024 YoctoNEAR, which allows the use of parseNearAmount to convert between the two. Read more on the decimal parameter here.


Creating Drop and Transferring FTs

In this section of the tutorial, you'll be creating the drop and transferring the FTs to Keypom using the Keypom SDK.

As outlined in to introduction, there are 2 tasks to complete in this section.

  • Create the drop
  • Transfer the FTs to Keypom

This process starts with calling the initKeypom function and will always be the first function you call to interact with the SDK.

initKeypom initializes the SDK to allow for interactions with the Keypom smart contracts. Without it, none of the other SDK functions would work as expected. If a NEAR connection is not already present, it will initialize a new one for you. More info on the initKeypom function can be found here.

Following the initKeypom call, the FT Drop is created. This is done by calling createDrop and adding an ftData parameter.

tip

Recall that the private keys being generated using createDrop are used to store the assets. These keys are then embedded within a link.

In an FT Drop, the assets consist of FTs and optional $NEAR.

ftData is an object with the following properties.

ftData
├── contractId
├── senderId
├── amount
  • contractId: The FT contract ID
  • senderId: The account from which the FTs will be sent to Keypom.
  • amount: This is the human readable amount of FT, based on the decimals value of the token

Including the ftData parameter categorizes this as an FT drop. Without it, the Keypom Protocol would treat this drop as a Simple Drop.

More information on the ftData parameter can be found here.

info

So long as the funder has an adequate FT balance, all you need to do is call createDrop with ftData to create the drop.

The SDK will automatically register Keypom on the FT contract and transfer the FTs to Keypom for you.

To see what the SDK is doing behind the scenes, a NEAR-API-JS equivalent NodeJS script has been provided.

basic-tutorials/fungible-token-drop/ft-example.js
loading...

Creating Linkdrops

The last step in this process is to create the links themselves so that you can easily distribute the assets to people. This is done by embedding the private key, containing the $NEAR, into the link along with the Keypom contract ID.

With the Keypom SDK, this is all neatly wrapped up in the function formatLinkdropUrl. You just need to provide the base URL format and the private key you wish to embed.

basic-tutorials/fungible-token-drop/ft-example.js
loading...

Full Code

Now that everything has been put together, the final code can be seen below.

basic-tutorials/fungible-token-drop/ft-example.js
loading...

Testing

Running the Script

Here, you'll learn how to run the code that was just covered, and what to expect.

To view the completed code, clone the Keypom Docs Examples repository and navigate to the basic-tutorials/ft-drop.

git clone https://github.com/keypom/keypom-docs-examples.git && cd keypom-docs-examples/basic-tutorials/ft-drop

From there, you can and open the ft-example.js file.

To run the code you just cloned, return to the keypom-docs-examples directory and install all the necessary packages.

cd .. && cd .. && yarn
caution

Prior to running these scripts, ensure you replace all instances of keypom-docs-demo.testnet in the script with the credentials of your account found in your ~/.near-credentials folder

From there, you can run this FT Drop script that was made in this tutorial using the following command:

yarn basic:ft:keypom
note

The SDK script is being tested here; use yarn basic:ft:naj to test the NEAR-API-JS script instead.

This should return a successful drop creation and console log a Public Key and Linkdrop

Public Keys:  [ 'ed25519:DkvGVA8UuBRKtsXvBxnKkHs2aHzd221QSquinokfJ71a' ]
Linkdrops: [
'https://testnet.mynearwallet.com/linkdrop/v2.keypom.testnet/2H8i9Snk4v3wBBHeTxBFuzzi1SF5DL4nFHvMUp1nDz4ARSW3tB5b8z2Xxm6Y5rMzzVS3sDppPxM4jtRhyYkHfF2Y'
]
Keypom Contract Explorer Link: explorer.testnet.near.org/accounts/v2.keypom.testnet.com

To see the full console log from this drop creation, see the expandable section below.

Console Log of Test

Receipts: AxiAwWNkKQsyvdcAhwBr2B2Qqc5gVCBw2MLrbL7dLq6d, 6QCHm8YtpfreHYQvw9VAHU7rJXGgfVv4T1TDcuXHEtvC, 5CTcWfQ1BC1nensRK6NhcNSv5NjxdSaVSwti4j34fCa3
Log [v2.keypom.testnet]: Current Block Timestamp: 1682352345716601116
Log [v2.keypom.testnet]: 21 calls with 105000000000000 attached GAS. Pow outcome: 1.8602935. Required Allowance: 20248156910387200000000
Log [v2.keypom.testnet]: was_ft_registered: true
Log [v2.keypom.testnet]: Total required storage Yocto 11980000000000000000000
Log [v2.keypom.testnet]: Current balance: 8.2955772,
Required Deposit: 1.0332281,
total_required_storage: 0.01198,
Drop Fee: 0,
Key Fee: 0 Total Key Fee: 0,
allowance: 0.0202481 total allowance: 0.0202481,
access key storage: 0.001 total access key storage: 0.001,
deposits less none FCs: 1 total deposits: 1 lazy registration: false,
deposits for FCs: 0 total deposits for FCs: 0,
uses per key: 1
None FCs: 0,
length: 1
GAS to attach: 100000000000000
Log [v2.keypom.testnet]: New user balance 7.262349
Log [v2.keypom.testnet]: Fees collected 0
Log [v2.keypom.testnet]: Performing CCC to get storage from FT contract
Receipts: 4PPt4W1C9xYP2yc67CLVX6vvYshf1oCoDr9hBiZUniTZ, 8iSu5McdW8rvPApvYjbPhew6wGZ9raAPiR8SEA43tV86
Log [v2.keypom.testnet]: User has enough balance to cover FT storage. Subtracting 0.0025 from user balance. User balance is now 7.259849
Log [v2.keypom.testnet]: 21 calls with 105000000000000 attached GAS. Pow outcome: 1.8602935. Required Allowance: 20248156910387200000000
Log [v2.keypom.testnet]: FT contract already registered. Refunding user balance for 0.00125. Balance is now 7.261099
Receipts: 9FEiXh19PMMRirF4CGDTEfopWxf6eLWxNvJmUMnrrVX8, AwJ362Sj4PZ3EbusnwLo4qoyExXRRZPAyqUUT1uZ64oi, 8KquU3a2BA3AWb9keYfwYvYpD6iD5CQG1Vn78efBex9B
Log [ft.keypom.testnet]: EVENT_JSON:{"standard":"nep141","version":"1.0.0","event":"ft_transfer","data":[{"old_owner_id":"keypom-docs-demo.testnet","new_owner_id":"v2.keypom.testnet","amount":"1"}]}
Receipt: 9Ls4K4vm8pW7HcjD6PMBbJoWSsjwN16YEq3GdCqnahPx
Log [ft.keypom.testnet]: New uses registered 1
Public Keys: [ 'ed25519:DkvGVA8UuBRKtsXvBxnKkHs2aHzd221QSquinokfJ71a' ]
Linkdrops: [
'https://testnet.mynearwallet.com/linkdrop/v2.keypom.testnet/2H8i9Snk4v3wBBHeTxBFuzzi1SF5DL4nFHvMUp1nDz4ARSW3tB5b8z2Xxm6Y5rMzzVS3sDppPxM4jtRhyYkHfF2Y'
]
Keypom Contract Explorer Link: explorer.testnet.near.org/accounts/v2.keypom.testnet.com

Claiming and Explorer Transactions

Once you click the link, it will take you to the following NEAR Wallet page, where you will have the choice to claim with an existing account or create a new one.

NEAR Wallet claim

In your NEAR wallet, you should now be able to see the FT tokens that were transferred to you.

ft claim

To check the transactions, click the final link in the console log when you run the script.

Keypom Contract Explorer Link: https://explorer.testnet.near.org/accounts/v2.keypom.testnet 

From there, you should be able to see the create_drop, ft_transfer_call and claim transactions.

explorer transactions

note

Recall that ft_transfer_call is never explicitly called but rather createDrop calls it for you; this can be seen in the explorer shown above.

This is the SDK in action!


Conclusion

In this tutorial, you've learned to ensure the funder has a sufficient FT balance for the drop, create an FT drop with the SDK, and to transfer FTs to Keypom. Once the drop was created, you constructed a valid linkdrop using the private keys in order to claim the assets.

In the next tutorial, you will learn to create a function call drop.