@opencollective/token-factory
v0.1.1
Published
Library to deploy and manage ERC20 tokens for communities on any EVM chain
Readme
Open Collective Token Factory
Library to deploy and manage an ERC20 token for your community.
Features
- Deploy on any EVM chain
- Generate a SAFE wallet for any community member based on their email address or discord userid
- Mint and burn on behalf of any account.
Install
npm install @opencollective/token-factoryUsage
import { Token, utils } from "@opencollective/token-factory";
const privateKey = utils.loadPrivateKey(); // generates a new private key if needed, saves it in .privatekey
// or: const privateKey = process.env.PRIVATE_KEY;
const token = new Token(
{
name: "My Community Token",
symbol: "CT",
chain: "base_sepolia", // gnosis, base, celo, ...
deployerPrivateKey: privateKey, // optional: defaults to process.env.PRIVATE_KEY || utils.loadPrivateKey();
// tokenAddress?: optional: if you already have an ERC20 token deployed
});
// console.log("OpenCollective/token: using deployer address", publicKeyDerivedFromPrivateKey, "balance:", await utils.getNativeBalance(publicKeyDerivedFromPrivateKey));
const tokenAddress = await token.deployToken(); // Use CREATE2 to make sure it always returns the same address given the same deployerAddress, tokenName and tokenSymbol (deploy first a tokenFactory contract for testing). This makes sure we never deploy twice the same token.
const userAddress = await token.getUserAddress("discord", "1435736971011162152"); // returns a 0xAddress where the SAFE will be eventually be deployed (when needed). The address is a function of the publicKey of the deployer, the provider (email or discord), and the providerUserId (email address, or discordUserId)
token.mintTo(1000000, "0x123..."); // mint 1 CT token to 0x123..., gas paid by deployer address
token.burnFrom(1000000, "0x123..."); // mint 1 CT token from account 0x123...
token.mintTo(1000000, `discord:1435736971011162152`); // mint 1 CT token to discord user
token.burnFrom(1000000, `discord:1435736971011162152`); // mint 1 CT token from discord user
token.transfer(`discord:1435736971011162152`, `email:[email protected]`, 1000000); // send a token on behalf of the discord user (it's your responsibility to ensure the right discord user is logged in or sending the command). Gas paid by the deployer address since it it the default owner of all SAFE deployed for users. If the SAFE of the sender isn't deployed yet, this method deploys it first.
Design
This is a centralized model. The core principle is: "In Community We Trust". Since the community could anyway start minting a gazilion of new tokens (diluting the value of your holding), and since the wallets are only used to store that token, there is no reason to bother with proper independent ownership fo those wallets.
That's why all wallets are SAFE 1/n multisig owned by the community (represented by the deployer key). Therefore only the deployer key needs to be topped up with the native token to pay for gas fees.
Governance
In this first version, we use the benevolent dictator model (aka the source). The person that controls the deployer key controls the community. Not happy with it? Fork it.
What's important here is that every single transaction (mint, burn, transfer) is recorded on the blockchain and therefore cannot happen without the community noticing. At any point, anyone can "fork" the community and issue a new token and airdrop it to all existing holders.
API
- token.getBalance(userIdentifier) // check balances (e.g. token.getBalance("discord:1435736971011162152"))
- token.isDeployed(userIdentifier) // check if Safe exists
- token.getSafeOwners(userIdentifier) // who controls this Safe?
- Factory.deployToken(name, symbol) // deploys a new ERC20 burnable token.
- token.addMinter(userIdentifier)
- token.removeMinter(userIdentifier)Development & Testing
This project uses Deno for development and testing.
Prerequisites
Install Deno (if not already installed):
curl -fsSL https://deno.land/install.sh | shInstall Hardhat dependencies (required for tests):
deno task hh:install # or: cd hardhat && npm installSet up test environment:
cp .env.example .env.test # Edit .env.test and set PRIVATE_KEY
Running Tests
Check if your environment is ready for testing:
deno task test:checkRun all tests:
deno task testRun specific test suites:
deno task test:blockchain # Core blockchain operations
deno task test:mint # Token minting and burning
deno task test:safe # SAFE wallet operations
deno task test:token # Token class integration tests
deno task test:factory # Token factory (CREATE2) testsLocal Blockchain Testing
For tests that require a local blockchain:
Start Hardhat node (in a separate terminal):
deno task hh:nodeRun tests:
deno task test
Test Requirements
The test runner automatically checks for:
.env.testfile exists withPRIVATE_KEYconfigured- Hardhat dependencies installed (SAFE contracts)
- Local blockchain running (for localhost tests)
If requirements are not met, you'll see helpful error messages explaining how to fix them.
