How to blacklist tokens from a token sponsor
Have full control of which tokens can be used for a token sponsor.
Overview
Once you have created a token sponsor, you’ll want to add tokens that can or cannot be accepted for transaction fees.
Fun sponsors have the ability to blacklist tokens so you can enable all tokens for gas payments except for those selected.
In this guide, I’ll show you how to use this feature and some of the nuances in blacklisting tokens.
I’ll also reference information covered in How to create a token sponsor but I’ll quickly walk all the steps of creating one.
Import required objects
import {FunWallet,configureEnvironment,Auth,TokenSponsor,generatePrivateKey,} from "@funkit/core";
Configuring the environment
To begin, we need to set up the environment. Please visit our dashboard to receive your own production apiKey.
await configureEnvironment({chain: "goerli",apiKey: "ZrhepzWGxm74D0sqstuhT6dGrJxhoy8SZIToX6I3",});
Create FunWallet for testing token sponsor
We’ll also initialize a FunWallet here that will use the token sponsor once we create it.
const privateKeyWallet = generatePrivateKey();const funWalletAuth = new Auth({ privateKey: privateKeyWallet });const funWallet = new FunWallet({users: [{ userId: await funWalletAuth.getAddress() }],uniqueId: await funWalletAuth.getWalletUniqueId(),});
Creating a token sponsor
In order to create a token sponsor, we’ll first have to create its address. I’ll derive one from my private key.
const privateKey ="0x1bfda777ddaf097a791e98ea9bb8923f33f9a9e93c4ec3b0d8370de10782a825";const sponsor = new Auth({ privateKey });const sponsorAddress = await sponsor.getAddress();
We’ll initialize the token sponsor with this private key later but for now we can actually use the sponsorAddress to re-configure environment so that it has a token sponsor. It is important to note that token sponsor is not ready for use yet, we still have to configure all the following steps before transaction can be paid for in DAI.
await configureEnvironment({chain: "goerli",apiKey: "ZrhepzWGxm74D0sqstuhT6dGrJxhoy8SZIToX6I3",gasSponsor: {sponsorAddress,token: "0x0a1F0598A561af6b84A726bE007f581E812C3CDD",usePermit: true,},});
Staking ETH into token sponsor
After re-configuring the environment, we will create the token sponsor interface and use it to deposit (stake) ETH into the sponsor. The token sponsor will use this ETH to pay for transactions on behalf of other wallets.
// Creata token sponsor interfaceconst tokenSponsor = new TokenSponsor();// Stake native gas tokens to the gas sponsorconst depositAmount = 0.005;const depositorAddress = sponsorAddress;const depositEth = await tokenSponsor.stake(depositorAddress,sponsorAddress,depositAmount);
Make sure your private key holds ETH to stake into the sponsor.
Configuring token blacklist
With a Fun sponsor, you have the ability to tune who uses it and which tokens are not allowed and in this section I’ll show you the different methods to do that. However I’ll also recommend you check out How to whitelist users from a gas sponsor for more details.
Set to blacklist mode
First, we will set the gas sponsor to blacklist mode. Blacklist mode means you choose specific tokens that are not allowed to use the gas sponsor.
const blacklistMode = await tokenSponsor.setToBlacklistMode(5, sponsorAddress);
If no configurations on the sponsor have been set before, the sponsor will default to whitelist mode.
If the sponsor is switched to whitelist mode and switched back to blacklist mode, the blacklist will keep the last state.
Since we’re using the custom DAI token for gas and our token sponsor is set to blacklist mode, we can immediately start using DAI for gas. However, for this guide I’ll blacklist USDC on the token as an example.
Add a token to blacklist
Now we will add USDC so that it can’t be used for gas payments on the sponsor. Let me describe the parameters used in blacklisting.
sponsor - This is the address of the token sponsor we’re changing the blacklist for.
tokens[]- This array holds all the tokens you don’t want to accept for gas.
modes[] - This array corresponds to the tokens[] so that true in index 1 will disable the token in index 1 to be accepted for gas. false will enable the token for gas.
batchBlacklistTokens(sponsor: Address,tokens: string[],modes: boolean[],)
Since we’re disabling USDC for gas payments this is what we would fill it for parameters.
const blacklistToken = await tokenSponsor.batchBlacklistTokens(sponsorAddress,["USDC"],[true]);
Alternatively, since we’re just disabling one token we also use this method.
const removeToken = await tokenSponsor.batchBlacklistTokens(sponsorAddress,["USDC"],[false]);
Remove our token from whitelist
If at any point you want to remove USDC from the blacklist so that can be used again for gas, this is how you can do so.
const removeToken = await tokenSponsor.batchWhitelistTokens(sponsorAddress,["0x0a1F0598A561af6b84A726bE007f581E812C3CDD"],[false]);
Adding a FunWallet to the whitelist
Finally, we will whitelist our FunWallet, so that our FunWallet can use the sponsor.
const whitelistUser = await tokenSponsor.addSpenderToWhiteList(5,sponsorAddress,await funWallet.getAddress());//Send transactions for executionawait sponsor.sendTxs([depositEth,whitelistToken,whitelistMode,whitelistUser,]);
Using the token sponsor
Finally, we will whitelist our FunWallet, so that our FunWallet can use the sponsor.
const whitelistUser = await tokenSponsor.addSpenderToWhiteList(5,sponsorAddress,await funWallet.getAddress());//Send transactions for executionawait sponsor.sendTxs([depositEth,whitelistToken,whitelistMode,whitelistUser,]);
Now that we have created a DAI token sponsor, we’ll use it for a transaction. Note that I’m executing a transaction like normal - this is because we have already set up our environment to use the token sponsor.
const transferTokensToWallet = await new Token("0x0a1F0598A561af6b84A726bE007f581E812C3CDD").transfer(await funWallet.getAddress(), 100);await sponsor.sendTxs([transferTokensToWallet]);const op = await funWallet.create(funWalletAuth, await sponsor.getAddress());await funWallet.executeOperation(funWalletAuth, op);
Summary
Putting together all the pieces we have blacklistToken() that you can use to create a token sponsor, blacklist a token and execute a transaction using a different token for gas.
base-gas-token.js
import {FunWallet,configureEnvironment,Auth,TokenSponsor,Token,generatePrivateKey,} from "@funkit/core";const blacklistToken = async () => {await configureEnvironment({chain: "goerli",apiKey: "ZrhepzWGxm74D0sqstuhT6dGrJxhoy8SZIToX6I3",})const privateKeyWallet = generatePrivateKey()const funWalletAuth = new Auth({ privateKey: privateKeyWallet })const funWallet = new FunWallet({users: [{ userId: await funWalletAuth.getAddress() }],uniqueId: await funWalletAuth.getWalletUniqueId()})const privateKey = generatePrivateKey()const sponsor = new Auth({ privateKey })const sponsorAddress = await sponsor.getAddress()await configureEnvironment({chain: "goerli",apiKey: "ZrhepzWGxm74D0sqstuhT6dGrJxhoy8SZIToX6I3",gasSponsor: {sponsorAddress,token: "0x0a1F0598A561af6b84A726bE007f581E812C3CDD",usePermit: true}})const tokenSponsor = new TokenSponsor()const depositAmount = 0.005const depositorAddress = sponsorAddressconst depositEth = await tokenSponsor.stake(depositorAddress, sponsorAddress, depositAmount)const blacklistMode = await tokenSponsor.setToBlacklistMode(5, sponsorAddress)const blacklistToken = await tokenSponsor.batchBlacklistTokens(sponsorAddress, ["USDC"], [true])const removeToken = await tokenSponsor.batchBlacklistTokens(sponsorAddress, ["USDC"], [false])const whitelistUser = await tokenSponsor.addSpenderToWhiteList(5, sponsorAddress, await funWallet.getAddress())await sponsor.sendTxs([depositEth, blacklistMode, blacklistToken, removeToken, whitelistUser])const transferTokensToWallet = await new Token("0x0a1F0598A561af6b84A726bE007f581E812C3CDD").transfer(await funWallet.getAddress(), 100)await sponsor.sendTxs([transferTokensToWallet])const op = await funWallet.create(funWalletAuth, await sponsor.getAddress())console.log(await funWallet.executeOperation(funWalletAuth, op))}blacklistToken()