TIP-32 - TON provider javascript API

Summary

A JavaScript TON Provider API for consistency across clients and applications.

Abstract

A common convention in the TON web application (“DApp”) ecosystem is for key
management software (“wallets”) to expose their API via a JavaScript object in the web
page. This object is called “the Provider”.

The Provider implementations can have conflicting interfaces and behaviors between
wallets. This TIP formalizes an TON Provider API to promote wallet interoperability. The
API is designed to be minimal, event-driven, and agnostic of transport. Its functionality
is easily extended by defining new methods and message event types.

Offer for all providers to make available their features as window.ton in web browsers
for uniformity.

Motivation

Many teams have created their own solutions during recently conducted the 1st round of Contest on TON wallet as Chrome web extension. This proposal sets as the main aim to work
out an agreement for the Web3 like provider interface to avoid any artificial situation
when DApp developers can be forced to use only the one wallet on the market. Offer to
introduce the uniform Web3 like provider interface and implement its on 3rd stage the
contest to allow users using any wallet solution for decentralized applications (DApp)
interaction aims.

Specification

The last co-worked result will be posted here after resolving all proposals.

3 Likes

That’s great proposal, thanks for your work, @logvik!
I think we absolutely need it, but here’s my thoughts as extension developer:

  1. Proposed protocol is similar to JSON-RPC. I think we need to specify clearly JSON-RPC 2.0
  2. Specification should also cover desktop clients, not only browser extensions. For example, desktop client can run JSON-RPC server on user’s machine. In this case web app can query localhost if window.ton is not defined by extension (or user can select preferred Provider).
  3. We need to select uncommon port and specify it, so all applications and providers will use and expect the same port. E.g. 9337 (unassigned according to IANA - Service Name and Transport Protocol Port Number Registry)
  4. Implementation of public SDK methods seems redundant to me. Provider is just unnecessary proxy in this case. Only methods that require user keys should be called through Provider.
  5. “Handshake” method specification. Provider should check origin of request somehow, probably by checking request headers or signature. At first query user should be asked if he “trusts” this application. Then all public data should be available without additional confirmation. All actions that require private key must always ask for user’s confirmation.
  1. We have tried to create this specification by the analogous with EIP-1193: Ethereum Provider JavaScript API. We relied on the fact that DApp developers can be interested to migrate on the TON blockchain very quickly and without any head pain. We don’t offer to use the direct interaction with TON blockchain, only with TON SDK. Almost all extensions have this library in the wallets. For this reason, we don’t offer to use any RPC without TON SDK context.
  2. Desktop clients will interact also via TON SDK, by this circumstance we don’t see any reason to run an additional server on the client. The TON SDK works with endpoint, the wallet works with TON SDK. It doesn’t matter where the wallet runs - browser, mobile, desktop, etc, each time requests go via TON SDK.
  3. The same with port - need to specify the only endpoint and all. It works the same as you can add a new network in the Metamask or use presented networks. Need to have only an endpoint.
  4. I agree, but we didn’t find any working solution when we can allow to use TON SDK directly without specific naming, for example, “ton_sdk” and then in the params to specify needed module name and function name. We have offered our vision. Other wallets can create their own way to run SDK functions. In any case, to load in each page Wasm TON SDK library is not a good approach, in our opinion… The offered approach is robust and allows adding new functions when it will appear in TON SDK. Each wallet will decide which functions in TON SDK will be offered for use.
  5. Each injected.js script can get the hostname from the “location” object, only the “trusted” hostnames will be able to send requests from the DApp. Each user can manage “connected websites” in wallets.

Such approach is limiting DApps to active FreeTON users, who already have extension like extraTON or Liberton installed. However, DApps can be useful for any user, as well they can support multiple blockchains. They should attract new users to FreeTON ecosystem and also be useful for existing users. That’s why DApps should not rely on injected window.ton property, but load .wasm and interact with TON SDK directly instead. I agree that we need something similar to existing solutions, but we also can improve them instead of just copycat mindlessly. Anyways, we need to hear other’s extension developers opinion. Especially @qwertys318, who already have experience with developing something similar (GitHub - extraton/freeton) for FreeTON ecosystem.

load .wasm and interact with TON SDK directly instead

I can’t understand then how will users manage private keys? How to do secure solution for this approach. In this case, the wallet will work with its own TON SDK and yet one instance will be on the DApp page.
For example, Metamask cut off web3 library due to excess functionality and now it works directly with RPC. Also, Metamask works as a proxy that tracks some specific methods that demand private keys.
All understand that already exists some useful solutions, like extraton, but this TIP set the aim to uniform all approaches.
Here is the code used by extraton:

window.freeton = {
  request: (method, params) => request(method, params),
  eventListener: null,
};

That’s sad other developers ignored this proposal.

the wallet will work with its own TON SDK and yet one instance will be on the DApp page

Imagine dApp relies only on injected SDK. In this case, dApp should be always updated to support latest SDK version or even multiple versions that different wallets use. dApps should use injected SDK only for methods that require user’s private key. Otherwise dApp could be broken because of incompatibility which is not good.

https://tip32-demopage.pertinaxwallet.com/ To test proposed implementation