Files

TypeScript Smart Contract Template

A TypeScript/JavaScript-based smart contract client for Dragonchain Prime that connects via gRPC.

Prerequisites

  • Node.js 18 or later
  • npm

Quick Start

  1. Copy this template to create your smart contract:

    cp -r typescript /path/to/my-smart-contract
    cd /path/to/my-smart-contract
    
  2. Install dependencies:

    npm install
    
  3. Configure your connection by editing config.yaml:

    server_address: "your-dragonchain-server:50051"
    smart_contract_id: "your-smart-contract-id"
    api_key: "your-api-key"
    
  4. Implement your smart contract logic in src/process.ts by modifying the processTransaction function.

  5. Build and run:

    npm run build
    npm start -- --config config.yaml
    

    Or run in development mode:

    npm run dev -- --config config.yaml
    

Configuration

Field Description Default
server_address gRPC server address Required
smart_contract_id Your smart contract ID Required
api_key API key for authentication Required
use_tls Enable TLS encryption false
tls_cert_path Path to TLS certificate -
num_workers Concurrent transaction processors 10
reconnect_delay_seconds Delay between reconnection attempts 5
max_reconnect_attempts Max reconnect attempts (0 = infinite) 0

Implementing Your Smart Contract

Edit the processTransaction function in src/process.ts:

export async function processTransaction(
  txJson: string,
  envVars: Record<string, string>,
  secrets: Record<string, string>
): Promise<ProcessResult> {
  // Parse the transaction
  const tx: Transaction = JSON.parse(txJson);

  // Access transaction data
  const txnId = tx.header.txn_id;
  const txnType = tx.header.txn_type;
  const payload = tx.payload;

  // Access environment variables
  const scName = envVars["SMART_CONTRACT_NAME"];
  const dcId = envVars["DRAGONCHAIN_ID"];

  // Access secrets
  const mySecret = secrets["SC_SECRET_MY_SECRET"];

  // Implement your logic here
  const result = {
    status: "success",
    data: "your result data",
  };

  return {
    data: result,
    outputToChain: true,  // Set to true to persist result on chain
  };
}

Transaction Structure

The Transaction interface in src/process.ts matches the Dragonchain transaction format:

interface Transaction {
  version: string;
  header: TransactionHeader;
  payload: Record<string, unknown>;
}

interface TransactionHeader {
  tag: string;
  dc_id: string;
  txn_id: string;
  block_id: string;
  txn_type: string;
  timestamp: string;
  invoker: string;
}

Available Environment Variables

Variable Description
TZ Timezone
ENVIRONMENT Deployment environment
INTERNAL_ID Internal identifier
DRAGONCHAIN_ID Dragonchain ID
DRAGONCHAIN_ENDPOINT Dragonchain API endpoint
SMART_CONTRACT_ID This smart contract's ID
SMART_CONTRACT_NAME This smart contract's name
SC_ENV_* Custom environment variables

Secrets

Secrets are provided in the secrets object with keys prefixed by SC_SECRET_.

Project Structure

.
├── src/
│   ├── main.ts          # Client infrastructure (do not modify)
│   └── process.ts       # Your smart contract logic (modify this)
├── proto/
│   └── remote_sc.proto  # gRPC service definition
├── config.yaml          # Configuration file
├── package.json         # Node.js dependencies
├── tsconfig.json        # TypeScript configuration
├── Makefile             # Build commands
└── README.md            # This file

File Descriptions

  • src/process.ts - Contains the processTransaction function where you implement your smart contract logic. This is the only file you need to modify for most use cases.
  • src/main.ts - Contains the gRPC client infrastructure, connection handling, and worker pool. You typically don't need to modify this file.

NPM Scripts

npm install        # Install dependencies
npm run build      # Compile TypeScript to JavaScript
npm start          # Run the compiled application
npm run dev        # Run with ts-node (development)
npm run proto      # Generate TypeScript types from proto
npm run clean      # Remove build artifacts
npm run lint       # Lint the code
npm run format     # Format code with prettier

Make Commands

make setup   # Install dependencies
make proto   # Generate TypeScript types from proto
make build   # Build TypeScript
make run     # Build and run
make dev     # Run in development mode
make clean   # Remove build artifacts
make lint    # Lint code
make format  # Format code

Concurrent Processing

The client uses async/await with a concurrency limit to process multiple transactions simultaneously. The number of concurrent workers is configurable via num_workers in the config file.

Error Handling

  • Return errors from the processTransaction function via ProcessResult.error to report failures
  • The client automatically handles reconnection on connection failures
  • Logs are captured and sent back with the response

Docker

Example Dockerfile:

FROM node:20-slim

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

CMD ["node", "dist/main.js", "--config", "config.yaml"]

Using with JavaScript

If you prefer plain JavaScript instead of TypeScript:

  1. Write your code in src/process.js instead of src/process.ts
  2. Skip the build step and run directly:
    node src/main.js --config config.yaml
    

License

[Your License Here]