Skip to main content

Interacting with Dchain

Dchain provides multiple interfaces for interacting with the blockchain, from command-line tools to programmatic APIs. This guide will help you navigate the available options and direct you to the relevant documentation for each module.

Interaction Methods

Dchain supports three primary methods for interaction:

  1. CLI (Command-Line Interface) - Direct terminal commands using the dchain binary
  2. gRPC - Remote Procedure Call interface for programmatic access
  3. REST API - HTTP/JSON endpoints via gRPC-gateway

All three methods provide access to the same functionality, allowing you to choose based on your use case.

Getting Started

Prerequisites

  • Node Access: You need access to a running Dchain node (local or remote)
  • CLI Tool: Install the dchain binary for command-line interactions
  • Account: Create or import an account/key for signing transactions

Basic CLI Setup

# Query the chain status
dchain status

# Create a new key
dchain keys add mykey

# Query your account balance
dchain q bank balances $(dchain keys show mykey -a)

Dchain Custom Modules

Dchain extends Cosmos SDK with several custom modules that provide unique functionality:

Abstract Account Module

Enables smart contract-based account abstraction with customizable authentication.

Key capabilities:

  • Register abstract accounts with custom logic
  • Query actor and authenticator configurations
  • Manage supported proxy contracts

Documentation: Abstract Account Module

Common operations:

# Query supported proxies
dchain q abstractaccount supported-proxies

# Register a new abstract account
dchain tx abstractaccount register-account <code-id> <instantiate-msg-json> --from <key>

Notary Module

Provides asset notarisation with verifiable credential verification.

Key capabilities:

  • Notarise assets with cryptographic proof
  • Register and manage notary configurations
  • Query notarised assets and conversion rates

Documentation: Notary Module

Common operations:

# Query notarised asset
dchain query notary notarised-asset <asset-id>

# Notarise new asset
dchain tx notary notarise <notary-info-id> <verifier-input> <asset-data> --from <key>

Verifiable Credential Verifier (VCV)

Manages verification routes and verifier contracts for credential validation.

Key capabilities:

  • Query verification routes for message types
  • Get verifier contract configurations
  • Integration with notary and other modules requiring verification

Documentation: VCV Module

Common operations:

# Get verification routes registry
dchain query vcv get-routes-registry

# Get message-specific route
dchain query vcv get-message-route <message-type>

D-Gov Module

Provides oversight committee governance functionality.

Key capabilities:

  • Configure oversight committee authority
  • Query oversight committee parameters
  • Submit proposals through group policy

Documentation: D-Gov Module

Common operations:

# Get oversight committee parameters
dchain q gov oversight-committee-params

# Set oversight committee authority (one-time setup)
dchain tx gov oversight-committee-addr <address>

Mint Module

Custom minting mechanism with max supply support and epoch-based distribution.

Key capabilities:

  • Query minting parameters and epoch provisions
  • Monitor supply and minting rates
  • Propose parameter updates via governance

Documentation: Mint Module

Common operations:

# Query current minting parameters
dchain q mint params

# Query epoch provisions
dchain q mint epoch-provisions

# Check total supply
dchain q bank total --denom=udt

Example Standard Cosmos SDK Modules

Dchain inherits all standard Cosmos SDK modules. Here are the most commonly used:

Bank Module

Handle token transfers and balance queries.

# Query balances
dchain q bank balances <address>

# Send tokens
dchain tx bank send <from> <to> <amount> --from <key>

API Reference: cosmos/bank/v1beta1 - See Cosmos SDK Bank Module

Staking Module

Delegate tokens, create validators, and manage staking operations.

# Query validators
dchain q staking validators

# Delegate tokens
dchain tx staking delegate <validator-addr> <amount> --from <key>

API Reference: cosmos/staking/v1beta1 - See Cosmos SDK Staking Module

Distribution Module

Manage staking rewards and community pool.

# Query rewards
dchain q distribution rewards <delegator-addr>

# Withdraw rewards
dchain tx distribution withdraw-all-rewards --from <key>

API Reference: cosmos/distribution/v1beta1 - See Cosmos SDK Distribution Module

Group Module

Create and manage decision-making groups with voting policies.

# Query groups
dchain q group groups

# Create group
dchain tx group create-group <group.json> --from <key>

API Reference: cosmos/group/v1 - See Cosmos SDK Group Module

Using RPC with TypeScript/JavaScript

For frontend applications and TypeScript/JavaScript environments, you can interact with Dchain using CosmJS, the official TypeScript library for Cosmos SDK chains.

CosmJS Library

CosmJS provides a comprehensive set of tools for:

  • Connecting to RPC endpoints
  • Querying blockchain state
  • Signing and broadcasting transactions
  • Working with wallets and keys

Official Repository: https://github.com/cosmos/cosmjs

Installation

npm install @cosmjs/stargate @cosmjs/proto-signing @cosmjs/tendermint-rpc

Basic RPC Connection

import { StargateClient } from '@cosmjs/stargate';

// Connect to Dchain RPC endpoint
const client = await StargateClient.connect(<'rpc-endpoint-url'>);

// Query chain info
const chainId = await client.getChainId();
const height = await client.getHeight();

// Query account balance
const balance = await client.getBalance('dchain1...', 'udt');
console.log(balance);

Querying with CosmJS

Query validators:

import { QueryClient, createProtobufRpcClient } from "@cosmjs/stargate";
import { QueryClientImpl as StakingQueryClient } from "cosmjs-types/cosmos/staking/v1beta1/query";

const client = QueryClient.withExtensions(cometClient);
const rpc = createProtobufRpcClient(client);
const stakingQuery = new StakingQueryClient(rpc);

const validators = await stakingQuery.Validators({
status: "BOND_STATUS_BONDED",
});

Query proposals:

import { QueryClientImpl as GovQueryClient } from "cosmjs-types/cosmos/gov/v1/query";
import { ProposalStatus } from "cosmjs-types/cosmos/gov/v1/gov";

const govQuery = new GovQueryClient(rpc);
const proposals = await govQuery.Proposals({
proposalStatus: ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD,
voter: "",
depositor: "",
});

Query bank balances:

import { QueryClientImpl as BankQueryClient } from "cosmjs-types/cosmos/bank/v1beta1/query";

const bankQuery = new BankQueryClient(rpc);
const totalSupply = await bankQuery.TotalSupply({});

Signing and Broadcasting Transactions

Basic transaction example:

import { SigningStargateClient } from '@cosmjs/stargate';
import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing';

// Create wallet from mnemonic
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(
'your mnemonic here',
{ prefix: 'dchain' }
);

// Connect signing client
const client = await SigningStargateClient.connectWithSigner(
<'rpc-endpoint-url'>,
wallet
);

// Get sender address
const [account] = await wallet.getAccounts();

// Send tokens
const result = await client.sendTokens(
account.address,
'dchain1recipient...',
[{ denom: 'udt', amount: '1000000' }],
{ amount: [{ denom: 'udt', amount: '5000' }], gas: '200000' }
);

console.log('Transaction hash:', result.transactionHash);

Staking operations:

// Delegate tokens
const delegateMsg = {
typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
value: {
delegatorAddress: account.address,
validatorAddress: "dchainvaloper1...",
amount: { denom: "udt", amount: "1000000" },
},
};

const fee = {
amount: [{ denom: "udt", amount: "5000" }],
gas: "200000",
};

const result = await client.signAndBroadcast(account.address, [delegateMsg], fee);

Working with Verifiable Presentations

For Dchain-specific features that require VCV verification, you need to add extension options:

import { TxBodyEncodeObject } from "@cosmjs/proto-signing";
import { Any } from "cosmjs-types/google/protobuf/any";

// Prepare verifiable presentation extension
const vpExtension = Any.fromPartial({
typeUrl: "/d.vcv.v1.VerifiablePresentation",
value: vpBytes, // Your encoded VP
});

// Create transaction body with extension
const txBody: TxBodyEncodeObject = {
typeUrl: "/cosmos.tx.v1beta1.TxBody",
value: {
messages: [
/* your messages */
],
memo: "",
extensionOptions: [vpExtension],
},
};

RPC Endpoints

configured in ~/.dchain/config/config.toml

Local Development:

  • RPC: http://localhost:26657
  • REST: http://localhost:1317

CosmJS Resources

Working with APIs

gRPC Endpoints

All modules expose gRPC services on port 9090 (default).

Example with grpcurl:

# Query notary info
grpcurl -plaintext localhost:9090 d.notary.v1.Query/GetNotaryInfoById -d '{"id": 1}'

# Query bank balances
grpcurl -plaintext localhost:9090 cosmos.bank.v1beta1.Query/AllBalances -d '{"address": "dchain1..."}'

Generated Client Code:

  • Dchain modules: /api/d/<module>/v1/*_grpc.pb.go
  • Cosmos modules: /cosmos-sdk/api/cosmos/<module>/v1beta1/*_grpc.pb.go

REST API Endpoints

REST endpoints are available on port 1317 (default) via gRPC-gateway.

Dchain module endpoints:

  • Abstract Account: http://localhost:1317/d/abstractaccount/v1/*
  • Notary: http://localhost:1317/d/notary/v1/*
  • VCV: http://localhost:1317/d/vcv/v1/*
  • Mint: http://localhost:1317/d/mint/v1/*

Cosmos SDK endpoints:

  • Bank: http://localhost:1317/cosmos/bank/v1beta1/*
  • Staking: http://localhost:1317/cosmos/staking/v1beta1/*
  • Gov: http://localhost:1317/cosmos/gov/v1/*
  • Distribution: http://localhost:1317/cosmos/distribution/v1beta1/*

Example:

# Query notary fee rate
curl http://localhost:1317/d/notary/v1/notarisation_fee_rate

# Query bank balances
curl http://localhost:1317/cosmos/bank/v1beta1/balances/dchain1...

Verifiable Credentials Integration

Many Dchain operations require verifiable credentials for authentication and authorization. When using CLI commands that require verification:

Add the --verifiable-presentation flag:

dchain tx notary notarise <args> --from <key> \
--verifiable-presentation <base64-encoded-vp>

The verifiable presentation is:

  • Base64-encoded credential data
  • Validated by the VCV module's AnteHandler
  • Specific to the message route configuration

For more details on VCV integration, see the VCV Module documentation.

Example Usage for a token transfer and balance query

Current v0.8.2

In the current version, you can interact with bank balances and token transfers using the Cosmos SDK APIs.

Query Balance for a Denom

Using CLI:

# Query balance for native token (udt)
dchain q bank balances dchain1... --denom udt

# Query all balances for an address
dchain q bank balances dchain1...

Using REST API:

# Query balance for specific denom
curl http://localhost:1317/cosmos/bank/v1beta1/balances/dchain1.../by_denom?denom=udt

# Query all balances
curl http://localhost:1317/cosmos/bank/v1beta1/balances/dchain1...

Using CosmJS (TypeScript):

import { StargateClient } from "@cosmjs/stargate";

const client = await StargateClient.connect("http://localhost:26657");

// Query balance for specific denom
const balance = await client.getBalance("dchain1...", "udt");
console.log(balance); // { denom: 'udt', amount: '1000000' }

// Query all balances
const allBalances = await client.getAllBalances("dchain1...");
console.log(allBalances); // [{ denom: 'udt', amount: '1000000' }, ...]

Send Tokens

Using CLI:

# Send 1 DT (1,000,000 udt) to recipient
dchain tx bank send <sender-address> <recipient-address> 1000000udt \
--from <key> \
--chain-id dchain-1 \
--fees 5000udt

Using CosmJS (TypeScript):

import { SigningStargateClient } from "@cosmjs/stargate";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";

// Create wallet
const wallet = await DirectSecp256k1HdWallet.fromMnemonic("your mnemonic here", { prefix: "dchain" });

// Connect signing client
const client = await SigningStargateClient.connectWithSigner("http://localhost:26657", wallet);

// Get sender address
const [account] = await wallet.getAccounts();

// Send tokens
const result = await client.sendTokens(
account.address,
"dchain1recipient...",
[{ denom: "udt", amount: "1000000" }], // 1 DT
{
amount: [{ denom: "udt", amount: "5000" }],
gas: "200000",
},
"Transfer memo",
);

console.log("Transaction hash:", result.transactionHash);
console.log("Height:", result.height);

Broadcasting Pre-Signed Transactions

If you already have a signed transaction (e.g., signed externally), you can broadcast it directly using the broadcast APIs.

Using REST API to broadcast (BroadcastTxSync):

# Broadcast signed transaction bytes (base64 encoded)
curl -X POST http://localhost:1317/cosmos/tx/v1beta1/txs \
-H "Content-Type: application/json" \
-d '{
"tx_bytes": "<base64-encoded-tx-bytes>",
"mode": "BROADCAST_MODE_SYNC"
}'

Complete example with transaction construction and broadcasting:

import { StargateClient } from "@cosmjs/stargate";
import { Registry, makeSignDoc } from "@cosmjs/proto-signing";
import { TxRaw, TxBody, AuthInfo, SignDoc } from "cosmjs-types/cosmos/tx/v1beta1/tx";
import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx";
import { toBase64 } from "@cosmjs/encoding";

const client = await StargateClient.connect("http://localhost:26657");
const registry = new Registry();

// 1. Create the message
const sendMsg = {
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: MsgSend.fromPartial({
fromAddress: "dchain1sender...",
toAddress: "dchain1recipient...",
amount: [{ denom: "udt", amount: "1000000" }],
}),
};

// 2. Create transaction body
const txBody = TxBody.fromPartial({
messages: [sendMsg],
memo: "Transfer via API",
});
const txBodyBytes = TxBody.encode(txBody).finish();

// 3. Create auth info (fee and signer info)
const authInfo = AuthInfo.fromPartial({
signerInfos: [
{
sequence: BigInt(accountSequence),
modeInfo: { single: { mode: 1 } }, // SIGN_MODE_DIRECT
publicKey: publicKeyAny, // Your public key as Any type
},
],
fee: {
amount: [{ denom: "udt", amount: "5000" }],
gasLimit: BigInt(200000),
},
});
const authInfoBytes = AuthInfo.encode(authInfo).finish();

// 4. Create sign doc for signing
const chainId = await client.getChainId();
const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber);

// 5. Get signature (from your signing mechanism - WebAuthn, hardware wallet, etc.)
// const signatureBytes = await yourSigningFunction(SignDoc.encode(signDoc).finish());

// 6. Assemble the signed transaction
const txRaw = TxRaw.fromPartial({
bodyBytes: txBodyBytes,
authInfoBytes: authInfoBytes,
signatures: [signatureBytes],
});

// 7. Encode and broadcast
const txBytes = TxRaw.encode(txRaw).finish();
const result = await client.broadcastTx(txBytes);

console.log("Transaction hash:", result.transactionHash);
console.log("Result:", result);

Broadcast modes:

  • BROADCAST_MODE_SYNC: Returns after CheckTx (mempool validation)
  • BROADCAST_MODE_ASYNC: Returns immediately without checking
  • BROADCAST_MODE_BLOCK: Waits for transaction to be included in a block (deprecated in Cosmos SDK v0.50+)

Next v1.0.0

In the upcoming v1.0.0 release, Dchain will integrate with Cosmos-EVM which will provide an extended JSON-RPC interface for Ethereum-compatible interactions.

This will enable developers to interact with ERC20 tokens and use familiar Ethereum tools like ethers.js and MetaMask.

Query ERC20 Token Balance

Using ethers.js:

import { ethers } from "ethers";

// Connect to Dchain EVM JSON-RPC endpoint
const provider = new ethers.JsonRpcProvider("http://localhost:8545");

// ERC20 Contract ABI (minimal)
const erc20Abi = [
"function balanceOf(address owner) view returns (uint256)",
"function decimals() view returns (uint8)",
"function symbol() view returns (string)",
"function transfer(address to, uint256 amount) returns (bool)",
];

// Connect to ERC20 token contract
const tokenAddress = "0x..."; // ERC20 token contract address
const tokenContract = new ethers.Contract(tokenAddress, erc20Abi, provider);

// Query balance
const accountAddress = "0x..."; // User's Ethereum address
const balance = await tokenContract.balanceOf(accountAddress);
const decimals = await tokenContract.decimals();
const symbol = await tokenContract.symbol();

console.log(`Balance: ${ethers.formatUnits(balance, decimals)} ${symbol}`);

Using eth_call JSON-RPC directly:

// Encode balanceOf function call
const accountAddress = "0x1234567890123456789012345678901234567890";
const data = ethers.concat([
ethers.id("balanceOf(address)").slice(0, 10), // Function selector
ethers.zeroPadValue(accountAddress, 32), // Padded address
]);

// Make JSON-RPC call
const response = await fetch("http://localhost:8545", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
method: "eth_call",
params: [
{
to: "0x...", // ERC20 token contract address
data: data,
},
"latest",
],
id: 1,
}),
});

const result = await response.json();
const balance = BigInt(result.result);
console.log("Balance:", balance.toString());

Using curl:

# Query ERC20 balance using eth_call
curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_call",
"params": [{
"to": "0x...",
"data": "0x70a08231000000000000000000000000<address-without-0x>"
}, "latest"],
"id": 1
}'

Send ERC20 Tokens

Using ethers.js:

import { ethers } from "ethers";

// Connect with signer (using private key or wallet)
const provider = new ethers.JsonRpcProvider("http://localhost:8545");
const wallet = new ethers.Wallet("0xYourPrivateKey", provider);

// Connect to ERC20 contract with signer
const tokenContract = new ethers.Contract(tokenAddress, erc20Abi, wallet);

// Transfer tokens
const recipientAddress = "0x...";
const amount = ethers.parseUnits("1.0", 18); // 1 token with 18 decimals

const tx = await tokenContract.transfer(recipientAddress, amount);
console.log("Transaction hash:", tx.hash);

// Wait for confirmation
const receipt = await tx.wait();
console.log("Confirmed in block:", receipt.blockNumber);

Using MetaMask:

// Request account access
const accounts = await window.ethereum.request({
method: "eth_requestAccounts",
});

const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

// Connect to ERC20 contract
const tokenContract = new ethers.Contract(tokenAddress, erc20Abi, signer);

// Transfer tokens
const tx = await tokenContract.transfer(recipientAddress, amount);
await tx.wait();

Native ETH Balance Query (via EVM)

Using ethers.js:

// Query native ETH balance (mapped from Cosmos native token)
const balance = await provider.getBalance("0x...");
console.log("Balance:", ethers.formatEther(balance), "ETH");

Using JSON-RPC directly:

# Query ETH balance
curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getBalance",
"params": ["0x...", "latest"],
"id": 1
}'

Resources for v1.0.0 EVM Integration