Skip to main content

NEAR (NEAR)

Sign NEAR Protocol transactions. A plain transfer carries an amount in yoctoNEAR; NEP-141 tokens and NEP-171 NFTs are sent as FunctionCall actions with a JSON args object. The bridge signs with no network access — it looks nothing up and refreshes nothing, so you must send a complete transaction: supply blockHash, nonce and fee yourself — a missing one fails with -32602. publicKey is optional (the bridge derives it offline from the signing key), but a publicKey that does not match that derived key is rejected the same way.

FieldValue
FamilyNEAR
coinType397
keyPathm/44'/397'/<accountIdx>'
amount unityoctoNEAR
chainIdnear:mainnet/slip44:397

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

Firmware versions below are for the DCENT Biometric Wallet line — DCENT X supports them from 1.0.0. NEAR token (not native NEAR) requires firmware 2.27.1 or higher.

getAddress — account address

Retrieves the NEAR account for a chainId + keyPath. Call it before building transactions. NEAR has no address variants, so addressFormat is not used. The value returned is the implicit account id — the 64-character lowercase hex encoding of the ed25519 public key. Named accounts (e.g. name.near) are created on top of this key on-chain.

FieldTypeRequiredSourceDescription
chainIdstringRequiredAppnear:mainnet/slip44:397 (CAIP-19)
keyPathstringRequiredAppBIP-44; default m/44'/397'/0'

Request

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

Response

FieldTypeDescription
header.statusstringsuccess on success
body.commandstringgetAddress
body.parameter.addressstringNEAR implicit account id — the 64-character lowercase hex of the ed25519 public key
{
"header": {
"version": "1.0",
"status": "success"
},
"body": {
"command": "getAddress",
"parameter": {
"address": "9c1d…"
}
}
}
info

Address format: a NEAR implicit account id is the raw ed25519 public key rendered as 64 lowercase hex characters (no 0x prefix). It is also the value the device signs with — the same key appears in signTransaction as publicKey in ed25519: base58 form.

signTransaction — <NEAR transaction>

Variant — native transfer

FieldTypeRequiredSourceDescription
typeenumRequiredApptransfer
senderstringRequired-RealWalletDevice NEAR account (e.g. name.near); must exist on-chain
recipientstringRequiredAppRecipient account id
amountstringRequiredAppyoctoNEAR; 1 NEAR = 1e24
blockHashstringRequired-RealAppRequired — the app must supply a fresh value (otherwise param_error)
feestringRequired-RealAppTotal fee in yoctoNEAR. Mapped to the device's fee display; omitting it fails with -32602
publicKeystringOptionalAppSender's access-key public key (ed25519: base58). The bridge derives it offline from the signing key, so you may omit it; if you do send it and it disagrees with the derived value the request fails with -32602

Request

await dcent.sign({
method: 'signTransaction',
chainId: 'near:mainnet/slip44:397',
payload: {
keyPath: "m/44'/397'/0'",
transaction: {
"type": "transfer",
"family": "near",
"symbol": "NEAR",
"decimals": 24,
"sender": "sender.near",
"recipient": "receiver.near",
"amount": "1000000000000000000000000",
"blockHash": "GJp9NRJGBnXqWJAKFxkzD8p9cJTiSNi1J3UWKVBbcfRw",
"nonce": 0,
"fee": "100000000000000000000"
}
}
})

Response

{
"header": {
"status": "success"
},
"body": {
"command": "signTransaction",
"parameter": {
"signature": "ed25519:…"
}
}
}

Response fields

FieldTypeDescription
header.statusstringsuccess on success
body.commandstringsignTransaction
body.parameter.signaturestringThe ed25519 signature (base58, ed25519: prefix) the device produced over the borsh-encoded NEAR transaction hash. Combine it with the transaction to assemble the borsh-serialized SignedTransaction, then broadcast via broadcast_tx_commit. Returned identically for the native, NEP-141, and NEP-171 variants below.

Variant — NEP-141 token (ft_transfer)

info

Token model: form-D descriptor. Always send the token under transaction.token with its symbol and trustworthy decimals (read from the chain yourself) — the bridge signs with no network access and never looks symbol / decimals up, so without the descriptor it fails closed with -32602. See Core Concepts → Token descriptors.

Token transfers use the near-api-js Transaction shape (signerId / receiverId / actions[]). The bridge converts the FunctionCall action into a contract call. receiverId is the token contract account and args is a plain JSON object (not base64).

FieldTypeRequiredSourceDescription
signerIdstringRequired-RealWalletDevice NEAR account; must exist on-chain
receiverIdstringRequired-RealAppToken contract account (e.g. usdt.tether-token.near)
actions[].params.methodNamestringRequiredAppft_transfer
actions[].params.argsobjectRequiredApp{ receiver_id, amount }; amount in token base units
actions[].params.gasstringRequiredAppe.g. "30000000000000" (30 TGas)
actions[].params.depositstringRequiredApp"1" yoctoNEAR (NEP-141 security requirement)
blockHash / noncestring / numberRequired-RealAppRequired — the app must supply a fresh value (otherwise param_error)
feestringRequired-RealAppTotal fee in yoctoNEAR. Omitting it fails with -32602

Request

await dcent.sign({
method: 'signTransaction',
chainId: 'near:mainnet/slip44:397',
payload: {
keyPath: "m/44'/397'/0'",
transaction: {
"signerId": "sender.near",
"receiverId": "usdt.tether-token.near",
"actions": [
{
"type": "FunctionCall",
"params": {
"methodName": "ft_transfer",
"args": {
"receiver_id": "receiver.near",
"amount": "1000000"
},
"gas": "30000000000000",
"deposit": "1"
}
}
],
"blockHash": "GJp9NRJGBnXqWJAKFxkzD8p9cJTiSNi1J3UWKVBbcfRw",
"nonce": 0,
"fee": "100000000000000000000"
}
}
})
info

USDT on NEAR has 6 decimals, so amount: "1000000" = 1 USDT. The token base unit is unrelated to yoctoNEAR — only the deposit is in yoctoNEAR.

info

Unregistered FT tokens. Send the token as a form-D descriptortransaction.token = { contract, to, amount, decimals, symbol } — and the bridge builds the ft_transfer from it and synthesizes the token screen (e.g. USDC 1.0 → receiver.near). The bridge does not query ft_metadata over RPC: it signs with no network access, so the decimals you supply are what the device shows. There is no silent native fallback — without the descriptor the resolver loud-fails with -32602 rather than signing raw calldata. Playground preset: near-ft-transfer-unregistered.

Variant — NEP-171 NFT (nft_transfer)

Same FunctionCall path; receiverId is the NFT contract account and args carries { receiver_id, token_id }.

Request

await dcent.sign({
method: 'signTransaction',
chainId: 'near:mainnet/slip44:397',
payload: {
keyPath: "m/44'/397'/0'",
transaction: {
"signerId": "sender.near",
"receiverId": "nft.contract.near",
"actions": [
{
"type": "FunctionCall",
"params": {
"methodName": "nft_transfer",
"args": {
"receiver_id": "receiver.near",
"token_id": "1"
},
"gas": "30000000000000",
"deposit": "1"
}
}
],
"blockHash": "GJp9NRJGBnXqWJAKFxkzD8p9cJTiSNi1J3UWKVBbcfRw",
"nonce": 0,
"fee": "100000000000000000000"
}
}
})

Common Mistakes

danger

Sender not on-chain — the bridge never reads the sender's access key (it derives the public key offline and makes no RPC call), so signing still succeeds; the transaction is rejected later, at broadcast, because the account has no matching access key. Wrong network — a mainnet account does not exist on testnet (and vice-versa); select the network that matches the account you signed up. Amounts not in yoctoNEAR — native transfer amount uses 1 NEAR = 1e24; NEP-141 args.amount uses the token's own base units. Missing FunctionCall deposit — NEP-141/171 transfers require exactly "1" yoctoNEAR, and args must be a JSON object (not base64).