Skip to main content
Zondax Github LinkZondax Github Link
Theme SwitchTheme Switch

Stacks App

General structure

The general structure of commands and responses is as follows:

Commands

FieldTypeContentNote
CLAbyte (1)Application Identifier0x09
INSbyte (1)Instruction ID
P1byte (1)Parameter 1
P2byte (1)Parameter 2
Lbyte (1)Bytes in payload
PAYLOADbyte (L)Payload

Response

FieldTypeContentNote
ANSWERbyte (?)Answerdepends on the command
SW1-SW2byte (2)Return codesee list of return codes

Return codes

Return codeDescription
0x6400Execution Error
0x6982Empty buffer
0x6983Output buffer too small
0x6986Command not allowed
0x6D00INS not supported
0x6E00CLA not supported
0x6F00Unknown
0x9000Success

Command definition

GET_VERSION

Command

FieldTypeContentExpected
CLAbyte (1)Application Identifier0x09
INSbyte (1)Instruction ID0x00
P1byte (1)Parameter 1ignored
P2byte (1)Parameter 2ignored
Lbyte (1)Bytes in payload0

Response

FieldTypeContentNote
TESTbyte (1)Test Mode0xFF means test mode is enabled
MAJORbyte (1)Version Major
MINORbyte (1)Version Minor
PATCHbyte (1)Version Patch
LOCKEDbyte (1)Device is locked
SW1-SW2byte (2)Return codesee list of return codes

INS_GET_ADDR_SECP256K1

Command

FieldTypeContentExpected
CLAbyte (1)Application Identifier0x09
INSbyte (1)Instruction ID0x01
P1byte (1)Request User confirmationNo = 0
P2byte (1)Parameter 2ignored
Lbyte (1)Bytes in payload(depends)
Path[0]byte (4)Derivation Path Data0x8000002c
Path[1]byte (4)Derivation Path Data0x8000167d
Path[2]byte (4)Derivation Path Data?
Path[3]byte (4)Derivation Path Data?
Path[4]byte (4)Derivation Path Data?

Response

FieldTypeContentNote
PKbyte (65)Public Key
ADDR_RAW_LENbyte (1)ADDR_RAW Length
ADDR_RAWbyte (??)Address as Raw Bytes
ADDR_HUMAN_LENbyte (1)ADDR_HUMAN Len
ADDR_HUMANbyte (??)Address as String
SW1-SW2byte (2)Return codesee list of return codes

INS_GET_AUTH_PUBKEY

Command

FieldTypeContentExpected
CLAbyte (1)Application Identifier0x09
INSbyte (1)Instruction ID0x03
P1byte (1)Retrieval mode0 (Only retrieve)
P2byte (1)Parameter 20 (ignored)
Lbyte (1)Bytes in payload(depends)
Pathbyte (?)Derivation Path Data(see below)
Derivation Path
  • Starts with "m"
  • Can be either 6 or 4 levels deep
  • For 6 levels: "m/44'/5757'/5'/0/3"
  • For 4 levels (Identity): "m/888'/0'/<account>"
  • Each level is serialized as a 4-byte little-endian unsigned integer
  • Hardened levels (with ') have 0x80000000 added to their value

Response

FieldTypeContentNote
publicKeybyte (??)Public Key
addressbyte (??)Address as String
SW1-SW2byte (2)Return code0x9000 for success

Processing

  1. The command is sent with the serialized derivation path as payload.
  2. The device derives the public key and address for the given path.
  3. The device returns the public key and address in the response.

Notes

  • The CLA (0x09) is specific to this application.
  • The INS (0x03) identifies this as a GET_AUTH_PUBKEY operation.
  • P1 is set to 0, indicating "only retrieve" mode.
  • P2 is ignored in this command.
  • The expected successful return code is 0x9000.
  • In case of an error, the response will include a return code and an error message instead of the public key and address.

INS_SIGN_SECP256K1

Command

FieldTypeContentExpected
CLAbyte (1)Application Identifier0x09
INSbyte (1)Instruction ID0x02
P1byte (1)Payload desc0 = init
1 = add
2 = last
P2byte (1)----not used
Lbyte (1)Bytes in payload(depends)

The first packet/chunk includes only the derivation path

All other packets/chunks contain data chunks that are described below

First Packet

FieldTypeContentExpected
Path[0]byte (4)Derivation Path Data0x8000002c
Path[1]byte (4)Derivation Path Data0x8000167d
Path[2]byte (4)Derivation Path Data?
Path[3]byte (4)Derivation Path Data?
Path[4]byte (4)Derivation Path Data?

Other Chunks/Packets

FieldTypeContentExpected
Databytes...Message

Data is defined as:

FieldTypeContentExpected
Messagebytes..Data to sign

Response

FieldTypeContentNote
secp256k1 Rbyte (32)Signature
secp256k1 Sbyte (32)Signature
secp256k1 Vbyte (1)Signature
SIGbyte (variable)SignatureDER format
SW1-SW2byte (2)Return codesee list of return codes

INS_SIGN_JWT_SECP256K1

Command

FieldTypeContentExpected
CLAbyte (1)Application Identifier0x09
INSbyte (1)Instruction ID0x04
P1byte (1)Chunk index1 to N
P2byte (1)Total chunksN
Lbyte (1)Bytes in payload(depends)
Pathbyte (?)Derivation Path Data(see below)
Messagebyte (?)JWT message to sign(variable)
Derivation Path
  • Starts with "m"
  • Can be either 6 or 4 levels deep
  • For 6 levels: "m/44'/5757'/5'/0/3"
  • For 4 levels (Identity): "m/888'/0'/<account>"
  • Each level is serialized as a 4-byte little-endian unsigned integer
  • Hardened levels (with ') have 0x80000000 added to their value

Response

FieldTypeContentNote
returnCodebyte (2)Return codesee list of return codes
errorMessagebyte (??)Error message stringOptional
postSignHashbyte (32)Hash after signingOptional
signatureCompactbyte (65)Compact signatureOptional
signatureDERbyte (??)DER-encoded signatureOptional

Processing

  1. The message is split into chunks of up to 250 bytes each.
  2. Each chunk is sent in a separate APDU command.
  3. P1 indicates the current chunk index (starting from 1).
  4. P2 indicates the total number of chunks.
  5. The first chunk includes the derivation path.
  6. Subsequent chunks only contain message data.
  7. The device processes all chunks and returns the final result.

Notes

  • The CLA (0x09) is specific to this application.
  • The INS (0x04) identifies this as a SIGN_JWT_SECP256K1 operation.
  • The message length is determined by the total payload across all chunks.
  • Error responses may not include all fields of the success response.