First Deployment
This guide walks you through deploying a complete RWA token system with all components configured and ready for production use.
What Gets Deployedā
When you deploy an RWA system, the SDK deploys and configures the following contracts:
| Contract | Purpose |
|---|---|
| RWAToken | ERC-3643 compliant security token |
| KYCRegistry | Investor verification and accreditation |
| YieldDistributor | Dividend and yield payments |
| AssetVault | Asset custody and management |
| ComplianceModule | Transfer restrictions and rules |
Prerequisitesā
Before deploying, ensure you have:
- Completed the Quick Start guide
- Testnet MNT tokens for gas fees
- Decided on your token parameters
Step 1: Plan Your Tokenā
Before deploying, define your token parameters:
// Token identity
const tokenConfig = {
name: 'Manhattan Real Estate Fund',
symbol: 'MREF',
initialSupply: '10000000', // 10 million tokens
};
// Compliance rules
const complianceConfig = {
maxHolders: 2000, // Maximum number of token holders
minInvestment: '1000', // Minimum tokens per investor
maxInvestment: '500000', // Maximum tokens per investor
accreditedOnly: true, // Require accredited investor status
lockupPeriod: 365 * 24 * 60 * 60, // 1 year lockup in seconds
};
// Yield configuration
const yieldConfig = {
paymentToken: 'USDC', // Payment token for yields
distributionFrequency: 'quarterly',
};
Step 2: Deploy the Systemā
Create your deployment script:
src/deploy-production.ts
import 'dotenv/config';
import { RWAClient } from '@mantle-rwa/sdk';
const client = new RWAClient({
network: 'mantle-sepolia', // Change to 'mantle' for mainnet
privateKey: process.env.PRIVATE_KEY!,
});
async function deploy() {
console.log('š Starting RWA System Deployment\n');
console.log('Deployer:', client.address);
console.log('Network:', client.network);
console.log('');
const deployment = await client.deployRWASystem({
// Token configuration
tokenName: 'Manhattan Real Estate Fund',
tokenSymbol: 'MREF',
initialSupply: '10000000',
// Compliance configuration
compliance: {
maxHolders: 2000,
minInvestment: '1000',
maxInvestment: '500000',
accreditedOnly: true,
lockupPeriod: 365 * 24 * 60 * 60,
},
// Yield configuration
yield: {
paymentToken: '0x...', // USDC address on Mantle
},
// Access control
roles: {
admin: client.address,
compliance: client.address,
treasury: client.address,
},
});
console.log('ā
Deployment Complete!\n');
return deployment;
}
deploy()
.then((deployment) => {
console.log('š Deployed Contracts:');
console.log('');
console.log('RWAToken:', deployment.token.address);
console.log('KYCRegistry:', deployment.kycRegistry.address);
console.log('YieldDistributor:', deployment.yieldDistributor.address);
console.log('AssetVault:', deployment.assetVault.address);
console.log('');
console.log('š Explorer Links:');
console.log(`Token: https://sepolia.mantlescan.xyz/address/${deployment.token.address}`);
})
.catch(console.error);
Step 3: Verify Deploymentā
After deployment, verify everything is configured correctly:
src/verify-deployment.ts
import 'dotenv/config';
import { RWAClient } from '@mantle-rwa/sdk';
const client = new RWAClient({
network: 'mantle-sepolia',
privateKey: process.env.PRIVATE_KEY!,
});
async function verify(tokenAddress: string) {
const token = client.token(tokenAddress);
console.log('š Verifying Deployment\n');
// Token info
const name = await token.name();
const symbol = await token.symbol();
const totalSupply = await token.totalSupply();
const decimals = await token.decimals();
console.log('Token Info:');
console.log(` Name: ${name}`);
console.log(` Symbol: ${symbol}`);
console.log(` Total Supply: ${totalSupply}`);
console.log(` Decimals: ${decimals}`);
console.log('');
// Compliance info
const compliance = await token.getComplianceConfig();
console.log('Compliance Config:');
console.log(` Max Holders: ${compliance.maxHolders}`);
console.log(` Min Investment: ${compliance.minInvestment}`);
console.log(` Max Investment: ${compliance.maxInvestment}`);
console.log(` Accredited Only: ${compliance.accreditedOnly}`);
console.log('');
// Role verification
const isAdmin = await token.hasRole('ADMIN', client.address);
console.log('Roles:');
console.log(` Admin: ${isAdmin ? 'ā
' : 'ā'}`);
console.log('\nā
Verification Complete!');
}
// Replace with your deployed token address
verify('0x...');
Step 4: Configure KYCā
Set up your KYC provider to start verifying investors:
src/setup-kyc.ts
import 'dotenv/config';
import { RWAClient } from '@mantle-rwa/sdk';
const client = new RWAClient({
network: 'mantle-sepolia',
privateKey: process.env.PRIVATE_KEY!,
});
async function setupKYC(kycRegistryAddress: string) {
const kyc = client.kyc(kycRegistryAddress);
// Configure KYC provider (example with Persona)
await kyc.configureProvider({
provider: 'persona',
apiKey: process.env.PERSONA_API_KEY!,
templateId: 'your-template-id',
});
console.log('ā
KYC Provider configured');
// Manually verify an investor (for testing)
await kyc.verifyInvestor({
address: '0x...',
accreditationLevel: 'accredited',
country: 'US',
expirationDate: Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60,
});
console.log('ā
Test investor verified');
}
setupKYC('0x...');
Step 5: Mint Initial Tokensā
Mint tokens to verified investors:
src/mint-tokens.ts
import 'dotenv/config';
import { RWAClient } from '@mantle-rwa/sdk';
const client = new RWAClient({
network: 'mantle-sepolia',
privateKey: process.env.PRIVATE_KEY!,
});
async function mintTokens(tokenAddress: string) {
const token = client.token(tokenAddress);
// Mint to a single investor
await token.mint({
to: '0x...', // Verified investor address
amount: '10000',
});
console.log('ā
Tokens minted');
// Batch mint to multiple investors
await token.batchMint([
{ to: '0x...', amount: '5000' },
{ to: '0x...', amount: '7500' },
{ to: '0x...', amount: '2500' },
]);
console.log('ā
Batch mint complete');
}
mintTokens('0x...');
Deployment Checklistā
Before going to mainnet, ensure you've completed:
- Deployed all contracts successfully
- Verified contract addresses on explorer
- Configured KYC provider
- Set up compliance rules
- Assigned appropriate roles
- Tested token transfers with verified addresses
- Configured yield distribution (if applicable)
- Reviewed security best practices
Next Stepsā
Your RWA system is now deployed! Here's what to do next:
- Set up KYC Integration - Configure investor verification
- Configure Yield Distribution - Set up dividend payments
- Review Security - Ensure your deployment is secure
- Build Your Frontend - Create a user interface
Troubleshootingā
Deployment Failedā
If deployment fails:
- Check you have sufficient gas (at least 0.5 MNT recommended)
- Verify your private key is correct
- Check network connectivity
Contract Verification Failedā
To verify contracts on the explorer:
npx hardhat verify --network mantle-sepolia CONTRACT_ADDRESS