> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oumla.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Contract Deployment Workflow

> Complete guide to deploying smart contracts using templates

export const supportEmail = 'support@oumla.com';

This guide walks you through deploying smart contracts using Oumla's contract template system.

<Note>
  **Two Ways to Use Oumla**: This guide uses the TypeScript SDK. You can also accomplish the same tasks using direct REST API calls - see the [API Reference](/api-reference/introduction) for endpoint details.
</Note>

## Overview

The contract deployment workflow involves:

1. **Create or Select Template** - Use an existing template or create a new one
2. **Get Constructor Info** - Understand required constructor parameters
3. **Deploy Contract** - Deploy with your parameters
4. **Check Status** - Monitor the async deployment workflow
5. **Interact with Contract** - Call functions on the deployed contract

<Tip>
  Contract deployment uses **async workflows** for async processing. You'll need to check workflow status to know when deployment completes.
</Tip>

## Prerequisites

Before starting, ensure you have:

* An initialized SDK client
* A profile created
* An address generated (for contract deployment)
* Your client share (for signing operations)

## Step 1: Get Available Templates

List available contract templates:

```javascript theme={null}
import { OumlaSdkApiClient, OumlaSdkApiEnvironment } from '@oumla/sdk';

const client = new OumlaSdkApiClient({
  environment: OumlaSdkApiEnvironment.Sandbox,
  apiKey: 'your-api-key-here'
});

// Get all templates
const templates = await client.contractTemplates.getContracts({
  skip: 0,
  take: 25
});

console.log('Available templates:', templates.data);
```

## Step 2: Get Template Details

Retrieve details for a specific template:

```javascript theme={null}
const template = await client.contractTemplates.getContractById('template-id-here');

console.log('Template:', template.data);
console.log('Name:', template.data.name);
console.log('Network:', template.data.network);
```

## Step 3: Get Constructor Information

Before deploying, understand what constructor parameters are required:

```javascript theme={null}
const constructorInfo = await client.contractTemplates.getContractConstructorById('template-id-here');

// inputs describes the constructor's argument list
console.log('Constructor inputs:', constructorInfo.data.contractConstructor?.inputs);
console.log('Constructor type:', constructorInfo.data.contractConstructor?.type);
```

### Understanding Constructor Parameters

Constructor parameters are sent as an **array of objects**, where each object contains `name`, `type`, and `value`:

```javascript theme={null}
// Example constructor parameters structure
[
  {
    name: 'name',        // Parameter name
    type: 'string',      // Parameter type
    value: 'MyToken'     // Parameter value
  },
  {
    name: 'symbol',
    type: 'string',
    value: 'MTK'
  },
  {
    name: 'initialSupply',
    type: 'uint256',
    value: '1000000'
  }
]
```

<Tip>
  The `getContractConstructorById()` method returns the constructor parameter definitions. Use those to build your `constructorParameters` array with the correct `name`, `type`, and `value` for each parameter.
</Tip>

## Step 4: Get Function Information

Understand available functions on the contract:

```javascript theme={null}
// Get all functions
const functions = await client.contractTemplates.getContractFunctionById('template-id-here');

console.log('Available functions:', functions.data);

// Functions include both read and write operations
functions.data.forEach(func => {
  console.log(`Function: ${func.name}`);
  console.log(`Type: ${func.type}`); // 'read' or 'write'
  console.log(`Parameters:`, func.parameters);
});
```

## Step 5: Deploy Contract

Deploy the contract with your parameters:

```javascript theme={null}
const deployment = await client.contractTemplates.deployContract('template-id-here', {
  networkId: 'your-network-id',
  addressId: 'your-address-id',
  clientShare: 'your-client-share',
  constructorParameters: [
    { name: 'name', type: 'string', value: 'MyToken' },
    { name: 'symbol', type: 'string', value: 'MTK' },
    { name: 'initialSupply', type: 'uint256', value: '1000000' }
  ]
});

console.log('Deployment Workflow ID:', deployment.data.workflowResult.workflowId);
```

<Warning>
  Ensure constructor parameters match the types and order defined in the constructor info. Incorrect parameters will cause deployment to fail.
</Warning>

## Step 6: Check Deployment Status

Deployment is async. Check workflow status:

```javascript theme={null}
const status = await client.workflows.getWorkflowStatus(deployment.data.workflowResult.workflowId);

console.log('Status:', status.data.status); // COMPLETED, RUNNING, FAILED

if (status.data.status === 'COMPLETED') {
  console.log('Contract deployed at:', status.data.result.contractAddress);
  console.log('Transaction Hash:', status.data.result.transactionHash);
} else if (status.data.status === 'FAILED') {
  console.error('Deployment failed:', status.data.error);
}
```

### Workflow Status Values

* **RUNNING**: Deployment in progress
* **COMPLETED**: Deployment successful
* **FAILED**: Deployment failed (check error details)
* **CANCELLED**: Deployment was cancelled

## Step 7: Get Deployed Contract Details

Once deployment completes, retrieve contract details:

```javascript theme={null}
const deployedContract = await client.deployedContracts.getDeployedContractById(
  deployment.data.workflowResult.operationId
);

console.log('Contract Address:', deployedContract.data.deployedContract?.contractAddress);
console.log('Network:', deployedContract.data.deployedContract?.network);
console.log('Template ID:', deployedContract.data.deployedContract?.contractTemplateId);
```

## Step 8: Interact with Contract

After deployment, you can interact with the contract:

### Read Functions

```javascript theme={null}
const result = await client.contractInteractions.readCallFunction(
  'your-network-id',
  deployedContract.data.deployedContract?.contractAddress!,
  {
    abiFunction: {
      name: 'name',
      type: 'function',
      inputs: [],
      outputs: [{ name: '', type: 'string' }]
    }
  }
);

console.log('Function result:', result.data.result?.data?.result);
```

### Write Functions

```javascript theme={null}
const writeResult = await client.contractInteractions.writeCallFunction(
  'your-network-id',
  deployedContract.data.deployedContract?.contractAddress!,
  {
    addressId: 'your-address-id',
    clientShare: 'your-client-share',
    abiFunction: {
      name: 'transfer',
      type: 'function',
      inputs: [
        { name: 'to', type: 'address' },
        { name: 'amount', type: 'uint256' }
      ],
      outputs: []
    },
    amount: '0',
    feeLevel: 'standard'
  }
);

console.log('Workflow ID:', writeResult.data.workflowResult.workflowId);

// Poll the workflow until it completes to get the transaction hash from the result payload
const writeStatus = await client.workflows.getWorkflowStatus(writeResult.data.workflowResult.workflowId);
const transactionHash = writeStatus.data.result?.transactionHash;

// Then fetch the transaction receipt
const receipt = await client.contractInteractions.getTransactionReceipt('your-network-id', transactionHash);

console.log('Transaction Status:', receipt.data.receipt?.status);
```

## Complete Example

Here's a complete example:

```javascript theme={null}
import { OumlaSdkApiClient, OumlaSdkApiEnvironment } from '@oumla/sdk';

const client = new OumlaSdkApiClient({
  environment: OumlaSdkApiEnvironment.Sandbox,
  apiKey: process.env.OUMLA_API_KEY
});

async function deployContract() {
  try {
    // Step 1: Get templates
    const templates = await client.contractTemplates.getContracts({
      skip: 0,
      take: 10
    });

    const template = templates.data.result?.data?.[0]; // Use first template
    console.log('Using template:', template?.name);

    // Step 2: Get constructor info
    const constructorInfo = await client.contractTemplates.getContractConstructorById(template!.id!);

    console.log('Constructor inputs:', constructorInfo.data.contractConstructor?.inputs);

    // Step 3: Deploy contract
    const deployment = await client.contractTemplates.deployContract(template!.id!, {
      addressId: process.env.ADDRESS_ID,
      clientShare: process.env.CLIENT_SHARE,
      constructorParameters: [
        // Map parameters based on constructor info
        { name: 'name', type: 'string', value: 'MyToken' },
        { name: 'symbol', type: 'string', value: 'MTK' }
      ]
    });

    console.log('Deployment started. Workflow ID:', deployment.data.workflowResult.workflowId);

    // Step 4: Wait for deployment
    let status;
    do {
      await new Promise(resolve => setTimeout(resolve, 3000));
      status = await client.workflows.getWorkflowStatus(deployment.data.workflowResult.workflowId);
      console.log('Status:', status.data.status);
    } while (status.data.status === 'RUNNING');

    if (status.data.status === 'COMPLETED') {
      const contractAddress = status.data.result.contractAddress;
      console.log('Contract deployed at:', contractAddress);

      // Step 5: Interact with contract
      const name = await client.contractInteractions.readCallFunction(
        'your-network-id',
        contractAddress,
        {
          abiFunction: {
            name: 'name',
            type: 'function',
            inputs: [],
            outputs: [{ name: '', type: 'string' }]
          }
        }
      );

      console.log('Contract name:', name.data.result?.data?.result);
    }

  } catch (error) {
    console.error('Error:', error);
  }
}

deployContract();
```

## Managing Contract ABIs

### Fetch ABI from Contract Address

```javascript theme={null}
const abi = await client.deployedContracts.fetchContractAbi({
  networkId: 'your-network-id',
  contractAddress: '0x...'
});

console.log('Contract ABI:', abi.data.contractAbi?.abi);
```

### Add Custom ABI

```javascript theme={null}
await client.deployedContracts.addContractAbi({
  networkId: 'your-network-id',
  contractAddress: '0x...',
  name: 'MyContract',
  abi: [
    // Your ABI JSON array
  ]
});
```

## Common Issues

### Deployment Fails

**Causes:**

* Invalid constructor parameters
* Insufficient gas balance
* Network connectivity issues

**Solutions:**

* Verify constructor parameters match template requirements
* Ensure address has sufficient balance for gas
* Check network status and retry

### Constructor Parameter Errors

**Causes:**

* Wrong parameter types
* Missing required parameters
* Parameter order mismatch

**Solutions:**

* Review constructor info carefully
* Ensure types match (string, uint256, address, etc.)
* Provide all required parameters

### Function Call Fails

**Causes:**

* Function doesn't exist
* Wrong parameter types
* Insufficient gas

**Solutions:**

* Verify function exists in contract ABI
* Check parameter types match function signature
* Ensure sufficient gas balance

## Best Practices

1. **Always check constructor info** before deploying
2. **Validate parameters** before deployment
3. **Monitor workflow status** until completion
4. **Store deployment IDs** for future reference
5. **Handle errors gracefully** - deployments can fail
6. **Test on testnet** before mainnet deployment
7. **Verify contract address** after deployment

## Next Steps

* Learn about [Tokenization Workflow](/guides/workflows/tokenization)
* Explore [Withdrawal Workflow](/guides/workflows/withdrawal)
* Review [Error Reference](/guides/error-reference) for troubleshooting
