Stacks (STX)
Sign Stacks (STX) transactions. The device signs a structured transaction object — either a native STX tokenTransfer or a contractCall (e.g. a SIP-010 fungible-token transfer). Account number / nonce placeholders pass the format check so the device will sign, but the result cannot be broadcast — supply the real nonce and fee, and the sender must exist on-chain.
| Field | Value |
|---|---|
| Family | Stacks |
| coinType | 5757 |
| keyPath | m/44'/5757'/<accountIdx>'/0/0 |
| amount unit | microSTX |
| chainId | stacks:1/slip44:5757 |
Supported Methods
| Method | Supported |
|---|---|
| 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.
| Method | DCENT Biometric Wallet | DCENT X |
|---|---|---|
getAddress | 2.14.1 or higher | 1.0.0 or higher |
signTransaction | 2.14.1 or higher | 1.0.0 or higher |
getAddress — account address
Retrieves the Stacks account address for the given keyPath. Returns a c32check-encoded mainnet address (SP…). Stacks has no address variants, so no addressFormat is needed.
| Field | Type | Required | Source | Description |
|---|---|---|---|---|
chainId | string | Required | App | Full CAIP-19 id — stacks:1/slip44:5757 |
keyPath | string | Required-Real | Wallet | BIP-44 path of the device account; default m/44'/5757'/0'/0/0 |
Request
await dcent.getAddress({
chainId: 'stacks:1/slip44:5757',
keyPath: "m/44'/5757'/0'/0/0"
})
Response
| Field | Type | Description |
|---|---|---|
header.status | string | success on success; failure otherwise |
body.command | string | getAddress |
parameter.address | string | c32check-encoded mainnet Stacks address (SP…) |
{
"header": {
"version": "1.0",
"status": "success"
},
"body": {
"command": "getAddress",
"parameter": {
"address": "SP…"
}
}
}
signTransaction — <transaction>
Variant — native STX (tokenTransfer)
await dcent.sign({
method: 'signTransaction',
chainId: 'stacks:1/slip44:5757',
payload: {
keyPath: "m/44'/5757'/0'/0/0",
transaction: {
txType: "tokenTransfer",
recipient: "SP000000000000000000002Q6VF78",
amount: "1000000", // microSTX — 1 STX
memo: "",
fee: "180",
nonce: "0",
anchorMode: 3,
postConditionMode: 1,
network: "mainnet"
}
}
})
| Field | Type | Required | Source | Description |
|---|---|---|---|---|
keyPath | string | Required-Real | Wallet | BIP-44 path of the signing device account (SP…) |
txType | enum | Required | App | tokenTransfer for native STX |
recipient | string | Required-Real | App | Destination Stacks address (SP…) |
amount | string | Required | App | microSTX — 1 STX = 1,000,000 |
memo | string | Optional | App | Optional plain-text memo |
fee | string | Required | App | Transaction fee in microSTX |
nonce | string | Required-Real | App | Real, current account nonce — the app must supply it; not auto-filled |
anchorMode | number | Required | App | 3 = any (on/off-chain) |
postConditionMode | number | Required | App | 1 = allow |
network | enum | Required | App | Must be mainnet for stacks:1/slip44:5757 |
Variant — SIP-010 token transfer (contractCall)
What the bridge accepts today. (1) contractCall currently routes only the SIP-010 transfer function. Other Clarity calls (swap, mint, staking) return -32602 today because that branch is not wired up yet — the device signs whatever completed payload it is handed, so this is a gap to fill, not a signing limit. (2) This shape has nowhere to put decimals, so it only works for a token DCENT already supports (see Supported Coins & Tokens); anything else fails with -32602 cannot resolve token. For every other SIP-010 token, send the form-D descriptor shape below instead.
Token model: form-D descriptor. Always send the token's symbol and decimals under transaction.token — the bridge signs with no network access and uses the decimals you supply directly, so the device shows the correct token name and amount. See Core Concepts → Token descriptors.
await dcent.sign({
method: 'signTransaction',
chainId: 'stacks:1/slip44:5757',
payload: {
keyPath: "m/44'/5757'/0'/0/0",
transaction: {
txType: "contractCall",
contractAddress: "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR",
contractName: "arkadiko-token",
functionName: "transfer",
functionArgs: [
1000000, // amount in token base units (DIKO, 6 decimals)
"SP0000000000000000006YNMHVRQZ0", // sender — your device account
"SP0000000000000000006AZVJGZ4FR", // recipient
"" // memo
],
nonce: 0,
fee: 180
}
}
})
| Field | Type | Required | Source | Description |
|---|---|---|---|---|
txType | enum | Required | App | contractCall — SIP-010 transfer only. Any other Clarity function is rejected with -32602 |
contractAddress | string | Required-Real | App | Deployer address of the token contract (case-sensitive) |
contractName | string | Required-Real | App | Contract name, e.g. arkadiko-token (case-sensitive) |
functionName | string | Required | App | transfer for SIP-010 |
functionArgs | array | Required-Real | App | [amount, sender, recipient, memo]; accepts ClarityValue objects or plain values |
nonce | number | Required-Real | App | Real, current account nonce — the app must supply it; not auto-filled |
fee | number | Required | App | Transaction fee in microSTX |
For SIP-010, amount is in the token's own base units (per its decimals), not microSTX — DIKO has 6 decimals, so 1000000 = 1 DIKO. The wallet auto-builds the post-condition.
Response
| Field | Type | Description |
|---|---|---|
header.status | string | success on success; failure otherwise |
body.command | string | signTransaction |
parameter.signature | string | The broadcast-ready serialized signed Stacks transaction (hex) — a full serialized signed transaction in Stacks wire format, not a bare signature. Submit it as-is to a Stacks node (/v2/transactions). |
{
"header": {
"status": "success"
},
"body": {
"command": "signTransaction",
"parameter": {
"signature": "<signed serialized tx hex>"
}
}
}
On failure, header.status === 'failure' and body.error = { code, message }.
Common Mistakes
Amounts not in microSTX — native STX amount / fee are microSTX (1 STX = 1,000,000). SIP-010 amounts use the token's base units instead. Case-sensitive contract identifiers — contractAddress and contractName must match the deployed contract exactly, or the call is rejected. Wrong sender / recipient in functionArgs — functionArgs[1] (sender) must be your own device Stacks account (SP…) for the signature to be valid. Wrong network — use mainnet with stacks:1/slip44:5757; testnet (stacks:2147483648/slip44:5757) is supported — a native STX transfer was signed on-device and broadcast successfully (verified 2026-07-21); any token signs — supply a form-D descriptor (see Core Concepts → Token descriptors).