Web3 API Extensions

The Keycard wallet behaves like a regular hardware wallet and thus dApps can use it transparently as any other account. The Cash applet however, not being associated to a wallet and not being suitable to sign transactions (since it does not hold funds), must be specifically supported by dApps supporting it, usually to sign EIP-712 formatted metatx. For this reason we defined some extensions to the Web3 API. At the moment, these are supported by the Status app. The specifications in this page are both for dApps developers wanting to support Keycard Cash in their dApp as well as for wallet app developers wanting to implement these extensions.

EIP-712 signing

Support for this is provided by a single function: keycard_signTypedData(data).

This function takes the EIP-712 data in the same format as eth_signTypedData and returns a signature generated by the tapped Keycard Cash. Unlike eth_signTypedData there is no address argument because the address will be that of the Cash applet of whatever Keycard is tapped by the user. The returned signature can then be sent, together with the message data, to an EIP-712 compatible smartcontract by the dApp. Assuming the Web 3.0 browser runs on a smartphone, calling this function will cause a pop-up to appear on the phone prompting to tap the Keycard. Since the function has all of the data being signed available, the screen can display this data in a user friendly way. In Status, messages for some specific smartcontracts are recognized and a custom UI is shown. These UX concern are not part of the specification itself, but implementers may want to consider this approach.

In order to generate the signature using Keycard Cash, browsers implementing this function should hash the message data using keccak256, listen on the NFC interface and send the hash to the Keycard Cash applet which will return a signature. More details can be found in the Cash applet section of this site.

This function only returns a signature. If your dApp requires knowing the address of the signer you can use recoverTypedSignature(data, sig) from the eth-sig-util package.

Implementation notes

This section explains some UX choices adopted by Status when implementing the keycard_signTypedData(data) in the browser. While these are not part of the specifications, it helps to visualize what happens when a dApp invokes this function and can be used by both web3 browser devs and dApp developers as a reference.

The idea behind’s Status implementation, is to have a generic way to display these transactions, but if it finds specific fields in the data to sign then try to show a more user friendly interface. The generic screen looks like this

Generic EIP-712 screen

Clicking on the “Show transaction data” brings up something like this

Generic EIP-712 deta screen

When however the data to be signed contains uint256 amount and address currency among its fields this is interpreted as a payment transaction, and the following screen is shown instead.

EIP-712 ERC20 screen

If the currency field address is considered to be the address of an ERC20 token. If this address is zero, the amount is interpreted as plain ETH. This transaction format is used by the Keycard Payment Network project.

Another example of a custom screen, is the one displayed for the Keycard Redeem project. In this case we recognize the address recipient and bytes32 code field as a redeem request and we display the recipient field address clearly in the signature screen. If the recipient field in account managed by Status, instead of the plain address, the account name is shown. See screenshot below

EIP-712 ERC20 screen

One thing to keep in mind however, is that these custom screens are only there to provide better UX for some specific use case we are aware of. Any unrecognized message format can still be displayed generically and signed. If you are implementing a web3 browser you can adopt any strategy you prefer on this. Conversely, if you are developing SmartContract and dApps, you might want consider naming the fields of the message in a way that will trigger a specific interface on a browser. For example if your use case scenario involve transferring a certain amount of currency in a transaction, naming the message fields like that will show an easy to understand screen in Status.