Initial commit: smart contract templates for bash, go, python, and typescript
This commit is contained in:
220
typescript/README.md
Executable file
220
typescript/README.md
Executable file
@@ -0,0 +1,220 @@
|
||||
# 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:
|
||||
```bash
|
||||
cp -r typescript /path/to/my-smart-contract
|
||||
cd /path/to/my-smart-contract
|
||||
```
|
||||
|
||||
2. **Install dependencies**:
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
3. **Configure your connection** by editing `config.yaml`:
|
||||
```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**:
|
||||
```bash
|
||||
npm run build
|
||||
npm start -- --config config.yaml
|
||||
```
|
||||
|
||||
Or run in development mode:
|
||||
```bash
|
||||
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`:
|
||||
|
||||
```typescript
|
||||
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:
|
||||
|
||||
```typescript
|
||||
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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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`:
|
||||
|
||||
```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:
|
||||
```bash
|
||||
node src/main.js --config config.yaml
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[Your License Here]
|
||||
Reference in New Issue
Block a user