Skip to content

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

2 watching

Forks

Repository files navigation

KeystoneSDK

Signing API changes

The legacy keystone-sign-request / keystone-sign-result APIs have been removed. Use TRON Native for TRON and PSBT Extend for LTC, BCH, DASH and DOGE. These protocols require different transaction inputs and response handling; they are not drop-in replacements. Integrations that still require the removed APIs must pin an earlier SDK version.

A swift package of KeystoneSDK. It's based on KeystoneSDK which is generated by keystone-sdk-rust

Installation

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler.
To add KeystoneSDK as a dependency to your Xcode project, select File > Add Packages and enter URL: https://github.com/KeystoneHQ/keystone-sdk-ios.git.

PSBT Extend

Use generatePSBTExtend and parsePSBTExtend for the crypto-psbt-extend UR type. These APIs require the sdk-0.2.5 binary dependency or later.

Generate QR fragments

Pass the raw PSBT bytes as Data:

import Foundation
import KeystoneSDK

let sdk = KeystoneSDK()
let psbtData = try Data(contentsOf: psbtFileURL) // URL of your PSBT file

// Litecoin. Display successive fragments as QR codes for the device to scan.
let encoder = try sdk.btc.generatePSBTExtend(psbt: psbtData, coinId: 2)
let qrFragment = encoder.nextPart()
// Call encoder.nextPart() again for each subsequent QR frame.

// Bitcoin: omit coinId, or pass 0. The coin field is omitted from the payload.
let bitcoinEncoder = try sdk.btc.generatePSBTExtend(psbt: psbtData)
Coin coinId
Bitcoin 0 (default)
Litecoin 2
Dogecoin 3
Dash 5
Bitcoin Cash 145

coinId is an Int32. Unsupported values throw KeystoneError.generatePSBTError.

Parse scanned QR fragments

Reuse the same KeystoneSDK instance across frames so the decoder can assemble multipart URs:

// Call for each scanned QR string, using the sdk instance above.
func receivePSBTExtendFragment(_ qrString: String) throws -> PSBTExtend? {
    let decoded = try sdk.decodeQR(qrCode: qrString)
    guard let ur = decoded.ur else {
        return nil // More fragments are needed.
    }

    defer { sdk.resetQRDecoder() }
    return try sdk.btc.parsePSBTExtend(ur: ur)
}

// Inside your scanner callback:
if let result = try receivePSBTExtendFragment(scannedQRCode) {
    let psbt: Data = result.psbt
    let coinId: Int32? = result.coinId // nil means Bitcoin.
    // Pass psbt and coinId to your transaction handling code.
}

If you already have a decoded UR, call sdk.btc.parsePSBTExtend(ur: ur) directly. A different UR type throws QRCodeError.unexpectedQRCode; an invalid Extend payload throws KeystoneError.parsePSBTError.

For ordinary crypto-psbt URs, continue using generatePSBT(psbt:) and parsePSBT(ur:).

How to update the binary library URRegistryFFI

  1. Install Rust https://www.rust-lang.org/learn/get-started

  2. Clone the rust repo.

git clone https://github.com/KeystoneHQ/keystone-sdk-rust
cd keystone-sdk-rust
  1. Install ios targets
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
  1. Generate XCFramework

Make sure the header file keystone-sdk-rust/include/URRegistryFFI/lib_ur_registry_ffi.h is up to date.

make generate_xcframework
  1. Replace the URRegistryFFI.xcframework in URRegistry/Library from the target build folder

TRON native signing

Use sdk.tronNative. The URRegistryFFI dependency is pinned to sdk-0.2.6, which includes generate_tron_native_sign_request and parse_tron_native_signature. Native TRON signing requires this release or a compatible later version.

Generate a request

import Foundation
import KeystoneSDK

let sdk = KeystoneSDK()
let requestId = UUID().uuidString.lowercased()
// transactionRawDataHex is the unsigned transaction's raw_data_hex.
// deviceXfp is the master fingerprint obtained when connecting the device.
let request = TronNativeSignRequest(
    requestId: requestId,
    signData: transactionRawDataHex,
    path: "m/44'/195'/0'/0/0",
    xfp: deviceXfp,
    dataType: 1,
    origin: "My Wallet"
)
let encoder = try sdk.tronNative.generateSignRequest(tronSignRequest: request)
let qrFragment = encoder.nextPart()
// Display successive encoder.nextPart() values as QR frames.

Parse the response

Keep the same SDK instance while scanning a multipart response:

enum SigningResponseError: Error { case unexpectedRequest }

func receiveTronFragment(_ qr: String) throws -> Signature? {
    let decoded = try sdk.decodeQR(qrCode: qr)
    guard let ur = decoded.ur else { return nil }
    defer { sdk.resetQRDecoder() }
    let result = try sdk.tronNative.parseSignature(ur: ur)
    guard result.requestId.lowercased() == requestId else {
        throw SigningResponseError.unexpectedRequest
    }
    return result // result.signature is hex.
}

Invalid requests or responses throw. If you already have a decoded UR, call sdk.tronNative.parseSignature(ur: ur) directly.

Request parameters

Parameter Meaning
requestId A new UUID for each signing request. Match the response UUID before using its signature.
signData Hex with or without a 0x / 0X prefix; the SDK strips the prefix before validation and encoding. For dataType = 1, use the serialized TRON transaction raw_data (raw_data_hex), not JSON, a full signed transaction, or a transaction hash. For dataType = 2, use the original personal-message bytes encoded as hex.
path Signing derivation path, for example m/44'/195'/0'/0/0.
xfp The connected device's master fingerprint: exactly 8 hex characters.
dataType 1 = transaction (default in mobile SDKs); 2 = personal message.
address Optional TRON Base58Check address; an empty string omits it.
origin Optional wallet/application name; an empty string omits it.

signData must contain 1–32768 bytes. path is limited to 256 bytes and origin to 128 UTF-8 bytes.

The request UR type is tron-sign-request; the response UR type is tron-signature. The response contains requestId and a 65-byte signature encoded as hex. It does not contain a signed transaction or transaction ID. For transactions, retain the original transaction, verify the response request ID and signature against the intended signer, then attach the signature to that transaction before broadcasting. Parsing does not perform that cryptographic verification or broadcast.

Use a firmware version that supports the native TRON UR types.

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages