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

# Using Linkdrops

> Learn about linkdrops following NEP-452 standard - distribute assets and onboard users to Web3 apps through simple web links using access keys and the Keypom platform.

export const TryOutOnLantstool = ({path, user = 'lantstool', repo = 'examples.near-protocol', branch = 'main'}) => {
  const lantstoolUrl = `https://app.lantstool.dev/import/gh/${user}/${repo}/${branch}/${path}`;
  const githubUrl = `https://github.com/${user}/${repo}/blob/${branch}/${path}`;
  const [code, setCode] = useState(null);
  function toRaw(ref) {
    const [org, repoName, , branchName, ...pathSeg] = new URL(ref).pathname.split('/').slice(1);
    return `https://raw.githubusercontent.com/${org}/${repoName}/${branchName}/${pathSeg.join('/')}`;
  }
  useEffect(() => {
    const rawUrl = toRaw(githubUrl);
    (async () => {
      try {
        let res;
        const validUntil = typeof window !== 'undefined' && localStorage.getItem(`${rawUrl}-until`);
        if (validUntil && Number(validUntil) > Date.now()) {
          res = localStorage.getItem(rawUrl);
        }
        if (!res) {
          res = await (await fetch(rawUrl)).text();
          if (typeof window !== 'undefined') {
            localStorage.setItem(rawUrl, res);
            localStorage.setItem(`${rawUrl}-until`, String(Date.now() + 60000));
          }
        }
        setCode(res);
      } catch {
        setCode('Error fetching code, please try reloading');
      }
    })();
  }, [githubUrl]);
  return <div>
      <p>
        Try it out on{' '}
        <a href={lantstoolUrl} target="_blank" rel="noopener noreferrer">
          Lantstool
        </a>
      </p>
      <div className="rounded-[0.625rem] border border-[#d0d7de] dark:border-[#30363d] overflow-hidden my-3 text-[0.8125rem] font-mono shadow-sm dark:shadow-[0_4px_24px_rgba(0,0,0,0.18)]">
        <div className="flex items-center gap-2 py-2 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-b border-[#d0d7de] dark:border-[#30363d]">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor" className="text-[#656d76] dark:text-[#8b949e]">
            <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z" />
          </svg>
          <span className="text-xs font-medium text-[#1f2328] dark:text-[#e6edf3]">
            {githubUrl.split('/').pop()}
          </span>
        </div>
        <div className="overflow-auto max-h-[480px] bg-white dark:bg-[#0d1117] [&_tr]:border-b-0 [&_td]:border-b-0">
          {code === null ? <div className="py-5 px-4 text-xs text-[#656d76] dark:text-[#6e7681]">Loading...</div> : <table className="w-full border-collapse leading-[1.6]">
              <tbody>
                {code.split('\n').map((line, i) => <tr key={i} className="align-top border-0">
                    <td style={{
    minWidth: '60px'
  }} className="select-none pl-2 pr-3 text-right text-[0.7rem] text-[#8c959f] dark:text-[#3d444d] w-[1%] whitespace-nowrap border-r border-0 border-r-[#d0d7de] dark:border-r-[#21262d]">
                      {i + 1}
                    </td>
                    <td className="pl-4 pr-6 text-[0.8125rem] text-[#1f2328] dark:text-[#e6edf3] whitespace-pre">
                      {line || ' '}
                    </td>
                  </tr>)}
              </tbody>
            </table>}
        </div>
      </div>
    </div>;
};

Wanting to use Linkdrops in your dApp? Here you will find all the information you need to get started.

<Tip>
  The simplest way to create a linkdrop is by interacting with our LinkDrop Generator
</Tip>

***

## AccessKeys

In order to create any kind of drop, you need to first generate key pairs. You will need to create **one key per drop**.

* The `linkdrop` contract will store the **`public`** part of the key.
* You will give the `private` part of the key to the user you want to receive the drop.

<Tabs>
  <Tab title="🌐 WebApp">
    ```js theme={null}
    import { KeyPair } from 'near-api-js';

    const newKeyPair = KeyPair.fromRandom('ed25519');
    newKeyPair.public_key = newKeyPair.publicKey.toString();
    ```
  </Tab>

  <Tab title="🖥️ CLI">
    ```bash theme={null}
    near generate-key

    # Key pair with ed25519:33Vn9VtNEtWQPPd1f4jf5HzJ5weLcvGHU8oz7o5UnPqy public key for an account "1e5b1346bdb4fc5ccd465f6757a9082a84bcacfd396e7d80b0c726252fe8b3e8"
    ```
  </Tab>

  <Tab title="Lantstool" icon="https://mintcdn.com/neardocs-migrate-blog/ZW_VVLXFrN_7lu5M/assets/docs/tools/lantstool-logo-circle.svg?fit=max&auto=format&n=ZW_VVLXFrN_7lu5M&q=85&s=14d6291741111764d81598caa5c6aaa3" width="100" height="100" data-path="assets/docs/tools/lantstool-logo-circle.svg">
    <p>Generate a new key on [Lantstool](https://app.lantstool.dev/)</p>

    <img src="https://mintcdn.com/neardocs-migrate-blog/ZW_VVLXFrN_7lu5M/assets/docs/tools/lantstool-near_protocol-utils-key_generator.png?fit=max&auto=format&n=ZW_VVLXFrN_7lu5M&q=85&s=923afd133a16d7bfc3eaa516139b52e1" alt="lantstool" width="2560" height="1801" data-path="assets/docs/tools/lantstool-near_protocol-utils-key_generator.png" />
  </Tab>
</Tabs>

***

## `$NEAR` Drops

To create a `$NEAR` drop you will ask the contract to create a drop (`create_drop`), passing the public part of the keys you generated, and how much you want to drop on each key use (`deposit_per_use`).

The contract will create a drop and **return the numerical ID** that identifies it.

<Tabs>
  <Tab title="🌐 WebApp">
    ```js theme={null}
    import { useNearWallet } from "near-connect-hooks";

    const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near";
    const DROP_AMOUNT = "10000000000000000000000"; // 0.1 NEAR

    const { callFunction } = useNearWallet();

    await callFunction({
      contractId: KEYPOM_CONTRACT_ADDRESS,
      method: "create_drop",
      args: {
        public_keys: state.publicKeys,
        deposit_per_use: DROP_AMOUNT,
      },
      deposit: "23000000000000000000000", // state.publicKeys.length * dropAmount + 3000000000000000000000
      gas: "100000000000000",
    });
    ```

    Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application
  </Tab>

  <Tab title="🖥️ CLI">
    ```bash theme={null}
    near call v2.keypom.near create_drop '{"public_keys": <PUBLIC_KEYS>, "deposit_per_use": "10000000000000000000000"}' --depositYocto 23000000000000000000000 --gas 100000000000000 --useAccount bob.near
    ```
  </Tab>

  <Tab title="Lantstool" icon="https://mintcdn.com/neardocs-migrate-blog/ZW_VVLXFrN_7lu5M/assets/docs/tools/lantstool-logo-circle.svg?fit=max&auto=format&n=ZW_VVLXFrN_7lu5M&q=85&s=14d6291741111764d81598caa5c6aaa3" width="100" height="100" data-path="assets/docs/tools/lantstool-logo-circle.svg">
    <TryOutOnLantstool path="docs/2.build/5.primitives/linkdrop/create-near-drop.json" />
  </Tab>
</Tabs>

<Info>
  To claim the drop, you will need to send the user a [link with the private key](#building-drop-links)
</Info>

***

## NFT Drops

To drop an existing NFT, you will (1) create a drop, and then (2) **transfer the NFT** to keypom.

#### 1. Creating the Drop

To create an NFT drop, you will call the `create_drop` method, now passing a `nft` argument, which will tell the linkdrop contract to wait for an NFT to be transferred.

The contract will then create a drop and **return the numerical ID** that identifies it.

<Tabs>
  <Tab title="🌐 WebApp">
    ```js theme={null}
    import { useNearWallet } from "near-connect-hooks";

    const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near";
    const NFT_CONTRACT_ADDRESS = "nft.primitives.near";
    const DROP_AMOUNT = "10000000000000000000000";

    const { callFunction, accountId } = useNearWallet();

    await callFunction({
      contractId: KEYPOM_CONTRACT_ADDRESS,
      method: "create_drop",
      args: {
        public_keys: state.publicKeys,
        deposit_per_use: DROP_AMOUNT,
        nft: {
          // Who will be sending the NFTs to the Keypom contract
          sender_id: accountId,
          // NFT Contract Id that the tokens will come from
          contract_id: NFT_CONTRACT_ADDRESS,
        },
      },
      deposit: "23000000000000000000000", // state.publicKeys.length * dropAmount + 3000000000000000000000
      gas: "100000000000000",
    });
    ```

    Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application
  </Tab>

  <Tab title="🖥️ CLI">
    ```bash theme={null}
    near call v2.keypom.near create_drop '{"public_keys": <PUBLIC_KEYS>, "deposit_per_use": "10000000000000000000000", "nft": {"sender_id": "bob.near", "contract_id": "nft.primitives.near"}}' --depositYocto 23000000000000000000000 --gas 100000000000000 --useAccount bob.near
    ```
  </Tab>

  <Tab title="Lantstool" icon="https://mintcdn.com/neardocs-migrate-blog/ZW_VVLXFrN_7lu5M/assets/docs/tools/lantstool-logo-circle.svg?fit=max&auto=format&n=ZW_VVLXFrN_7lu5M&q=85&s=14d6291741111764d81598caa5c6aaa3" width="100" height="100" data-path="assets/docs/tools/lantstool-logo-circle.svg">
    <TryOutOnLantstool path="docs/2.build/5.primitives/linkdrop/create-nft-drop.json" />
  </Tab>
</Tabs>

#### 2. Transferring the NFT

Having the Drop ID, you now need to transfer the NFT to the linkdrop contract, specifying to which drop you want to add it.

<Tabs>
  <Tab title="🌐 WebApp">
    ```js theme={null}
    import { useNearWallet } from "near-connect-hooks";

    const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near";
    const NFT_CONTRACT_ADDRESS = "nft.primitives.near";
    const NFT_TOKEN_ID = "1";

    const { callFunction } = useNearWallet();

    await callFunction({
      contractId: NFT_CONTRACT_ADDRESS,
      method: "nft_transfer_call",
      args: {
        receiver_id: KEYPOM_CONTRACT_ADDRESS,
        token_id: NFT_TOKEN_ID,
        msg: dropId.toString()
      },
      deposit: 1,
      gas: "100000000000000",
    });
    ```

    Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application
  </Tab>

  <Tab title="🖥️ CLI">
    ```bash theme={null}
    near call nft.primitives.near nft_transfer_call '{"receiver_id": "v2.keypom.near", "token_id": <YOUR TOKEN ID>, "msg": <YOUR DROP ID>}' --depositYocto 1 --gas 100000000000000 --useAccount bob.near
    ```
  </Tab>

  <Tab title="Lantstool" icon="https://mintcdn.com/neardocs-migrate-blog/ZW_VVLXFrN_7lu5M/assets/docs/tools/lantstool-logo-circle.svg?fit=max&auto=format&n=ZW_VVLXFrN_7lu5M&q=85&s=14d6291741111764d81598caa5c6aaa3" width="100" height="100" data-path="assets/docs/tools/lantstool-logo-circle.svg">
    <TryOutOnLantstool path="docs/2.build/5.primitives/linkdrop/transfer-nft-to-v2keypomnear.json" />
  </Tab>
</Tabs>

<Tip>
  The `linkdrop` contract will validate that you are transferring the NFT to a drop that belongs to you
</Tip>

<Tip>
  The simplest way to create a linkdrop is by interacting with our LinkDrop Generator
</Tip>

***

## FT Drops

The process to drop a Fungible Token is very similar to that of creating an [NFT drop](#nft-drops). You will first create the drop, and then fund it with FTs.

#### 1.Creating a drop

To create a FT drop you will call the `create_drop` method, now passing a `ftData` argument, which will tell the linkdrop contract to wait for a certain amount of FT to be transferred.

The contract will then create a drop and **return the numerical ID** that identifies it.

<Tabs>
  <Tab title="🌐 WebApp">
    ```js theme={null}
    import { useNearWallet } from "near-connect-hooks";

    const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near";
    const FT_CONTRACT_ADDRESS = "ft.primitives.near";
    const DROP_AMOUNT = "10000000000000000000000";

    const { callFunction, accountId } = useNearWallet();

    await callFunction({
      contractId: KEYPOM_CONTRACT_ADDRESS,
      method: "create_drop",
      args: {
        public_keys: state.publicKeys,
        deposit_per_use: DROP_AMOUNT,
        ftData: {
          contractId: FT_CONTRACT_ADDRESS,
          senderId: accountId,
          // This balance per use is balance of human readable FTs per use.
          amount: "1"
          // Alternatively, you could use absoluteAmount, which is dependent on the decimals value of the FT
          // ex. if decimals of an ft = 8, then 1 FT token would be absoluteAmount = 100000000
        },
      },
      deposit: "23000000000000000000000", // state.publicKeys.length * dropAmount + 3000000000000000000000
      gas: "100000000000000",
    });
    ```

    Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application
  </Tab>

  <Tab title="🖥️ CLI">
    ```bash theme={null}
    near call v2.keypom.near create_drop '{"public_keys": <PUBLIC_KEYS>, "deposit_per_use": "10000000000000000000000", "ftData": {"contractId": "ft.primitives.near","senderId": "bob.near", "amount": "1"}}}' --depositYocto 23000000000000000000000 --gas 100000000000000 --useAccount bob.near
    ```
  </Tab>

  <Tab title="Lantstool" icon="https://mintcdn.com/neardocs-migrate-blog/ZW_VVLXFrN_7lu5M/assets/docs/tools/lantstool-logo-circle.svg?fit=max&auto=format&n=ZW_VVLXFrN_7lu5M&q=85&s=14d6291741111764d81598caa5c6aaa3" width="100" height="100" data-path="assets/docs/tools/lantstool-logo-circle.svg">
    <TryOutOnLantstool path="docs/2.build/5.primitives/linkdrop/create-ft-drop.json" />
  </Tab>
</Tabs>

#### 2. Transferring FT

Having the Drop ID, you now need to transfer the fungible tokens to the linkdrop contract.

<Note>
  To transfer FTs to an account, you need to first [register](/primitives/ft/ft#registering-a-user) the receiver account (e.g. the keypom contract) on the FT contract.
</Note>

<Tabs>
  <Tab title="🌐 WebApp">
    ```js theme={null}
    import { useNearWallet } from "near-connect-hooks";

    const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near";
    const FT_CONTRACT_ADDRESS = "ft.primitives.near";

    const { callFunction } = useNearWallet();

    await callFunction({
      contractId: FT_CONTRACT_ADDRESS,
      method: "ft_transfer",
      args: {
        receiver_id: KEYPOM_CONTRACT_ADDRESS,
        amount: "1"
      },
      deposit: "1",
      gas: "100000000000000"
    });
    ```

    Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application
  </Tab>

  <Tab title="🖥️ CLI">
    ```bash theme={null}
    near call ft.primitives.near ft_transfer '{"receiver_id": "v2.keypom.near", "amount": "1"}' --depositYocto 1 --gas 100000000000000 --useAccount bob.near
    ```
  </Tab>

  <Tab title="Lantstool" icon="https://mintcdn.com/neardocs-migrate-blog/ZW_VVLXFrN_7lu5M/assets/docs/tools/lantstool-logo-circle.svg?fit=max&auto=format&n=ZW_VVLXFrN_7lu5M&q=85&s=14d6291741111764d81598caa5c6aaa3" width="100" height="100" data-path="assets/docs/tools/lantstool-logo-circle.svg">
    <TryOutOnLantstool path="docs/2.build/5.primitives/linkdrop/transfer-ft-to-v2keypomnear.json" />
  </Tab>
</Tabs>

<Tip>
  The simplest way to create a linkdrop is by interacting with our LinkDrop Generator
</Tip>

***

## Function Call Drop

Linkdrop contracts allow to create `function call` drops. These drops will execute one or more methods on a contract when the user claims the drop.

<Tip>
  Function call drops can be thought as the abstract version of other drops: you can create a drop that will mint an NFT, register a user in a DAO, or pay for a service.
</Tip>

<Tabs>
  <Tab title="🌐 WebApp">
    ```js theme={null}
    import { useNearWallet } from "near-connect-hooks";

    const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near";
    const NFT_CONTRACT_ADDRESS = "nft.primitives.near";
    const NFT_TOKEN_ID = "1";
    const DROP_AMOUNT = "10000000000000000000000";

    const { callFunction } = useNearWallet();

    await callFunction({
      contractId: KEYPOM_CONTRACT_ADDRESS,
      method: "create_drop",
      args: {
        public_keys: state.publicKeys,
        deposit_per_use: DROP_AMOUNT,
        fcData: {
          // 2D array of function calls. In this case, there is 1 function call to make for a key use
          // By default, if only one array of methods is present, this array of function calls will be used for all key uses
          methods: [
            // Array of functions for Key use 1.
              [{
                receiverId: NFT_CONTRACT_ADDRESS,
                methodName: "nft_mint",
                args: JSON.stringify({
                // Change this token_id if it already exists -> check explorer transaction
                    token_id: NFT_TOKEN_ID,
                    metadata: {
                      title: "My NFT drop",
                      description: "",
                      media: "",
                    }
                }),
                accountIdField: "receiver_id",
                // Attached deposit for when the receiver makes this function call
                attachedDeposit: "10000000000000000000000"
              }]
          ]
        }
      },
      deposit: "23000000000000000000000", // state.publicKeys.length * dropAmount + 3000000000000000000000
      gas: "100000000000000",
    });
    ```

    Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application
  </Tab>

  <Tab title="🖥️ CLI">
    ```bash theme={null}
    near call v2.keypom.near create_drop '{"public_keys": <PUBLIC_KEYS>, "deposit_per_use": "10000000000000000000000", "fcData": {"methods": [[{"receiverId": "nft.primitives.near","methodName": "nft_mint","args": {"token_id": "1", "metadata": {"title": "My NFT drop","description": "","media": ""}, "accountIdField": "receiver_id", "attachedDeposit": "10000000000000000000000"}]]}}' --depositYocto 23000000000000000000000 --gas 100000000000000 --useAccount bob.near
    ```
  </Tab>

  <Tab title="Lantstool" icon="https://mintcdn.com/neardocs-migrate-blog/ZW_VVLXFrN_7lu5M/assets/docs/tools/lantstool-logo-circle.svg?fit=max&auto=format&n=ZW_VVLXFrN_7lu5M&q=85&s=14d6291741111764d81598caa5c6aaa3" width="100" height="100" data-path="assets/docs/tools/lantstool-logo-circle.svg">
    <TryOutOnLantstool path="docs/2.build/5.primitives/linkdrop/create-function-call-drop.json" />
  </Tab>
</Tabs>

***

## Building drop links

To create a linkdrop link, simply append the private key to the `claim` page:

```text theme={null}
http://localhost:3001/claim/linkdrop?id=ed25519:5Ly2arHZ4niWBVyEuzpN3J8QQX1BrYfWsirGqdYR3JfqUDhJ3SRK7JeQfVsh4UL8Wn6uf8RzWE4RPHymkePywVVd
```
