Skip to main content

Conflux (CFX)

Sign Conflux Core Space transactions. The fields are EVM-style, but addresses use the CIP-37 base32 format (cfx:…) — the device firmware expects base32, not hex.

FieldValue
FamilyConflux (Core Space)
coinType503 in the chainId (slip44:503); keys are derived on the EVM path m/44'/60'
keyPathm/44'/60'/<accountIdx>'
amount unitDrip
chainIdconflux:cfx/slip44:503

Supported Methods​

MethodSupported
getAddress✓
signTransaction✓
signMessage✗
signTypedData✗
signData✗

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.18.3 or higher1.0.0 or higher
signTransaction2.18.3 or higher1.0.0 or higher
info

Conflux derives keys on the EVM path m/44'/60'/0' even though the chainId's slip44 segment is 503. The path and the coinType are intentionally different.

getAddress — account address​

Retrieves the Conflux Core Space account address. On DCENT X it returns a CIP-37 base32 address (cfx:…), not a hex address.

FieldTypeRequiredSourceNotes
chainIdstringRequiredAppFull CAIP-19 — conflux:cfx/slip44:503
keyPathstringRequiredAppBIP-44 EVM path — m/44'/60'/0'

Request

await dcent.getAddress({
chainId: 'conflux:cfx/slip44:503',
keyPath: "m/44'/60'/0'"
})

Response

FieldTypeDescription
header.statusstringsuccess on completion
body.commandstringgetAddress
body.parameter.addresscfx addressAccount address in CIP-37 base32 (cfx:…) on DCENT X; mainnet prefix is cfx:
{
"header": {
"version": "1.0",
"status": "success",
"response_from": "getAddress"
},
"body": {
"command": "getAddress",
"parameter": {
"address": "cfx:…"
}
}
}

signTransaction — Core Space transaction​

payload.transaction:

{
"from": "cfx:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0sfbnjm2",
"to": "cfx:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0sfbnjm2",
"value": "0x10",
"gas": "0x5208",
"gasPrice": "0x3b9aca00",
"nonce": "0x0",
"chainId": "0x405",
"epochHeight": "0x0",
"storageLimit": "0x0",
"data": "0x"
}
FieldTypeRequiredSourceDescription
fromcfx addressOptionalWalletDevice CFX account in CIP-37 base32 (cfx:…). Not used for signing and not checked — the signer is always the keyPath account
tocfx addressRequired-RealAppRecipient in CIP-37 base32 (cfx:…)
valuehexOptionalAppAmount in Drip — 0x10 = 16 Drip (1 CFX = 1e18 Drip). Omitted → 0
gashexRequiredApp0x5208 = 21000 (plain transfer)
gasPricehexRequiredAppPrice per gas in Drip — 0x3b9aca00 = 1e9
noncehexRequired-RealAppReal, current sender transaction count — the app must supply it; not auto-filled
chainIdhexOptionalAppIgnored — the bridge always signs with chain id 1029 (Conflux mainnet)
epochHeighthexRequired-RealAppReal, current Conflux epoch height — the app must supply it; not auto-filled
storageLimithexRequiredAppCollateral storage cap; 0x0 for plain transfer
datahexOptionalApp0x for a plain transfer; contract calldata otherwise

Request

await dcent.sign({ method: 'signTransaction',
chainId: 'conflux:cfx/slip44:503',
payload: { keyPath: "m/44'/60'/0'",
transaction: {
"from": "cfx:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0sfbnjm2",
"to": "cfx:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0sfbnjm2",
"value": "0x10", "gas": "0x5208", "gasPrice": "0x3b9aca00",
"nonce": "0x0", "chainId": "0x405", "epochHeight": "0x0",
"storageLimit": "0x0", "data": "0x" } } })

Response

FieldTypeDescription
header.statusstringsuccess on completion
body.commandstringsignTransaction
body.parameter.signaturehexThe RLP-encoded signed Core Space transaction (not a bare signature). A native CFX transfer returns it as bare hex (no 0x); a CRC-20 transfer returns it 0x-prefixed — add 0x if it is missing before cfx_sendRawTransaction
{
"header": {
"version": "1.0",
"status": "success",
"response_from": "signTransaction"
},
"body": {
"command": "signTransaction",
"parameter": {
"signature": "<signed tx hex>"
}
}
}

Variant — CRC-20 token transfer (raw calldata)​

warning

Only for a token on DCENT's supported list. The bridge recognizes the transfer(address,uint256) calldata and signs it as a token transfer of that registered CRC-20 token. For a token that is not on the list, this shape is rejected with param_error (-32602) — send the form-D descriptor below with decimals instead.

payload.transaction:

{
"from": "cfx:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0sfbnjm2",
"to": "cfx:achc8nxj7r451c223m18w2dwjnmhkd6rxawrvkvsy2",
"value": "0x0",
"gas": "0x186a0",
"gasPrice": "0x3b9aca00",
"nonce": "0x0",
"chainId": "0x405",
"epochHeight": "0x6a1b2c",
"storageLimit": "0x0",
"data": "0xa9059cbb0000000000000000000000001cad0b19bb29d4674531d6f115237e16afce377c0000000000000000000000000000000000000000000000000de0b6b3a7640000"
} // to = FansCoin (FC) contract, a registered token (CIP-37 base32); data = transfer(address,uint256) selector + recipient + amount (1 FC)
FieldTypeRequiredSourceDescription
tocfx addressRequired-RealAppThe token contract, in CIP-37 base32 (cfx:…) — must be a token on DCENT's supported list
valuehexOptionalApp0x0 (or omit) for a token call
datahexRequiredAppABI-encoded transfer(address,uint256) — 0xa9059cbb + 32-byte recipient + 32-byte base-unit amount

Variant — CRC-20 token transfer, unregistered token (form-D)​

For a CRC-20 token that is not on DCENT's supported list, put the token under transaction.token with its decimals (see form-D vs form-E). The bridge builds the transfer(address,uint256) call itself. Do not send a non-zero data or a non-zero value alongside token — either is rejected with param_error (-32602).

payload.transaction:

{
"from": "cfx:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0sfbnjm2",
"gas": "0x186a0",
"gasPrice": "0x3b9aca00",
"nonce": "0x0",
"chainId": "0x405",
"epochHeight": "0x6a1b2c",
"storageLimit": "0x0",
"token": {
"contract": "cfx:acg158kvr8zanb1bs048ryb6rtrhr283ma70vz70tx",
"to": "0x1cad0b19bb29d4674531d6f115237e16afce377c",
"amount": "1000000000000000000",
"decimals": 18,
"symbol": "WCFX"
}
} // token.contract = WCFX (not on the supported list); amount in base units (1 WCFX)

Common Mistakes​

danger

Hex (0x…) addresses instead of CIP-37 base32 — Conflux Core Space addresses are cfx:…. A hex address (to, or token.to) is converted to cfx: base32 by the bridge before it reaches the device, so either form works; base32 matches the format the device shows. Using a testnet address — only Conflux mainnet is supported (chain id 1029, cfx: addresses). A cfxtest: address is rejected for a token transfer (-32602); don't use one for a native transfer either. Confusing coinType with keyPath — coinType is 503 but derivation uses the EVM path m/44'/60'/0'. Stale epochHeight — it bounds transaction validity; refresh it near the current epoch or the network rejects the tx.