Skip to main content

Deploy Contract

Use deployContract() to deploy a new smart contract to any supported chain. The Engine supports both template-based deployment (ERC-20, ERC-721, ERC-1155, marketplace, staking, governance) and custom bytecode deployment.

Method Signature

client.deployContract(params: ContractDeployParams): Promise<ApiResponse<ContractDeployResult>>

ContractDeployParams

import type { ContractDeployParams, ContractType } from '@one_deploy/sdk';

interface ContractDeployParams {
type: ContractType; // Template type or 'custom'
chainId: number; // Target chain
name: string; // Human-readable contract name
constructorArgs?: Record<string, unknown>; // Named constructor arguments
bytecode?: string; // Required when type is 'custom'
abi?: Record<string, unknown>[]; // Required when type is 'custom'
metadata?: Record<string, unknown>; // Optional metadata stored by the Engine
}

ContractType

The ContractType enum determines which template the Engine uses:

type ContractType =
| 'erc20' // Fungible token (ERC-20)
| 'erc721' // Non-fungible token (ERC-721)
| 'erc1155' // Multi-token (ERC-1155)
| 'custom' // Custom bytecode -- bring your own
| 'marketplace' // NFT marketplace contract
| 'staking' // Token staking / reward distribution
| 'governance'; // On-chain governance (voting + proposals)

ContractDeployResult

interface ContractDeployResult {
transactionHash: string;
contractAddress: string; // Predicted address (may be pending confirmation)
chainId: number;
status: 'pending' | 'submitted';
}
note

The contractAddress is computed deterministically and returned immediately. The contract is not usable until the deployment transaction is confirmed. Poll getTransactionStatus() to confirm.

Examples

Deploy an ERC-20 Token

import { useOneEngine } from '@one_deploy/sdk';

function DeployToken() {
const { client } = useOneEngine();

async function handleDeploy() {
const res = await client.deployContract({
type: 'erc20',
chainId: 137, // Polygon
name: 'Acme Token',
constructorArgs: {
name: 'Acme Token', // Token name (on-chain)
symbol: 'ACME', // Token symbol
initialSupply: '1000000', // 1 000 000 tokens (in whole units)
decimals: 18,
owner: '0xYourWallet...', // Initial owner / minter
},
});

if (!res.success) {
console.error('Deploy failed:', res.error?.message);
return;
}

console.log('Deploy tx:', res.data.transactionHash);
console.log('Predicted address:', res.data.contractAddress);

// Wait for confirmation
let confirmed = false;
while (!confirmed) {
const tx = await client.getTransactionStatus(
res.data.transactionHash,
137,
);
if (tx.data.status === 'confirmed') {
confirmed = true;
console.log('Contract live at:', res.data.contractAddress);
} else if (tx.data.status === 'failed') {
throw new Error(`Deploy failed: ${tx.data.reason}`);
}
await new Promise((r) => setTimeout(r, 3000));
}
}

return <button onClick={handleDeploy}>Deploy ACME Token</button>;
}

Deploy an ERC-721 NFT Collection

const res = await client.deployContract({
type: 'erc721',
chainId: 1, // Ethereum mainnet
name: 'CryptoCreatures',
constructorArgs: {
name: 'CryptoCreatures', // Collection name
symbol: 'CRTR', // Collection symbol
baseURI: 'ipfs://QmXyz.../metadata/', // Base URI for token metadata
maxSupply: 10000, // Maximum mintable tokens
owner: '0xYourWallet...', // Contract owner
royaltyRecipient: '0xYourWallet...', // EIP-2981 royalty recipient
royaltyBps: 500, // 5% royalty (basis points)
},
metadata: {
description: 'A 10k generative NFT collection.',
website: 'https://cryptocreatures.xyz',
},
});

if (res.success) {
console.log('NFT collection deploying:', res.data.contractAddress);
}

Deploy an ERC-1155 Multi-Token

const res = await client.deployContract({
type: 'erc1155',
chainId: 42161, // Arbitrum
name: 'GameItems',
constructorArgs: {
name: 'GameItems',
uri: 'https://api.mygame.com/items/{id}.json', // ERC-1155 URI template
owner: '0xYourWallet...',
},
});

Deploy a Custom Contract

Provide your own compiled bytecode and ABI:

import MyContractABI from './abis/MyContract.json';
import { BYTECODE } from './bytecodes/MyContract';

const res = await client.deployContract({
type: 'custom',
chainId: 137,
name: 'MyCustomVault',
bytecode: BYTECODE, // '0x6080604052...'
abi: MyContractABI,
constructorArgs: {
_token: '0xA0b8...3E7a', // address
_lockDuration: 2592000, // uint256 (30 days in seconds)
_feeRecipient: '0xFeeWallet...', // address
},
});

if (res.success) {
console.log('Custom contract deploying:', res.data.contractAddress);
}

Constructor Arguments Reference

Each template type accepts different constructor arguments. The table below lists the required and optional fields.

ERC-20

ArgumentTypeRequiredDescription
namestringYesToken name
symbolstringYesToken symbol
initialSupplystringYesInitial supply in whole units
decimalsnumberNoToken decimals (default 18)
ownerstringYesInitial owner address

ERC-721

ArgumentTypeRequiredDescription
namestringYesCollection name
symbolstringYesCollection symbol
baseURIstringNoBase metadata URI
maxSupplynumberNoMax mintable supply (0 = unlimited)
ownerstringYesContract owner
royaltyRecipientstringNoEIP-2981 royalty address
royaltyBpsnumberNoRoyalty in basis points (0-10000)

ERC-1155

ArgumentTypeRequiredDescription
namestringYesCollection name
uristringYesURI template with {id} placeholder
ownerstringYesContract owner

Node.js / Edge Runtime

import { OneEngineClient } from '@one_deploy/sdk';

const client = new OneEngineClient({
apiKey: process.env.ONE_API_KEY!,
projectId: process.env.ONE_PROJECT_ID!,
});

const res = await client.deployContract({
type: 'erc20',
chainId: 137,
name: 'ServerToken',
constructorArgs: {
name: 'ServerToken',
symbol: 'SRVR',
initialSupply: '500000',
owner: '0xDeployerWallet...',
},
});

console.log('Deployed:', res.data.contractAddress);

Error Handling

const res = await client.deployContract({ /* ... */ });

if (!res.success) {
switch (res.error?.code) {
case 'INSUFFICIENT_FUNDS':
console.error('Deployer wallet does not have enough native token for gas.');
break;
case 'INVALID_CONSTRUCTOR_ARGS':
console.error('Constructor arguments do not match the expected types.');
break;
case 'UNSUPPORTED_CHAIN':
console.error('The specified chainId is not supported for deployment.');
break;
case 'BYTECODE_REQUIRED':
console.error('Custom contract type requires the bytecode field.');
break;
default:
console.error('Deploy error:', res.error?.message);
}
}

Next Steps