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:
- CLI (Command-Line Interface) - Direct terminal commands using the
dchainbinary - gRPC - Remote Procedure Call interface for programmatic access
- 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
dchainbinary 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
- Documentation: https://cosmos.github.io/cosmjs
- GitHub: https://github.com/cosmos/cosmjs
- Examples: https://github.com/cosmos/cosmjs/tree/main/packages/stargate
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 checkingBROADCAST_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
- Cosmos EVM JSON-RPC: https://evm.cosmos.network/docs/evm/v0.5.0/api-reference/ethereum-json-rpc
- Ethers.js Documentation: https://docs.ethers.org/v6/
- ERC20 with ethers.js: https://support.metamask.io/develop/building-with-infura/javascript-typescript/how-to-retrieve-balance-erc20-ethersjs/
- MetaMask Integration: https://docs.metamask.io/wallet/