> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.prividium.com/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

Now your token contract is deployed and the permissions are configured. The next step is to try interacting with it
using a script. Our script will transfer some of the tokens to another wallet address.

Because our token contract automatically mints some tokens to the contract deployer in the constructor function, the
sender address should have some tokens to transfer already.

This guide assumes you still have the Prividium proxy running and are using the same `hardhat.config.ts` file set up in
the [contract deployment guide](/developers/quickstart/deploying-contracts).

With the proxy running, the only Prividium-specific configuration you need to use Hardhat scripts is to define the chain
and configure the clients to use that chain. The proxy will handle the authentication and transaction authorization for
you.

## Creating the script

Create a new file in the `scripts` folder called `send-tokens.ts`.

```bash
touch scripts/send-tokens.ts
```

Copy and paste the script file below.

**send-tokens.ts**

```typescript
import { artifacts, network } from 'hardhat';
import {
    type Abi,
    type Account,
    type Address,
    defineChain,
    formatUnits,
    isAddress,
    type PublicClient,
    parseUnits
} from 'viem';

// Replace with your deployed token address
const TOKEN_CONTRACT_ADDRESS = (process.env.TOKEN_CONTRACT_ADDRESS as Address) ?? '0x...';

// Update this to change the recipient of the tokens
const recipientAddress = (process.env.RECIPIENT_ADDRESS as Address) ?? '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC';

// Update this to change the amount of tokens to send or the token decimals
// This sends 20 tokens and each token has 18 decimals
const amount = parseUnits('20', 18);

type FeeData = {
    gasPrice?: bigint;
    maxFeePerGas?: bigint;
    maxPriorityFeePerGas?: bigint;
};

type FeeOverrides = { gasPrice: bigint } | { maxFeePerGas: bigint; maxPriorityFeePerGas: bigint };

async function main() {
    if (!isAddress(TOKEN_CONTRACT_ADDRESS) || !isAddress(recipientAddress) || amount === 0n) {
        throw new Error('Invalid TOKEN_CONTRACT_ADDRESS, recipientAddress, or amount.');
    }

    const { viem } = await network.create('localPrividium');

    const localPrividium = defineChain({
        id: 506,
        name: 'Local Prividium',
        network: 'localPrividium',
        nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
        rpcUrls: { default: { http: ['http://127.0.0.1:24101/rpc'] } }
    });

    const publicClient = await viem.getPublicClient({ chain: localPrividium });
    const [senderClient] = await viem.getWalletClients({ chain: localPrividium });
    if (!senderClient) throw new Error('No wallet client.');

    const abi = (await artifacts.readArtifact('QuickstartToken')).abi;

    const balanceBefore = await getRecipientBalance(publicClient, abi);
    console.log('balance before: ', formatUnits(balanceBefore as bigint, 18));

    const txOptions = await estimateWriteTransactionOptions(publicClient, {
        address: TOKEN_CONTRACT_ADDRESS,
        abi,
        functionName: 'transfer',
        args: [recipientAddress, amount],
        account: senderClient.account
    });

    const tx = await senderClient.writeContract({
        address: TOKEN_CONTRACT_ADDRESS,
        abi,
        functionName: 'transfer',
        args: [recipientAddress, amount],
        account: senderClient.account,
        ...txOptions
    });

    await publicClient.waitForTransactionReceipt({ hash: tx });
    console.log(`Transferred ${amount.toString()} token units to ${recipientAddress}.`);

    const balanceAfter = await getRecipientBalance(publicClient, abi);
    console.log('balance after: ', formatUnits(balanceAfter as bigint, 18));
}

async function estimateWriteTransactionOptions(
    publicClient: PublicClient,
    params: {
        address: Address;
        abi: Abi;
        functionName: string;
        args?: readonly unknown[];
        account: Account;
        value?: bigint;
    }
) {
    const gas = await publicClient.estimateContractGas({
        address: params.address,
        abi: params.abi,
        functionName: params.functionName,
        args: params.args,
        account: params.account,
        ...(params.value !== undefined ? { value: params.value } : {})
    });
    const feeOverrides = await resolveFeeOverrides(publicClient);
    return { gas, ...feeOverrides };
}

async function resolveFeeOverrides(publicClient: {
    estimateFeesPerGas: () => Promise<FeeData>;
}): Promise<FeeOverrides> {
    const DEFAULT_MAX_FEE_PER_GAS = 1_000_000_000n;
    const DEFAULT_MAX_PRIORITY_FEE_PER_GAS = 100_000_000n;

    const feeData = await publicClient.estimateFeesPerGas().catch(() => undefined);
    const gasPrice = feeData?.gasPrice !== undefined && feeData.gasPrice > 0n ? feeData.gasPrice : undefined;
    const maxFeePerGas =
        feeData?.maxFeePerGas !== undefined && feeData.maxFeePerGas > 0n
            ? feeData.maxFeePerGas
            : DEFAULT_MAX_FEE_PER_GAS;
    const maxPriorityFeePerGas =
        feeData?.maxPriorityFeePerGas !== undefined && feeData.maxPriorityFeePerGas > 0n
            ? feeData.maxPriorityFeePerGas
            : DEFAULT_MAX_PRIORITY_FEE_PER_GAS;

    return gasPrice !== undefined ? { gasPrice } : { maxFeePerGas, maxPriorityFeePerGas };
}

async function getRecipientBalance(publicClient: PublicClient, abi: Abi) {
    const balance = await publicClient.readContract({
        address: TOKEN_CONTRACT_ADDRESS,
        abi,
        functionName: 'balanceOf',
        args: [recipientAddress]
    });
    return balance;
}

main().catch((error) => {
    console.error(error);
    process.exitCode = 1;
});
```

This script will:

1. Check the token balance of the recipient before the transfer.
2. Transfer the defined amount of tokens from the default sender defined in `hardhat.config.ts` to the recipient
   address.
3. Check the final token balance of the recipient after the transfer.

## Configuring the token transfer

Replace the `TOKEN_CONTRACT_ADDRESS` at the top of the file with your deployed token contract address.

You can also change the `recipientAddress` and `amount` if you need.

## Running the script

:::note[Paying for gas]
Ensure the sender account has some ETH to pay for gas fees if gas is required.
:::

To run the token transfer script, use one of the commands below. Choose either `localPrividium` or `testnetPrividium`.

```bash
npx hardhat run scripts/send-tokens.ts --network localPrividium
```

```bash
npx hardhat run scripts/send-tokens.ts --network testnetPrividium
```

After running the script, you should see that the balance of the tokens has increased for the recipient address.
