Algorand (ALGO)
Sign Algorand transactions. Provide a transaction object with the suggested-params round window; the device signs the encoded transaction by its keyPath. Both native ALGO payments (pay) and ASA token transfers (axfer) are supported.
| Field | Value |
|---|---|
| coinType | 283 |
| keyPath | m/44'/283'/<accountIdx>'/0/0 |
| amount unit | microAlgo |
| chainId | algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73k/slip44:283 |
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.29.0 or higher | 1.0.0 or higher |
signTransaction | 2.29.0 or higher | 1.0.0 or higher |
getAddress — account address
Retrieves the Algorand account address. Returns a 58-character base32 address (the ed25519 public key plus a 4-byte checksum). Call before building a transaction so the from field matches the device account.
| Field | Type | Required | Source | Notes |
|---|---|---|---|---|
chainId | string | Required | App | Full CAIP-19 — algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73k/slip44:283 |
keyPath | string | Required | App | BIP-44 — m/44'/283'/0'/0/0 |
Request
await dcent.getAddress({
chainId: 'algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73k/slip44:283',
keyPath: "m/44'/283'/0'/0/0"
})
Response
| Field | Type | Description |
|---|---|---|
header.status | string | success on completion |
body.command | string | getAddress |
parameter.address | string | Algorand account address — 58-char base32 (ed25519 public key + 4-byte checksum) |
{
"header": {
"version": "1.0",
"status": "success"
},
"body": {
"command": "getAddress",
"parameter": {
"address": "737777777777777777777777777777777777777777777777777UFEJ2CI"
}
}
}
Algorand has a single address format — there are no addressFormat variants. The returned address already encodes the public key, so no separate pubkey field is returned.
signTransaction
Variant — payment (pay)
payload.transaction:
{
"type": "pay",
"from": "737777777777777777777777777777777777777777777777777UFEJ2CI",
"to": "737777777777777777777777777777777777777777777777777UFEJ2CI",
"amount": 1000000,
"fee": 1000,
"firstRound": 1,
"lastRound": 1000,
"genesisID": "mainnet-v1.0",
"genesisHash": "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiHc0CYz/uo="
}
| Field | Type | Required | Source | Description |
|---|---|---|---|---|
type | enum | Required | App | pay for native ALGO transfer |
from | string | Required-Real | Wallet | Device Algorand account; must own the funds |
to | string | Required-Real | App | Recipient address |
amount | number | Required | App | microAlgo (1 ALGO = 1,000,000) |
fee | number | Required | App | microAlgo; minimum 1000 |
firstRound / lastRound | number | Required-Real | App | Real validity window — the app must supply current values; not auto-filled |
genesisID | string | Required | App | e.g. mainnet-v1.0 |
genesisHash | base64 | Required-Real | RPC | Network genesis hash; pins the chain |
Request
await dcent.sign({
method: 'signTransaction',
chainId: 'algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73k/slip44:283',
payload: {
keyPath: "m/44'/283'/0'/0/0",
transaction: {
"type": "pay",
"from": "737777777777777777777777777777777777777777777777777UFEJ2CI",
"to": "737777777777777777777777777777777777777777777777777UFEJ2CI",
"amount": 1000000,
"fee": 1000,
"firstRound": 1,
"lastRound": 1000,
"genesisID": "mainnet-v1.0",
"genesisHash": "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiHc0CYz/uo="
}
}
})
Response
| Field | Type | Description |
|---|---|---|
header.status | string | success on completion |
body.command | string | signTransaction |
parameter.signature | string | Broadcast-ready signed transaction — the msgpack-encoded signed Algorand transaction (not a bare signature), ready to submit to an algod node. Same shape for both pay and axfer. |
{
"header": {
"status": "success"
},
"body": {
"command": "signTransaction",
"parameter": {
"signature": "<signed tx>"
}
}
}
Variant — ASA token transfer (axfer)
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.
payload.transaction:
{
"type": "axfer",
"assetIndex": 31566704,
"from": "737777777777777777777777777777777777777777777777777UFEJ2CI",
"to": "737777777777777777777777777777777777777777777777777UFEJ2CI",
"amount": 1000,
"fee": 1000,
"firstRound": 1,
"lastRound": 1000,
"genesisID": "mainnet-v1.0",
"genesisHash": "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiHc0CYz/uo="
}
| Field | Type | Required | Source | Description |
|---|---|---|---|---|
type | enum | Required | App | axfer for ASA token transfer |
assetIndex | number | Required-Real | App | On-chain ASA id (e.g. 31566704 = USDC, decimals 6) |
from | string | Required-Real | Wallet | Device account; must hold the ASA |
to | string | Required-Real | App | Recipient; must have opted in to the ASA |
amount | number | Required | App | Base units of the ASA (e.g. 1000 = 0.001 USDC) |
fee | number | Required | App | microAlgo (ASA fees are always paid in ALGO) |
ASA transfers must be signed on the Algorand mainnet chain — the USDC ASA (assetIndex 31566704) is registered only under the Algorand mainnet parent. Selecting another chain raises a lookup miss (-32602).
Variant — ASA descriptor
Always pass a form-D token descriptor instead of a bare axfer. The bridge builds the axfer envelope from token.contract (the ASA id), token.to and token.amount, so any assetIndex can be signed — including an unregistered one.
payload.transaction:
{
"token": {
"contract": "312769",
"to": "737777777777777777777777777777777777777777777777777UFEJ2CI",
"amount": "1000",
"decimals": 6,
"symbol": "USDt"
},
"from": "737777777777777777777777777777777777777777777777777UFEJ2CI",
"fee": 1000,
"firstRound": 1,
"lastRound": 1000,
"genesisID": "mainnet-v1.0",
"genesisHash": "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiHc0CYz/uo="
}
| Field | Type | Required | Source | Description |
|---|---|---|---|---|
token.contract | string | Required-Real | App | ASA id as a positive-integer string — must match /^[1-9][0-9]*$/ (non-numeric → -32602). Listing on the supported-token page not required. |
token.to | string | Required-Real | App | Recipient; must have opted in to the ASA |
token.amount | string | Required | App | Base units of the ASA (decimals applied for display) |
token.decimals / token.symbol | number / string | Optional | App | Display metadata synthesized when the ASA is unregistered |
from | string | Required-Real | Wallet | Device account (top-level) — must be present as a string, else the tx passes through unsigned |
fee / firstRound / lastRound / genesisHash | number / base64 | Required-Real | App | Real, current suggested-params values — the app must supply them; not auto-filled |
Response shape is the same broadcast-ready msgpack-encoded signTransaction as the pay / axfer variants — the descriptor only changes how the axfer is built, not the output. Sign on Algorand mainnet (slip44:283).
Common Mistakes
Amounts not in microAlgo — 1 ALGO = 1,000,000; the fee minimum is 1000 microAlgo. ASA recipient not opted in — an axfer to an account that has not opted in to the asset is rejected at broadcast. Wrong chain for an ASA — sign ASA transfers on Algorand mainnet, not on another network, or the asset lookup fails with -32602. Stale round window — firstRound/lastRound come from suggested params; an expired validity window is rejected.