Thanks to Bitcoin scripts (little programs specifying conditions under which a transaction is valid), people can come up with many sorts of never-seen before protocols. Multi-party escrows, “nash equilibrium” insurance deposits, rapidly adjusted micropayments, crowdfunding etc. All of these require multi-step actions from a user’s application which holds the private keys.

Today such applications are very simple: they only support sending and receiving money on “addresses”. Anything more complex is just not supported by general-purpose wallets. If one comes up with a new protocol, they either have to extend existing wallets, or make their own, or simply have a server doing the work (which defeats all the security promised by a decentralized protocol in the first place). These options involve basically redoing wallet and key management from scratch and introduce a lot of extra hassle for the users.

A good compromise between the impossible Most Universal Bitcoin Wallet and millions of specialized wallet apps would be a system of JavaScript plugins. Each plugin is a short single file of JavaScript code that is executed in a very restricted environment. Why JavaScript? It is the most ubiquitous scripting language with flexible implementations on most (if not all) major platforms.

A JavaScript plugin is cryptographically signed by multiple auditors and wallet app always verifies the integrity of each plugin when executing one. Every plugin can only be invoked explicitly by the user. The wallet, not the plugin, shows a summary of what is about to happen (“you are going to send 0.34 BTC in this transaction”). A single plugin is invoked when a particular kind of contract is initiated or needs an update. Plugin state is not only isolated from other plugins, but from each contract as well.

This is how it may look like. Take for a example a simple escrow. You send money to 2-of-3 multisignature script, where two keys belong to you and your counterparty and the third key belongs to a semi-trusted third party which may act as an arbiter if needed. When the contract is completed, depending on the result, user must be able to provide a signature for a particular outcome (either money goes to a counterparty, or back to the user, or only a portion is refunded).

The plugin may implement this by using two kinds of inputs: creation of a contract and completion of the contract. For each state, plugin checks the integrity of the data (e.g. “contract can be completed only if it was started by me in the first place”) and provides data with compact informational messages to the user. Plugin does not implement the UI. It should be done by an external application or a website with which the user interacts. For confirmation of the action, plugin can only provide compact description like “Unlock 100% of funds to Buyer Inc.?” or “Refund 90% to your address 1RefuNd3eBnt66345…?” Once confirmed, the result is sent back to the application that requested participation in the contract.

For security reasons, plugins should be very compact, easy to read and understand, not use dynamically linked external libraries, not have any access to external devices, file system, network etc. A plugin may be bundled with static data like images or localization strings, all covered by the code signature and verified by the wallet application on each run.

More details on how this could be done and what the API may look like will follow.