Mint your DAT in Node.JS

Prerequisites

  • Node.js ≥ 18.x (LTS)

  • A funded Testnet wallet (for gas)

  • Credentials:

    • PRIVATE_KEY – your wallet’s private key (starts with 0x)

    • IPFS_JWT – Pinata (or compatible) IPFS JWT

1) Project setup

mkdir LazAI-contribution
cd LazAI-contribution
npm init -y

2) Install SDK & dependencies

npm install alith@latest axios dotenv node-rsa ts-node typescript
npm install --save-dev @types/node-rsa

dotenv loads env vars, axios sends the proof request, node-rsa encrypts the symmetric key for the verifier.

3) Create files

index.ts

Create a file index.ts and paste:

import { config } from 'dotenv'
import { Client } from 'alith/lazai'
import { PinataIPFS } from 'alith/data/storage'
import { encrypt } from 'alith/data'
import NodeRSA from 'node-rsa'
import axios from 'axios'
import { promises as fs } from 'fs'

// Load environment variables
config()
 
async function main() {
  try {
    // Check for required environment variables
    const privateKey = process.env.PRIVATE_KEY
    const ipfsJwt = process.env.IPFS_JWT
    
    if (!privateKey) {
      throw new Error('PRIVATE_KEY environment variable is required')
    }
    
    if (!ipfsJwt) {
      console.warn('Warning: IPFS_JWT environment variable not set. IPFS operations may fail.')
    }
    
    // Initialize client with private key as third parameter
    const client = new Client(undefined, undefined, privateKey)
    const ipfs = new PinataIPFS()
    
    console.log('✅ Client initialized successfully')
    console.log('✅ IPFS client initialized successfully')
    
    // 1. Prepare your privacy data and encrypt it
    const dataFileName = 'your_encrypted_data.txt'
    const privacyData = 'Your Privacy Data'
    const encryptionSeed = 'Sign to retrieve your encryption key'
    const password = client.getWallet().sign(encryptionSeed).signature
    const encryptedData = await encrypt(Uint8Array.from(privacyData), password)
    
    console.log('✅ Data encrypted successfully')
    
    // 2. Upload the privacy data to IPFS and get the shared url
    const fileMeta = await ipfs.upload({
      name: dataFileName,
      data: Buffer.from(encryptedData),
      token: ipfsJwt || '',
    })
    const url = await ipfs.getShareLink({ token: ipfsJwt || '', id: fileMeta.id })
    
    console.log('✅ File uploaded to IPFS:', url)
    
    // 3. Upload the privacy url to LazAI
    let fileId = await client.getFileIdByUrl(url)
    if (fileId == BigInt(0)) {
      fileId = await client.addFile(url)
    }
    
    console.log('✅ File registered with LazAI, file ID:', fileId.toString())
    
    // 4. Request proof in the verified computing node
    await client.requestProof(fileId, BigInt(100))
    const jobIds = await client.fileJobIds(fileId)
    const jobId = jobIds[jobIds.length - 1]
    const job = await client.getJob(jobId)
    const nodeInfo = await client.getNode(job.nodeAddress)
    const nodeUrl = nodeInfo.url
    const pubKey = nodeInfo.publicKey
    const rsa = new NodeRSA(pubKey, 'pkcs1-public-pem')
    const encryptedKey = rsa.encrypt(password, 'hex')
    const proofRequest = {
      job_id: Number(jobId),
      file_id: Number(fileId),
      file_url: url,
      encryption_key: encryptedKey,
      encryption_seed: encryptionSeed,
      nonce: null,
      proof_url: null,
    }

    console.log('✅ Proof request prepared')

    // Write proof request to file
    await fs.writeFile('proof_request.json', JSON.stringify(proofRequest, null, 2))
    console.log('✅ Proof request saved to proof_request.json')
    
    const response = await axios.post(`${nodeUrl}/proof`, proofRequest, {
      headers: { 'Content-Type': 'application/json' },
    })
   
    if (response.status === 200) {
      console.log('✅ Proof request sent successfully')
    } else {
      console.log('❌ Failed to send proof request:', response.data)
    }
    
    // 5. Request DAT reward
    await client.requestReward(fileId)
    console.log('✅ Reward requested for file id', fileId.toString())
    
    console.log('All operations completed successfully!')
    
  } catch (error) {
    console.error('❌ Error in main function:', error)
    process.exit(1)
  }
}

// Execute the main function
main().catch((error) => {
  console.error('❌ Unhandled error:', error)
  process.exit(1)
})

4) Add tsconfig.json

Create tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "node16",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "allowJs": true,
    "resolveJsonModule": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "ts-node": {
    "esm": true,
    "experimentalSpecifierResolution": "node"
  },
  "include": ["*.ts"],
  "exclude": ["node_modules"]
}

5) Set environment variables

Create a .env (recommended) or export in your shell:

# .env
PRIVATE_KEY=<your wallet private key>
IPFS_JWT=<your pinata ipfs jwt>

Your PRIVATE_KEY must start with 0x.

The script reads these via dotenv.

6) Run

 node --loader ts-node/esm index.ts

Expected output

✅ Client initialized successfully
✅ IPFS client initialized successfully
✅ Data encrypted successfully
✅ File uploaded to IPFS: https://...
✅ File registered with LazAI, file ID: <id>
✅ Proof request prepared
✅ Proof request saved to proof_request.json
✅ Proof request sent successfully
✅ Reward requested for file id <id>
All operations completed successfully!

Last updated