제한과 오류
제한
| 항목 | 제한 |
|---|---|
| 스캔당 QR 프레임 수 | 2,048 (BBQr: 1,295) |
| 프레임당 문자 수 | 4,300 |
| 세션당 보관하는 스캔 텍스트 | 1 MiB |
| 디코딩된 페이로드(CBOR 또는 PSBT) | 128 KiB |
| CBOR 중첩 / 항목 | 24단계 / 20,000개 |
| 지갑 레벨 페어링 페이로드(생성 시) | 4,096바이트 |
| 요청 ID | 16바이트 (eth-sign-request: 1–64) |
| Origin | 256자 |
| Bitcoin 입력과 출력 | 각각 1–100개 |
| EVM calldata | 64 KiB |
| EVM 개인 메시지 | 1–8,192바이트 |
| EIP-712 | 타입 32개, 타입당 필드 64개, 배열 최대 128개 항목 |
| TRON 메시지 | 1–8,192바이트 |
| Solana 메시지(sign-type 2) | UTF-8 텍스트 1–1,024바이트 |
| Solana 트랜잭션 | 명령어 1–64개, 1,232바이트 패킷 |
자주 보는 거부 메시지
BitTool Signer가 요청을 거부하면 스캐너나 검토 화면에 짧은 메시지를 표시합니다. 연동 개발자가 가장 자주 만나는 메시지는 다음과 같습니다.
| 메시지 | 원인 | 해결 방법 |
|---|---|---|
| Unsupported signing UR type | UR 타입이 crypto-psbt, psbt, eth-sign-request, sol-sign-request, tron-sign-request 중 하나가 아님 | 공개 레지스트리 타입을 사용하세요. 페어링 QR 코드는 서명할 수 없습니다 |
| Unsupported signing request field | 맵 키가 1–7(ETH) 또는 1–6(SOL/TRON) 범위를 벗어남 | 사용자 정의 필드를 제거하세요 |
| Invalid request UUID tag / requestId has invalid length | 요청 ID가 태그 37로 감싸져 있지 않거나, SOL/TRON에서 16바이트가 아님 | 37(16 random bytes) |
| Signing path must be concrete | * 와일드카드, 빈 자식, 또는 231 이상의 인덱스 | true/false 강화 플래그를 포함한 전체 리프 경로를 보내세요 |
| Transaction data type does not match payload | 타입 트랜잭션에 data-type 1을 쓰거나, legacy RLP에 4를 씀 | legacy RLP는 1, 0x01/0x02 엔벨로프는 4 |
| Unprotected or missing-chain-ID EVM transactions are refused | EIP-155 체인 ID가 없는 legacy 트랜잭션 | 체인 ID를 넣어 직렬화하세요(v = chainId, r = s = 0) |
| Chain ID does not match the signing request | 트랜잭션, 키 4, EIP-712 도메인의 값이 서로 다름 | 모든 체인 ID를 일치시키세요 |
| Unsupported network | 지원하는 8개 EVM 네트워크 밖의 체인 ID, 또는 메인넷이 아닌 요청 | 지원 네트워크를 사용하세요 |
| Typed message has extra unsigned or missing fields | message 필드가 선언된 타입과 다름 | 선언된 필드만 정확히 보내세요 |
| Use strings for large typed integers | EIP-712 데이터에 253를 넘는 JSON 숫자가 있음 | 10진수 문자열로 인코딩하세요 |
| Full previous transactions (nonWitnessUtxo) are required … | nonWitnessUtxo가 없는 SegWit v0 또는 legacy 입력 | 이전 트랜잭션 전체를 추가하세요 |
| Only SIGHASH_ALL or Taproot SIGHASH_DEFAULT is accepted | 입력에 다른 sighash 타입이 있음 | SIGHASH_ALL을 사용하세요 |
| No unsigned input belongs to this wallet … | 이 지갑의 키에 대한 bip32Derivation이 있는 입력이 없음 | 올바른 지문과 경로로 파생 데이터를 추가하세요 |
| Exactly one TRON contract is supported per transaction | raw_data.contract에 항목이 0개이거나 여러 개임 | 트랜잭션당 컨트랙트 하나 |
| TRON contract calls require an explicit fee limit | fee_limit이 없는 TriggerSmartContract | fee_limit을 설정하세요 |
| Invalid TRON timestamp or expiration | timestamp가 없거나, expiration ≤ timestamp | 노드에서 받은 값을 사용하세요 |
| Address lookup tables require independently trusted account data … | 조회 테이블을 사용하는 v0 Solana 메시지 | 정적 계정 키로 컴파일하세요 |
| This wallet is not a required signer in the transaction | 키 4가 메시지의 필수 서명자에 없음 | 서명해야 하는 계정을 사용하세요 |
| Solana message prefix could represent a transaction header | 트랜잭션처럼 보이는 바이트에 sign-type 2를 사용함 | 트랜잭션에는 sign-type 1을 사용하세요 |
| Mixed UR fountain sessions / Multiple unrelated QR payloads | 한 번의 스캔에 서로 다른 두 QR 코드의 프레임이 섞임 | 한 번에 요청 하나만 표시하세요 |
오류 문구는 엔진 자체 검사에서만 나옵니다. 예상치 못한 예외는 일반 오류로 보고되므로, 악의적인 페이로드가 서명 기기 인터페이스에 임의의 텍스트를 주입할 수 없습니다.
매칭 결과
비밀번호 입력 화면이 나오기 전에 요청을 iPhone의 지갑들과 매칭합니다. 서명할 수 있는 상태는 ready뿐입니다.
| 상태 | 의미 |
|---|---|
ready | 정확히 하나의 지갑이 키를 보유하며, 서명 작업이 확정됨 |
noMatch | 이 iPhone의 어떤 지갑에도 요청한 키가 없음(지문이나 경로가 틀렸거나, 지갑을 가져오지 않음) |
missingSigner | 요청에 어떤 키로 서명할지 나와 있지 않음(파생 데이터도 주소도 없음) |
ambiguous | 둘 이상의 지갑이 해당됨(예: 같은 문구를 두 번 가져온 경우) |
setupRequired | 지갑의 공개 데이터를 다시 만들어야 함(비밀번호 한 번 입력) |
invalid | 요청의 구조가 유효하지 않음 |