Creating a spec in the IIP for an "ICON Provider JS API" and "BIP44 coin_type and path derivation" (discussion)

ICON Provider JS API

The following is a proposal to create an ICON Provider JS API specification to provide consistency across clients and applications in the ICON network.

Abstract

To allow communication between software wallets and web applications is necessary for these software wallets to expose an API via Javascript in the web page.

To ensure seamless user experience and avoid implementation of several API communication protocols in each web application to support several software wallets, it is necessary to implement a standardized protocol for all software wallets and web applications to adhere to.

API

The following specification requires that a dispatching and a listening event be created using CustomEvent in the web applications. The type and payload of the events are assigned to the detail field in the CustomEvent.

Data in detail field:

Field Type Description
type string Predefined type of events
payload any Data required for the request or response.

Dispatch Event for Request

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
		type: '...',
		payload: {...}
	}
});
window.dispatchEvent(customEvent);

Listening Event for Response

const eventHandler = event => {
	const { type, payload } = event.detail;
	switch (type) { ...	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

Methods

HAS_ACCOUNT

REQUEST_HAS_ACCOUNT Requests for whether the software wallet has any ICON wallet.

RESPONSE_HAS_ACCOUNT Returns boolean-typed results.

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
		type: 'REQUEST_HAS_ACCOUNT'
	}
});
window.dispatchEvent(customEvent);

const eventHandler = event => {
	const { type, payload } = event.detail;
	if (type === 'RESPONSE_HAS_ACCOUNT') {
		console.log(payload.hasAccount); // true or false
	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

HAS_ADDRESS

REQUEST_HAS_ADDRESS Requests for whether the software wallet has the specified wallet address.

RESPONSE_HAS_ADDRESS Returns boolean-typed results.

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
		type: 'REQUEST_HAS_ADDRESS',
		payload: 'hx19870922...'
	}
});
window.dispatchEvent(customEvent);

const eventHandler = event => {
	const { type, payload } = detail
	if (type === 'RESPONSE_HAS_ADDRESS') {
		console.log(payload); // true or false
	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

ADDRESS

REQUEST_ADDRESS Requests for the address to be used for service.

RESPONSE_ADDRESS Returns the icx address selected by the user.

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
 		type: 'REQUEST_ADDRESS'
	}
});
window.dispatchEvent(customEvent);

const eventHandler = event => {
	const { type, payload } = detail;
	if (type === 'RESPONSE_ADDRESS') {
		console.log(payload); // e.g., hx19870922...
	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

JSON-RPC

REQUEST_JSON-RPC Requests for calling standard ICON JSON-RPC API. (User confirmation is required in some cases.)

RESPONSE_JSON-RPC Returns the JSON-RPC response.

CANCEL_JSON-RPC User canceled the JSON-RPC request.

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
		type: 'REQUEST_JSON-RPC',
		payload: {
			jsonrpc: "2.0",
			method: "icx_method",
			id: 6339,
			params: {
				from: "hx19870922...",
				...
			}
		}
	}
});
window.dispatchEvent(customEvent);

const eventHandler = event => {
	const { type, payload } = detail;
	if (type === 'RESPONSE_JSON-RPC') {
		console.log(payload); // e.g., {"jsonrpc": "2.0", "id": 6339, "result": { ... }}
	}
	else if (type === 'CANCEL_JSON-RPC') {
		console.error('User canceled JSON-RPC request')
	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

SIGNING

REQUEST_SIGNING Request for only signing tx hash. (User confirmation is always required.)

RESPONSE_SIGNING Returns signature.

CANCEL_SIGNING User canceled the signing request.

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
		type: 'REQUEST_SIGNING',
		payload: {
			from: 'hx19870922...',
			hash: '0x13979...'
		}
	}
});
window.dispatchEvent(customEvent);

const eventHandler = event => {
	const { type, payload } = detail
	if (type === 'RESPONSE_SIGNING') {
		console.log(payload) // e.g., 'q/dVc3qj4En0GN+...'
	}
	else if (type === 'CANCEL_SIGNING') {
		console.error('User canceled signing request')
	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

Can you please edit the API post to lay out the possible types of interactions that a developer would want for the user to have access to? This will help inform other viewers of the specification as to whether all of those interactions are accomplished and whether that list of interaction types is the correct list to pursue

@espanicon I would additionally recommend to move the discussion about creating a ICON Provider JS API into a Github Issue as soon as tomorrow because you have already created the proposed specification

for this I would like to wait and read the recommendation of other developers in this subject, specially those that have already created web apps and wallets and have a better idea of what type of interactions will be needed in this specifications.

If you dont have any issue I think that it would be best to wait a few days to allow other developers in the community to give their input in this matter, this can allow us to create a more functional and better detailed specification.

That’s fine with me. Note that these discussions may also take place on the Github (e.g. here), which can potentially make it easier to link to specifics of the proposal as well as the updates made to the proposal during discussion

Sorry I was confused, I understand now that you want for this discussion to be done in a github issue to better track the progress.

Im going to open an issue and continue the discussion there.

Please link the issue here. As well as any pull request that you may make with the proposed specification

I see that in the template for the issues there is a “label” category, is there a list of predefined labels to be used? what label do you recommend for this specific proposal?

since I dont know the internal process in which the foundation works for this type of proposals If you can give me some pointers on how should I fill the header section i would appreciate it, for example

iip: 16
title: ICON Security Token Standard
author: Patrick Park (@cordiallys)
discussions-to: https://github.com/icon-project/IIPs/issues/16
status: Draft
type: Standards Track
category: IRC
created: 2019-01-21

Or you can open the issue if you prefer.

1 Like

I’m making an updated template for this. I would recommend to discuss here in the meantime. Taking inspiration from Ethereum Magicians on this. I would also recommend splitting the BIP44 discussion into a different topic. I’ll let you know once the updated template is pushed through, and then you can use that

I’m going to copy some of my thoughts for extending the spec from Discord into here. For now I think we should just formalise the spec that everyone is already using.

  • Should there be an error response, or a CANCEL_ADDRESS response if the user rejects the REQUEST_ADDRESS request? At the moment I’m assuming dApp developers just have to guess after a timeout that the user rejected it.

  • Should there be a concept of an active/current network like Ethereum providers/dApps. At the moment Hana could be connected to no ICON network (ICON chain disabled, or user has selected a testnet from a different chain), or it could be connected to ICON mainnet, or one of the testnets. But there’s no way to communicate this with dApps, and no way for dApps to communicate which network they’re trying to use. A suite of REQUEST_NETWORK, REQUEST_ADD_NETWORK and REQUEST_SWITCH_NETWORK messages/responses might be useful?

  • Should there be a suite of messages that the provider/Hana can send to dApps without getting a request first? E.g. if user revokes dApp permission, if user changes active wallet/address, if user disables ICON chain or changes network

1 Like

do you think we should change the CustomEvent name from ICONEX_RELAY_REQUEST to ICON_RELAY_REQUEST?

I think it would be a more general and appropriate name but it will add unnecessary work to the current wallets and web apps.

Yeah, I go back and forth on it. I do think it’s a good idea, just not sure if it’s worth the churn in the ICON dApp ecosystem.

If we wanted to do this, we could make it so that Hana supports both, and put a console warning that ICONEX_RELAY_REQUEST is deprecated (similar to what MetaMask does with deprecated messages). I’m sure other wallets would follow suit, especially if there’s a clear spec in place to reference.

That said I don’t think ICONex is being actively maintained, so it’s likely that it would never be updated, so there might not be much incentive for dApp developers to make the change. I’m not sure how many users ICONex still has.

@espanicon @bb_reliantnode Linking the forum post about the updated IIP process here for convenience

Forum post

my impression with ICONex is that is not being actively developed in terms of having a team behind it constantly creating new features, but the repo can still receive pull request and get updates like this.

If we create a spec with a new CustomEvent name, the necessary change in the code is minimal for ICONex, and I (or anyone) can make the change and propose it in a pull request, the only thing that will be missing is to build the dapp and upload and update in the chrome webstore, so it will be good if we have a confirmation from the ICONex repository collaborators that if we implement this change and then make a pull request they will continue follow with the build and update steps.

@errcsool is it possible to contact the person in charge of the ICONex repo and have a confirmation that this is possible or not?

Sure, that might be Jinwoo from IconLoop. Looks like they are the one merging a lot of the Pull Requests

Edit: I’ve reached out to IconLoop team to confirm who is in charge of that project and will get back to you with the response

Just found out that a similar standard already exist but for communicating with ICONex in mobile (IIP-14)

now im wondering if we should expand the IIP-14 to also detail the communication protocol for web or we should create a separate IIP for this.

@espanicon Sorry for the delay. I was at a conference last week with the rest of the Icon Foundation team. Separate standard is better for sure

iip: TBD
title: ICON Provider JS API
author: Fidel (github.com/FidelVe), Ben (github.com/bkbooth), Eric (github.com/han-so1omon)
discussions-to: https://forum.icon.community/t/creating-a-spec-in-the-iip-for-an-icon-provider-js-api-and-bip44-coin-type-and-path-derivation-discussion/2700/21
status: Draft
type: Standards Track
category: IRC
created: 2022-06-04
---

Simple Summary

An specification to provide consistency across clients and applications in the ICON network for communication between software wallets and web applications.

Abstract

To allow communication between software wallets and web applications is necessary for these software wallets to expose an API via Javascript in the web page. For the wallets and web apps to communicate it is necessary the creation of dispatching and listening events using Javascript in the browser.

Motivation

To ensure seamless user experience and avoid implementation of several API communication protocols in each web application to support several software wallets, it is necessary to implement a standardized protocol for all software wallets and web applications to adhere to.

Specification

The following specification requires that a dispatching and a listening event be created using CustomEvent in the web applications. The type and payload of the events are assigned to the detail field in the CustomEvent.

Data in detail field:

Field Type Description
type string Predefined type of events
payload any Data required for the request or response.

Dispatch Event for Request

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
		type: '...',
		payload: {...}
	}
});
window.dispatchEvent(customEvent);

Listening Event for Response

const eventHandler = event => {
	const { type, payload } = event.detail;
	switch (type) { ...	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

Methods

HAS_ACCOUNT

REQUEST_HAS_ACCOUNT Requests for whether the software wallet has any ICON wallet.

RESPONSE_HAS_ACCOUNT Returns boolean-typed results.

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
		type: 'REQUEST_HAS_ACCOUNT'
	}
});
window.dispatchEvent(customEvent);

const eventHandler = event => {
	const { type, payload } = event.detail;
	if (type === 'RESPONSE_HAS_ACCOUNT') {
		console.log(payload.hasAccount); // true or false
	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

HAS_ADDRESS

REQUEST_HAS_ADDRESS Requests for whether the software wallet has the specified wallet address.

RESPONSE_HAS_ADDRESS Returns boolean-typed results.

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
		type: 'REQUEST_HAS_ADDRESS',
		payload: 'hx19870922...'
	}
});
window.dispatchEvent(customEvent);

const eventHandler = event => {
	const { type, payload } = detail
	if (type === 'RESPONSE_HAS_ADDRESS') {
		console.log(payload); // true or false
	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

ADDRESS

REQUEST_ADDRESS Requests for the address to be used for service.

RESPONSE_ADDRESS Returns the icx address selected by the user.

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
 		type: 'REQUEST_ADDRESS'
	}
});
window.dispatchEvent(customEvent);

const eventHandler = event => {
	const { type, payload } = detail;
	if (type === 'RESPONSE_ADDRESS') {
		console.log(payload); // e.g., hx19870922...
	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

JSON-RPC

REQUEST_JSON-RPC Requests for calling standard ICON JSON-RPC API. (User confirmation is required in some cases.)

RESPONSE_JSON-RPC Returns the JSON-RPC response.

CANCEL_JSON-RPC User canceled the JSON-RPC request.

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
		type: 'REQUEST_JSON-RPC',
		payload: {
			jsonrpc: "2.0",
			method: "icx_method",
			id: 6339,
			params: {
				from: "hx19870922...",
				...
			}
		}
	}
});
window.dispatchEvent(customEvent);

const eventHandler = event => {
	const { type, payload } = detail;
	if (type === 'RESPONSE_JSON-RPC') {
		console.log(payload); // e.g., {"jsonrpc": "2.0", "id": 6339, "result": { ... }}
	}
	else if (type === 'CANCEL_JSON-RPC') {
		console.error('User canceled JSON-RPC request')
	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

SIGNING

REQUEST_SIGNING Request for only signing tx hash. (User confirmation is always required.)

RESPONSE_SIGNING Returns signature.

CANCEL_SIGNING User canceled the signing request.

const customEvent = new CustomEvent('ICONEX_RELAY_REQUEST', {
	detail: {
		type: 'REQUEST_SIGNING',
		payload: {
			from: 'hx19870922...',
			hash: '0x13979...'
		}
	}
});
window.dispatchEvent(customEvent);

const eventHandler = event => {
	const { type, payload } = detail
	if (type === 'RESPONSE_SIGNING') {
		console.log(payload) // e.g., 'q/dVc3qj4En0GN+...'
	}
	else if (type === 'CANCEL_SIGNING') {
		console.error('User canceled signing request')
	}
}
window.addEventListener('ICONEX_RELAY_RESPONSE', eventHandler);

Rationale

Backwards Compatibility

Test Cases

Implementation

Copyright

Copyright and related rights waived via CC0.

pull request created to continue with this IIP proposal.

Created corresponding Github Discussion for the IIP Pull Request #49. Let’s continue the conversation in the issue, so that we can better suggest and track updates to the IIP spec.