Skip to main content

Constellation (DAG)

Sign Constellation (DAG / Hypergraph) transfers. The device signs a wire transaction built from a source / destination / amount shape; DAG addresses carry a checksum, so placeholder zero-addresses are rejected.

FieldValue
FamilyConstellation
coinType1137
keyPathm/44'/1137'/<accountIdx>'/0/0
amount unitDATUM (1 DAG = 1e8)
chainIdconstellation:mainnet/slip44:1137

Supported Methods

MethodSupported
getAddress
signTransaction
signMessage
signTypedData

Requirements

Minimum firmware for each method. The two models are on different version lines, so DCENT Biometric Wallet and DCENT X are listed separately (the numbers are not comparable across models). Below this the request returns the firmware-update error (5005) and the bridge prompts to update.

MethodDCENT Biometric WalletDCENT X
getAddress2.34.0 or higher1.0.0 or higher
signTransaction2.34.0 or higher1.0.0 or higher

getAddress — account address

Retrieves the Constellation account address for a chainId + keyPath. Call before building a transfer so source can be substituted with the device account. Returns a checksummed DAG address.

FieldTypeRequiredSourceNotes
chainIdstringRequiredAppFull CAIP-19 — constellation:mainnet/slip44:1137
keyPathstringRequiredAppBIP-44 — default m/44'/1137'/0'/0/0

Request

await dcent.getAddress({
chainId: 'constellation:mainnet/slip44:1137',
keyPath: "m/44'/1137'/0'/0/0"
})

Response

FieldTypeDescription
header.statusstringsuccess on completion
body.commandstringgetAddress
parameter.addressstringChecksummed DAG address in Constellation (Hypergraph) format — e.g. DAG…
{
"header": {
"version": "1.0",
"status": "success"
},
"body": {
"command": "getAddress",
"parameter": {
"address": "DAG…"
}
}
}

signTransaction — transfer

payload.transaction:

{
"type": "transfer",
"source": "DAG…",
"destination": "DAG0000000000000000000000000000000000001",
"amount": "100000000",
"fee": "0",
"salt": "0",
"lastRef": {
"ordinal": 1024,
"hash": "58ba6390b751a9e04edea64ada97024798e91519983a94f5992d6a3fd72953b1"
}
}
FieldTypeRequiredSourceDescription
typeenumRequiredAppTransaction kind — transfer
sourcestringRequired-RealWalletSender DAG address — must be the device account; substituted from getAddress
destinationstringRequired-RealAppRecipient DAG address (checksum-validated)
amountstringRequiredAppDATUM as a decimal string — 1 DAG = 1e8 (here 1 DAG)
feestringOptionalAppDATUM; "0" is valid on Constellation
lastRef{ ordinal, hash }Required-RealAppLast transaction reference — ordinal (number) and hash (prev tx hash) from the DAG address’s current state; the app must supply real values
saltstring | numberRequired-RealAppNon-negative safe integer. dag4 generates a random salt when it is absent, and the salt is inside the signed hash — so the app must pin it to be able to rebuild the transaction for broadcast. Omitting it fails with -32602

Request

await dcent.sign({
method: 'signTransaction',
chainId: 'constellation:mainnet/slip44:1137',
payload: {
keyPath: "m/44'/1137'/0'/0/0",
transaction: {
type: 'transfer',
source: 'DAG…',
destination: 'DAG0000000000000000000000000000000000001',
amount: '100000000',
fee: '0',
salt: '0',
lastRef: {
ordinal: 1024,
hash: '58ba6390b751a9e04edea64ada97024798e91519983a94f5992d6a3fd72953b1'
}
}
}
})

Response

FieldTypeDescription
header.statusstringsuccess on completion
body.commandstringsignTransaction
parameter.signaturestringBroadcast-ready signed Constellation wire transaction — the full serialized signed tx for the DAG / Hypergraph format, not a bare signature
{
"header": {
"version": "1.0",
"status": "success"
},
"body": {
"command": "signTransaction",
"parameter": {
"signature": "<signed wire tx>"
}
}
}
info

DAG addresses include a checksum. In the playground, clicking getAddress (substitute) replaces source (always) and destination (only when it is a placeholder) with the connected wallet address, producing a valid self-transfer. A zero-style placeholder such as DAG0000… is not a valid address and will break recipient / amount display.

signTransaction — metagraph L0 token transfer

info

Token model: form-D descriptor (same pattern as Havah / Hedera / Stacks / Tezos). Always send a token descriptor ({ contract, decimals, symbol }) and it signs — the signature bytes are byte-identical to a native DAG transfer (the token field never enters the signed payload); the device trusts your declared decimals/symbol for unregistered metagraphs, and shows DCENT's own verified values for registered ones. See Core Concepts → Token descriptors.

Constellation metagraph (L0) tokens are transferred with the same source / destination / amount / fee wire shape as native DAG — the wire body is byte-identical. The metagraph is identified out-of-band by token.contract (the metagraph id). The bridge resolves that id against DCENT's supported metagraphs and signs via the token's L0 / L1 endpoints instead of the base DAG network.

metagraph L0 · form-D

payload.transaction — DOR (registered):

{
"type": "transfer",
"source": "DAG…",
"destination": "DAG0000000000000000000000000000000000001",
"amount": "100000000",
"fee": "0",
"token": {
"contract": "DAG0CyySf35ftDQDQBnd1bdQ9aPyUdacMghpnCuM",
"decimals": 8,
"symbol": "DOR"
},
"salt": "0",
"lastRef": {
"ordinal": 1024,
"hash": "58ba6390b751a9e04edea64ada97024798e91519983a94f5992d6a3fd72953b1"
}
}
FieldTypeRequiredSourceDescription
token.contractstringRequired-RealAppMetagraph id (a DAG-format address). Must be a registered metagraph token — DCENT's supported list supplies the L0 / L1 endpoints.
token.decimals / token.symbolnumber / stringOptionalAppDisplay metadata (DOR = 8 decimals; amount 100000000 = 1 DOR)
source / destination / amount / feestringRequiredWallet / AppSame wire fields as a native DAG transfer; source must be the device account (use resolve-sender)
lastRef{ ordinal, hash }Required-RealAppSame as native — last transaction reference (ordinal + hash); the app must supply real values
saltstring | numberRequired-RealAppNon-negative safe integer. dag4 generates a random salt when it is absent, and the salt is inside the signed hash — so the app must pin it to be able to rebuild the transaction for broadcast. Omitting it fails with -32602

Request

await dcent.sign({
method: 'signTransaction',
chainId: 'constellation:mainnet/slip44:1137',
payload: {
keyPath: "m/44'/1137'/0'/0/0",
transaction: {
type: 'transfer',
source: 'DAG…',
destination: 'DAG0000000000000000000000000000000000001',
amount: '100000000',
fee: '0',
salt: '0',
token: {
contract: 'DAG0CyySf35ftDQDQBnd1bdQ9aPyUdacMghpnCuM',
decimals: 8,
symbol: 'DOR'
},
lastRef: {
ordinal: 1024,
hash: '58ba6390b751a9e04edea64ada97024798e91519983a94f5992d6a3fd72953b1'
}
}
}
})
info

An unregistered metagraph — e.g. token: { contract: 'DAG7X5idd4aLfp4XC6WQdG1eDfR3LGPVEwtUUB2W', decimals: 8, symbol: 'UNREG' } — signs the same way as a registered one. The only difference is trust: for a registered metagraph the device shows DCENT's own verified symbol/decimals; for an unregistered one it shows whatever your app declared, with no cryptographic binding to the real token. Because the wire body is byte-identical to a native DAG transfer, it is the L0/L1 endpoint used at broadcast time — not the signed bytes — that determines which network actually receives it, so get token.contract right.

Common Mistakes

danger

Placeholder zero-address — EVM/Solana-style DAG0000… fails the checksum; use a real getAddress result for source / destination. Amount not in DATUMamount is an integer string in DATUM, not DAG (1 DAG = 1e8 DATUM). source not the device accountsource must be the wallet's own DAG address or the device will refuse to sign.