Skip to main content

Permissionless Token Factory

The GhostERC20Factory allows anyone to create Ghost-enabled ERC-20 tokens on Umbraline Testnet.

Factory Address

ContractAddress
GhostERC20Factory0xb984253C697EbAd0A2221881bcD6bd65f5961ee5

Creating a Token

const FACTORY_ADDRESS = '0xb984253C697EbAd0A2221881bcD6bd65f5961ee5';

const factory = new ethers.Contract(FACTORY_ADDRESS, FACTORY_ABI, signer);

const tx = await factory.createGhostERC20(
"My Token", // name
"MTK", // symbol
18, // decimals
ethers.parseEther("1000000") // initial supply
);

const receipt = await tx.wait();
// Token address from event logs

Factory ABI

const FACTORY_ABI = [
{
name: 'createGhostERC20',
type: 'function',
inputs: [
{ name: 'name', type: 'string' },
{ name: 'symbol', type: 'string' },
{ name: 'decimals', type: 'uint8' },
{ name: 'initialSupply', type: 'uint256' },
],
outputs: [{ name: 'token', type: 'address' }],
stateMutability: 'nonpayable',
},
{
name: 'GhostTokenCreated',
type: 'event',
inputs: [
{ name: 'token', type: 'address', indexed: true },
{ name: 'creator', type: 'address', indexed: true },
{ name: 'name', type: 'string', indexed: false },
{ name: 'symbol', type: 'string', indexed: false },
],
},
];

Token Features

Tokens created by the factory are automatically:

  • Registered with GhostVault for vanish/summon support
  • ERC-20 compliant
  • Owned by the deployer

Use Cases

  • Project tokens: Launch tokens with built-in privacy
  • Wrapped assets: Create Ghost-enabled versions of external tokens
  • Testing: Deploy test tokens for development

Getting Token Address

After creating a token, get the address from the event:

const receipt = await tx.wait();
const event = receipt.logs.find(log => {
try {
const parsed = factory.interface.parseLog(log);
return parsed.name === 'GhostTokenCreated';
} catch {
return false;
}
});

const tokenAddress = event.args.token;
console.log('Token deployed at:', tokenAddress);

Using the Token

Once created, the token works like any ERC-20:

const token = new ethers.Contract(tokenAddress, ERC20_ABI, signer);

// Check balance
const balance = await token.balanceOf(userAddress);

// Transfer
await token.transfer(recipient, amount);

// Vanish to GhostVault
await token.approve(VAULT_ADDRESS, amount);
await vault.vanish(tokenAddress, amount, commitment);