Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TIP-1193: TRON Provider JavaScript API #466

Closed
EllenWhitmore opened this issue Sep 27, 2022 · 9 comments
Closed

TIP-1193: TRON Provider JavaScript API #466

EllenWhitmore opened this issue Sep 27, 2022 · 9 comments

Comments

@EllenWhitmore
Copy link
Contributor

EllenWhitmore commented Sep 27, 2022

tip: 1193
title: TRON Provider JavaScript API
author: Aaron.Luo
discussions to: 
category: Interface
status: Last Call
created: 2022-09-26

Table of Contents

Summary

This protocol specifies a JavaScript TRON provider, it is used to ensure the consistency of interaction between TRON wallets and TRON DApps.

Abstract

A common convention in the TRON web application (“DApp”) ecosystem is that the key management software ("wallets") exposes their API via a JavaScript object on the web page. This object is called “the Provider”.

This protocol normalizes the TRON provider's API and is designed to be event-driven, independent of the call method. The Provider can be easily extended by defining new methods and event types.

This protocol recommends using window.tron as the Provider.

Historically, some TRON wallets provide tronWeb object, and this protocol recommends that the Provider will still provide tronWeb object to avoid additional compatible development of TRON DApps for the Provider of this protocol.

Specification

API

The Provider must implement and expose the API and property defined in this section. All API and property entities must adhere to the types and interfaces defined in this section.

API: request

Example
tron.request({
  method: 'requestMethod',
  params: ['param1', 'param2'],
})

Parameters
interface RequestArguments {
  readonly method: string;
  readonly params?: unknown[] | object;
}
  • The Provider must identify the requested method by the value of RequestArguments.method.
  • If the requested method takes any parameters, the Provider must accept them as the value of RequestArguments.params.
Returns
  • tron.request must be handled such that the returned Promise either resolves with a value per the requested method’s specification, or rejects with an error.
  • If resolved, the Promise must resolve with a result per the method’s specification, unless the method’s return type is particularly defined.
  • If the returned Promise rejects, it must reject as specified in the Error Code section below.
  • The returned Promise must reject if any of the following conditions are met:
    • An error is returned for the request.
    • The Provider encounters an error or fails to process the request for any reason.
  • The returned Promise should reject if any of the following conditions are met:
    • The Provider is disconnected. If rejecting for this reason, the Promise rejection error code must be 4900.
    • The tron.request request is directed at a specific chain, and the Provider is not connected to that chain, but is connected to at least one other chain. If rejecting for this reason, the Promise rejection error code must be 4901.
    • The Provider does not support the method in tron.request request. If rejecting for this reason, the Promise rejection error code must be 4200.
Error Code

The structure that returns the error is as follows:

interface ProviderRpcError extends Error {
	code: number;
	message: string;
	data?: unknown;
}
  • message
    • must be a human-readable string
    • Should be the message of the Provider Error section, or the message in the method's specification
  • code
    • must be an integer number
    • Should be the code of the Provider Error section, or the code in the method's specification
  • data
    • should contain any other useful information about the error

Provider Error
code message Description
4001 User Rejected Request The user rejected the request.
4100 Unauthorized The requested method and/or account has not been authorized by the user.
4200 Unsupported Method The Provider does not support the requested method.
4900 Disconnected The Provider is disconnected from all chains.
4901 Chain Disconnected The Provider is not connected to the requested chain.

Property

Property: tronWeb

wallet needs to import tronWeb library, instantiate tronWeb, The Provider provides instantiated tronWeb for DApps.

Example
const tronWeb = tron.tronWeb;
Constraints

tron.tronWeb needs to meet the following requirements:

  • When the wallet changes the currently connected chain, it must reinitialize tronWeb and update tron.tronWeb

Property: is[WalletName]

This is a non-normative property, but wallet implementation is recommended.
In actual development, the DApp may need to determine what wallet is currently providing the Provider, so as to facilitate the compatible development of different wallets by the DApp.
For example: isTronLink, isTokenPocket, isTrustWallet, etc.
This protocol does not limit the specific property name, nor does it require the implementation of this property.

Example
const isTronLink = tron.isTronLink as boolean;

Events

The Provider must implement the following event handling methods:

  • on
  • removeListener

These methods must be implemented according toNode.js EventEmitter API.

Event: connect

If the Provider becomes connected, the Provider must emit the event named connect.
This includes when:

  • The Provider first connects to a chain after initialization.
  • The Provider connects to a chain after the disconnect event was emitted.
    This event must be emitted with an object of the following form:
interface ProviderConnectInfo {
  readonly chainId: string;
}
  • The chainId must be obtained through the RPC method of TRON's eth_chainId.
Example
tron.on('connect', (connectInfo: ProviderConnectInfo) => {
  console.log(connectInfo); // example: {chainId: '0x2b6653dc' }
})

Event: disconnect

If the Provider becomes disconnected from all chains, the Provider must emit the event named disconnect with value error: ProviderRpcError object according to the Provider Error specification.

Example
tron.on('disconnect', (providerRpcError: ProviderRpcError) => {
  console.error(connectInfo); // example: { code: 4900, message: 'Disconnected' }
})

Event: chainChanged

If the chain to which the Provider is connected changes, the Provider must emit a chainChanged event and emit an object of type ProviderConnectInfo that explicitly informs the new chainId value.

Example
tron.on('chainChanged', (connectInfo: ProviderConnectInfo) => {
  console.log(connectInfo); // example: {chainId: '0x2b6653dc' }
})

Event: accountsChanged

If the Provider's current account changes, the Provider must emit the accountsChanged event and the currently available account address in the form of accounts: string[].

Example
tron.on('accountsChanged', (accounts: string[]) => {
  console.log(accounts); // example: ['TQKLs3GzCNLjzyCvaPWSrqcpUGUhadxm7P']
})

Security Considerations

The Provider is intended to pass messages between a TRON wallet and a TRON DApps. It is not responsible for private key or account management; it merely processes messages and emits events. Consequently, account security and user privacy need to be implemented in middleware between the Provider and its TRON wallet. The Provider can be thought of as an extension of the wallet, exposed in an untrusted environment, under the control of some third party.

Handling Adversarial Behavior

Since the Provider is a JavaScript object, consumers can generally perform arbitrary operations on the Provider, and all its properties can be read or overwritten.
Therefore, it is best to treat the Provider object as though it is controlled by an adversary. It is paramount that the Provider implementer protects the user, wallet by ensuring that:

  • The Provider does not contain any private user data.
  • The Provider and wallet programs are isolated from each other.
  • Set a limit for the Provider's request rate to the wallet.
  • The wallet validates all data sent from the Provider.

Backwards compatibility

Before this protocol was finalized, some wallets implemented non-normative versions. In order to be compatible with the historical DApps, the wallets can be compatible with non-normative versions on the premise of implementing this protocol.

@EllenWhitmore EllenWhitmore changed the title TIP-3326: TRON Provider JavaScript API TIP-1102: TRON Provider JavaScript API Sep 30, 2022
@EllenWhitmore EllenWhitmore changed the title TIP-1102: TRON Provider JavaScript API TIP-1193: TRON Provider JavaScript API Sep 30, 2022
@nobodywhen
Copy link

This is very helpful, I see that chainid is used in this connect event,but how to get the chainid of TRON mainent and testnet?

@EllenWhitmore
Copy link
Contributor Author

This is very helpful, I see that chainid is used in this connect event,but how to get the chainid of TRON mainent and testnet?

@nobodywhen
Currently chainId is mainly used to distinguish the identifiers of different chains.
The return value of our jsonrpc interface can be used:

curl -X POST 'https://api.trongrid.io/jsonrpc' --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":"1"}'
// mainnet: 0x2b6653dc

curl -X POST 'https://api.shasta.trongrid.io/jsonrpc' --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":"1"}'
// shasta: 0x94a9059e

curl -X POST 'https://nile.trongrid.io/jsonrpc' --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":"1"}'
// nile: 0xcd8690dc

@dmf3030
Copy link

dmf3030 commented Oct 11, 2022

Seems like a good idea, will need to read more into the docs, as long as it does not immediately break existing tronlink integration it should be fine. Everyone is using tronweb and it looks like this will still expose it.

@EllenWhitmore
Copy link
Contributor Author

Seems like a good idea, will need to read more into the docs, as long as it does not immediately break existing tronlink integration it should be fine. Everyone is using tronweb and it looks like this will still expose it.

@dmf3030
yeah, it will not immediately break existing TronLink integration, but it is recommended to use the new canonical interface as much as possible

@musknuibility
Copy link

This is a great improvement !!!

@chendatony31
Copy link

Looks great, TokenPocket will support this API when the proposal is fully discussed

@EllenWhitmore
Copy link
Contributor Author

Looks great, TokenPocket will support this API when the proposal is fully discussed

thank you !!

@ZxSix666
Copy link

Gg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants
@dmf3030 @chendatony31 @ethan1844 @musknuibility @nobodywhen @ZxSix666 @EllenWhitmore and others