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:

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=adt

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...', 'adt');
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: 'adt', amount: '1000000' }],
{ amount: [{ denom: 'adt', 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: "adt", amount: "1000000000000000000" },
},
};

const fee = {
amount: [{ denom: "adt", amount: "5000000000000000" }],
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:

  • 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 (adt)
dchain q bank balances dchain1... --denom adt

# 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=adt

# 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...", "adt");
console.log(balance); // { denom: 'adt', amount: '1000000' }

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

Send Tokens​

Using CLI:

# Send 1 DT (10^18 adt) to recipient
dchain tx bank send <sender-address> <recipient-address> 1000000000000000000adt \
--from <key> \
--chain-id dchain-1 \
--fees 5000000000000000adt

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: "adt", amount: "1000000000000000000" }], // 1 DT
{
amount: [{ denom: "adt", amount: "5000000000000000" }],
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: "adt", amount: "1000000000000000000" }],
}),
};

// 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: "adt", amount: "5000000000000000" }],
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​