Wallet Guide

Authoritative source

Guide for adding AOPP support to a wallet

Register AOPP URI handler

The app needs to register itself as an AOPP URI handler in the OS.

Sample URI

aopp:?v=0&msg=hello&asset=btc&format=p2wpkh&callback=https://api.testing.21analytics.xyz/proofs/vasp-chosen-token

Android

https://developer.android.com/guide/topics/manifest/intent-filter-element

Linux

See this example.

Windows

See this example.

iOS

https://celsiusnotes.com/url-schemes-in-ios/

If more than one app registers to handle the same URI scheme (e.g aopp: or also bitcoin:) there is no way to tell which app will be opened by iOS (see https://stackoverflow.com/a/13130477).

macOS

Add the following to your plist file:

<key>CFBundleURLTypes</key>
<array>
	<dict>
		<key>CFBundleURLName</key>
		<string>com.example.wallet</string>
		<key>CFBundleURLSchemes</key>
		<array>
			<string>aopp</string>
		</array>
	</dict>
</array>

Docs on how to handle the URI: https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app

Handle AOPP URIs via QR-code scanning

That only makes sense for mobile wallets.

Generate new address/pubkey

Generate a new address that follows the format from the AOPP URI format query string. Only addresses from compressed pubkeys are supported.

Sign msg from query string

In the AOPP URI, the msg query string contains the message to be signed using Bitcoin's sign message algorithm, i.e. this one.

Example with bitcoinjs-message

Note the omission of a segwit specifier for all address types.

const bitcoinMessage = require('bitcoinjs-message')
bitcoinMessage.sign(message, privateKey, keyPair.compressed)

Send result

Send result to the callback obtained from the AOPP URI callback query string. It should be a POST request with the following JSON body.

{
    "version": 0,
    "address": "address generated above",
    "signature": "signature created above"
}

The signature should be base64-encoded.

Implementation Playground

An end-user-facing webapp is made available for testing here.

You can see when your address has been registered in the 21 Analytics software stack, which features an AOPP-compatible backend: https://testing.21analytics.xyz/aopp

Username: admin

Password: admin

The logs of the docker AOPP backend container running on the server (for debugging) are available here: http://testing.21analytics.xyz:8888

Reference Implementation

There is a fork of the popular desktop wallet Electrum with built-in support for AOPP available here: https://gitlab.com/aopp/electrum

Open Source Wallets with AOPP Support

  • BlueWallet
    • Pull Request: https://github.com/BlueWallet/BlueWallet/pull/2915
  • Bitbox
    • Pull Requests: https://github.com/digitalbitbox/bitbox-wallet-app/pulls?q=is%3Apr+aopp+is%3Aclosed
    • Code (excluding the URI registration): https://github.com/digitalbitbox/bitbox-wallet-app/blob/master/backend/aopp.go
  • Sparrow Wallet
    • Code: https://github.com/sparrowwallet/sparrow/commit/425e476f202273dcc4e721a3aa92defca31196f4