Securely Signing Transactions with TezosKit

Keefer Taylor
3 min readApr 15, 2020

TezosKit is a Swift SDK that enables Tezos applications to be developed on Apple products, including iOS, macOS and iPadOS. TezosKit’s recent update allows developer to take advantage of the Secure Enclave and Keychain to securely store keys and sign transactions on iOS and macOS devices.

Previously, I’ve written about the benefits of using this technology. On device key storage and biometric authentication provides unparalleled security and safety to users. Additionally, Tezos’ smart contract properties position the network uniquely to use the Secure Enclave by creating a fail safe for key recovery and setting spending limits.

This work is completed as part of the Tezos Foundation’s generous grant. As the final component of our grant, TezosKit will undergo a security audit to verify the resiliency and security of the library and the cryptographic key storage implementations.

For those who are technically curious, let’s jump into some code.

TezosKit utilizes an abstraction called a SignatureProvider in order to manage keys. A SignatureProvider is an opaque object which can sign transactions and provide access to the associated public key.

/// An opaque object which implements public key cryptography functions.
public protocol SignatureProvider {
var publicKey: PublicKeyProtocol { get }
func sign(_ hex: String) -> [UInt8]?
}

Conceptually, a signature provider provides the authorization to perform an operation. Any time TezosKit attempts to perform an operation, a SignatureProvider is passed with the arguments. Separating the authorization from the source of the operation allows abstractions around signing. For instance, a key could be stored in memory, on disk, accessible via a remote RPC or in a hardware security module.

Up until now, TezosKit only provided one implementation of this abstraction: a Wallet class which stored keys in memory on a device. Developers could send XTZ between accounts using just a few lines of code:

// Create a new client to interact with a Tezos node.
let nodeClient = new TezosNodeClient(…)
// Generate a new wallet that holds keys.
let wallet = new Wallet(mnemonic: “abandon ability able …”)
// Send the transaction
//
// Pass wallet as signatureProvider, which makes wallet the
// signer of this transaction.
nodeClient.send(
amount: Tez(1.0),
to: “tz1NBAfG9MpKxxWpaAXa52Y9XYh6Wdv77xG7”,
from: wallet.address,
signatureProvider: wallet
operationFeePolicy: .estimate
)

TezosKit has introduced two new implementations of the SignatureProvider abstraction to increase security of key handling:

Since all classes (Wallet, SecureEnclaveWallet and KeychainWallet) all conform to the same interface these implementations can be swapped. For instance, only one line of code needs to be changed in the above code to use a key pair stored in the Secure Enclave rather than memory:

// Create a new client to interact with a Tezos node.
let nodeClient = new TezosNodeClient(…)
// Generate a new wallet that holds keys.
let wallet = new SecureEnclaveWallet(prompt: “Authorize signing with key in Secure Enclave?”)
// Send the transaction
//
// Pass wallet as signatureProvider, which makes wallet the
// signer of this transaction.
nodeClient.send(
amount: Tez(1.0),
to: “tz1NBAfG9MpKxxWpaAXa52Y9XYh6Wdv77xG7”,
from: wallet.address,
signatureProvider: wallet
operationFeePolicy: .estimate
)

TezosKit continues to make it easier and easier for developers to build on Tezos applications on mobile. Secure key storage is another step in the right direction.

Want to build for Tezos on the iOS or MacOS Platform? TezosKit is a Swift library that provides a client-side SDK for the Tezos blockchain on iOS, MacOS and iPadOS. You can get started here. Curious about where to start? Get in touch.

--

--