From 9bf36f7b60dedb52f8285daa3f271c202a490ee0 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 28 Aug 2018 16:54:10 +0900 Subject: [PATCH 01/96] init --- nep-dapi.mediawiki | 88 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 nep-dapi.mediawiki diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki new file mode 100644 index 00000000..0b3dc193 --- /dev/null +++ b/nep-dapi.mediawiki @@ -0,0 +1,88 @@ +
+  NEP: 
+  Title: Unified dApp API for trusted 3rd party wallet providers
+  Author: Nick Fujita , Matus Zamborsky 
+  Type: Standard
+  Status: Draft
+  Created: 2018-08-28
+
+ +==Abstract== + +This NEP describes a common API interface for dApps to communicate with external wallet providers. The use of a trusted 3rd party wallet provider will help users feel more sure when using dApps, and the unified interface will help dApp creators to have a more synchronous developer experience when making their dApps compatible with said providers. + + +==Motivation== + +===End Users=== + +As more dApps come into the ecosystem, there will be more concerns about the safety of their assets. If dApps all required users to input their private keys in order to use them, it just takes one malicious dApp to steal all their funds. By using a trusted 3rd party wallet provider which interfaces with the various dApps in the ecosystem on their behalf, users can reduce the exposure of their private keys. This will even allow users to use their hardware wallets with these wallet providers, and never reveal their private keys, even to the wallet itself. + +===dApp Developers=== + +One of the initial hurtles for any developer when starting to develop a dApp is to create a wallet module that will allow the user and application to interface with the NEO blockchain. While there are many quality SDKs out there such as neon-js for facilitating the communication of these requests, there are often many hurtles to successfully constructing the right combination of methods, along with input and output parsing. The issue only get amplified when trying to integrate with hardware wallet providers such as a Ledger device. + +While there may be several options for 3rd party wallet providers that will help them to facilitate these transactions, the is currently no common consensus on the consistency of their interfaces. With a lack of consistency in interfaces to use these wallet provider services, dApp developers will be forced to make a decision to have their platform supported by a single provider, or to double or even triple their development efforts to accommodate all the different wallet provider interfaces. This will lead to a fragmentation in the dApps ecosystem. + +===Wallet providers=== + +Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Provider developers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplication an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have a unified interface for such transactions, providers can spend more time on making their individual services better for their users. + + +==Specification== + +===Provider=== + +====getProvider==== +Returns information about the wallet API provider, including who this provider is, the version of their API, and the NEP that the interface is compatible with. + +##### Method Interface +
+function getProvider(): Promise
+
+ +#### Input arguments +None + +#### Return values +object - Provider information defined by the interface below: +
+interface Provider {
+  name: string;
+  version: string;
+  compatibility: string[];
+}
+
+ +The compatibility field will return a list of strings that corresponds to NEPs that the API conforms to. For example: +
+compatibility: [
+    'NEP-14',
+    'NEP-23',
+    'NEP-29'
+]
+
+ +#### Example +
+const dapi = window.NEO;
+// import dapi from 'dapi-provider-package';
+
+getProvider()
+.then((provider: Provider) => {
+  const {
+    name,
+    version,
+    compatibility,
+  } = provider;
+
+  console.log('Provider name: ' + name);
+  console.log('Provider API version: ' + version);
+  console.log('Provider API compatibility: ' + JSON.stringify(compatibility));
+})
+.catch(err => // no provider available);
+
+ +==Implementation== + +In progress. To be finalized as consensus is reached on the specifications of this NEP. From 2c9d369d9dd44d3c199b353c24cd78a7a3d1255c Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 28 Aug 2018 17:18:10 +0900 Subject: [PATCH 02/96] add connect method --- nep-dapi.mediawiki | 79 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 0b3dc193..9bbb65b7 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1,6 +1,6 @@
   NEP: 
-  Title: Unified dApp API for trusted 3rd party wallet providers
+  Title: Unified dApp API for trusted 3rd party wallet providers (dAPI)
   Author: Nick Fujita , Matus Zamborsky 
   Type: Standard
   Status: Draft
@@ -9,7 +9,7 @@
 
 ==Abstract==
 
-This NEP describes a common API interface for dApps to communicate with external wallet providers. The use of a trusted 3rd party wallet provider will help users feel more sure when using dApps, and the unified interface will help dApp creators to have a more synchronous developer experience when making their dApps compatible with said providers.
+This NEP describes a common API interface for dApps (dAPI) to communicate with external wallet providers. The use of a trusted 3rd party wallet provider will help users feel more sure when using dApps, and the unified interface will help dApp creators to have a more synchronous developer experience when making their dApps compatible with said providers.
 
 
 ==Motivation==
@@ -34,17 +34,17 @@ Each wallet provider, when deciding on supporting dApps to utilize their service
 ===Provider===
 
 ====getProvider====
-Returns information about the wallet API provider, including who this provider is, the version of their API, and the NEP that the interface is compatible with.
+Returns information about the  dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with.
 
-##### Method Interface
+=====Method Interface=====
 
 function getProvider(): Promise
 
-#### Input arguments +=====Input arguments===== None -#### Return values +=====Success return value===== object - Provider information defined by the interface below:
 interface Provider {
@@ -54,7 +54,7 @@ interface Provider {
 }
 
-The compatibility field will return a list of strings that corresponds to NEPs that the API conforms to. For example: +The compatibility field will return a list of strings that corresponds to NEPs that the dAPI conforms to. For example:
 compatibility: [
     'NEP-14',
@@ -63,11 +63,11 @@ compatibility: [
 ]
 
-#### Example -
-const dapi = window.NEO;
-// import dapi from 'dapi-provider-package';
+=====Error return value=====
+string - `NO_PROVIDER`
 
+=====Example=====
+
 getProvider()
 .then((provider: Provider) => {
   const {
@@ -77,12 +77,65 @@ getProvider()
   } = provider;
 
   console.log('Provider name: ' + name);
-  console.log('Provider API version: ' + version);
-  console.log('Provider API compatibility: ' + JSON.stringify(compatibility));
+  console.log('Provider dAPI version: ' + version);
+  console.log('Provider dAPI compatibility: ' + JSON.stringify(compatibility));
 })
 .catch(err => // no provider available);
 
+====connect=== +Requests a connection from the dApp to the dAPI provider. + +=====Method Interface===== +
+function connect(): Promise
+
+ +=====Input arguments===== +None + +=====Success return value===== +object - Account information defined by the interface below: +
+interface Account {
+  address: string;
+  publicKey: string;
+}
+
+ +=====Error return value===== +string - `NO_PROVIDER`|`CONNECTION_DENIED` + +=====Example===== +
+connect()
+.then((account: Account) => {
+  const {
+    address,
+    publicKey,
+  } = account;
+
+  console.log('Provider address: ' + address);
+  console.log('Provider public key: ' + publicKey);
+})
+.catch((err: string) => {
+  switch(err) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case CONNECTION_DENIED:
+      console.log('Connection request denied by user.');
+      break;
+  }
+});
+
+ +=====dAPI Provider Implementation===== +- Upon receiving a request to connect from a dApp, get the domain of the url from which the dApp is requesting to connect. +- Prompt the user if they would like to allow a dApp connection from the requesting domain, and which account they would like to use to interact with this dApp. Up to provider to provide a account by default based on the UX of their app. +- On user approval, resolve the request and provide the users Account information +- On user denial, reject the request with the message `CONNECTION_DENIED` + ==Implementation== In progress. To be finalized as consensus is reached on the specifications of this NEP. From eaf9440472e8d856ab9abef9d0683f7298f5991e Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 28 Aug 2018 17:34:55 +0900 Subject: [PATCH 03/96] update headers --- nep-dapi.mediawiki | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 9bbb65b7..98c9d1c5 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -7,44 +7,44 @@ Created: 2018-08-28
-==Abstract== +=Abstract= This NEP describes a common API interface for dApps (dAPI) to communicate with external wallet providers. The use of a trusted 3rd party wallet provider will help users feel more sure when using dApps, and the unified interface will help dApp creators to have a more synchronous developer experience when making their dApps compatible with said providers. -==Motivation== +=Motivation= -===End Users=== +==End Users== As more dApps come into the ecosystem, there will be more concerns about the safety of their assets. If dApps all required users to input their private keys in order to use them, it just takes one malicious dApp to steal all their funds. By using a trusted 3rd party wallet provider which interfaces with the various dApps in the ecosystem on their behalf, users can reduce the exposure of their private keys. This will even allow users to use their hardware wallets with these wallet providers, and never reveal their private keys, even to the wallet itself. -===dApp Developers=== +==dApp Developers== One of the initial hurtles for any developer when starting to develop a dApp is to create a wallet module that will allow the user and application to interface with the NEO blockchain. While there are many quality SDKs out there such as neon-js for facilitating the communication of these requests, there are often many hurtles to successfully constructing the right combination of methods, along with input and output parsing. The issue only get amplified when trying to integrate with hardware wallet providers such as a Ledger device. While there may be several options for 3rd party wallet providers that will help them to facilitate these transactions, the is currently no common consensus on the consistency of their interfaces. With a lack of consistency in interfaces to use these wallet provider services, dApp developers will be forced to make a decision to have their platform supported by a single provider, or to double or even triple their development efforts to accommodate all the different wallet provider interfaces. This will lead to a fragmentation in the dApps ecosystem. -===Wallet providers=== +==Wallet providers== Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Provider developers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplication an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have a unified interface for such transactions, providers can spend more time on making their individual services better for their users. -==Specification== +=Specification= -===Provider=== +==Provider== -====getProvider==== +===getProvider=== Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. -=====Method Interface===== +====Method Interface====
 function getProvider(): Promise
 
-=====Input arguments===== +====Input arguments==== None -=====Success return value===== +====Success return value==== object - Provider information defined by the interface below:
 interface Provider {
@@ -63,10 +63,10 @@ compatibility: [
 ]
 
-=====Error return value===== +====Error return value==== string - `NO_PROVIDER` -=====Example===== +====Example====
 getProvider()
 .then((provider: Provider) => {
@@ -83,18 +83,18 @@ getProvider()
 .catch(err => // no provider available);
 
-====connect=== +===connect=== Requests a connection from the dApp to the dAPI provider. -=====Method Interface===== +====Method Interface====
 function connect(): Promise
 
-=====Input arguments===== +====Input arguments==== None -=====Success return value===== +====Success return value==== object - Account information defined by the interface below:
 interface Account {
@@ -103,10 +103,10 @@ interface Account {
 }
 
-=====Error return value===== +====Error return value==== string - `NO_PROVIDER`|`CONNECTION_DENIED` -=====Example===== +====Example====
 connect()
 .then((account: Account) => {
@@ -130,12 +130,12 @@ connect()
 });
 
-=====dAPI Provider Implementation===== +====dAPI Provider Implementation==== - Upon receiving a request to connect from a dApp, get the domain of the url from which the dApp is requesting to connect. - Prompt the user if they would like to allow a dApp connection from the requesting domain, and which account they would like to use to interact with this dApp. Up to provider to provide a account by default based on the UX of their app. - On user approval, resolve the request and provide the users Account information - On user denial, reject the request with the message `CONNECTION_DENIED` -==Implementation== +=Implementation= In progress. To be finalized as consensus is reached on the specifications of this NEP. From 81d09f5c0f327449b902342fb5ce819c0500d221 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 28 Aug 2018 17:50:03 +0900 Subject: [PATCH 04/96] remove method detail headers from table of contents --- nep-dapi.mediawiki | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 98c9d1c5..7785bd41 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -36,15 +36,15 @@ Each wallet provider, when deciding on supporting dApps to utilize their service ===getProvider=== Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. -====Method Interface==== +'''Method Interface'''
 function getProvider(): Promise
 
-====Input arguments==== +'''Input arguments''' None -====Success return value==== +'''Success return value''' object - Provider information defined by the interface below:
 interface Provider {
@@ -63,10 +63,10 @@ compatibility: [
 ]
 
-====Error return value==== +'''Error return value''' string - `NO_PROVIDER` -====Example==== +'''Example'''
 getProvider()
 .then((provider: Provider) => {
@@ -86,15 +86,15 @@ getProvider()
 ===connect===
 Requests a connection from the dApp to the dAPI provider.
 
-====Method Interface====
+'''Method Interface'''
 
 function connect(): Promise
 
-====Input arguments==== +'''Input arguments''' None -====Success return value==== +'''Success return value''' object - Account information defined by the interface below:
 interface Account {
@@ -103,10 +103,10 @@ interface Account {
 }
 
-====Error return value==== +'''Error return value''' string - `NO_PROVIDER`|`CONNECTION_DENIED` -====Example==== +'''Example'''
 connect()
 .then((account: Account) => {
@@ -130,7 +130,7 @@ connect()
 });
 
-====dAPI Provider Implementation==== +'''dAPI Provider Implementation''' - Upon receiving a request to connect from a dApp, get the domain of the url from which the dApp is requesting to connect. - Prompt the user if they would like to allow a dApp connection from the requesting domain, and which account they would like to use to interact with this dApp. Up to provider to provide a account by default based on the UX of their app. - On user approval, resolve the request and provide the users Account information From 2ff1a5b72720b2782e786d4f1fcd972d1862b94b Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 28 Aug 2018 17:51:57 +0900 Subject: [PATCH 05/96] update formatting --- nep-dapi.mediawiki | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 7785bd41..f2b37d82 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -37,14 +37,17 @@ Each wallet provider, when deciding on supporting dApps to utilize their service Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. '''Method Interface''' +
 function getProvider(): Promise
 
'''Input arguments''' + None '''Success return value''' + object - Provider information defined by the interface below:
 interface Provider {
@@ -64,9 +67,11 @@ compatibility: [
 
'''Error return value''' + string - `NO_PROVIDER` '''Example''' +
 getProvider()
 .then((provider: Provider) => {
@@ -87,14 +92,17 @@ getProvider()
 Requests a connection from the dApp to the dAPI provider.
 
 '''Method Interface'''
+
 
 function connect(): Promise
 
'''Input arguments''' + None '''Success return value''' + object - Account information defined by the interface below:
 interface Account {
@@ -104,9 +112,11 @@ interface Account {
 
'''Error return value''' + string - `NO_PROVIDER`|`CONNECTION_DENIED` '''Example''' +
 connect()
 .then((account: Account) => {
@@ -131,10 +141,11 @@ connect()
 
'''dAPI Provider Implementation''' -- Upon receiving a request to connect from a dApp, get the domain of the url from which the dApp is requesting to connect. -- Prompt the user if they would like to allow a dApp connection from the requesting domain, and which account they would like to use to interact with this dApp. Up to provider to provide a account by default based on the UX of their app. -- On user approval, resolve the request and provide the users Account information -- On user denial, reject the request with the message `CONNECTION_DENIED` + +* Upon receiving a request to connect from a dApp, get the domain of the url from which the dApp is requesting to connect. +* Prompt the user if they would like to allow a dApp connection from the requesting domain, and which account they would like to use to interact with this dApp. Up to provider to provide a account by default based on the UX of their app. +* On user approval, resolve the request and provide the users Account information +* On user denial, reject the request with the message `CONNECTION_DENIED` =Implementation= From 4c5fe4f5641cfa84a4694f8b1c46e770e5af9951 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 28 Aug 2018 17:54:18 +0900 Subject: [PATCH 06/96] update format --- nep-dapi.mediawiki | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index f2b37d82..9a32d3b1 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -7,31 +7,29 @@ Created: 2018-08-28
-=Abstract= +==Abstract== This NEP describes a common API interface for dApps (dAPI) to communicate with external wallet providers. The use of a trusted 3rd party wallet provider will help users feel more sure when using dApps, and the unified interface will help dApp creators to have a more synchronous developer experience when making their dApps compatible with said providers. -=Motivation= +==Motivation== -==End Users== +===End Users=== As more dApps come into the ecosystem, there will be more concerns about the safety of their assets. If dApps all required users to input their private keys in order to use them, it just takes one malicious dApp to steal all their funds. By using a trusted 3rd party wallet provider which interfaces with the various dApps in the ecosystem on their behalf, users can reduce the exposure of their private keys. This will even allow users to use their hardware wallets with these wallet providers, and never reveal their private keys, even to the wallet itself. -==dApp Developers== +===dApp Developers=== One of the initial hurtles for any developer when starting to develop a dApp is to create a wallet module that will allow the user and application to interface with the NEO blockchain. While there are many quality SDKs out there such as neon-js for facilitating the communication of these requests, there are often many hurtles to successfully constructing the right combination of methods, along with input and output parsing. The issue only get amplified when trying to integrate with hardware wallet providers such as a Ledger device. While there may be several options for 3rd party wallet providers that will help them to facilitate these transactions, the is currently no common consensus on the consistency of their interfaces. With a lack of consistency in interfaces to use these wallet provider services, dApp developers will be forced to make a decision to have their platform supported by a single provider, or to double or even triple their development efforts to accommodate all the different wallet provider interfaces. This will lead to a fragmentation in the dApps ecosystem. -==Wallet providers== +===Wallet providers=== Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Provider developers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplication an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have a unified interface for such transactions, providers can spend more time on making their individual services better for their users. -=Specification= - -==Provider== +==Specification== ===getProvider=== Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. @@ -147,6 +145,6 @@ connect() * On user approval, resolve the request and provide the users Account information * On user denial, reject the request with the message `CONNECTION_DENIED` -=Implementation= +==Implementation== In progress. To be finalized as consensus is reached on the specifications of this NEP. From 09671d9cf6bb448bc2dde9e8a5cf1c167cd2c46b Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 28 Aug 2018 19:24:07 +0900 Subject: [PATCH 07/96] update to getBalance --- nep-dapi.mediawiki | 120 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 9a32d3b1..27993e94 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -138,13 +138,131 @@ connect() });
-'''dAPI Provider Implementation''' +'''dAPI Provider''' * Upon receiving a request to connect from a dApp, get the domain of the url from which the dApp is requesting to connect. * Prompt the user if they would like to allow a dApp connection from the requesting domain, and which account they would like to use to interact with this dApp. Up to provider to provide a account by default based on the UX of their app. * On user approval, resolve the request and provide the users Account information * On user denial, reject the request with the message `CONNECTION_DENIED` + +===getAccount=== +Return the Account that is currently connected to the dApp. + +'''Method Interface''' + +
+function getAccount(): Promise
+
+ +'''Input arguments''' + +None + +'''Success return value''' + +object - Account information defined by the interface below: +
+interface Account {
+  address: string;
+  publicKey: string;
+}
+
+ +'''Error return value''' + +string - `NO_PROVIDER`|`NO_CONNECTION` + +'''Example''' + +
+getAccount()
+.then((account: Account) => {
+  const {
+    address,
+    publicKey,
+  } = account;
+
+  console.log('Provider address: ' + address);
+  console.log('Provider public key: ' + publicKey);
+})
+.catch((err: string) => {
+  switch(err) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case NO_CONNECTION:
+      console.log('Connection dApp not connected. Please call the "connect" function.');
+      break;
+  }
+});
+
+ + + +===getBalance=== +Return balance of a specific asset for the connected account. + +'''Method Interface''' + +
+function getBalance({ asset }): Promise
+
+ +'''Input arguments''' + +object - Contains the asset symbol the check the balance for the connected account +
+interface Config {
+  asset: string;
+}
+
+ + +'''Success return value''' + +object - Contains formatted balance of connected account for a given asset +
+interface Result {
+  address: string;
+  asset: string;
+  amount: string;
+}
+
+ + +'''Error return value''' + +string - `NO_PROVIDER`|`NO_CONNECTION` + +'''Example''' + +
+getBalance()
+.then((result: Result) => {
+  const {
+    address,
+    asset,
+    amount,
+  } = result;
+
+  console.log('Provider address: ' + address);
+  console.log('Provider public key: ' + publicKey);
+  console.log('Provider public key: ' + publicKey);
+})
+.catch((err: string) => {
+  switch(err) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case NO_CONNECTION:
+      console.log('Connection dApp not connected. Please call the "connect" function.');
+      break;
+  }
+});
+
+ + ==Implementation== In progress. To be finalized as consensus is reached on the specifications of this NEP. From 396fa0b5430a15c1177d96adc52f207a3a4fc121 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 11 Sep 2018 16:49:08 +0900 Subject: [PATCH 08/96] Add send function --- nep-dapi.mediawiki | 83 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 27993e94..6c534579 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -152,7 +152,7 @@ Return the Account that is currently connected to the dApp. '''Method Interface'''
-function getAccount(): Promise
+function getAccount(): Promise<{ address: string, publicKey: string }>
 
'''Input arguments''' @@ -161,13 +161,8 @@ None '''Success return value''' -object - Account information defined by the interface below: -
-interface Account {
-  address: string;
-  publicKey: string;
-}
-
+address: string - Address of the connected account +publicKey: string - Address of the connected account '''Error return value''' @@ -206,17 +201,12 @@ Return balance of a specific asset for the connected account. '''Method Interface'''
-function getBalance({ asset }): Promise
+function getBalance({ asset: string }): Promise
 
'''Input arguments''' -object - Contains the asset symbol the check the balance for the connected account -
-interface Config {
-  asset: string;
-}
-
+string - The asset symbol the check the balance for the connected account '''Success return value''' @@ -263,6 +253,69 @@ getBalance()
+===send=== +Invoke a transfer of a specified amount of a given asset from the connected account to another account. + +'''Method Interface''' + +
+function send({ receiver: string, asset: string, amount: string, remark?: string }): Promise
+
+ +'''Input arguments''' + +receiver: string - Address of the receiver of the assets to be sent + +asset: string - The symbol of the asset to be sent + +amount: string - The parsed amount of the asset to be sent + +remark?: string - (Optional) Description of the transaction to be made + + +'''Success return value''' + +txid: string - The transaction ID of the send invocation + + +'''Error return value''' + +string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED` + +'''Example''' + +
+send({
+  receiver: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d',
+  asset: 'GAS',
+  amount: '0.0001',
+  remark: 'Hash puppy clothing purchase. Invoice#abc123',
+})
+.then((txid: string) => {
+  console.log('Send transaction success! Transaction ID: ' + txid);
+})
+.catch((err: string) => {
+  switch(err) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case CONNECTION_REFUSED:
+      console.log('Connection dApp not connected. Please call the "connect" function.');
+      break;
+   case SEND_ERROR:
+    console.log('There was an error when broadcasting this transaction to the network.');
+    break;
+   case MALFORMED_ADDRESS:
+      console.log('The receiver address provided is not valid.');
+      break;
+  case CANCELED:
+    console.log('The user has canceled this transaction.');
+    break;
+  }
+});
+
+ + ==Implementation== In progress. To be finalized as consensus is reached on the specifications of this NEP. From 15f8b51fff4838f7b3a46428e5203f4eec25359c Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 11 Sep 2018 18:12:09 +0900 Subject: [PATCH 09/96] invokeRead wip --- nep-dapi.mediawiki | 102 +++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 68 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 6c534579..6d36793a 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -28,6 +28,12 @@ While there may be several options for 3rd party wallet providers that will help Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Provider developers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplication an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have a unified interface for such transactions, providers can spend more time on making their individual services better for their users. +Incoming request handling: +* Upon receiving a request from a dApp, get the domain of the url from which the dApp is requesting to connect. +* Prompt the user if they would like to allow a dApp connection from the requesting domain, and which account they would like to use to interact with this dApp. Up to provider to provide a account by default based on the UX of their app. +* On user approval, resolve the request and save connection status for this domain according to the user preference. +* On user denial, reject the request with the message `CONNECTION_DENIED` + ==Specification== @@ -66,7 +72,7 @@ compatibility: [ '''Error return value''' -string - `NO_PROVIDER` +string - `NO_PROVIDER`|`CONNECTION_DENIED` '''Example''' @@ -83,69 +89,18 @@ getProvider() console.log('Provider dAPI version: ' + version); console.log('Provider dAPI compatibility: ' + JSON.stringify(compatibility)); }) -.catch(err => // no provider available); - - -===connect=== -Requests a connection from the dApp to the dAPI provider. - -'''Method Interface''' - -
-function connect(): Promise
-
- -'''Input arguments''' - -None - -'''Success return value''' - -object - Account information defined by the interface below: -
-interface Account {
-  address: string;
-  publicKey: string;
-}
-
- -'''Error return value''' - -string - `NO_PROVIDER`|`CONNECTION_DENIED` - -'''Example''' - -
-connect()
-.then((account: Account) => {
-  const {
-    address,
-    publicKey,
-  } = account;
-
-  console.log('Provider address: ' + address);
-  console.log('Provider public key: ' + publicKey);
-})
 .catch((err: string) => {
   switch(err) {
     case NO_PROVIDER:
       console.log('No provider available.');
       break;
     case CONNECTION_DENIED:
-      console.log('Connection request denied by user.');
+      console.log('The user rejected the request to connect with your dApp.');
       break;
   }
 });
 
-'''dAPI Provider''' - -* Upon receiving a request to connect from a dApp, get the domain of the url from which the dApp is requesting to connect. -* Prompt the user if they would like to allow a dApp connection from the requesting domain, and which account they would like to use to interact with this dApp. Up to provider to provide a account by default based on the UX of their app. -* On user approval, resolve the request and provide the users Account information -* On user denial, reject the request with the message `CONNECTION_DENIED` - - ===getAccount=== Return the Account that is currently connected to the dApp. @@ -162,11 +117,12 @@ None '''Success return value''' address: string - Address of the connected account + publicKey: string - Address of the connected account '''Error return value''' -string - `NO_PROVIDER`|`NO_CONNECTION` +string - `NO_PROVIDER`|`CONNECTION_DENIED` '''Example''' @@ -186,8 +142,8 @@ getAccount() case NO_PROVIDER: console.log('No provider available.'); break; - case NO_CONNECTION: - console.log('Connection dApp not connected. Please call the "connect" function.'); + case CONNECTION_DENIED: + console.log('The user rejected the request to connect with your dApp'); break; } }); @@ -201,7 +157,7 @@ Return balance of a specific asset for the connected account. '''Method Interface'''
-function getBalance({ asset: string }): Promise
+function getBalance({ asset: string }): Promise<{ address: string, asset: string, amount: string }}>
 
'''Input arguments''' @@ -211,19 +167,16 @@ string - The asset symbol the check the balance for the connected account '''Success return value''' -object - Contains formatted balance of connected account for a given asset -
-interface Result {
-  address: string;
-  asset: string;
-  amount: string;
-}
-
+address: string - Address of the connected account + +asset: string - Asset symbol for the requested balance + +amount: string - Parsed balance of the requested asset '''Error return value''' -string - `NO_PROVIDER`|`NO_CONNECTION` +string - `NO_PROVIDER`|`CONNECTION_DENIED` '''Example''' @@ -245,8 +198,8 @@ getBalance() case NO_PROVIDER: console.log('No provider available.'); break; - case NO_CONNECTION: - console.log('Connection dApp not connected. Please call the "connect" function.'); + case CONNECTION_DENIED: + console.log('The user rejected the request to connect with your dApp'); break; } }); @@ -316,6 +269,19 @@ send({ +===invokeRead=== +Execute a contract invocation in read-only mode. + +'''Method Interface''' + +
+function invokeRead({ scriptHash: string, operation: string, args: Object[] }): Promise
+
+ +'''Input arguments''' + +script + ==Implementation== In progress. To be finalized as consensus is reached on the specifications of this NEP. From a95621b1d0a619a0f1332653d980cabf865b4234 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Wed, 12 Sep 2018 18:50:47 +0900 Subject: [PATCH 10/96] invokeRead --- nep-dapi.mediawiki | 57 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 6d36793a..a0184171 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -275,12 +275,65 @@ Execute a contract invocation in read-only mode. '''Method Interface'''
-function invokeRead({ scriptHash: string, operation: string, args: Object[] }): Promise
+type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`;
+
+interface Argument {
+  type: ArgumentType;
+  value: any;
+}
+
+function invokeRead({ scriptHash: string, operation: string, args: Argument[] }): Promise
 
'''Input arguments''' -script +scriptHash: string - script hash of the smart contract to invoke a read on +operation: string - operation on the smart contract to call +args: Argument[] - any input arguments for the operation + + +'''Success return value''' + +result: Object - Response from RPC node + +'''Error return value''' + +string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR` + +'''Example''' + +
+invokeRead({
+  scriptHash: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d',
+  operation: 'calculatorAdd',
+  arguments: [
+    {
+      type: 'integer',
+      value: 2
+    },
+    {
+      type: 'integer',
+      value: 10
+    }
+  ],
+})
+.then((result: Object) => {
+  console.log('Read invocation result: ' + JSON.stringigy(result));
+})
+.catch((err: string) => {
+  switch(err) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case CONNECTION_REFUSED:
+      console.log('Connection dApp not connected. Please call the "connect" function.');
+      break;
+   case RPC_ERROR:
+    console.log('There was an error when broadcasting this transaction to the network.');
+    break;
+  }
+});
+
==Implementation== From 3f214504fc4fe7f98b65794aecf3670a6d961feb Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Wed, 12 Sep 2018 18:56:11 +0900 Subject: [PATCH 11/96] invoke --- nep-dapi.mediawiki | 68 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index a0184171..9453e03e 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -304,7 +304,7 @@ string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR`
 invokeRead({
-  scriptHash: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d',
+  scriptHash: '505663a29d83663a838eee091249abd167e928f5',
   operation: 'calculatorAdd',
   arguments: [
     {
@@ -335,6 +335,72 @@ invokeRead({
 });
 
+ +===invoke=== +Execute a contract invocation. + +'''Method Interface''' + +
+type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`;
+
+interface Argument {
+  type: ArgumentType;
+  value: any;
+}
+
+function invoke({ scriptHash: string, operation: string, args: Argument[] }): Promise
+
+ +'''Input arguments''' + +scriptHash: string - script hash of the smart contract to invoke a read on +operation: string - operation on the smart contract to call +args: Argument[] - any input arguments for the operation + + +'''Success return value''' + +txid: string - The transaction ID of the invocation + +'''Error return value''' + +string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED` + +'''Example''' + +
+invoke({
+  scriptHash: '505663a29d83663a838eee091249abd167e928f5',
+  operation: 'storeData',
+  arguments: [
+    {
+      type: 'string',
+      value: 'hello'
+    }
+  ],
+})
+.then((txid: string) => {
+  console.log('Invoke transaction success! Transaction ID: ' + txid);
+})
+.catch((err: string) => {
+  switch(err) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case CONNECTION_REFUSED:
+      console.log('Connection dApp not connected. Please call the "connect" function.');
+      break;
+    case RPC_ERROR:
+      console.log('There was an error when broadcasting this transaction to the network.');
+      break;
+    case CANCELED:
+      console.log('The user has canceled this transaction.');
+      break;
+  }
+});
+
+ ==Implementation== In progress. To be finalized as consensus is reached on the specifications of this NEP. From 38342c07a04b30cce3e52d6dff285ca079f5d91c Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Wed, 12 Sep 2018 19:02:31 +0900 Subject: [PATCH 12/96] getStorage --- nep-dapi.mediawiki | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 9453e03e..1c0fae9d 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -401,6 +401,55 @@ invoke({ }); + +===getStorage=== +Reads the raw value in smart contract storage. + +'''Method Interface''' + +
+function getStorage({ scriptHash: string, key: string }): Promise
+
+ +'''Input arguments''' + +scriptHash: string - script hash of the smart contract to invoke a read on +key: string - key of the storage value to retreive from the contract + +'''Success return value''' + +value: string - The raw value that's stored in the contract + +'''Error return value''' + +string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR` + +'''Example''' + +
+getStorage({
+  scriptHash: '505663a29d83663a838eee091249abd167e928f5',
+  key: 'game.status'
+})
+.then((value: string) => {
+  console.log('Storage value: ' + value);
+})
+.catch((err: string) => {
+  switch(err) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case CONNECTION_REFUSED:
+      console.log('Connection dApp not connected. Please call the "connect" function.');
+      break;
+   case RPC_ERROR:
+    console.log('There was an error when broadcasting this transaction to the network.');
+    break;
+  }
+});
+
+ + ==Implementation== In progress. To be finalized as consensus is reached on the specifications of this NEP. From 5cb6ea8910bd4c0ca49114afb40e8ceafd7544b9 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 13 Sep 2018 12:15:16 +0900 Subject: [PATCH 13/96] Update section structure --- nep-dapi.mediawiki | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 1c0fae9d..0414df16 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -37,7 +37,8 @@ Incoming request handling: ==Specification== -===getProvider=== +===Provider=== +====getProvider==== Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. '''Method Interface''' @@ -101,7 +102,8 @@ getProvider() }); -===getAccount=== +===Asset=== +====getAccount==== Return the Account that is currently connected to the dApp. '''Method Interface''' @@ -151,7 +153,7 @@ getAccount() -===getBalance=== +====getBalance==== Return balance of a specific asset for the connected account. '''Method Interface''' @@ -206,7 +208,7 @@ getBalance() -===send=== +====send==== Invoke a transfer of a specified amount of a given asset from the connected account to another account. '''Method Interface''' @@ -268,8 +270,9 @@ send({ }); +===Smart Contract=== -===invokeRead=== +====invokeRead==== Execute a contract invocation in read-only mode. '''Method Interface''' @@ -336,7 +339,7 @@ invokeRead({ -===invoke=== +====invoke==== Execute a contract invocation. '''Method Interface''' @@ -402,7 +405,7 @@ invoke({ -===getStorage=== +====getStorage==== Reads the raw value in smart contract storage. '''Method Interface''' From 5ff31e37a2c21b185418bb98330418275f69c243 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 13 Sep 2018 12:20:34 +0900 Subject: [PATCH 14/96] rational --- nep-dapi.mediawiki | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 0414df16..01d8cf4a 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -452,6 +452,9 @@ getStorage({ }); +==Rational== + +This protocol will allow dApp developers to create applications that interact with the NEO blockchain without having to be concerned about managing a full wallet within their application or the details related to handing transaction creation or broadcasting. This will also allow dApps to allow users to transact in a secure fashion that does not require sharing of their private key. ==Implementation== From a2563f872aa15bf12e793cc576fdb01fc402912a Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 13 Sep 2018 14:41:09 +0900 Subject: [PATCH 15/96] update summary --- nep-dapi.mediawiki | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 01d8cf4a..4dea62f3 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1,6 +1,6 @@
   NEP: 
-  Title: Unified dApp API for trusted 3rd party wallet providers (dAPI)
+  Title: Unified dApp API for wallet providers
   Author: Nick Fujita , Matus Zamborsky 
   Type: Standard
   Status: Draft
@@ -9,30 +9,34 @@
 
 ==Abstract==
 
-This NEP describes a common API interface for dApps (dAPI) to communicate with external wallet providers. The use of a trusted 3rd party wallet provider will help users feel more sure when using dApps, and the unified interface will help dApp creators to have a more synchronous developer experience when making their dApps compatible with said providers.
+This NEP describes a common API interface for dApps to communicate with external wallet providers. The use of a trusted 3rd party wallet providers will help users feel more secure when using dApps, and the unified interface will help dApp creators to have a more uniform developer experience when making their dApps compatible with various providers.
 
 
 ==Motivation==
 
 ===End Users===
 
-As more dApps come into the ecosystem, there will be more concerns about the safety of their assets. If dApps all required users to input their private keys in order to use them, it just takes one malicious dApp to steal all their funds. By using a trusted 3rd party wallet provider which interfaces with the various dApps in the ecosystem on their behalf, users can reduce the exposure of their private keys. This will even allow users to use their hardware wallets with these wallet providers, and never reveal their private keys, even to the wallet itself.
+As dApps come into the ecosystem, there will be more concerns about the safety of user assets. If dApps all required users to input their private keys in order to use them, it just takes one malicious dApp to steal all their funds. By using a trusted wallet provider which interfaces with the various dApps in the ecosystem on their behalf, users can reduce the exposure of their private keys. This will even allow users to transact with their hardware wallets via the wallet provider,  never having to reveal their private keys even to the wallet itself.
 
 ===dApp Developers===
 
-One of the initial hurtles for any developer when starting to develop a dApp is to create a wallet module that will allow the user and application to interface with the NEO blockchain. While there are many quality SDKs out there such as neon-js for facilitating the communication of these requests, there are often many hurtles to successfully constructing the right combination of methods, along with input and output parsing. The issue only get amplified when trying to integrate with hardware wallet providers such as a Ledger device.
+One of the initial hurtles for any developer when starting to develop a dApp is to create a wallet module that will allow the user and application to interface with the NEO blockchain. While there are many quality SDKs out there such as neon-js for facilitating the communication of these requests, there are often many hurtles to successfully constructing the right combination of methods, along with input and output parsing. The issue only gets amplified when trying to integrate with hardware wallet providers such as a Ledger device.
 
 While there may be several options for 3rd party wallet providers that will help them to facilitate these transactions, the is currently no common consensus on the consistency of their interfaces. With a lack of consistency in interfaces to use these wallet provider services, dApp developers will be forced to make a decision to have their platform supported by a single provider, or to double or even triple their development efforts to accommodate all the different wallet provider interfaces. This will lead to a fragmentation in the dApps ecosystem.
 
 ===Wallet providers===
 
-Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Provider developers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplication an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have a unified interface for such transactions, providers can spend more time on making their individual services better for their users.
+Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Wallet providers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplication an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted by both the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have a unified interface for such transactions, providers can spend more time on making their individual services better for their users.
 
-Incoming request handling:
-* Upon receiving a request from a dApp, get the domain of the url from which the dApp is requesting to connect.
-* Prompt the user if they would like to allow a dApp connection from the requesting domain, and which account they would like to use to interact with this dApp. Up to provider to provide a account by default based on the UX of their app.
-* On user approval, resolve the request and save connection status for this domain according to the user preference.
-* On user denial, reject the request with the message `CONNECTION_DENIED`
+The current list of wallet providers that can benefit from the use of this protocol are currently:
+- nOS dApps browser
+- NeoLink Chrome extension
+- NEX Chrome extension
+- O3 dApps browser
+
+Each wallet provider has their own value proposition to it's users beyond the interface from this protocol itself, so it seems that formalizing it would be a net positive for all.
+
+Additionally, since there are a significant amount of overlap in the protocols between NEO and Ontology for sending assets, and interacting with contract on NeoVM, this proposal is a joint effort with [OEP6](https://github.com/ontio/OEPs/pull/8). Since there are differences in the two platforms, the result of these proposals will not be identical, nor should they be, but getting as much overlap as possible will help to simplify cross-chain interactions for both platforms.
 
 
 ==Specification==

From 3803f28782f2e87d389c13caf05efd14b156b10d Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Thu, 13 Sep 2018 15:48:26 +0900
Subject: [PATCH 16/96] update wallet provider details

---
 nep-dapi.mediawiki | 153 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 135 insertions(+), 18 deletions(-)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index 4dea62f3..420d583d 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -36,13 +36,14 @@ The current list of wallet providers that can benefit from the use of this proto
 
 Each wallet provider has their own value proposition to it's users beyond the interface from this protocol itself, so it seems that formalizing it would be a net positive for all.
 
-Additionally, since there are a significant amount of overlap in the protocols between NEO and Ontology for sending assets, and interacting with contract on NeoVM, this proposal is a joint effort with [OEP6](https://github.com/ontio/OEPs/pull/8). Since there are differences in the two platforms, the result of these proposals will not be identical, nor should they be, but getting as much overlap as possible will help to simplify cross-chain interactions for both platforms.
+Additionally, since there are a significant amount of overlap in the protocols between NEO and Ontology for sending assets, and interacting with contract on NeoVM, this proposal is a joint effort with [https://github.com/ontio/OEPs/pull/8 OEP6]. Since there are differences in the two platforms, the result of these proposals will not be identical, nor should they be, but getting as much overlap as possible will help to simplify cross-chain interactions for both platforms.
 
 
 ==Specification==
 
-===Provider===
-====getProvider====
+===dApp API Interface===
+====Provider====
+=====getProvider=====
 Returns information about the  dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with.
 
 '''Method Interface'''
@@ -106,8 +107,8 @@ getProvider()
 });
 
-===Asset=== -====getAccount==== +====Assets==== +=====getAccount===== Return the Account that is currently connected to the dApp. '''Method Interface''' @@ -157,18 +158,20 @@ getAccount() -====getBalance==== -Return balance of a specific asset for the connected account. +=====getBalance===== +Return balance of a specific asset for the given account. '''Method Interface'''
-function getBalance({ asset: string }): Promise<{ address: string, asset: string, amount: string }}>
+function getBalance({ address: string, asset: string }): Promise<{ address: string, asset: string, amount: string }}>
 
'''Input arguments''' -string - The asset symbol the check the balance for the connected account +address: string - The asset symbol the check the balance for the connected account + +asset: string - The asset symbol the check the balance for the connected account '''Success return value''' @@ -187,7 +190,10 @@ string - `NO_PROVIDER`|`CONNECTION_DENIED` '''Example'''
-getBalance()
+getBalance({
+  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+  asset: 'NKN'
+})
 .then((result: Result) => {
   const {
     address,
@@ -195,9 +201,9 @@ getBalance()
     amount,
   } = result;
 
-  console.log('Provider address: ' + address);
-  console.log('Provider public key: ' + publicKey);
-  console.log('Provider public key: ' + publicKey);
+  console.log('Connected address: ' + address);
+  console.log('Asset: ' + asset);
+  console.log('Amount: ' + amount);
 })
 .catch((err: string) => {
   switch(err) {
@@ -212,7 +218,7 @@ getBalance()
 
-====send==== +=====send===== Invoke a transfer of a specified amount of a given asset from the connected account to another account. '''Method Interface''' @@ -274,9 +280,9 @@ send({ }); -===Smart Contract=== +====Smart Contract==== -====invokeRead==== +=====invokeRead===== Execute a contract invocation in read-only mode. '''Method Interface''' @@ -343,7 +349,7 @@ invokeRead({ -====invoke==== +=====invoke===== Execute a contract invocation. '''Method Interface''' @@ -409,7 +415,7 @@ invoke({ -====getStorage==== +=====getStorage===== Reads the raw value in smart contract storage. '''Method Interface''' @@ -456,6 +462,117 @@ getStorage({ }); + +===Provider Request Handling=== +====getProvider==== +Upon receiving this request, return: +* The name of the provider wallet +* The privider specifc version of the wallet +* A list of NEP for which the specific provider protocol is compatable with + +'''Example''' +
+{
+  name: 'Awesome Wallet',
+  version: 'v0.0.1',
+  compatibility: [
+    'NEP-14',
+    'NEP-23',
+    'NEP-29'
+  ]
+}
+
+ +====getAccount==== +Upon receiving this request, return: +- The address and public key of account currently selected by the user in the wallet interface + +'''Example''' +
+{
+  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+  publicKey: '03d43468721ef8936548878071b534d8228c313e02e6d90cef8c65fd3c2d4eaeed'
+}
+
+ +====getBalance==== +Upon receiving this request, fetch the latest balance of the given account for the specific asset, and return the amount with an echo of the request details. + +'''Example''' +
+{
+  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+  asset: 'NKN',
+  amount: '0.00000233'
+}
+
+ +====send==== +Upon receiving this request +* Validate the inputs +** Receiver address is valid +** Asset symbol is valid +** Amount is valid value, and account has enough balance +* Broadcast the RPC request +* Return the transaction Id + +'''Example''' +
+'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77'
+
+ +====invokeRead==== +Upon receiving this request +* Validate and format the inputs +** Script hash is valid +** Format parameters +*** If `byteArray`, convert to appropriate hexstring based on assumed format +* Broadcast the RPC request +* Return the RPC response results + +'''Example''' +
+{
+  script: '8h89fh398f42f.....89hf2894hf9834',
+  state: 'HALT, BREAK',
+  gas_consumed: '0.13',
+  stack: [
+    {
+      type: 'Integer',
+      value: '1337'
+    }
+  ]
+}
+
+ +====invoke==== + +Upon receiving this request +* Validate and format the inputs +** Script hash is valid +** Format parameters +*** If `byteArray`, convert to appropriate hexstring based on assumed format +* Broadcast the RPC request +* Return the transaction id + +'''Example''' +
+'34e07328e50984b28a26e3a534878f7db23a8b6827fbfbb20419c3b6b7410129'
+
+ +====getStorage==== + +Upon receiving this request +* Validate and format the inputs +** Script hash is valid +* Broadcast the RPC request +* Return the RPC response results + +'''Example''' +
+'hello world'
+
+ ==Rational== This protocol will allow dApp developers to create applications that interact with the NEO blockchain without having to be concerned about managing a full wallet within their application or the details related to handing transaction creation or broadcasting. This will also allow dApps to allow users to transact in a secure fashion that does not require sharing of their private key. From 97d3e59ed4b8926b096da728477a88b15de316e6 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 13 Sep 2018 15:52:51 +0900 Subject: [PATCH 17/96] Update nep-dapi.mediawiki --- nep-dapi.mediawiki | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 420d583d..3e85ff96 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -42,8 +42,7 @@ Additionally, since there are a significant amount of overlap in the protocols b ==Specification== ===dApp API Interface=== -====Provider==== -=====getProvider===== +====getProvider==== Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. '''Method Interface''' @@ -107,8 +106,7 @@ getProvider() }); -====Assets==== -=====getAccount===== +====getAccount==== Return the Account that is currently connected to the dApp. '''Method Interface''' @@ -158,7 +156,7 @@ getAccount() -=====getBalance===== +====getBalance==== Return balance of a specific asset for the given account. '''Method Interface''' @@ -218,7 +216,7 @@ getBalance({ -=====send===== +====send==== Invoke a transfer of a specified amount of a given asset from the connected account to another account. '''Method Interface''' @@ -280,9 +278,8 @@ send({ }); -====Smart Contract==== -=====invokeRead===== +====invokeRead==== Execute a contract invocation in read-only mode. '''Method Interface''' @@ -349,7 +346,7 @@ invokeRead({ -=====invoke===== +====invoke==== Execute a contract invocation. '''Method Interface''' @@ -415,7 +412,7 @@ invoke({ -=====getStorage===== +====getStorage==== Reads the raw value in smart contract storage. '''Method Interface''' @@ -464,6 +461,8 @@ getStorage({ ===Provider Request Handling=== +Implementation details of per dApp domain handling will be left to the discression of the wallet provider. Proviers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface. + ====getProvider==== Upon receiving this request, return: * The name of the provider wallet From cb70c793db4f99e566a7591947f6dd885b3c391b Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 13 Sep 2018 15:59:36 +0900 Subject: [PATCH 18/96] provider example formattting --- nep-dapi.mediawiki | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 3e85ff96..ea80c1ae 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -469,7 +469,7 @@ Upon receiving this request, return: * The privider specifc version of the wallet * A list of NEP for which the specific provider protocol is compatable with -'''Example''' +Example
 {
   name: 'Awesome Wallet',
@@ -486,7 +486,7 @@ Upon receiving this request, return:
 Upon receiving this request, return:
 - The address and public key of account currently selected by the user in the wallet interface
 
-'''Example'''
+Example
 
 {
   address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
@@ -497,7 +497,7 @@ Upon receiving this request, return:
 ====getBalance====
 Upon receiving this request, fetch the latest balance of the given account for the specific asset, and return the amount with an echo of the request details.
 
-'''Example'''
+Example
 
 {
   address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
@@ -515,7 +515,7 @@ Upon receiving this request
 * Broadcast the RPC request
 * Return the transaction Id
 
-'''Example'''
+Example
 
 'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77'
 
@@ -529,7 +529,7 @@ Upon receiving this request * Broadcast the RPC request * Return the RPC response results -'''Example''' +Example
 {
   script: '8h89fh398f42f.....89hf2894hf9834',
@@ -554,7 +554,7 @@ Upon receiving this request
 * Broadcast the RPC request
 * Return the transaction id
 
-'''Example'''
+Example
 
 '34e07328e50984b28a26e3a534878f7db23a8b6827fbfbb20419c3b6b7410129'
 
@@ -567,7 +567,7 @@ Upon receiving this request * Broadcast the RPC request * Return the RPC response results -'''Example''' +Example
 'hello world'
 
From 9303ac8aa6bd8652b14a65da9bc8193cd3084e37 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 13 Sep 2018 16:26:52 +0900 Subject: [PATCH 19/96] update send `receiver` to `to` --- nep-dapi.mediawiki | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index ea80c1ae..f667e842 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -222,12 +222,12 @@ Invoke a transfer of a specified amount of a given asset from the connected acco '''Method Interface'''
-function send({ receiver: string, asset: string, amount: string, remark?: string }): Promise
+function send({ to: string, asset: string, amount: string, remark?: string }): Promise
 
'''Input arguments''' -receiver: string - Address of the receiver of the assets to be sent +to: string - Address of the receiver of the assets to be sent asset: string - The symbol of the asset to be sent @@ -249,7 +249,7 @@ string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CA
 send({
-  receiver: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d',
+  to: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d',
   asset: 'GAS',
   amount: '0.0001',
   remark: 'Hash puppy clothing purchase. Invoice#abc123',
@@ -509,7 +509,7 @@ Example
 ====send====
 Upon receiving this request
 * Validate the inputs
-** Receiver address is valid
+** To address is valid
 ** Asset symbol is valid
 ** Amount is valid value, and account has enough balance
 * Broadcast the RPC request

From 36ea766816607e201d33aafb76e497effdb174ac Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Fri, 14 Sep 2018 16:45:12 +0900
Subject: [PATCH 20/96] add website to provider return details

---
 nep-dapi.mediawiki | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index f667e842..536ae3c0 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -61,6 +61,7 @@ object - Provider information defined by the interface below:
 
 interface Provider {
   name: string;
+  website: string;
   version: string;
   compatibility: string[];
 }
@@ -86,11 +87,13 @@ getProvider()
 .then((provider: Provider) => {
   const {
     name,
+    website,
     version,
     compatibility,
   } = provider;
 
   console.log('Provider name: ' + name);
+  console.log('Provider website: ' + website);
   console.log('Provider dAPI version: ' + version);
   console.log('Provider dAPI compatibility: ' + JSON.stringify(compatibility));
 })
@@ -466,6 +469,7 @@ Implementation details of per dApp domain handling will be left to the discressi
 ====getProvider====
 Upon receiving this request, return:
 * The name of the provider wallet
+* The provider website
 * The privider specifc version of the wallet
 * A list of NEP for which the specific provider protocol is compatable with
 
@@ -473,6 +477,7 @@ Example
 
 {
   name: 'Awesome Wallet',
+  website: 'https://www.awesome.com',
   version: 'v0.0.1',
   compatibility: [
     'NEP-14',

From b833e908e795c6c6bb1650d08324cfb6f0b87699 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Mon, 15 Oct 2018 15:28:58 +0900
Subject: [PATCH 21/96] clean up typos

---
 nep-dapi.mediawiki | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index 536ae3c0..6ebf54f6 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -170,7 +170,7 @@ function getBalance({ address: string, asset: string }): Promise<{ address: stri
 
 '''Input arguments'''
 
-address: string - The asset symbol the check the balance for the connected account
+address: string - The address to check the balance for the connected account
 
 asset: string - The asset symbol the check the balance for the connected account
 
@@ -427,7 +427,7 @@ function getStorage({ scriptHash: string, key: string }): Promise
 '''Input arguments'''
 
 scriptHash: string - script hash of the smart contract to invoke a read on
-key: string - key of the storage value to retreive from the contract
+key: string - key of the storage value to retrieve from the contract
 
 '''Success return value'''
 
@@ -464,14 +464,14 @@ getStorage({
 
 
 ===Provider Request Handling===
-Implementation details of per dApp domain handling will be left to the discression of the wallet provider. Proviers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface.
+Implementation details of per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface.
 
 ====getProvider====
 Upon receiving this request, return:
 * The name of the provider wallet
 * The provider website
-* The privider specifc version of the wallet
-* A list of NEP for which the specific provider protocol is compatable with
+* The provider specific version of the wallet
+* A list of NEP for which the specific provider protocol is compatible with
 
 Example
 

From 72f57cf84cc5a2affda50e0aa461ac05a82c7efe Mon Sep 17 00:00:00 2001
From: nicolasfujita 
Date: Mon, 15 Oct 2018 23:30:38 +0900
Subject: [PATCH 22/96] add send network fee

---
 nep-dapi.mediawiki | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index 6ebf54f6..c3b128a1 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -225,7 +225,7 @@ Invoke a transfer of a specified amount of a given asset from the connected acco
 '''Method Interface'''
 
 
-function send({ to: string, asset: string, amount: string, remark?: string }): Promise
+function send({ to: string, asset: string, amount: string, remark?: string, fee?: string }): Promise
 
'''Input arguments''' @@ -238,6 +238,8 @@ amount: string - The parsed amount of the asset to be sent remark?: string - (Optional) Description of the transaction to be made +fee?: string - (Optional) The parsed amount of network fee (in GAS) to include with transaction + '''Success return value''' @@ -256,6 +258,7 @@ send({ asset: 'GAS', amount: '0.0001', remark: 'Hash puppy clothing purchase. Invoice#abc123', + fee: '0.0001', }) .then((txid: string) => { console.log('Send transaction success! Transaction ID: ' + txid); From abe15fad5e8bafb800aa21a971566d605ac6dcec Mon Sep 17 00:00:00 2001 From: nicolasfujita Date: Mon, 15 Oct 2018 23:36:17 +0900 Subject: [PATCH 23/96] add transfer insufficient funds error --- nep-dapi.mediawiki | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index c3b128a1..d34bbdde 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -248,7 +248,7 @@ txid: string - The transaction ID of the send invocation '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED` +string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED`|`INSUFFICIENT_FUNDS` '''Example''' @@ -269,17 +269,20 @@ send({ console.log('No provider available.'); break; case CONNECTION_REFUSED: - console.log('Connection dApp not connected. Please call the "connect" function.'); + console.log('dApp not connected. Please call the "connect" function.'); break; - case SEND_ERROR: - console.log('There was an error when broadcasting this transaction to the network.'); - break; - case MALFORMED_ADDRESS: + case SEND_ERROR: + console.log('There was an error when broadcasting this transaction to the network.'); + break; + case MALFORMED_ADDRESS: console.log('The receiver address provided is not valid.'); break; - case CANCELED: - console.log('The user has canceled this transaction.'); - break; + case CANCELED: + console.log('The user has canceled this transaction.'); + break; + case INSUFFICIENT_FUNDS: + console.log('The user has insufficient funds to execute this transaction.'); + break; } });
From 60135a5dbffbdab1b2c3d4ffc02b0a80d36ff636 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 12:15:04 +0900 Subject: [PATCH 24/96] Reorganize method details to consolidate sections --- nep-dapi.mediawiki | 218 ++++++++++++++++++++++----------------------- 1 file changed, 106 insertions(+), 112 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index d34bbdde..cd9aa4ca 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -41,8 +41,10 @@ Additionally, since there are a significant amount of overlap in the protocols b ==Specification== -===dApp API Interface=== -====getProvider==== +'''Provider Request Handling''' +Implementation details of per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface. + +===getProvider=== Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. '''Method Interface''' @@ -109,7 +111,28 @@ getProvider() });
-====getAccount==== +'''Provider Request Handling''' +Upon receiving this request, return: +* The name of the provider wallet +* The provider website +* The provider specific version of the wallet +* A list of NEP for which the specific provider protocol is compatible with + +Example +
+{
+  name: 'Awesome Wallet',
+  website: 'https://www.awesome.com',
+  version: 'v0.0.1',
+  compatibility: [
+    'NEP-14',
+    'NEP-23',
+    'NEP-29'
+  ]
+}
+
+ +===getAccount=== Return the Account that is currently connected to the dApp. '''Method Interface''' @@ -157,9 +180,20 @@ getAccount() });
+'''Provider Request Handling''' +Upon receiving this request, return: +- The address and public key of account currently selected by the user in the wallet interface + +Example +
+{
+  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+  publicKey: '03d43468721ef8936548878071b534d8228c313e02e6d90cef8c65fd3c2d4eaeed'
+}
+
-====getBalance==== +===getBalance=== Return balance of a specific asset for the given account. '''Method Interface''' @@ -218,8 +252,20 @@ getBalance({ });
+'''Provider Request Handling''' +Upon receiving this request, fetch the latest balance of the given account for the specific asset, and return the amount with an echo of the request details. -====send==== +Example +
+{
+  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+  asset: 'NKN',
+  amount: '0.00000233'
+}
+
+ + +===send=== Invoke a transfer of a specified amount of a given asset from the connected account to another account. '''Method Interface''' @@ -287,8 +333,21 @@ send({ });
+'''Provider Request Handling''' +Upon receiving this request +* Validate the inputs +** To address is valid +** Asset symbol is valid +** Amount is valid value, and account has enough balance +* Broadcast the RPC request +* Return the transaction Id + +Example +
+'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77'
+
-====invokeRead==== +===invokeRead=== Execute a contract invocation in read-only mode. '''Method Interface''' @@ -354,8 +413,32 @@ invokeRead({ });
+'''Provider Request Handling''' +Upon receiving this request +* Validate and format the inputs +** Script hash is valid +** Format parameters +*** If `byteArray`, convert to appropriate hexstring based on assumed format +* Broadcast the RPC request +* Return the RPC response results -====invoke==== +Example +
+{
+  script: '8h89fh398f42f.....89hf2894hf9834',
+  state: 'HALT, BREAK',
+  gas_consumed: '0.13',
+  stack: [
+    {
+      type: 'Integer',
+      value: '1337'
+    }
+  ]
+}
+
+ + +===invoke=== Execute a contract invocation. '''Method Interface''' @@ -420,8 +503,22 @@ invoke({ });
+'''Provider Request Handling''' +Upon receiving this request +* Validate and format the inputs +** Script hash is valid +** Format parameters +*** If `byteArray`, convert to appropriate hexstring based on assumed format +* Broadcast the RPC request +* Return the transaction id -====getStorage==== +Example +
+'34e07328e50984b28a26e3a534878f7db23a8b6827fbfbb20419c3b6b7410129'
+
+ + +===getStorage=== Reads the raw value in smart contract storage. '''Method Interface''' @@ -468,110 +565,7 @@ getStorage({ });
- -===Provider Request Handling=== -Implementation details of per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface. - -====getProvider==== -Upon receiving this request, return: -* The name of the provider wallet -* The provider website -* The provider specific version of the wallet -* A list of NEP for which the specific provider protocol is compatible with - -Example -
-{
-  name: 'Awesome Wallet',
-  website: 'https://www.awesome.com',
-  version: 'v0.0.1',
-  compatibility: [
-    'NEP-14',
-    'NEP-23',
-    'NEP-29'
-  ]
-}
-
- -====getAccount==== -Upon receiving this request, return: -- The address and public key of account currently selected by the user in the wallet interface - -Example -
-{
-  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
-  publicKey: '03d43468721ef8936548878071b534d8228c313e02e6d90cef8c65fd3c2d4eaeed'
-}
-
- -====getBalance==== -Upon receiving this request, fetch the latest balance of the given account for the specific asset, and return the amount with an echo of the request details. - -Example -
-{
-  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
-  asset: 'NKN',
-  amount: '0.00000233'
-}
-
- -====send==== -Upon receiving this request -* Validate the inputs -** To address is valid -** Asset symbol is valid -** Amount is valid value, and account has enough balance -* Broadcast the RPC request -* Return the transaction Id - -Example -
-'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77'
-
- -====invokeRead==== -Upon receiving this request -* Validate and format the inputs -** Script hash is valid -** Format parameters -*** If `byteArray`, convert to appropriate hexstring based on assumed format -* Broadcast the RPC request -* Return the RPC response results - -Example -
-{
-  script: '8h89fh398f42f.....89hf2894hf9834',
-  state: 'HALT, BREAK',
-  gas_consumed: '0.13',
-  stack: [
-    {
-      type: 'Integer',
-      value: '1337'
-    }
-  ]
-}
-
- -====invoke==== - -Upon receiving this request -* Validate and format the inputs -** Script hash is valid -** Format parameters -*** If `byteArray`, convert to appropriate hexstring based on assumed format -* Broadcast the RPC request -* Return the transaction id - -Example -
-'34e07328e50984b28a26e3a534878f7db23a8b6827fbfbb20419c3b6b7410129'
-
- -====getStorage==== - +'''Provider Request Handling''' Upon receiving this request * Validate and format the inputs ** Script hash is valid From 9a38fad435d7ad97b48af7ac42d173f93fb730dc Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 12:20:46 +0900 Subject: [PATCH 25/96] fix raw line spacing --- nep-dapi.mediawiki | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index cd9aa4ca..0cd9ba34 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -47,16 +47,19 @@ Implementation details of per dApp domain handling will be left to the discretio ===getProvider=== Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. + '''Method Interface'''
 function getProvider(): Promise
 
+ '''Input arguments''' None + '''Success return value''' object - Provider information defined by the interface below: @@ -78,10 +81,12 @@ compatibility: [ ] + '''Error return value''' string - `NO_PROVIDER`|`CONNECTION_DENIED` + '''Example'''
@@ -111,7 +116,9 @@ getProvider()
 });
 
+ '''Provider Request Handling''' + Upon receiving this request, return: * The name of the provider wallet * The provider website @@ -135,26 +142,31 @@ Example ===getAccount=== Return the Account that is currently connected to the dApp. + '''Method Interface'''
 function getAccount(): Promise<{ address: string, publicKey: string }>
 
+ '''Input arguments''' None + '''Success return value''' address: string - Address of the connected account publicKey: string - Address of the connected account + '''Error return value''' string - `NO_PROVIDER`|`CONNECTION_DENIED` + '''Example'''
@@ -180,7 +192,9 @@ getAccount()
 });
 
+ '''Provider Request Handling''' + Upon receiving this request, return: - The address and public key of account currently selected by the user in the wallet interface @@ -196,12 +210,14 @@ Example ===getBalance=== Return balance of a specific asset for the given account. + '''Method Interface'''
 function getBalance({ address: string, asset: string }): Promise<{ address: string, asset: string, amount: string }}>
 
+ '''Input arguments''' address: string - The address to check the balance for the connected account @@ -222,6 +238,7 @@ amount: string - Parsed balance of the requested asset string - `NO_PROVIDER`|`CONNECTION_DENIED` + '''Example'''
@@ -252,7 +269,9 @@ getBalance({
 });
 
+ '''Provider Request Handling''' + Upon receiving this request, fetch the latest balance of the given account for the specific asset, and return the amount with an echo of the request details. Example @@ -268,12 +287,14 @@ Example ===send=== Invoke a transfer of a specified amount of a given asset from the connected account to another account. + '''Method Interface'''
 function send({ to: string, asset: string, amount: string, remark?: string, fee?: string }): Promise
 
+ '''Input arguments''' to: string - Address of the receiver of the assets to be sent @@ -296,6 +317,7 @@ txid: string - The transaction ID of the send invocation string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED`|`INSUFFICIENT_FUNDS` + '''Example'''
@@ -333,7 +355,9 @@ send({
 });
 
+ '''Provider Request Handling''' + Upon receiving this request * Validate the inputs ** To address is valid @@ -350,6 +374,7 @@ Example ===invokeRead=== Execute a contract invocation in read-only mode. + '''Method Interface'''
@@ -366,7 +391,9 @@ function invokeRead({ scriptHash: string, operation: string, args: Argument[] })
 '''Input arguments'''
 
 scriptHash: string - script hash of the smart contract to invoke a read on
+
 operation: string - operation on the smart contract to call
+
 args: Argument[] - any input arguments for the operation
 
 
@@ -374,10 +401,12 @@ args: Argument[] - any input arguments for the operation
 
 result: Object - Response from RPC node
 
+
 '''Error return value'''
 
 string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR`
 
+
 '''Example'''
 
 
@@ -413,7 +442,9 @@ invokeRead({
 });
 
+ '''Provider Request Handling''' + Upon receiving this request * Validate and format the inputs ** Script hash is valid @@ -441,6 +472,7 @@ Example ===invoke=== Execute a contract invocation. + '''Method Interface'''
@@ -454,10 +486,13 @@ interface Argument {
 function invoke({ scriptHash: string, operation: string, args: Argument[] }): Promise
 
+ '''Input arguments''' scriptHash: string - script hash of the smart contract to invoke a read on + operation: string - operation on the smart contract to call + args: Argument[] - any input arguments for the operation @@ -465,10 +500,12 @@ args: Argument[] - any input arguments for the operation txid: string - The transaction ID of the invocation + '''Error return value''' string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED` + '''Example'''
@@ -503,7 +540,9 @@ invoke({
 });
 
+ '''Provider Request Handling''' + Upon receiving this request * Validate and format the inputs ** Script hash is valid @@ -521,25 +560,31 @@ Example ===getStorage=== Reads the raw value in smart contract storage. + '''Method Interface'''
 function getStorage({ scriptHash: string, key: string }): Promise
 
+ '''Input arguments''' scriptHash: string - script hash of the smart contract to invoke a read on + key: string - key of the storage value to retrieve from the contract + '''Success return value''' value: string - The raw value that's stored in the contract + '''Error return value''' string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR` + '''Example'''
@@ -565,7 +610,9 @@ getStorage({
 });
 
+ '''Provider Request Handling''' + Upon receiving this request * Validate and format the inputs ** Script hash is valid From b86633c63f3cc9fe2af02385da59b4ca8ac6aaff Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 12:27:57 +0900 Subject: [PATCH 26/96] Formatting dapp provider list --- nep-dapi.mediawiki | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 0cd9ba34..c6499b4d 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -29,10 +29,10 @@ While there may be several options for 3rd party wallet providers that will help Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Wallet providers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplication an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted by both the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have a unified interface for such transactions, providers can spend more time on making their individual services better for their users. The current list of wallet providers that can benefit from the use of this protocol are currently: -- nOS dApps browser -- NeoLink Chrome extension -- NEX Chrome extension -- O3 dApps browser +* nOS dApps browser +* NeoLink Chrome extension +* NEX Chrome extension +* O3 dApps browser Each wallet provider has their own value proposition to it's users beyond the interface from this protocol itself, so it seems that formalizing it would be a net positive for all. From 4e906ce038efcc96e11c0f1245df8bbe6737ad00 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 14:28:29 +0900 Subject: [PATCH 27/96] Update method inputs formatting --- nep-dapi.mediawiki | 103 ++++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index c6499b4d..160c4731 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -42,6 +42,7 @@ Additionally, since there are a significant amount of overlap in the protocols b ==Specification== '''Provider Request Handling''' + Implementation details of per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface. ===getProvider=== @@ -157,9 +158,12 @@ None '''Success return value''' -address: string - Address of the connected account - -publicKey: string - Address of the connected account +
+interface Account {
+  address: string; // Address of the connected account
+  publicKey: string; // Public key of the connected account
+}
+
'''Error return value''' @@ -220,18 +224,23 @@ function getBalance({ address: string, asset: string }): Promise<{ address: stri '''Input arguments''' -address: string - The address to check the balance for the connected account - -asset: string - The asset symbol the check the balance for the connected account +
+interface GetBalanceArgs {
+  address: string; // Address to check balance(s)
+  asset: string; // Asset symbol or script hash to check balance
+}
+
'''Success return value''' -address: string - Address of the connected account - -asset: string - Asset symbol for the requested balance - -amount: string - Parsed balance of the requested asset +
+interface Balance {
+  address: string; // Address to check balance(s)
+  asset: string; // Asset symbol or script hash to check balance
+  amount: string; // Parsed balance of the requested asset
+}
+
'''Error return value''' @@ -246,7 +255,7 @@ getBalance({ address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru', asset: 'NKN' }) -.then((result: Result) => { +.then((result: Balance) => { const { address, asset, @@ -297,15 +306,15 @@ function send({ to: string, asset: string, amount: string, remark?: string, fee? '''Input arguments''' -to: string - Address of the receiver of the assets to be sent - -asset: string - The symbol of the asset to be sent - -amount: string - The parsed amount of the asset to be sent - -remark?: string - (Optional) Description of the transaction to be made - -fee?: string - (Optional) The parsed amount of network fee (in GAS) to include with transaction +
+interface SendArgs {
+  to: string; // Address of the receiver of the assets to be sent
+  asset: string; // The symbol of the asset to be sent
+  amount: string; // The parsed amount of the asset to be sent
+  remark?: string; // (Optional) Description of the transaction to be made
+  fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction
+}
+
'''Success return value''' @@ -378,23 +387,26 @@ Execute a contract invocation in read-only mode. '''Method Interface'''
-type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`;
-
-interface Argument {
-  type: ArgumentType;
-  value: any;
-}
 
 function invokeRead({ scriptHash: string, operation: string, args: Argument[] }): Promise
 
'''Input arguments''' -scriptHash: string - script hash of the smart contract to invoke a read on +
+interface InvokeReadArgs {
+  scriptHash: string; // script hash of the smart contract to invoke a read on
+  operation: string; // operation on the smart contract to call
+  args: Argument[]; // any input arguments for the operation
+}
 
-operation: string - operation on the smart contract to call
+interface Argument {
+  type: ArgumentType;
+  value: any;
+}
 
-args: Argument[] - any input arguments for the operation
+type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`;
+
'''Success return value''' @@ -476,24 +488,26 @@ Execute a contract invocation. '''Method Interface'''
-type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`;
-
-interface Argument {
-  type: ArgumentType;
-  value: any;
-}
-
 function invoke({ scriptHash: string, operation: string, args: Argument[] }): Promise
 
'''Input arguments''' -scriptHash: string - script hash of the smart contract to invoke a read on +
+interface InvokeArgs {
+  scriptHash: string; // script hash of the smart contract to invoke
+  operation: string; // operation on the smart contract to call
+  args: Argument[]; // any input arguments for the operation
+}
 
-operation: string - operation on the smart contract to call
+interface Argument {
+  type: ArgumentType;
+  value: any;
+}
 
-args: Argument[] - any input arguments for the operation
+type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`;
+
'''Success return value''' @@ -570,9 +584,12 @@ function getStorage({ scriptHash: string, key: string }): Promise '''Input arguments''' -scriptHash: string - script hash of the smart contract to invoke a read on - -key: string - key of the storage value to retrieve from the contract +
+interface GetStorageArgs {
+  scriptHash: string; // script hash of the smart contract to invoke a read on
+  key: string; // key of the storage value to retrieve from the contract
+}
+
'''Success return value''' From bea61c8c15edd0205ccb83a21ae3ecd2cd522f04 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 15:31:06 +0900 Subject: [PATCH 28/96] Update getBalance to support multiple requests --- nep-dapi.mediawiki | 106 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 23 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 160c4731..a93252ac 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -218,16 +218,16 @@ Return balance of a specific asset for the given account. '''Method Interface'''
-function getBalance({ address: string, asset: string }): Promise<{ address: string, asset: string, amount: string }}>
+function getBalance(args: BalanceRequest|BalanceRequest[]): Promise}>
 
'''Input arguments'''
-interface GetBalanceArgs {
+interface BalanceRequest {
   address: string; // Address to check balance(s)
-  asset: string; // Asset symbol or script hash to check balance
+  asset?: string; // Asset symbol or script hash to check balance
 }
 
@@ -235,11 +235,15 @@ interface GetBalanceArgs { '''Success return value'''
-interface Balance {
-  address: string; // Address to check balance(s)
-  asset: string; // Asset symbol or script hash to check balance
-  amount: string; // Parsed balance of the requested asset
+interface BalanceResults {
+  [address: string]: Balances;
+}
+
+interface Balances {
+  [asset: string]: amount: string;
 }
+// Asset symbol or script hash to check balance
+// Parsed balance of the requested asset
 
@@ -255,16 +259,21 @@ getBalance({ address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru', asset: 'NKN' }) -.then((result: Balance) => { - const { - address, - asset, - amount, - } = result; - - console.log('Connected address: ' + address); - console.log('Asset: ' + asset); - console.log('Amount: ' + amount); +.then((results: BalanceResults) => { + // results array should return a single entry + Object.keys(results).forEach(address => { + + const { balances } = results[address]; + + Object.keys(balances).forEach(asset => { + + const amount = balances[asset]; + + console.log('Connected address: ' + address); + console.log('Asset: ' + asset); + console.log('Amount: ' + amount); + }); + }); }) .catch((err: string) => { switch(err) { @@ -278,20 +287,71 @@ getBalance({ });
+Single asset balance request sample +
+// input
+{
+  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+  asset: 'NKN'
+}
 
-'''Provider Request Handling'''
-
-Upon receiving this request, fetch the latest balance of the given account for the specific asset, and return the amount with an echo of the request details.
+// output
+{
+  'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': {
+    'NKN': '0.00000233',
+  },
+}
+
-Example +Single account balances request sample
+// input
 {
   address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
-  asset: 'NKN',
-  amount: '0.00000233'
+}
+
+// output
+{
+  'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': {
+    'NEO': '10',
+    'GAS': '777.0001',
+    'NKN': '0.00000233',
+    'NNC': '2000',
+  },
+}
+
+Multiple account balances request sample
+
+// input
+[
+  {
+    address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+  },
+  {
+    address: 'AbKNY45nRDy6B65YPVz1B6YXiTnzRqU2uQ',
+    asset: 'PHX',
+  },
+]
+
+// output
+{
+  'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': {
+    'NEO': '10',
+    'GAS': '777.0001',
+    'NKN': '0.00000233',
+    'NNC': '2000',
+  },
+  'AbKNY45nRDy6B65YPVz1B6YXiTnzRqU2uQ': {
+    'PHX': '11000',
+  },
 }
 
+'''Provider Request Handling''' + +Upon receiving this request, fetch the latest balance(s) for each given account, for the specific asset if applicable. +Typechecking will be required on the input argument, as it can be eather a single BalanceRequest object, or an array of BalanceRequest objects. In the case where a specific asset is not provided to check the balance for, the wallet provider will fetch balances for all assets and tokens for that account. + ===send=== Invoke a transfer of a specified amount of a given asset from the connected account to another account. From 1d52c9201dd84df2fbf451acbb360be56cc271ae Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 15:41:37 +0900 Subject: [PATCH 29/96] Update Invoke to allow attached assets --- nep-dapi.mediawiki | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index a93252ac..55dfa9b1 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -240,10 +240,10 @@ interface BalanceResults { } interface Balances { - [asset: string]: amount: string; + [asset: string]: string; } -// Asset symbol or script hash to check balance -// Parsed balance of the requested asset +// KEY: Asset symbol or script hash to check balance +// VALUE: Parsed balance of the requested asset
@@ -260,15 +260,11 @@ getBalance({ asset: 'NKN' }) .then((results: BalanceResults) => { - // results array should return a single entry Object.keys(results).forEach(address => { - const { balances } = results[address]; - Object.keys(balances).forEach(asset => { - const amount = balances[asset]; - + console.log('Connected address: ' + address); console.log('Asset: ' + asset); console.log('Amount: ' + amount); @@ -548,7 +544,7 @@ Execute a contract invocation. '''Method Interface'''
-function invoke({ scriptHash: string, operation: string, args: Argument[] }): Promise
+function invoke({ scriptHash: string, operation: string, args: Argument[], assets?: AttachedAssets }): Promise
 
@@ -559,6 +555,7 @@ interface InvokeArgs { scriptHash: string; // script hash of the smart contract to invoke operation: string; // operation on the smart contract to call args: Argument[]; // any input arguments for the operation + assets?: AttachedAssets } interface Argument { @@ -567,6 +564,12 @@ interface Argument { } type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`; + +interface AttachedAssets { + [asset: 'NEO'|'GAS']: string, +} +// KEY: Asset symbol (only NEO or GAS) +// VALUE: Parsed amount to attach @@ -592,6 +595,10 @@ invoke({ value: 'hello' } ], + assets: { + NEO: '100', + GAS: '0.0001', + }, }) .then((txid: string) => { console.log('Invoke transaction success! Transaction ID: ' + txid); From a6158d6bc1bc8d25a8ca0edf836d9a408f50ec97 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 16:02:14 +0900 Subject: [PATCH 30/96] Add getNetwork method --- nep-dapi.mediawiki | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 55dfa9b1..000c956e 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -140,6 +140,70 @@ Example } + +===getNetwork=== +Return the network the wallet provider is connected to. + + +'''Method Interface''' + +
+function getNetwork(): Promise<{ network: Network }>
+
+ + +'''Input arguments''' + +None + + +'''Success return value''' + +
+enum Network {
+  MainNet = 'MainNet';
+  TestNet = 'TestNet';
+  PrivateNet = 'PrivateNet';
+}
+
+ + +'''Error return value''' + +string - `NO_PROVIDER`|`CONNECTION_DENIED` + + +'''Example''' + +
+getNetwork()
+.then((network: Network) => {
+  console.log('Network: ' + network);
+})
+.catch((err: string) => {
+  switch(err) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case CONNECTION_DENIED:
+      console.log('The user rejected the request to connect with your dApp');
+      break;
+  }
+});
+
+ + +'''Provider Request Handling''' + +Upon receiving this request, return: +- The NEO network which the wallet provider is connected to. + +Example +
+'MainNet'
+
+ + ===getAccount=== Return the Account that is currently connected to the dApp. From 10aa3539e5a3b9b86416a54d14dff04cffd3f997 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 16:16:33 +0900 Subject: [PATCH 31/96] Update method categories --- nep-dapi.mediawiki | 214 +++++++++++++++++++++++---------------------- 1 file changed, 109 insertions(+), 105 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 000c956e..caa3706c 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -45,7 +45,8 @@ Additionally, since there are a significant amount of overlap in the protocols b Implementation details of per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface. -===getProvider=== +===Read Methods=== +====getProvider==== Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. @@ -141,7 +142,7 @@ Example -===getNetwork=== +====getNetwork==== Return the network the wallet provider is connected to. @@ -204,7 +205,7 @@ Example -===getAccount=== +====getAccount==== Return the Account that is currently connected to the dApp. @@ -275,7 +276,7 @@ Example -===getBalance=== +====getBalance==== Return balance of a specific asset for the given account. @@ -413,52 +414,46 @@ Upon receiving this request, fetch the latest balance(s) for each given account, Typechecking will be required on the input argument, as it can be eather a single BalanceRequest object, or an array of BalanceRequest objects. In the case where a specific asset is not provided to check the balance for, the wallet provider will fetch balances for all assets and tokens for that account. -===send=== -Invoke a transfer of a specified amount of a given asset from the connected account to another account. +====getStorage==== +Reads the raw value in smart contract storage. '''Method Interface'''
-function send({ to: string, asset: string, amount: string, remark?: string, fee?: string }): Promise
+function getStorage({ scriptHash: string, key: string }): Promise
 
'''Input arguments'''
-interface SendArgs {
-  to: string; // Address of the receiver of the assets to be sent
-  asset: string; // The symbol of the asset to be sent
-  amount: string; // The parsed amount of the asset to be sent
-  remark?: string; // (Optional) Description of the transaction to be made
-  fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction
+interface GetStorageArgs {
+  scriptHash: string; // script hash of the smart contract to invoke a read on
+  key: string; // key of the storage value to retrieve from the contract
 }
 
'''Success return value''' -txid: string - The transaction ID of the send invocation +value: string - The raw value that's stored in the contract '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED`|`INSUFFICIENT_FUNDS` +string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR` '''Example'''
-send({
-  to: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d',
-  asset: 'GAS',
-  amount: '0.0001',
-  remark: 'Hash puppy clothing purchase. Invoice#abc123',
-  fee: '0.0001',
+getStorage({
+  scriptHash: '505663a29d83663a838eee091249abd167e928f5',
+  key: 'game.status'
 })
-.then((txid: string) => {
-  console.log('Send transaction success! Transaction ID: ' + txid);
+.then((value: string) => {
+  console.log('Storage value: ' + value);
 })
 .catch((err: string) => {
   switch(err) {
@@ -466,20 +461,11 @@ send({
       console.log('No provider available.');
       break;
     case CONNECTION_REFUSED:
-      console.log('dApp not connected. Please call the "connect" function.');
-      break;
-    case SEND_ERROR:
-      console.log('There was an error when broadcasting this transaction to the network.');
-      break;
-    case MALFORMED_ADDRESS:
-      console.log('The receiver address provided is not valid.');
-      break;
-    case CANCELED:
-      console.log('The user has canceled this transaction.');
-      break;
-    case INSUFFICIENT_FUNDS:
-      console.log('The user has insufficient funds to execute this transaction.');
+      console.log('Connection dApp not connected. Please call the "connect" function.');
       break;
+   case RPC_ERROR:
+    console.log('There was an error when broadcasting this transaction to the network.');
+    break;
   }
 });
 
@@ -488,19 +474,18 @@ send({ '''Provider Request Handling''' Upon receiving this request -* Validate the inputs -** To address is valid -** Asset symbol is valid -** Amount is valid value, and account has enough balance +* Validate and format the inputs +** Script hash is valid * Broadcast the RPC request -* Return the transaction Id +* Return the RPC response results Example
-'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77'
+'hello world'
 
-===invokeRead=== + +====invokeRead==== Execute a contract invocation in read-only mode. @@ -601,71 +586,53 @@ Example -===invoke=== -Execute a contract invocation. +===Write Methods=== +====send==== +Invoke a transfer of a specified amount of a given asset from the connected account to another account. '''Method Interface'''
-function invoke({ scriptHash: string, operation: string, args: Argument[], assets?: AttachedAssets }): Promise
+function send({ to: string, asset: string, amount: string, remark?: string, fee?: string }): Promise
 
'''Input arguments'''
-interface InvokeArgs {
-  scriptHash: string; // script hash of the smart contract to invoke
-  operation: string; // operation on the smart contract to call
-  args: Argument[]; // any input arguments for the operation
-  assets?: AttachedAssets
-}
-
-interface Argument {
-  type: ArgumentType;
-  value: any;
-}
-
-type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`;
-
-interface AttachedAssets {
-  [asset: 'NEO'|'GAS']: string,
+interface SendArgs {
+  to: string; // Address of the receiver of the assets to be sent
+  asset: string; // The symbol of the asset to be sent
+  amount: string; // The parsed amount of the asset to be sent
+  remark?: string; // (Optional) Description of the transaction to be made
+  fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction
 }
-// KEY: Asset symbol (only NEO or GAS)
-// VALUE: Parsed amount to attach
 
'''Success return value''' -txid: string - The transaction ID of the invocation +txid: string - The transaction ID of the send invocation '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED` +string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED`|`INSUFFICIENT_FUNDS` '''Example'''
-invoke({
-  scriptHash: '505663a29d83663a838eee091249abd167e928f5',
-  operation: 'storeData',
-  arguments: [
-    {
-      type: 'string',
-      value: 'hello'
-    }
-  ],
-  assets: {
-    NEO: '100',
-    GAS: '0.0001',
-  },
+send({
+  to: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d',
+  asset: 'GAS',
+  amount: '0.0001',
+  remark: 'Hash puppy clothing purchase. Invoice#abc123',
+  fee: '0.0001',
 })
 .then((txid: string) => {
-  console.log('Invoke transaction success! Transaction ID: ' + txid);
+  console.log('Send transaction success! Transaction ID: ' + txid);
 })
 .catch((err: string) => {
   switch(err) {
@@ -673,14 +640,20 @@ invoke({
       console.log('No provider available.');
       break;
     case CONNECTION_REFUSED:
-      console.log('Connection dApp not connected. Please call the "connect" function.');
+      console.log('dApp not connected. Please call the "connect" function.');
       break;
-    case RPC_ERROR:
+    case SEND_ERROR:
       console.log('There was an error when broadcasting this transaction to the network.');
       break;
+    case MALFORMED_ADDRESS:
+      console.log('The receiver address provided is not valid.');
+      break;
     case CANCELED:
       console.log('The user has canceled this transaction.');
       break;
+    case INSUFFICIENT_FUNDS:
+      console.log('The user has insufficient funds to execute this transaction.');
+      break;
   }
 });
 
@@ -689,59 +662,84 @@ invoke({ '''Provider Request Handling''' Upon receiving this request -* Validate and format the inputs -** Script hash is valid -** Format parameters -*** If `byteArray`, convert to appropriate hexstring based on assumed format +* Validate the inputs +** To address is valid +** Asset symbol is valid +** Amount is valid value, and account has enough balance * Broadcast the RPC request -* Return the transaction id +* Return the transaction Id Example
-'34e07328e50984b28a26e3a534878f7db23a8b6827fbfbb20419c3b6b7410129'
+'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77'
 
-===getStorage=== -Reads the raw value in smart contract storage. +====invoke==== +Execute a contract invocation. '''Method Interface'''
-function getStorage({ scriptHash: string, key: string }): Promise
+function invoke({ scriptHash: string, operation: string, args: Argument[], assets?: AttachedAssets }): Promise
 
'''Input arguments'''
-interface GetStorageArgs {
-  scriptHash: string; // script hash of the smart contract to invoke a read on
-  key: string; // key of the storage value to retrieve from the contract
+interface InvokeArgs {
+  scriptHash: string; // script hash of the smart contract to invoke
+  operation: string; // operation on the smart contract to call
+  args: Argument[]; // any input arguments for the operation
+  assets?: AttachedAssets
+}
+
+interface Argument {
+  type: ArgumentType;
+  value: any;
 }
+
+type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`;
+
+interface AttachedAssets {
+  [asset: 'NEO'|'GAS']: string,
+}
+// KEY: Asset symbol (only NEO or GAS)
+// VALUE: Parsed amount to attach
 
'''Success return value''' -value: string - The raw value that's stored in the contract +txid: string - The transaction ID of the invocation '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR` +string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED` '''Example'''
-getStorage({
+invoke({
   scriptHash: '505663a29d83663a838eee091249abd167e928f5',
-  key: 'game.status'
+  operation: 'storeData',
+  arguments: [
+    {
+      type: 'string',
+      value: 'hello'
+    }
+  ],
+  assets: {
+    NEO: '100',
+    GAS: '0.0001',
+  },
 })
-.then((value: string) => {
-  console.log('Storage value: ' + value);
+.then((txid: string) => {
+  console.log('Invoke transaction success! Transaction ID: ' + txid);
 })
 .catch((err: string) => {
   switch(err) {
@@ -751,9 +749,12 @@ getStorage({
     case CONNECTION_REFUSED:
       console.log('Connection dApp not connected. Please call the "connect" function.');
       break;
-   case RPC_ERROR:
-    console.log('There was an error when broadcasting this transaction to the network.');
-    break;
+    case RPC_ERROR:
+      console.log('There was an error when broadcasting this transaction to the network.');
+      break;
+    case CANCELED:
+      console.log('The user has canceled this transaction.');
+      break;
   }
 });
 
@@ -764,14 +765,17 @@ getStorage({ Upon receiving this request * Validate and format the inputs ** Script hash is valid +** Format parameters +*** If `byteArray`, convert to appropriate hexstring based on assumed format * Broadcast the RPC request -* Return the RPC response results +* Return the transaction id Example
-'hello world'
+'34e07328e50984b28a26e3a534878f7db23a8b6827fbfbb20419c3b6b7410129'
 
+ ==Rational== This protocol will allow dApp developers to create applications that interact with the NEO blockchain without having to be concerned about managing a full wallet within their application or the details related to handing transaction creation or broadcasting. This will also allow dApps to allow users to transact in a secure fashion that does not require sharing of their private key. From 46d3bff23a347d4357151f73480f3a408284237e Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 16:31:31 +0900 Subject: [PATCH 32/96] Add eventing method --- nep-dapi.mediawiki | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index caa3706c..770d4545 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -776,6 +776,46 @@ Example +===Events=== + +dApps can listen for events emitted by the wallet provider using the `addEventListener` method. + +====addEventListener==== + +'''Method Interface''' + +
+function addEventListener(event: Event, callback: Function): Void
+
+ +'''Input arguments''' + +
+enum Event {
+  NETWORK_CHANGED = 'NETWORK_CHANGED',
+  ACCOUNT_CHANGED = 'ACCOUNT_CHANGED',
+}
+
+ +'''Callback arguments''' + +On a NETWORK_CHANGED event, the callback will fire with a single argument of the new network. +
+enum Network {
+  MainNet = 'MainNet';
+  TestNet = 'TestNet';
+  PrivateNet = 'PrivateNet';
+}
+
+ +On a ACCOUNT_CHANGED event, the callback will fire with a single argument of the new account. In the case that the user logs out without providing a new account to connect, this will be null. +
+interface Account {
+  address: string; // Address of the connected account
+  publicKey: string; // Public key of the connected account
+}
+
+ ==Rational== This protocol will allow dApp developers to create applications that interact with the NEO blockchain without having to be concerned about managing a full wallet within their application or the details related to handing transaction creation or broadcasting. This will also allow dApps to allow users to transact in a secure fashion that does not require sharing of their private key. From 6905baa30c4b3cdf8115984acff7eb72b6cb1961 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 16:37:11 +0900 Subject: [PATCH 33/96] add removeEventListener --- nep-dapi.mediawiki | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 770d4545..0f1aefe0 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -797,7 +797,7 @@ enum Event { } -'''Callback arguments''' +=====NETWORK_CHANGED===== On a NETWORK_CHANGED event, the callback will fire with a single argument of the new network.
@@ -808,6 +808,8 @@ enum Network {
 }
 
+=====ACCOUNT_CHANGED===== + On a ACCOUNT_CHANGED event, the callback will fire with a single argument of the new account. In the case that the user logs out without providing a new account to connect, this will be null.
 interface Account {
@@ -816,6 +818,27 @@ interface Account {
 }
 
+ +====removeEventListener==== + +Removes any callback listeners previously set for a given event. + +'''Method Interface''' + +
+function removeEventListener(event: Event): Void
+
+ +'''Input arguments''' + +
+enum Event {
+  NETWORK_CHANGED = 'NETWORK_CHANGED',
+  ACCOUNT_CHANGED = 'ACCOUNT_CHANGED',
+}
+
+ + ==Rational== This protocol will allow dApp developers to create applications that interact with the NEO blockchain without having to be concerned about managing a full wallet within their application or the details related to handing transaction creation or broadcasting. This will also allow dApps to allow users to transact in a secure fashion that does not require sharing of their private key. From 769c81e9a7890ea668433660dc757505f1833e64 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 16 Oct 2018 16:45:15 +0900 Subject: [PATCH 34/96] add ready method and event --- nep-dapi.mediawiki | 55 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 0f1aefe0..c31c8440 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -46,6 +46,41 @@ Additionally, since there are a significant amount of overlap in the protocols b Implementation details of per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface. ===Read Methods=== + +====isReady==== +Used to check if the protocol is ready to start exchanging messages. + + +'''Method Interface''' + +
+function isReady(): Promise
+
+ + +'''Input arguments''' + +None + + +'''Success return value''' + +boolean - `true` if connection is ready to exchange messages, and `false` if not + + +'''Example''' + +
+isReady()
+.then((result: boolean) => {
+  console.log('Provider isReady: ' + result);
+})
+.catch((err: string) => {
+  console.log('Unknown error' + err);
+});
+
+ + ====getProvider==== Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. @@ -792,19 +827,32 @@ function addEventListener(event: Event, callback: Function): Void
 enum Event {
+  READY = 'READY',
   NETWORK_CHANGED = 'NETWORK_CHANGED',
   ACCOUNT_CHANGED = 'ACCOUNT_CHANGED',
 }
 
+=====READY===== + +On a READY event, the callback will fire with a single argument with information about the wallet provider. +
+interface Provider {
+  name: string;
+  website: string;
+  version: string;
+  compatibility: string[];
+}
+
+ =====NETWORK_CHANGED===== On a NETWORK_CHANGED event, the callback will fire with a single argument of the new network.
 enum Network {
-  MainNet = 'MainNet';
-  TestNet = 'TestNet';
-  PrivateNet = 'PrivateNet';
+  MainNet = 'MainNet',
+  TestNet = 'TestNet',
+  PrivateNet = 'PrivateNet',
 }
 
@@ -833,6 +881,7 @@ function removeEventListener(event: Event): Void
 enum Event {
+  READY = 'READY',
   NETWORK_CHANGED = 'NETWORK_CHANGED',
   ACCOUNT_CHANGED = 'ACCOUNT_CHANGED',
 }

From 6cfd6a133b0d3c4b4982c9c9ac1e525667bae923 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Tue, 16 Oct 2018 19:00:28 +0900
Subject: [PATCH 35/96] add network fee to invoke

---
 nep-dapi.mediawiki | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index c31c8440..1d730bbd 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -729,6 +729,7 @@ interface InvokeArgs {
   operation: string; // operation on the smart contract to call
   args: Argument[]; // any input arguments for the operation
   assets?: AttachedAssets
+  fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction
 }
 
 interface Argument {
@@ -772,6 +773,7 @@ invoke({
     NEO: '100',
     GAS: '0.0001',
   },
+  fee: '0.001',
 })
 .then((txid: string) => {
   console.log('Invoke transaction success! Transaction ID: ' + txid);

From 20a0af03129ff341baa905e849a6f22a6b216806 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Thu, 18 Oct 2018 00:16:29 +0900
Subject: [PATCH 36/96] update send function asset comments

---
 nep-dapi.mediawiki | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index 1d730bbd..ea2a92be 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -638,7 +638,7 @@ function send({ to: string, asset: string, amount: string, remark?: string, fee?
 
 interface SendArgs {
   to: string; // Address of the receiver of the assets to be sent
-  asset: string; // The symbol of the asset to be sent
+  asset: string; // Asset symbol or script hash to be sent
   amount: string; // The parsed amount of the asset to be sent
   remark?: string; // (Optional) Description of the transaction to be made
   fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction
@@ -699,7 +699,7 @@ send({
 Upon receiving this request
 * Validate the inputs
 ** To address is valid
-** Asset symbol is valid
+** Map asset symbol to script hash of one is provided instead of script hash
 ** Amount is valid value, and account has enough balance
 * Broadcast the RPC request
 * Return the transaction Id

From d05bb3e805863a9971660b8b370f4910f634566c Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Mon, 29 Oct 2018 19:58:58 +0900
Subject: [PATCH 37/96] Update network handling, Update balanceOf result

Network handling was updated to give dapp developer more control, since wallet network may be changed async which can cause a race condition where a tx has the potential to be sent to the incorrect network.

getBalance success result format updated to provide more details
---
 nep-dapi.mediawiki | 268 ++++++++++++++++++++++++++++++---------------
 1 file changed, 178 insertions(+), 90 deletions(-)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index ea2a92be..9eeff49e 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -177,14 +177,14 @@ Example
 
-====getNetwork==== -Return the network the wallet provider is connected to. +====getNetworks==== +Returns the networks the wallet provider has available to connect to. '''Method Interface'''
-function getNetwork(): Promise<{ network: Network }>
+function getNetworks(): Promise<{ network: string[] }>
 
@@ -195,13 +195,7 @@ None '''Success return value''' -
-enum Network {
-  MainNet = 'MainNet';
-  TestNet = 'TestNet';
-  PrivateNet = 'PrivateNet';
-}
-
+string[] - Array of network names the wallet provider has available for the dapp developer to connect to. '''Error return value''' @@ -212,9 +206,10 @@ string - `NO_PROVIDER`|`CONNECTION_DENIED` '''Example'''
-getNetwork()
-.then((network: Network) => {
-  console.log('Network: ' + network);
+getNetworks()
+.then((networks: string[]) => {
+  console.log('Networks: ' + networks);
+  // eg. ["MainNet", "TestNet", "PrivateNet"]
 })
 .catch((err: string) => {
   switch(err) {
@@ -232,11 +227,11 @@ getNetwork()
 '''Provider Request Handling'''
 
 Upon receiving this request, return:
-- The NEO network which the wallet provider is connected to.
+- The list of NEO networks that the wallet is able to connect to. The return values will be used by the dapp developer to communicate to which network they would like their request to be directed to. The wallet provider will be responsible for the logistics of which node to submit any request to for each network alias provided.
 
 Example
 
-'MainNet'
+["MainNet", "TestNet", "PrivateNet"]
 
@@ -314,20 +309,29 @@ Example ====getBalance==== Return balance of a specific asset for the given account. +If the asset is omited from a request to MainNet, all asset and token balances will be returned. + '''Method Interface'''
-function getBalance(args: BalanceRequest|BalanceRequest[]): Promise}>
+function getBalance(args: GetBalanceArgs): Promise}>
 
'''Input arguments'''
+interface GetBalanceArgs {
+  params: BalanceRequest|BalanceRequest[];
+  network?: string - Network alias to submit this request to. If omitted, will default to "MainNet".
+}
+
 interface BalanceRequest {
   address: string; // Address to check balance(s)
-  asset?: string; // Asset symbol or script hash to check balance
+  asset?: string; // Asset script hash to check balance.
+  // Requests to "MainNet" will accept the asset symbols we well.
+  // Only optional for request to "MainNet"
 }
 
@@ -336,14 +340,14 @@ interface BalanceRequest {
 interface BalanceResults {
-  [address: string]: Balances;
+  [address: string]: Balance[];
 }
 
-interface Balances {
-  [asset: string]: string;
+interface Balance {
+  scriptHash: string;
+  symbol: string;
+  amount: string;
 }
-// KEY: Asset symbol or script hash to check balance
-// VALUE: Parsed balance of the requested asset
 
@@ -356,17 +360,21 @@ string - `NO_PROVIDER`|`CONNECTION_DENIED`
 getBalance({
-  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
-  asset: 'NKN'
+  params: {
+    address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+    asset: 'NKN'
+  },
+  network: 'MainNet',
 })
 .then((results: BalanceResults) => {
   Object.keys(results).forEach(address => {
     const { balances } = results[address];
-    Object.keys(balances).forEach(asset => {
-      const amount = balances[asset];
+    Object.keys(balances).forEach(balance => {
+      const { scriptHash, symbol, amount } = balance
 
-      console.log('Connected address: ' + address);
-      console.log('Asset: ' + asset);
+      console.log('Address: ' + address);
+      console.log('Asset scriptHash: ' + scriptHash);
+      console.log('Asset symbol: ' + symbol);
       console.log('Amount: ' + amount);
     });
   });
@@ -387,15 +395,22 @@ Single asset balance request sample
 
 // input
 {
-  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
-  asset: 'NKN'
+  params: {
+    address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+    asset: 'NKN'
+  },
+  network: 'MainNet',
 }
 
 // output
 {
-  'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': {
-    'NKN': '0.00000233',
-  },
+  'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': [
+    {
+      'scriptHash': 'c36aee199dbba6c3f439983657558cfb67629599',
+      'symbol': 'NKN',
+      'amount': '0.00000233',
+    }
+  ],
 }
 
@@ -403,43 +418,85 @@ Single account balances request sample
 // input
 {
-  address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+  params: {
+    address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+  },
+  network: 'MainNet',
 }
 
 // output
 {
-  'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': {
-    'NEO': '10',
-    'GAS': '777.0001',
-    'NKN': '0.00000233',
-    'NNC': '2000',
-  },
+  'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': [
+    {
+      'scriptHash': 'c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b',
+      'symbol': 'NEO',
+      'amount': '10',
+    },
+    {
+      'scriptHash': '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7',
+      'symbol': 'GAS',
+      'amount': '777.0001',
+    },
+    {
+      'scriptHash': 'c36aee199dbba6c3f439983657558cfb67629599',
+      'symbol': 'NKN',
+      'amount': '0.00000233',
+    },
+    {
+      'scriptHash': 'fc732edee1efdf968c23c20a9628eaa5a6ccb934',
+      'symbol': 'NNC',
+      'amount': '2000',
+    }
+  ]
 }
 
 Multiple account balances request sample
 
 // input
-[
-  {
-    address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
-  },
-  {
-    address: 'AbKNY45nRDy6B65YPVz1B6YXiTnzRqU2uQ',
-    asset: 'PHX',
-  },
-]
+{
+  params: [
+    {
+      address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
+    },
+    {
+      address: 'AbKNY45nRDy6B65YPVz1B6YXiTnzRqU2uQ',
+      asset: 'PHX',
+    },
+  ],
+  network: 'MainNet',
+}
 
 // output
 {
-  'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': {
-    'NEO': '10',
-    'GAS': '777.0001',
-    'NKN': '0.00000233',
-    'NNC': '2000',
-  },
-  'AbKNY45nRDy6B65YPVz1B6YXiTnzRqU2uQ': {
-    'PHX': '11000',
-  },
+  'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': [
+    {
+      'scriptHash': 'c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b',
+      'symbol': 'NEO',
+      'amount': '10',
+    },
+    {
+      'scriptHash': '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7',
+      'symbol': 'GAS',
+      'amount': '777.0001',
+    },
+    {
+      'scriptHash': 'c36aee199dbba6c3f439983657558cfb67629599',
+      'symbol': 'NKN',
+      'amount': '0.00000233',
+    },
+    {
+      'scriptHash': 'fc732edee1efdf968c23c20a9628eaa5a6ccb934',
+      'symbol': 'NNC',
+      'amount': '2000',
+    }
+  ],
+  'AbKNY45nRDy6B65YPVz1B6YXiTnzRqU2uQ': [
+    {
+      'scriptHash': '1578103c13e39df15d0d29826d957e85d770d8c9',
+      'symbol': 'PHX',
+      'amount': '11000',
+    }
+  ]
 }
 
@@ -456,7 +513,7 @@ Reads the raw value in smart contract storage. '''Method Interface'''
-function getStorage({ scriptHash: string, key: string }): Promise
+function getStorage({ scriptHash: string, key: string, network?: string }): Promise
 
@@ -466,6 +523,7 @@ function getStorage({ scriptHash: string, key: string }): Promise interface GetStorageArgs { scriptHash: string; // script hash of the smart contract to invoke a read on key: string; // key of the storage value to retrieve from the contract + network?: string; // Network alias to submit this request to. If omitted, will default to "MainNet". }
@@ -485,7 +543,8 @@ string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR`
 getStorage({
   scriptHash: '505663a29d83663a838eee091249abd167e928f5',
-  key: 'game.status'
+  key: 'game.status',
+  network: 'TestNet'
 })
 .then((value: string) => {
   console.log('Storage value: ' + value);
@@ -498,9 +557,9 @@ getStorage({
     case CONNECTION_REFUSED:
       console.log('Connection dApp not connected. Please call the "connect" function.');
       break;
-   case RPC_ERROR:
-    console.log('There was an error when broadcasting this transaction to the network.');
-    break;
+    case RPC_ERROR:
+      console.log('There was an error when broadcasting this transaction to the network.');
+      break;
   }
 });
 
@@ -527,8 +586,12 @@ Execute a contract invocation in read-only mode. '''Method Interface'''
-
-function invokeRead({ scriptHash: string, operation: string, args: Argument[] }): Promise
+function invokeRead({
+  scriptHash: string,
+  operation: string,
+  args: Argument[]
+  network?: string,
+ }): Promise
 
'''Input arguments''' @@ -538,6 +601,7 @@ interface InvokeReadArgs { scriptHash: string; // script hash of the smart contract to invoke a read on operation: string; // operation on the smart contract to call args: Argument[]; // any input arguments for the operation + network?: string; // Network alias to submit this request to. If omitted, will default to "MainNet". } interface Argument { @@ -575,6 +639,7 @@ invokeRead({ value: 10 } ], + network: 'PrivNet' }) .then((result: Object) => { console.log('Read invocation result: ' + JSON.stringigy(result)); @@ -629,7 +694,14 @@ Invoke a transfer of a specified amount of a given asset from the connected acco '''Method Interface'''
-function send({ to: string, asset: string, amount: string, remark?: string, fee?: string }): Promise
+function send({
+  to: string,
+  asset: string,
+  amount: string,
+  remark?: string,
+  fee?: string,
+  network?: string,
+}): Promise
 
@@ -638,17 +710,23 @@ function send({ to: string, asset: string, amount: string, remark?: string, fee?
 interface SendArgs {
   to: string; // Address of the receiver of the assets to be sent
-  asset: string; // Asset symbol or script hash to be sent
+  asset: string; // Asset script hash to be sent. Accepts asset symbol only for "MainNet"
   amount: string; // The parsed amount of the asset to be sent
   remark?: string; // (Optional) Description of the transaction to be made
   fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction
+  network?: string; // Network alias to submit this request to. If omitted, will default to "MainNet".
 }
 
'''Success return value''' -txid: string - The transaction ID of the send invocation +
+interface SendOutput {
+  txid: string; // The transaction ID of the send invocation
+  nodeUrl: string; // The node which the transaction was broadcast to.
+}
+
'''Error return value''' @@ -665,9 +743,12 @@ send({ amount: '0.0001', remark: 'Hash puppy clothing purchase. Invoice#abc123', fee: '0.0001', + network: 'MainNet' }) -.then((txid: string) => { - console.log('Send transaction success! Transaction ID: ' + txid); +.then(({txid, nodeUrl}: SendOutput) => { + console.log('Send transaction success!'); + console.log('Transaction ID: ' + txid); + console.log('RPC node URL: ' + nodeUrl); }) .catch((err: string) => { switch(err) { @@ -702,11 +783,14 @@ Upon receiving this request ** Map asset symbol to script hash of one is provided instead of script hash ** Amount is valid value, and account has enough balance * Broadcast the RPC request -* Return the transaction Id +* Return the transaction Id and the url of the rpc node which the tx was broadcast to Example
-'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77'
+{
+  txid: 'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77',
+  nodeUrl: 'http://seed7.ngd.network:10332',
+}:
 
@@ -717,7 +801,13 @@ Execute a contract invocation. '''Method Interface'''
-function invoke({ scriptHash: string, operation: string, args: Argument[], assets?: AttachedAssets }): Promise
+function invoke({
+  scriptHash: string,
+  operation: string,
+  args: Argument[],
+  assets?: AttachedAssets,
+  network?: string,
+}): Promise
 
@@ -730,6 +820,7 @@ interface InvokeArgs { args: Argument[]; // any input arguments for the operation assets?: AttachedAssets fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction + network?: string; // Network alias to submit this request to. If omitted, will default to "MainNet". } interface Argument { @@ -749,7 +840,10 @@ interface AttachedAssets { '''Success return value''' -txid: string - The transaction ID of the invocation +interface InvokeOutput { + txid: string; // The transaction ID of the invocation + nodeUrl: string; // The node which the transaction was broadcast to. +} '''Error return value''' @@ -774,9 +868,12 @@ invoke({ GAS: '0.0001', }, fee: '0.001', + network: 'TestNet', }) -.then((txid: string) => { - console.log('Invoke transaction success! Transaction ID: ' + txid); +.then(({txid, nodeUrl}: InvokeOutput) => { + console.log('Invoke transaction success!'); + console.log('Transaction ID: ' + txid); + console.log('RPC node URL: ' + nodeUrl); }) .catch((err: string) => { switch(err) { @@ -805,11 +902,14 @@ Upon receiving this request ** Format parameters *** If `byteArray`, convert to appropriate hexstring based on assumed format * Broadcast the RPC request -* Return the transaction id +* Return the transaction Id and the url of the rpc node which the tx was broadcast to Example
-'34e07328e50984b28a26e3a534878f7db23a8b6827fbfbb20419c3b6b7410129'
+{
+  txid: 'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77',
+  nodeUrl: 'http://seed7.ngd.network:10332',
+}:
 
@@ -830,7 +930,6 @@ function addEventListener(event: Event, callback: Function): Void
 enum Event {
   READY = 'READY',
-  NETWORK_CHANGED = 'NETWORK_CHANGED',
   ACCOUNT_CHANGED = 'ACCOUNT_CHANGED',
 }
 
@@ -847,17 +946,6 @@ interface Provider { }
-=====NETWORK_CHANGED===== - -On a NETWORK_CHANGED event, the callback will fire with a single argument of the new network. -
-enum Network {
-  MainNet = 'MainNet',
-  TestNet = 'TestNet',
-  PrivateNet = 'PrivateNet',
-}
-
- =====ACCOUNT_CHANGED===== On a ACCOUNT_CHANGED event, the callback will fire with a single argument of the new account. In the case that the user logs out without providing a new account to connect, this will be null. From ae65defc44a510bedc3631fbc55392762fcfc614 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 30 Oct 2018 19:51:04 +0900 Subject: [PATCH 38/96] Add implementation example --- nep-dapi.mediawiki | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 9eeff49e..151260df 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -984,4 +984,6 @@ This protocol will allow dApp developers to create applications that interact wi ==Implementation== -In progress. To be finalized as consensus is reached on the specifications of this NEP. +JS implementation to demonstrate the usage of these methods from a dapp developer. + +o3-dapi-neo - [https://github.com/O3Labs/o3-dapi/tree/master/packages/neo Github] From c790f3b35facb811edf6b157b5469e2671aa034e Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 6 Nov 2018 15:59:15 +0900 Subject: [PATCH 39/96] Update send input args to be more verbose There is a small race condition for the connected account, as all dapp to wallet provider communications are assumed to be async. There is a chance that the dapp developer submits the send request to the wallet provider as the `ACCOUNT_CHANGED` event is fired, resulting in the dapp developer sending assets from the incorrect account. --- nep-dapi.mediawiki | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 151260df..3a5a57a8 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -695,7 +695,8 @@ Invoke a transfer of a specified amount of a given asset from the connected acco
 function send({
-  to: string,
+  fromAddress: string,
+  toAddress: string,
   asset: string,
   amount: string,
   remark?: string,
@@ -709,7 +710,8 @@ function send({
 
 
 interface SendArgs {
-  to: string; // Address of the receiver of the assets to be sent
+  fromAddress: string; // Address of the connected account to send the assets from
+  toAddress: string; // Address of the receiver of the assets to be sent
   asset: string; // Asset script hash to be sent. Accepts asset symbol only for "MainNet"
   amount: string; // The parsed amount of the asset to be sent
   remark?: string; // (Optional) Description of the transaction to be made
@@ -738,7 +740,8 @@ string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CA
 
 
 send({
-  to: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d',
+  fromAddress: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d',
+  toAddress: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d',
   asset: 'GAS',
   amount: '0.0001',
   remark: 'Hash puppy clothing purchase. Invoice#abc123',
@@ -779,6 +782,7 @@ send({
 
 Upon receiving this request
 * Validate the inputs
+** From address matches connected account
 ** To address is valid
 ** Map asset symbol to script hash of one is provided instead of script hash
 ** Amount is valid value, and account has enough balance
@@ -972,7 +976,6 @@ function removeEventListener(event: Event): Void
 
 enum Event {
   READY = 'READY',
-  NETWORK_CHANGED = 'NETWORK_CHANGED',
   ACCOUNT_CHANGED = 'ACCOUNT_CHANGED',
 }
 
From ae32d369870188ba40633aaa2f574daf1e28a9a9 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Wed, 21 Nov 2018 17:56:10 +0900 Subject: [PATCH 40/96] Update how ready is handled --- nep-dapi.mediawiki | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 3a5a57a8..c833e24a 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -47,40 +47,6 @@ Implementation details of per dApp domain handling will be left to the discretio ===Read Methods=== -====isReady==== -Used to check if the protocol is ready to start exchanging messages. - - -'''Method Interface''' - -
-function isReady(): Promise
-
- - -'''Input arguments''' - -None - - -'''Success return value''' - -boolean - `true` if connection is ready to exchange messages, and `false` if not - - -'''Example''' - -
-isReady()
-.then((result: boolean) => {
-  console.log('Provider isReady: ' + result);
-})
-.catch((err: string) => {
-  console.log('Unknown error' + err);
-});
-
- - ====getProvider==== Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. @@ -940,7 +906,7 @@ enum Event { =====READY===== -On a READY event, the callback will fire with a single argument with information about the wallet provider. +On a READY event, the callback will fire with a single argument with information about the wallet provider. At any time a READY event listener is added, it will immidiately be called if the provider is already in a ready state. This provides a single flow for dapp developers since this listener should start any and all interactions with the dapi protocol.
 interface Provider {
   name: string;

From bee91b15d3ef8f5e3a3918061f5a60bd0b9ad570 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Wed, 21 Nov 2018 18:17:47 +0900
Subject: [PATCH 41/96] Updates to invoke method

---
 nep-dapi.mediawiki | 40 +++++++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index c833e24a..16fe9b54 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -571,11 +571,11 @@ interface InvokeReadArgs {
 }
 
 interface Argument {
-  type: ArgumentType;
+  type: ArgumentDataType;
   value: any;
 }
 
-type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`;
+type ArgumentDataType = 'String'|'Boolean'|'Hash160'|'Integer'|'ByteArray'|'Array'|'Address';
 
@@ -775,7 +775,10 @@ function invoke({ scriptHash: string, operation: string, args: Argument[], - assets?: AttachedAssets, + attachedAssets?: AttachedAssets, + fee?: string, + assetIntentOverrides?: AssetIntentOverrides, + triggerContractVerification?: boolean, network?: string, }): Promise
@@ -788,23 +791,46 @@ interface InvokeArgs { scriptHash: string; // script hash of the smart contract to invoke operation: string; // operation on the smart contract to call args: Argument[]; // any input arguments for the operation - assets?: AttachedAssets fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction network?: string; // Network alias to submit this request to. If omitted, will default to "MainNet". + attachedAssets?: AttachedAssets; + + assetIntentOverrides?: AssetIntentOverrides; + // A hard override of all transaction utxo inputs and outputs. + // IMPORTANT: If provided, fee and attachedAssets will be ignored. + + triggerContractVerification?: boolean; // Adds the instruction to invoke the contract verification trigger } interface Argument { - type: ArgumentType; + type: ArgumentDataType; value: any; } -type ArgumentType = `string`|`boolean`|`hash160`|`integer`|`bytearray`|`array`; +type ArgumentDataType = 'String'|'Boolean'|'Hash160'|'Integer'|'ByteArray'|'Array'|'Address'; interface AttachedAssets { - [asset: 'NEO'|'GAS']: string, + [asset: 'NEO'|'GAS']: string; } // KEY: Asset symbol (only NEO or GAS) // VALUE: Parsed amount to attach + +interface AssetIntentOverrides { + inputs: AssetInput[]; + outputs: AssetOutput[]; +} + +interface AssetInput { + txid: string; + index: number; +} + +interface AssetOutput { + asset: string; + address: number; + value: string; +} +
From 40e6f86d99d9c7245bee677d276a4d395fc2bc07 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 3 Dec 2018 16:05:32 +0900 Subject: [PATCH 42/96] Updates based on proposal feedback - getBalance: update input structure, add option to allow for returning UTXOs - getNetworks: update output format to be wrapped in object - getStorage: update output format to be wrapped in object --- nep-dapi.mediawiki | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 16fe9b54..a06836e7 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -150,7 +150,7 @@ Returns the networks the wallet provider has available to connect to. '''Method Interface'''
-function getNetworks(): Promise<{ network: string[] }>
+function getNetworks(): Promise
 
@@ -161,8 +161,14 @@ None '''Success return value''' -string[] - Array of network names the wallet provider has available for the dapp developer to connect to. +interface Networks { +
+interface Networks {
+  networks: string[];
+  // Array of network names the wallet provider has available for the dapp developer to connect to.
+}
+
'''Error return value''' @@ -173,7 +179,8 @@ string - `NO_PROVIDER`|`CONNECTION_DENIED`
 getNetworks()
-.then((networks: string[]) => {
+.then(response => {
+  const networks = response.networks;
   console.log('Networks: ' + networks);
   // eg. ["MainNet", "TestNet", "PrivateNet"]
 })
@@ -295,9 +302,11 @@ interface GetBalanceArgs {
 
 interface BalanceRequest {
   address: string; // Address to check balance(s)
-  asset?: string; // Asset script hash to check balance.
+  assets?: string|string[]; // Asset script hash to check balance.
   // Requests to "MainNet" will accept the asset symbols we well.
-  // Only optional for request to "MainNet"
+  // Requests to non "MainNet" will just return asset balances for NEO and GAS
+  fetchUTXO?: boolean;
+  // Fetches to UTXO data for NEO and/or GAS if attribute is 'true'
 }
 
@@ -328,7 +337,7 @@ string - `NO_PROVIDER`|`CONNECTION_DENIED` getBalance({ params: { address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru', - asset: 'NKN' + assets: ['NKN'] }, network: 'MainNet', }) @@ -363,7 +372,7 @@ Single asset balance request sample { params: { address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru', - asset: 'NKN' + assets: ['NKN'] }, network: 'MainNet', } @@ -479,7 +488,7 @@ Reads the raw value in smart contract storage. '''Method Interface'''
-function getStorage({ scriptHash: string, key: string, network?: string }): Promise
+function getStorage({ scriptHash: string, key: string, network?: string }): Promise
 
@@ -496,7 +505,11 @@ interface GetStorageArgs { '''Success return value''' -value: string - The raw value that's stored in the contract +
+interface StorageResponse {
+  result: string; // The raw value that's stored in the contract
+}
+
'''Error return value''' @@ -512,7 +525,8 @@ getStorage({ key: 'game.status', network: 'TestNet' }) -.then((value: string) => { +.then(res => { + const value = res.result; console.log('Storage value: ' + value); }) .catch((err: string) => { @@ -541,7 +555,9 @@ Upon receiving this request Example
-'hello world'
+{
+  result: 'hello world'
+}
 
From 52b0a6337c74c9956c24f72b900ad2674805b18f Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 18 Dec 2018 14:33:41 +0900 Subject: [PATCH 43/96] Update getNetworks response --- nep-dapi.mediawiki | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index a06836e7..f8c2596e 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -144,7 +144,7 @@ Example ====getNetworks==== -Returns the networks the wallet provider has available to connect to. +Returns the networks the wallet provider has available to connect to, along with the default network the wallet is currently set to. '''Method Interface''' @@ -161,12 +161,10 @@ None '''Success return value''' -interface Networks { -
 interface Networks {
-  networks: string[];
-  // Array of network names the wallet provider has available for the dapp developer to connect to.
+  networks: string[]; // Array of network names the wallet provider has available for the dapp developer to connect to.
+  defaultNetwork: string; // Network the wallet is currently set to.
 }
 
@@ -180,9 +178,16 @@ string - `NO_PROVIDER`|`CONNECTION_DENIED`
 getNetworks()
 .then(response => {
-  const networks = response.networks;
+  const {
+    networks,
+    defaultNetwork,
+  } = response.networks;
+
   console.log('Networks: ' + networks);
   // eg. ["MainNet", "TestNet", "PrivateNet"]
+  
+  console.log('Default network: ' + defaultNetwork);
+  // eg. "MainNet"
 })
 .catch((err: string) => {
   switch(err) {
@@ -201,10 +206,14 @@ getNetworks()
 
 Upon receiving this request, return:
 - The list of NEO networks that the wallet is able to connect to. The return values will be used by the dapp developer to communicate to which network they would like their request to be directed to. The wallet provider will be responsible for the logistics of which node to submit any request to for each network alias provided.
+- The wallet provider is to also return the default network that the wallet UI is currently set to by user.
 
 Example
 
-["MainNet", "TestNet", "PrivateNet"]
+{
+  networks: ["MainNet", "TestNet", "PrivateNet"],
+  defaultNetwork: "TestNet", 
+}
 
From 5dbad9ac5aa288a7714475dc29495a6b62686197 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 18 Dec 2018 15:06:49 +0900 Subject: [PATCH 44/96] Update error handling response definitions --- nep-dapi.mediawiki | 126 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 31 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index f8c2596e..b6449ab2 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -87,7 +87,13 @@ compatibility: [ '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_DENIED` +
+interface Error {
+  type: string; // `NO_PROVIDER`|`CONNECTION_DENIED`
+  description: string;
+  data: string;
+}
+
'''Example''' @@ -107,8 +113,8 @@ getProvider() console.log('Provider dAPI version: ' + version); console.log('Provider dAPI compatibility: ' + JSON.stringify(compatibility)); }) -.catch((err: string) => { - switch(err) { +.catch(({type: string, description: string, data: any}) => { + switch(type) { case NO_PROVIDER: console.log('No provider available.'); break; @@ -170,7 +176,13 @@ interface Networks { '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_DENIED` +
+interface Error {
+  type: string; // `NO_PROVIDER`|`CONNECTION_DENIED`
+  description: string;
+  data: string;
+}
+
'''Example''' @@ -189,8 +201,8 @@ getNetworks() console.log('Default network: ' + defaultNetwork); // eg. "MainNet" }) -.catch((err: string) => { - switch(err) { +.catch(({type: string, description: string, data: any}) => { + switch(type) { case NO_PROVIDER: console.log('No provider available.'); break; @@ -245,7 +257,13 @@ interface Account { '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_DENIED` +
+interface Error {
+  type: string; // `NO_PROVIDER`|`CONNECTION_DENIED`
+  description: string;
+  data: string;
+}
+
'''Example''' @@ -261,8 +279,8 @@ getAccount() console.log('Provider address: ' + address); console.log('Provider public key: ' + publicKey); }) -.catch((err: string) => { - switch(err) { +.catch(({type: string, description: string, data: any}) => { + switch(type) { case NO_PROVIDER: console.log('No provider available.'); break; @@ -337,7 +355,13 @@ interface Balance { '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_DENIED` +
+interface Error {
+  type: string; // `NO_PROVIDER`|`CONNECTION_DENIED`
+  description: string;
+  data: string;
+}
+
'''Example''' @@ -363,8 +387,8 @@ getBalance({ }); }); }) -.catch((err: string) => { - switch(err) { +.catch(({type: string, description: string, data: any}) => { + switch(type) { case NO_PROVIDER: console.log('No provider available.'); break; @@ -523,7 +547,13 @@ interface StorageResponse { '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR` +
+interface Error {
+  type: string; // `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR`
+  description: string;
+  data: string;
+}
+
'''Example''' @@ -538,8 +568,8 @@ getStorage({ const value = res.result; console.log('Storage value: ' + value); }) -.catch((err: string) => { - switch(err) { +.catch(({type: string, description: string, data: any}) => { + switch(type) { case NO_PROVIDER: console.log('No provider available.'); break; @@ -611,7 +641,13 @@ result: Object - Response from RPC node '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR` +
+interface Error {
+  type: string; // `NO_PROVIDER`|`CONNECTION_REFUSED`|`RPC_ERROR`
+  description: string;
+  data: string;
+}
+
'''Example''' @@ -635,8 +671,8 @@ invokeRead({ .then((result: Object) => { console.log('Read invocation result: ' + JSON.stringigy(result)); }) -.catch((err: string) => { - switch(err) { +.catch(({type: string, description: string, data: any}) => { + switch(type) { case NO_PROVIDER: console.log('No provider available.'); break; @@ -724,7 +760,13 @@ interface SendOutput { '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED`|`INSUFFICIENT_FUNDS` +
+interface Error {
+  type: string; // `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_INPUT`|`CANCELED`|`INSUFFICIENT_FUNDS`
+  description: string;
+  data: string;
+}
+
'''Example''' @@ -744,18 +786,15 @@ send({ console.log('Transaction ID: ' + txid); console.log('RPC node URL: ' + nodeUrl); }) -.catch((err: string) => { - switch(err) { +.catch(({type: string, description: string, data: any}) => { + switch(type) { case NO_PROVIDER: console.log('No provider available.'); break; - case CONNECTION_REFUSED: - console.log('dApp not connected. Please call the "connect" function.'); - break; case SEND_ERROR: console.log('There was an error when broadcasting this transaction to the network.'); break; - case MALFORMED_ADDRESS: + case MALFORMED_INPUT: console.log('The receiver address provided is not valid.'); break; case CANCELED: @@ -869,7 +908,13 @@ interface InvokeOutput { '''Error return value''' -string - `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_ADDRESS`|`CANCELED` +
+interface Error {
+  type: string; // `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_INPUT`|`CANCELED`
+  description: string;
+  data: string;
+}
+
'''Example''' @@ -896,14 +941,11 @@ invoke({ console.log('Transaction ID: ' + txid); console.log('RPC node URL: ' + nodeUrl); }) -.catch((err: string) => { - switch(err) { +.catch(({type: string, description: string, data: any}) => { + switch(type) { case NO_PROVIDER: console.log('No provider available.'); break; - case CONNECTION_REFUSED: - console.log('Connection dApp not connected. Please call the "connect" function.'); - break; case RPC_ERROR: console.log('There was an error when broadcasting this transaction to the network.'); break; @@ -997,6 +1039,28 @@ enum Event { }
+===Error handling=== + +All methods return a promise which will result in a resolve or reject. In the case of a rejection, the return argument will be an object formatted with standard fields for the type of error, a brief description, and any raw error data. + +
+interface Error {
+  type: string;
+  description: string;
+  data?: string;
+}
+
+ +Common error definitions +
+NO_PROVIDER -> Thrown when there is no interface capable of interacting with NEO blockchain
+CONNECTION_DENIED -> Thrown when API provider refuses to execute a transaction (e.g. trying to execute a transaction on an unavialable network)
+RPC_ERROR -> Thrown when a command relying on RPC connection to a network node fails
+MALFORMED_INPUT -> Thrown when an input such as the address is not a valid NEO address
+CANCELED -> Thrown when a user cancels, or refuses the dapps request
+INSUFFICIENT_FUNDS -> Thrown when the action does not have a sufficient balance
+
+ ==Rational== From 91a6b8444f8e98ab70f0de071461b6b356674377 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 28 Jan 2019 15:06:14 +0900 Subject: [PATCH 45/96] Updates to getAccount and getProvider based on feedback --- nep-dapi.mediawiki | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index b6449ab2..521a65b7 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -29,6 +29,7 @@ While there may be several options for 3rd party wallet providers that will help Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Wallet providers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplication an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted by both the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have a unified interface for such transactions, providers can spend more time on making their individual services better for their users. The current list of wallet providers that can benefit from the use of this protocol are currently: +* NEL Chrome extension * nOS dApps browser * NeoLink Chrome extension * NEX Chrome extension @@ -72,6 +73,7 @@ interface Provider { website: string; version: string; compatibility: string[]; + extra: object; //this object can contain any attributes specific to the dapi provider, such as an app theme. }
@@ -106,12 +108,14 @@ getProvider() website, version, compatibility, + extra, } = provider; console.log('Provider name: ' + name); console.log('Provider website: ' + website); console.log('Provider dAPI version: ' + version); console.log('Provider dAPI compatibility: ' + JSON.stringify(compatibility)); + console.log('Extra provider specific atributes: ' + JSON.stringify(compatibility)); }) .catch(({type: string, description: string, data: any}) => { switch(type) { @@ -144,7 +148,10 @@ Example 'NEP-14', 'NEP-23', 'NEP-29' - ] + ], + extra: { + theme: 'Dark Mode' + } }
@@ -250,7 +257,7 @@ None
 interface Account {
   address: string; // Address of the connected account
-  publicKey: string; // Public key of the connected account
+  label?: string; // A label the users has set to identify their wallet
 }
 
@@ -273,11 +280,11 @@ getAccount() .then((account: Account) => { const { address, - publicKey, + label } = account; console.log('Provider address: ' + address); - console.log('Provider public key: ' + publicKey); + console.log('Provider account label (Optional): ' + label); }) .catch(({type: string, description: string, data: any}) => { switch(type) { @@ -301,7 +308,7 @@ Example
 {
   address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
-  publicKey: '03d43468721ef8936548878071b534d8228c313e02e6d90cef8c65fd3c2d4eaeed'
+  label: 'My Spending Wallet'
 }
 
From 8731dc37d7551897b71cbed8cdf8efed7dab082f Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 28 Jan 2019 15:58:33 +0900 Subject: [PATCH 46/96] Add DISCONNECTED event --- nep-dapi.mediawiki | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 521a65b7..f91c486a 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1018,15 +1018,20 @@ interface Provider { =====ACCOUNT_CHANGED===== -On a ACCOUNT_CHANGED event, the callback will fire with a single argument of the new account. In the case that the user logs out without providing a new account to connect, this will be null. +On a ACCOUNT_CHANGED event, the callback will fire with a single argument of the new account. This occurs when an account is already connected to the dapp, and the user has changed the connected account from the dapi provider side.
 interface Account {
   address: string; // Address of the connected account
-  publicKey: string; // Public key of the connected account
+  label?: string; // A label the users has set to identify their wallet
 }
 
+=====DISCONNECTED===== + +On a DISCONNECTED event, the account connected to the dapp via the dapi provider has been disconnected (logged out). + + ====removeEventListener==== Removes any callback listeners previously set for a given event. @@ -1043,6 +1048,7 @@ function removeEventListener(event: Event): Void enum Event { READY = 'READY', ACCOUNT_CHANGED = 'ACCOUNT_CHANGED', + DISCONNECTED = 'DISCONNECTED' }
From 8b7564a8afc64bb372e56db7a773a8f4efcac482 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 31 Jan 2019 12:27:32 +0900 Subject: [PATCH 47/96] Add NETWORK_CHANGED event --- nep-dapi.mediawiki | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index f91c486a..a9dfcf5f 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1032,6 +1032,26 @@ interface Account { On a DISCONNECTED event, the account connected to the dapp via the dapi provider has been disconnected (logged out). +=====NETWORK_CHANGED===== + +On a NETWORK_CHANGED event, the callback will fire with a single argument of the new network details. This occurs when the user has changed the network on their provider wallet. + +
+interface Networks {
+  networks: string[]; // Array of network names the wallet provider has available for the dapp developer to connect to.
+  defaultNetwork: string; // Network the wallet is currently set to.
+}
+
+ +Example: +
+{
+  networks: ["MainNet"],
+  defaultNetwork: "MainNet", 
+}
+
+ + ====removeEventListener==== Removes any callback listeners previously set for a given event. From 07942269ca15cc8795d0da9360b290d677179597 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 31 Jan 2019 12:32:29 +0900 Subject: [PATCH 48/96] Update getBalance return attribute key from scriptHash to assetID --- nep-dapi.mediawiki | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index a9dfcf5f..dd5b7b22 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -336,7 +336,7 @@ interface GetBalanceArgs { interface BalanceRequest { address: string; // Address to check balance(s) - assets?: string|string[]; // Asset script hash to check balance. + assets?: string|string[]; // Asset ID or script hash to check balance. // Requests to "MainNet" will accept the asset symbols we well. // Requests to non "MainNet" will just return asset balances for NEO and GAS fetchUTXO?: boolean; @@ -353,7 +353,7 @@ interface BalanceResults { } interface Balance { - scriptHash: string; + assetID: string; symbol: string; amount: string; } @@ -385,10 +385,10 @@ getBalance({ Object.keys(results).forEach(address => { const { balances } = results[address]; Object.keys(balances).forEach(balance => { - const { scriptHash, symbol, amount } = balance + const { assetID, symbol, amount } = balance console.log('Address: ' + address); - console.log('Asset scriptHash: ' + scriptHash); + console.log('Asset ID: ' + assetID); console.log('Asset symbol: ' + symbol); console.log('Amount: ' + amount); }); @@ -421,7 +421,7 @@ Single asset balance request sample { 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': [ { - 'scriptHash': 'c36aee199dbba6c3f439983657558cfb67629599', + 'assetID': 'c36aee199dbba6c3f439983657558cfb67629599', 'symbol': 'NKN', 'amount': '0.00000233', } @@ -443,22 +443,22 @@ Single account balances request sample { 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': [ { - 'scriptHash': 'c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b', + 'assetID': 'c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b', 'symbol': 'NEO', 'amount': '10', }, { - 'scriptHash': '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7', + 'assetID': '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7', 'symbol': 'GAS', 'amount': '777.0001', }, { - 'scriptHash': 'c36aee199dbba6c3f439983657558cfb67629599', + 'assetID': 'c36aee199dbba6c3f439983657558cfb67629599', 'symbol': 'NKN', 'amount': '0.00000233', }, { - 'scriptHash': 'fc732edee1efdf968c23c20a9628eaa5a6ccb934', + 'assetID': 'fc732edee1efdf968c23c20a9628eaa5a6ccb934', 'symbol': 'NNC', 'amount': '2000', } @@ -485,29 +485,29 @@ Multiple account balances request sample { 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru': [ { - 'scriptHash': 'c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b', + 'assetID': 'c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b', 'symbol': 'NEO', 'amount': '10', }, { - 'scriptHash': '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7', + 'assetID': '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7', 'symbol': 'GAS', 'amount': '777.0001', }, { - 'scriptHash': 'c36aee199dbba6c3f439983657558cfb67629599', + 'assetID': 'c36aee199dbba6c3f439983657558cfb67629599', 'symbol': 'NKN', 'amount': '0.00000233', }, { - 'scriptHash': 'fc732edee1efdf968c23c20a9628eaa5a6ccb934', + 'assetID': 'fc732edee1efdf968c23c20a9628eaa5a6ccb934', 'symbol': 'NNC', 'amount': '2000', } ], 'AbKNY45nRDy6B65YPVz1B6YXiTnzRqU2uQ': [ { - 'scriptHash': '1578103c13e39df15d0d29826d957e85d770d8c9', + 'assetID': '1578103c13e39df15d0d29826d957e85d770d8c9', 'symbol': 'PHX', 'amount': '11000', } From 95373d8ff5948bdffd49bc102f73882545da9e91 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 7 Feb 2019 16:51:14 +0900 Subject: [PATCH 49/96] Update error response format --- nep-dapi.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index dd5b7b22..67a5d87c 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1079,8 +1079,8 @@ All methods return a promise which will result in a resolve or reject. In the ca
 interface Error {
   type: string;
-  description: string;
-  data?: string;
+  description?: string;
+  data?: any;
 }
 
From b9a96dcd69460559dfd97bdf4f933ded414479f1 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 7 Feb 2019 16:53:04 +0900 Subject: [PATCH 50/96] Update nep-dapi.mediawiki --- nep-dapi.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 67a5d87c..6907ece9 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1068,6 +1068,8 @@ function removeEventListener(event: Event): Void enum Event { READY = 'READY', ACCOUNT_CHANGED = 'ACCOUNT_CHANGED', + NETWORK_CHANGED = 'NETWORK_CHANGED', + CONNECTED = 'CONNECTED', DISCONNECTED = 'DISCONNECTED' } From 916b675bcca91402803e50a27943bcdd0102d9df Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 7 Feb 2019 17:00:03 +0900 Subject: [PATCH 51/96] Update nep-dapi.mediawiki --- nep-dapi.mediawiki | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 6907ece9..0c6395a7 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1001,6 +1001,9 @@ function addEventListener(event: Event, callback: Function): Void enum Event { READY = 'READY', ACCOUNT_CHANGED = 'ACCOUNT_CHANGED', + NETWORK_CHANGED = 'NETWORK_CHANGED', + CONNECTED = 'CONNECTED', + DISCONNECTED = 'DISCONNECTED' } From 4088c23b769eaef166a8392dd03276e541fde968 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 25 Feb 2019 14:28:36 +0900 Subject: [PATCH 52/96] Add argument data type Hash256 --- nep-dapi.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 0c6395a7..96ddbfba 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -637,7 +637,7 @@ interface Argument { value: any; } -type ArgumentDataType = 'String'|'Boolean'|'Hash160'|'Integer'|'ByteArray'|'Array'|'Address'; +type ArgumentDataType = 'String'|'Boolean'|'Hash160'|'Hash256'|'Integer'|'ByteArray'|'Array'|'Address'; @@ -878,7 +878,7 @@ interface Argument { value: any; } -type ArgumentDataType = 'String'|'Boolean'|'Hash160'|'Integer'|'ByteArray'|'Array'|'Address'; +type ArgumentDataType = 'String'|'Boolean'|'Hash160'|'Hash256'|'Integer'|'ByteArray'|'Array'|'Address'; interface AttachedAssets { [asset: 'NEO'|'GAS']: string; From 94f188ffa926f61096f52ca3a04bd58c26ceceb8 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 25 Feb 2019 15:12:58 +0900 Subject: [PATCH 53/96] add getPublicKey method --- nep-dapi.mediawiki | 81 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 96ddbfba..3d66954a 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -243,7 +243,7 @@ Return the Account that is currently connected to the dApp. '''Method Interface'''
-function getAccount(): Promise<{ address: string, publicKey: string }>
+function getAccount(): Promise<{ address: string, label: string }>
 
@@ -302,7 +302,7 @@ getAccount() '''Provider Request Handling''' Upon receiving this request, return: -- The address and public key of account currently selected by the user in the wallet interface +- The address and label of account currently selected by the user in the wallet interface Example
@@ -313,6 +313,83 @@ Example
 
+====getPublicKey==== +Return the public key of the Account that is currently connected to the dApp. + + +'''Method Interface''' + +
+function getPublicKey(): Promise<{ address: string, publicKey: string }>
+
+ + +'''Input arguments''' + +None + + +'''Success return value''' + +
+interface Account {
+  address: string; // Address of the connected account
+  publicKey: string; // Public key of the connected account
+}
+
+ + +'''Error return value''' + +
+interface Error {
+  type: string; // `NO_PROVIDER`|`CONNECTION_DENIED`
+  description: string;
+  data: string;
+}
+
+ + +'''Example''' + +
+getPublicKey()
+.then((publicKeyData: PublicKeyData) => {
+  const {
+    address,
+    publicKey,
+  } = publicKeyData;
+
+  console.log('Account address: ' + address);
+  console.log('Account public key: ' + publicKey);
+})
+.catch(({type: string, description: string, data: any}) => {
+  switch(type) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case CONNECTION_DENIED:
+      console.log('The user rejected the request to connect with your dApp');
+      break;
+  }
+});
+
+ + +'''Provider Request Handling''' + +Upon receiving this request, return: +- The address and public key of account currently selected by the user in the wallet interface + +Example +
+{
+  address: 'ATUaTd3LA4kZiyB6it9fdb5oJpZYMBF4DX',
+  publicKey: '03fa41b6ff75ebeff8464556629cfceae7402f5d815626a7a6542f786974b942e0'
+}
+
+ + ====getBalance==== Return balance of a specific asset for the given account. From 59a06625df3ad6f435752e3ef9f0b69a5358bb13 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 25 Feb 2019 16:32:20 +0900 Subject: [PATCH 54/96] Add signMessage & verifyMessage --- nep-dapi.mediawiki | 177 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 1 deletion(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 3d66954a..c1c70e37 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -797,6 +797,90 @@ Example +====verifyMessage==== +Returns whether the provided signature data matches the provided message and was signed by the account of the provided public key. + + +'''Method Interface''' + +
+function verifyMessage({
+  message: string,
+  data: string,
+  publicKey: string,
+}): Promise<{result: boolean}>
+
+ + +'''Input arguments''' + +
+interface VerifyMessageArgs {
+  message: string; // Salt prefix + original message
+  data: string; // Signed message
+  publicKey: string; // Public key of account that signed message
+}
+
+ + +'''Success return value''' + +
+interface Response {
+  result: boolean;
+}
+
+ + +'''Error return value''' + +
+interface Error {
+  type: string;
+  description: string;
+  data: string;
+}
+
+ + +'''Example''' + +
+verifyMessage({
+  message: '058b9e03e7154e4db1e489c99256b7faHello World!',
+  data: '0147fb89d0999e9d8a90edacfa26152fe695ec8b3770dcad522048297ab903822e12472364e254ff2e088fc3ebb641cc24722c563ff679bb1d1623d08bd5863d0d',
+  publicKey: '0241392007396d6ef96159f047967c5a61f1af0871ecf9dc82afbedb68afbb949a',
+})
+.then(({result: bool}) => {
+  console.log('Signature data matches provided message and public key: ' + result);
+})
+.catch(({type: string, description: string, data: any}) => {
+  switch(type) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case CONNECTION_DENIED:
+      console.log('The user rejected the request to connect with your dApp');
+      break;
+  }
+});
+
+ + +'''Provider Request Handling''' + +Upon receiving this request +* Verify that the signed data matches the provided public key and message +* Return result to dapp + +Example +
+{
+  result: true,
+}
+
+ + ===Write Methods=== ====send==== Invoke a transfer of a specified amount of a given asset from the connected account to another account. @@ -908,7 +992,7 @@ Example { txid: 'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77', nodeUrl: 'http://seed7.ngd.network:10332', -}: +} @@ -1060,6 +1144,97 @@ Example +====signMessage==== +Signs a provided messaged with an account selected by user. A salt prefix is added to the input string, and provided as a part of the data while signing. In the example, the signed value would be `058b9e03e7154e4db1e489c99256b7faHello World!`. + + +'''Method Interface''' + +
+function signMessage({message: string}): Promise
+
+ + +'''Input arguments''' + +
+interface SignMessageArgs {
+  message: string; // Arbitrary message to sign
+}
+
+ + +'''Success return value''' + +
+interface SignedMessage {
+  publicKey: string; // Public key of account that signed message
+  message: string; // Original message signed
+  salt: string; // Salt added to original message as prefix, before signing
+  data; sring; // Signed message
+}
+
+ + +'''Error return value''' + +
+interface Error {
+  type: string;
+  description: string;
+  data: string;
+}
+
+ + +'''Example''' + +
+signMessage({
+  message: 'Hello World!',
+})
+.then((signedMessage: SignedMessage) => {
+  const {
+    publicKey,
+    message,
+    salt,
+    data,
+  } = signedMessage;
+
+  console.log('Public key used to sign:', publicKey);
+  console.log('Original message:', message);
+  console.log('Salt added to message:', salt);
+  console.log('Signed data:', data);
+})
+.catch(({type: string, description: string, data: any}) => {
+  switch(type) {
+    case UNKNOWN_ERROR:
+      console.log(description);
+      break;
+  }
+});
+
+ + +'''Provider Request Handling''' + +Upon receiving this request +* Present the message to the user for signing +* Create a randomized salt value to be prefixed to the message before signing +* Sign the salt + message value once the user confirms +* Return to dapp + +Example +
+{
+  publicKey: '0241392007396d6ef96159f047967c5a61f1af0871ecf9dc82afbedb68afbb949a',
+  data: '0147fb89d0999e9d8a90edacfa26152fe695ec8b3770dcad522048297ab903822e12472364e254ff2e088fc3ebb641cc24722c563ff679bb1d1623d08bd5863d0d',
+  salt: '058b9e03e7154e4db1e489c99256b7fa',
+  message: 'Hello World!',
+}
+
+ + ===Events=== dApps can listen for events emitted by the wallet provider using the `addEventListener` method. From 96a4540660d17600d558e020a96183e2f4f63395 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 26 Feb 2019 19:23:54 +0900 Subject: [PATCH 55/96] Update nep-dapi.mediawiki --- nep-dapi.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index c1c70e37..abb8efc0 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1097,7 +1097,7 @@ invoke({ value: 'hello' } ], - assets: { + attachedAssets: { NEO: '100', GAS: '0.0001', }, From 0286d1ca7d4612bb84875fd10c28dcb35197a6f4 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 26 Feb 2019 19:31:54 +0900 Subject: [PATCH 56/96] Update nep-dapi.mediawiki --- nep-dapi.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index abb8efc0..ed29b0b6 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -460,8 +460,8 @@ getBalance({ }) .then((results: BalanceResults) => { Object.keys(results).forEach(address => { - const { balances } = results[address]; - Object.keys(balances).forEach(balance => { + const balances = results[address]; + balances.forEach(balance => { const { assetID, symbol, amount } = balance console.log('Address: ' + address); From 3f440da21281ea7d7d866cce1e6762f8cfe9ace7 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Wed, 13 Mar 2019 15:38:55 +0900 Subject: [PATCH 57/96] Add deploy method --- nep-dapi.mediawiki | 112 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index ed29b0b6..e60a5ac2 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1234,6 +1234,118 @@ Example } +====deploy==== +Will deploy a compiled smart contract to the blockchain with the provided input parameters. The GAS cost for deploying the contract will be calculated by the provider, and displayed to the user upon tx acceptance or rejection. + + +'''Method Interface''' + +
+function deploy({
+  network: any,
+  name: string,
+  version: string,
+  author: string,
+  email: string,
+  description: string,
+  needsStorage?: boolean,
+  dynamicInvoke?: boolean,
+  isPayable?: boolean,
+  parameterList: string,
+  returnType: string,
+  code: string,
+}): Promise
+
+ + +'''Input arguments''' + +
+interface DeployArgs {
+  network: any;
+  name: string;
+  version: string;
+  author: string;
+  email: string;
+  description: string;
+  needsStorage?: boolean;
+  dynamicInvoke?: boolean;
+  isPayable?: boolean;
+  parameterList: string;
+  returnType: string;
+  code: string;
+}
+
+ + +'''Success return value''' + +
+interface DeployOutput {
+  txid: string;
+  nodeUrl: string;
+}
+
+ + +'''Error return value''' + +
+interface Error {
+  type: string;
+  description: string;
+  data: string;
+}
+
+ + +'''Example''' + +
+deploy({
+  network: 'PrivateNet',
+  name: 'Hello world!',
+  version: 'v0.0.1',
+  author: 'John Smith',
+  email: 'info@o3.network',
+  description: 'My first contract.',
+  needsStorage: true,
+  dynamicInvoke: false,
+  isPayable: false,
+  parameterList: '0710',
+  returnType: '05',
+  code: '53c56b0d57616b652075702c204e454f21680f4e656f2e52756e74696d652e4c6f6761006c7566',
+})
+.then(({txid, nodeUrl}: InvokeOutput) => {
+  console.log('Deploy transaction success!');
+  console.log('Transaction ID: ' + txid);
+  console.log('RPC node URL: ' + nodeUrl);
+})
+.catch(({type: string, description: string, data: any}) => {
+  switch(type) {
+    case UNKNOWN_ERROR:
+      console.log(description);
+      break;
+  }
+});
+
+ + +'''Provider Request Handling''' + +Upon receiving this request +* Run a testinvoke on the deploy transaction to get the gas cost in order to deploy the contract +* Display the deploy input parameters to the user along with the associated deployment fee +* Sign and broadcast transaction upon receiving confirmation from user + +Example +
+{
+  txid: 'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77',
+  nodeUrl: 'http://seed7.ngd.network:10332',
+}
+
+ ===Events=== From 94bc791fdc768026d2c23a4821e407e06e7dd5a3 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Wed, 17 Apr 2019 12:33:45 +0900 Subject: [PATCH 58/96] update network input attribute on all methods to be optional --- nep-dapi.mediawiki | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index e60a5ac2..760cebc9 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -204,7 +204,7 @@ getNetworks() console.log('Networks: ' + networks); // eg. ["MainNet", "TestNet", "PrivateNet"] - + console.log('Default network: ' + defaultNetwork); // eg. "MainNet" }) @@ -231,7 +231,7 @@ Example
 {
   networks: ["MainNet", "TestNet", "PrivateNet"],
-  defaultNetwork: "TestNet", 
+  defaultNetwork: "TestNet",
 }
 
@@ -408,7 +408,7 @@ function getBalance(args: GetBalanceArgs): Promise}>
 interface GetBalanceArgs {
   params: BalanceRequest|BalanceRequest[];
-  network?: string - Network alias to submit this request to. If omitted, will default to "MainNet".
+  network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to.
 }
 
 interface BalanceRequest {
@@ -456,7 +456,6 @@ getBalance({
     address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
     assets: ['NKN']
   },
-  network: 'MainNet',
 })
 .then((results: BalanceResults) => {
   Object.keys(results).forEach(address => {
@@ -491,7 +490,6 @@ Single asset balance request sample
     address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
     assets: ['NKN']
   },
-  network: 'MainNet',
 }
 
 // output
@@ -513,7 +511,6 @@ Single account balances request sample
   params: {
     address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru',
   },
-  network: 'MainNet',
 }
 
 // output
@@ -554,8 +551,7 @@ Multiple account balances request sample
       address: 'AbKNY45nRDy6B65YPVz1B6YXiTnzRqU2uQ',
       asset: 'PHX',
     },
-  ],
-  network: 'MainNet',
+  ]
 }
 
 // output
@@ -615,7 +611,7 @@ function getStorage({ scriptHash: string, key: string, network?: string }): Prom
 interface GetStorageArgs {
   scriptHash: string; // script hash of the smart contract to invoke a read on
   key: string; // key of the storage value to retrieve from the contract
-  network?: string; // Network alias to submit this request to. If omitted, will default to "MainNet".
+  network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to.
 }
 
@@ -645,8 +641,7 @@ interface Error {
 getStorage({
   scriptHash: '505663a29d83663a838eee091249abd167e928f5',
-  key: 'game.status',
-  network: 'TestNet'
+  key: 'game.status'
 })
 .then(res => {
   const value = res.result;
@@ -706,7 +701,7 @@ interface InvokeReadArgs {
   scriptHash: string; // script hash of the smart contract to invoke a read on
   operation: string; // operation on the smart contract to call
   args: Argument[]; // any input arguments for the operation
-  network?: string; // Network alias to submit this request to. If omitted, will default to "MainNet".
+  network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to.
 }
 
 interface Argument {
@@ -749,8 +744,7 @@ invokeRead({
       type: 'integer',
       value: 10
     }
-  ],
-  network: 'PrivNet'
+  ]
 })
 .then((result: Object) => {
   console.log('Read invocation result: ' + JSON.stringigy(result));
@@ -911,7 +905,7 @@ interface SendArgs {
   amount: string; // The parsed amount of the asset to be sent
   remark?: string; // (Optional) Description of the transaction to be made
   fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction
-  network?: string; // Network alias to submit this request to. If omitted, will default to "MainNet".
+  network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to.
 }
 
@@ -946,8 +940,7 @@ send({ asset: 'GAS', amount: '0.0001', remark: 'Hash puppy clothing purchase. Invoice#abc123', - fee: '0.0001', - network: 'MainNet' + fee: '0.0001' }) .then(({txid, nodeUrl}: SendOutput) => { console.log('Send transaction success!'); @@ -1024,13 +1017,13 @@ interface InvokeArgs { operation: string; // operation on the smart contract to call args: Argument[]; // any input arguments for the operation fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction - network?: string; // Network alias to submit this request to. If omitted, will default to "MainNet". + network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to. attachedAssets?: AttachedAssets; - + assetIntentOverrides?: AssetIntentOverrides; // A hard override of all transaction utxo inputs and outputs. // IMPORTANT: If provided, fee and attachedAssets will be ignored. - + triggerContractVerification?: boolean; // Adds the instruction to invoke the contract verification trigger } @@ -1101,8 +1094,7 @@ invoke({ NEO: '100', GAS: '0.0001', }, - fee: '0.001', - network: 'TestNet', + fee: '0.001' }) .then(({txid, nodeUrl}: InvokeOutput) => { console.log('Invoke transaction success!'); @@ -1242,7 +1234,6 @@ Will deploy a compiled smart contract to the blockchain with the provided input
 function deploy({
-  network: any,
   name: string,
   version: string,
   author: string,
@@ -1254,6 +1245,7 @@ function deploy({
   parameterList: string,
   returnType: string,
   code: string,
+  network?: string,
 }): Promise
 
@@ -1262,7 +1254,6 @@ function deploy({
 interface DeployArgs {
-  network: any;
   name: string;
   version: string;
   author: string;
@@ -1274,6 +1265,7 @@ interface DeployArgs {
   parameterList: string;
   returnType: string;
   code: string;
+  network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to.
 }
 
@@ -1303,7 +1295,6 @@ interface Error {
 deploy({
-  network: 'PrivateNet',
   name: 'Hello world!',
   version: 'v0.0.1',
   author: 'John Smith',
@@ -1414,7 +1405,7 @@ Example:
 
 {
   networks: ["MainNet"],
-  defaultNetwork: "MainNet", 
+  defaultNetwork: "MainNet",
 }
 
From 7a8e1cd3e7733100fc29eafb0c89cabd28d4f58a Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Wed, 17 Apr 2019 17:12:29 +0900 Subject: [PATCH 59/96] update signMessage & verifyMessage to encase into non-executable tx for ledger support --- nep-dapi.mediawiki | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 760cebc9..9efab746 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -864,8 +864,14 @@ verifyMessage({ '''Provider Request Handling''' Upon receiving this request -* Verify that the signed data matches the provided public key and message -* Return result to dapp +* The input message should have the salt already added. +* Create the hexstring that was signed. '010001f0' + + message + '0000' +For more details, please see: +[https://docs.switcheo.network/#signing-messages-for-neo] + +* Verify that the signed data matches the provided public key and hexstring. +* Return to dapp + Example
@@ -1137,7 +1143,7 @@ Example
 
 
 ====signMessage====
-Signs a provided messaged with an account selected by user. A salt prefix is added to the input string, and provided as a part of the data while signing. In the example, the signed value would be `058b9e03e7154e4db1e489c99256b7faHello World!`.
+Signs a provided messaged with an account selected by user. A randomized salt prefix is added to the input string before it is signed, and it is encased in a non-executable transaction before signed. This ensures allow compatibility with Ledger devices.
 
 
 '''Method Interface'''
@@ -1163,7 +1169,7 @@ interface SignedMessage {
   publicKey: string; // Public key of account that signed message
   message: string; // Original message signed
   salt: string; // Salt added to original message as prefix, before signing
-  data; sring; // Signed message
+  data; string; // Signed message
 }
 
@@ -1213,9 +1219,13 @@ signMessage({ Upon receiving this request * Present the message to the user for signing * Create a randomized salt value to be prefixed to the message before signing -* Sign the salt + message value once the user confirms +* Create the hexstring to be signed. '010001f0' + + salt + message + '0000' +* Sign the hexstring value once the user confirms * Return to dapp +For more details, please see: +[https://docs.switcheo.network/#signing-messages-for-neo] + Example
 {

From 446e414cb95e93ec446336e18b12654e5d3833b6 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Thu, 9 May 2019 15:09:45 +0900
Subject: [PATCH 60/96] update for new methods, getBlock, getTransaction,
 getApplicationLog, update for new events BLOCK_HEIGHT_CHANGED and
 TRANSACTION_CONFIRMED

---
 nep-dapi.mediawiki | 489 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 489 insertions(+)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index 9efab746..68fadbe0 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -881,6 +881,447 @@ Example
 
+====getBlock==== +Get information about a specific block. + + +'''Method Interface''' + +
+function getBlock({
+  blockHeight: integer,
+  network?: string
+}): Promise<{result: BlockDetails}>
+
+ + +'''Input arguments''' + +
+interface GetBlockInputArgs {
+  blockHeight: integer;
+  network?: string;
+}
+
+ + +'''Success return value''' + +
+interface BlockDetails {
+  hash: string; // Block hash
+  size: number; // Block size (bytes)
+  version: number; // The version number of the block execution
+  previousblockhash: string; // Previous block Hash
+  merkleroot: string; // Merkel root
+  time: number; // Block generation timestamp
+  index: number; // Block index (height)
+  nonce: string; // Block pseudo-random number
+  nextconsensus: string; // Next master biller
+  script: ScriptDetails; // Block call signature authentication information
+  tx: BlockTransactionDetails[]; // Block containing trading group
+  confirmations: number; // Confirmation number (number of blocks after this block)
+  nextblockhash: string; // Next block hash
+}
+
+interface BlockTransactionDetails {
+  txid: string;
+  size: number;
+  type: string;
+  version: number;
+  attributes: any[];
+  vin: any[];
+  vout: any[];
+  sys_fee: string;
+  net_fee: string;
+  scripts: any[];
+  nonce: number;
+}
+
+interface ScriptDetails {
+  invocation: string;
+  verification: string;
+}
+
+ + +'''Error return value''' + +
+interface Error {
+  type: string;
+  description: string;
+  data: string;
+}
+
+ + +'''Example''' + +
+getBlock({
+  blockHeight: 2619690,
+  network: 'TestNet'
+})
+.then((result: Object) => {
+  console.log('Block information: ' + JSON.stringigy(result));
+})
+.catch(({type: string, description: string, data: any}) => {
+  switch(type) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+   case RPC_ERROR:
+    console.log('There was an error when broadcasting this transaction to the network.');
+    break;
+  }
+});
+
+ + +'''Provider Request Handling''' + +Upon receiving this request +* Broadcast the RPC request +* Return the RPC response results + + +Example +
+{
+  "hash": "0xc1668a114ee680597196ed402a0e0507fd8348e6090a54250d7accfadbd74b6e",
+  "size": 686,
+  "version": 0,
+  "previousblockhash": "0xbae289c94e17ae90022673186fd6e1e48b7dd7afb89319bff0e2832db06d16b3",
+  "merkleroot": "0x07d70f7337d3869a7daa538425d78a47212fb8c6130d66d84ac48526853a4e51",
+  "time": 1557376153,
+  "index": 2619690,
+  "nonce": "8efd62ebb85ee68b",
+  "nextconsensus": "AWZo4qAxhT8fwKL93QATSjCYCgHmCY1XLB",
+  "script": {
+    "invocation": "402a1dab9e5593d1d7d2a22a36772d4541b8053d33f8b8474b7d5a20066c1bd821e051fc252ed16146930d55ecb17fbb74972fba4c4b27af81a707999ca1313dd2401520eba2dd3b54a74a798cbb716c484ba6f6f21218f099e3d622a0fbd15989f38f9b0b344daf9b89175055d3a92f49df65118e8598735d651bedd4f1811baeb140e6491c03f3057f404d2fe7db50e40e82ade405a9dc7fccd81f4ba0b499a4a29f8570d631b8d40c5995b17d9391fe9ff8c73f28a4e1eb922b7a1ce9d1a5dc0448402cfcdede54828875d45402120aa2d8f78c7bd40df5e5d3b1873fd7e4d03672ebd0904f90c90fa519c623968f55550ae55374de66dc0db9c9d865c593bb95be5640214db0cd3cea6f4ad866df4129d482b89583805d1bdb08ce8399881e70351778a3e4a4093cf69aa7b99b83347fbfd38d85ff45d6a78ca2ab8cacffbfbc8c2d16",
+    "verification": "5521030ef96257401b803da5dd201233e2be828795672b775dd674d69df83f7aec1e36210327da12b5c40200e9f65569476bbff2218da4f32548ff43b6387ec1416a231ee821025bdf3f181f53e9696227843950deb72dcd374ded17c057159513c3d0abe20b64210266b588e350ab63b850e55dbfed0feeda44410a30966341b371014b803a15af0721026ce35b29147ad09e4afe4ec4a7319095f08198fa8babbe3c56e970b143528d222103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c12103fd95a9cb3098e6447d0de9f76cc97fd5e36830f9c7044457c15a0e81316bf28f57ae"
+  },
+  "tx": [
+    {
+      "txid": "0x07d70f7337d3869a7daa538425d78a47212fb8c6130d66d84ac48526853a4e51",
+      "size": 10,
+      "type": "MinerTransaction",
+      "version": 0,
+      "attributes": [],
+      "vin": [],
+      "vout": [],
+      "sys_fee": "0",
+      "net_fee": "0",
+      "scripts": [],
+      "nonce": 3093227147
+    }
+  ],
+  "confirmations": 70,
+  "nextblockhash": "0x2c9d6a107b21e83e09dd1b89df344a726895147d410120c46996290692ba29aa"
+}
+
+ + +====getTransaction==== +Get information about a specific transaction. + + +'''Method Interface''' + +
+function getTransaction({
+  txid: string,
+  network?: string
+}): Promise<{result: TransactionDetails}>
+
+ + +'''Input arguments''' + +
+interface TransactionInputArgs {
+  txid: string;
+  network?: string;
+}
+
+ + +'''Success return value''' + +
+export interface TransactionDetails {
+  txid: string;
+  size: number;
+  type: string;
+  version: number;
+  attributes: TransactionAttribute[];
+  vin: any[];
+  vout: any[];
+  sys_fee: string;
+  net_fee: string;
+  scripts: TransactionScript[];
+  script: string;
+  gas: string;
+  blockhash: string;
+  confirmations: number;
+  blocktime: number;
+}
+
+interface TransactionAttribute {
+  usage: string;
+  data: string;
+}
+
+interface TransactionScript {
+  invocation: string;
+  verification: string;
+}
+
+ + +'''Error return value''' + +
+interface Error {
+  type: string;
+  description: string;
+  data: string;
+}
+
+ + +'''Example''' + +
+getTransaction({
+  txid: '7e049fd7c253dabf38e4156df30c78b30d49f307196aa89b99a47d2330789bf2',
+  network: 'TestNet'
+})
+.then((result: Object) => {
+  console.log('Transaction details: ' + JSON.stringigy(result));
+})
+.catch(({type: string, description: string, data: any}) => {
+  switch(type) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+   case RPC_ERROR:
+    console.log('There was an error when broadcasting this transaction to the network.');
+    break;
+  }
+});
+
+ + +'''Provider Request Handling''' + +Upon receiving this request +* Broadcast the RPC request +* Return the RPC response results + + +Example +
+{
+  "txid": "0x7e049fd7c253dabf38e4156df30c78b30d49f307196aa89b99a47d2330789bf2",
+  "size": 556,
+  "type": "InvocationTransaction",
+  "version": 1,
+  "attributes": [
+    {
+      "usage": "Script",
+      "data": "296ac124021a71c449a9bad320c16429b08ad6ee"
+    },
+    {
+      "usage": "Remark",
+      "data": "cbb549adec34d741"
+    }
+  ],
+  "vin": [],
+  "vout": [],
+  "sys_fee": "0",
+  "net_fee": "0",
+  "scripts": [
+    {
+      "invocation": "4072b83e8aca62c27dc36b032b895e757db00620384e26f43cd0ecc9904bff1e652dd94a03226d6dcb0b6f91104cb40be6455aa0fc3b474a8a8e5fa43ff4b10b8d40af726dc0976f15cd8a134634074c5613ab1e59979fec37b611392975c92afa11038fd9d96ddfb306df12ae200dc3c15fa17cb9530389e28f090fd8c9721c3307",
+      "verification": "53c56b6c766b00527ac46c766b51527ac4616c766b00c36121022949376faacb0c6783da8ab63548926cb3a2e8d786063a449833f927fa8853f0ac642f006c766b51c361210292a25f5f0772d73d3fb50d42bb3cb443505b15e106789d19efa4d09c5ddca756ac635f006c766b00c361210292a25f5f0772d73d3fb50d42bb3cb443505b15e106789d19efa4d09c5ddca756ac642f006c766b51c36121022949376faacb0c6783da8ab63548926cb3a2e8d786063a449833f927fa8853f0ac62040000620400516c766b52527ac46203006c766b52c3616c7566"
+    }
+  ],
+  "script": "0400e1f505147869ef9732cdf6f6d54adaa5cae3b55a9396bceb14296ac124021a71c449a9bad320c16429b08ad6ee53c1087472616e7366657267f1dfcf0051ec48ec95c8d0569e0b95075d099d84f10400e1f50514b1fdddf658ce5ff9f83e66ede2f333ecfcc0463e14296ac124021a71c449a9bad320c16429b08ad6ee53c1087472616e7366657267f1dfcf0051ec48ec95c8d0569e0b95075d099d84f1",
+  "gas": "0",
+  "blockhash": "0x4ea57fe267a392933d2b03fa733fbf1fa12c13f7e8ae2051e45465800e1a7cdb",
+  "confirmations": 9,
+  "blocktime": 1557377749
+}
+
+ + +====getApplicationLog==== +Get the application log for a given transaction. + + +'''Method Interface''' + +
+function getApplicationLog({
+  txid: string,
+  network?: string
+}): Promise<{result: ApplicationLog}>
+
+ + +'''Input arguments''' + +
+interface TransactionInputArgs {
+  txid: string;
+  network?: string;
+}
+
+ + +'''Success return value''' + +
+export interface ApplicationLog {
+  txid: string;
+  blockindex: number;
+  executions: ExecutionDetails[];
+}
+
+interface ExecutionDetails {
+  trigger: string;
+  contract: string;
+  vmstate: string;
+  gas_consumed: string;
+  stack: Argument[];
+  notifications: Notification[];
+}
+
+interface Notification {
+  contract: string;
+  state: {
+    type: 'Array';
+    value: Argument[];
+  };
+}
+
+interface Argument {
+  type: string;
+  value: string;
+}
+
+ + +'''Error return value''' + +
+interface Error {
+  type: string;
+  description: string;
+  data: string;
+}
+
+ + +'''Example''' + +
+getApplicationLog({
+  txid: '7e049fd7c253dabf38e4156df30c78b30d49f307196aa89b99a47d2330789bf2',
+  network: 'TestNet'
+})
+.then((result: Object) => {
+  console.log('Application log of transaction execution: ' + JSON.stringigy(result));
+})
+.catch(({type: string, description: string, data: any}) => {
+  switch(type) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+   case RPC_ERROR:
+    console.log('There was an error when broadcasting this transaction to the network.');
+    break;
+  }
+});
+
+ + +'''Provider Request Handling''' + +Upon receiving this request +* Broadcast the RPC request +* Return the RPC response results + + +Example +
+{
+  "txid": "0x7e049fd7c253dabf38e4156df30c78b30d49f307196aa89b99a47d2330789bf2",
+  "executions": [
+    {
+      "trigger": "Application",
+      "contract": "0x72985e7f2cea98b89af54d8607bc6400814c4b45",
+      "vmstate": "HALT",
+      "gas_consumed": "5.292",
+      "stack": [],
+      "notifications": [
+        {
+          "contract": "0x849d095d07950b9e56d0c895ec48ec5100cfdff1",
+          "state": {
+            "type": "Array",
+            "value": [
+              {
+                "type": "ByteArray",
+                "value": "7472616e73666572"
+              },
+              {
+                "type": "ByteArray",
+                "value": "296ac124021a71c449a9bad320c16429b08ad6ee"
+              },
+              {
+                "type": "ByteArray",
+                "value": "7869ef9732cdf6f6d54adaa5cae3b55a9396bceb"
+              },
+              {
+                "type": "ByteArray",
+                "value": "00e1f505"
+              }
+            ]
+          }
+        },
+        {
+          "contract": "0x849d095d07950b9e56d0c895ec48ec5100cfdff1",
+          "state": {
+            "type": "Array",
+            "value": [
+              {
+                "type": "ByteArray",
+                "value": "7472616e73666572"
+              },
+              {
+                "type": "ByteArray",
+                "value": "296ac124021a71c449a9bad320c16429b08ad6ee"
+              },
+              {
+                "type": "ByteArray",
+                "value": "b1fdddf658ce5ff9f83e66ede2f333ecfcc0463e"
+              },
+              {
+                "type": "ByteArray",
+                "value": "00e1f505"
+              }
+            ]
+          }
+        }
+      ]
+    }
+  ]
+}
+
+ + ===Write Methods=== ====send==== Invoke a transfer of a specified amount of a given asset from the connected account to another account. @@ -1419,6 +1860,54 @@ Example: }
+=====BLOCK_HEIGHT_CHANGED===== + +On a BLOCK_HEIGHT_CHANGED event, the block has advanced to the next. + +
+interface BlockHeightChanged {
+  network: string; // Network of the block which changed
+  blockHeight: integer; // Height of the new block
+  blockTime: integer; // Timestamp of the new block
+  blockHash: string; // Hash of the new block
+  tx: string[]; // List of transaction ids executed in the new block
+}
+
+ +Example: +
+{
+  "blockHash": "0x5d19f31f5488ebcb0ab4aabfbead2118744b59e6c91b42696cee73f026e6dde8",
+  "blockHeight": 2619937,
+  "blockTime": 1557382020,
+  "network": "TestNet",
+  "tx": [
+    "8f321fe22c4993d863e369fe30798c50a24400cec714373f63fcd88cb5402976"
+  ]
+}
+
+ +=====TRANSACTION_CONFIRMED===== + +On a TRANSACTION_CONFIRMED event, a previously broadcast transaction via the dapi has been confirmed by the blockchain. + +
+interface BlockHeightChanged {
+  txid: string; // Transaction id which was confirmed on chain
+  blockHeight: integer; // Height of the new block
+  blockTime: integer; // Timestamp of the new block
+}
+
+ +Example: +
+{
+  "txid": "8f321fe22c4993d863e369fe30798c50a24400cec714373f63fcd88cb5402976",
+  "blockHeight": 2619937,
+  "blockTime": 1557382020
+}
+
+ ====removeEventListener==== From 2522f8f255aa8bb51012a1c7b92b398114fa0d15 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Fri, 10 May 2019 14:25:12 +0900 Subject: [PATCH 61/96] add broadcastOverride option to write methods --- nep-dapi.mediawiki | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 68fadbe0..134c4f84 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1338,6 +1338,7 @@ function send({ remark?: string, fee?: string, network?: string, + broadcastOverride?: boolean, }): Promise @@ -1352,7 +1353,8 @@ interface SendArgs { amount: string; // The parsed amount of the asset to be sent remark?: string; // (Optional) Description of the transaction to be made fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction - network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to. + network?: string; // Network to submit this request to. If omitted, will default to network the wallet is currently set to. + broadcastOverride?: boolean; // In the case that the dApp would like to be responsible for broadcasting the signed transaction rather than the wallet provider } @@ -1362,7 +1364,8 @@ interface SendArgs {
 interface SendOutput {
   txid: string; // The transaction ID of the send invocation
-  nodeUrl: string; // The node which the transaction was broadcast to.
+  nodeUrl?: string; // The node which the transaction was broadcast to. Returned if transaction is broadcast by wallet provider
+  signedTx?: string; // The serialized signed transaction. Only returned if the broadcastOverride input argument was set to True
 }
 
@@ -1424,7 +1427,8 @@ Upon receiving this request ** To address is valid ** Map asset symbol to script hash of one is provided instead of script hash ** Amount is valid value, and account has enough balance -* Broadcast the RPC request +* If the "broadcastOverride" input argument is set to True, return the serialized signed transaction to the dApp +* Else broadcast the RPC request * Return the transaction Id and the url of the rpc node which the tx was broadcast to Example @@ -1452,6 +1456,7 @@ function invoke({ assetIntentOverrides?: AssetIntentOverrides, triggerContractVerification?: boolean, network?: string, + broadcastOverride?: boolean, }): Promise @@ -1466,6 +1471,7 @@ interface InvokeArgs { fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to. attachedAssets?: AttachedAssets; + broadcastOverride?: boolean; // In the case that the dApp would like to be responsible for broadcasting the signed transaction rather than the wallet provider assetIntentOverrides?: AssetIntentOverrides; // A hard override of all transaction utxo inputs and outputs. @@ -1510,7 +1516,8 @@ interface AssetOutput { interface InvokeOutput { txid: string; // The transaction ID of the invocation - nodeUrl: string; // The node which the transaction was broadcast to. + nodeUrl?: string; // The node which the transaction was broadcast to. Returned if transaction is broadcast by wallet provider + signedTx?: string; // The serialized signed transaction. Only returned if the broadcastOverride input argument was set to True } @@ -1571,7 +1578,8 @@ Upon receiving this request ** Script hash is valid ** Format parameters *** If `byteArray`, convert to appropriate hexstring based on assumed format -* Broadcast the RPC request +* If the "broadcastOverride" input argument is set to True, return the serialized signed transaction to the dApp +* Else broadcast the RPC request * Return the transaction Id and the url of the rpc node which the tx was broadcast to Example @@ -1697,6 +1705,7 @@ function deploy({ returnType: string, code: string, network?: string, + broadcastOverride?: boolean, }): Promise @@ -1717,6 +1726,7 @@ interface DeployArgs { returnType: string; code: string; network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to. + broadcastOverride?: boolean; // In the case that the dApp would like to be responsible for broadcasting the signed transaction rather than the wallet provider } @@ -1726,7 +1736,8 @@ interface DeployArgs {
 interface DeployOutput {
   txid: string;
-  nodeUrl: string;
+  nodeUrl?: string; // The node which the transaction was broadcast to. Returned if transaction is broadcast by wallet provider
+  signedTx?: string; // The serialized signed transaction. Only returned if the broadcastOverride input argument was set to True
 }
 
@@ -1778,7 +1789,10 @@ deploy({ Upon receiving this request * Run a testinvoke on the deploy transaction to get the gas cost in order to deploy the contract * Display the deploy input parameters to the user along with the associated deployment fee -* Sign and broadcast transaction upon receiving confirmation from user +* Sign transaction upon receiving confirmation from user +* If the "broadcastOverride" input argument is set to True, return the serialized signed transaction to the dApp +* Else broadcast the RPC request +* Return the transaction Id and the url of the rpc node which the tx was broadcast to Example

From de5cacb845dfc7bd7ea58bd6053da8c4ec56eb56 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Wed, 15 May 2019 15:53:41 +0900
Subject: [PATCH 62/96] Update invoke with optional argument to add hash tx
 attributes

---
 nep-dapi.mediawiki | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index 134c4f84..1edac896 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -1457,6 +1457,7 @@ function invoke({
   triggerContractVerification?: boolean,
   network?: string,
   broadcastOverride?: boolean,
+  txHashAttributes?: TxHashAttribute[],
 }): Promise
 
@@ -1478,6 +1479,8 @@ interface InvokeArgs { // IMPORTANT: If provided, fee and attachedAssets will be ignored. triggerContractVerification?: boolean; // Adds the instruction to invoke the contract verification trigger + + txHashAttributes?: TxHashAttribute[]; // Adds transaction attributes for the "Hash" usage block } interface Argument { @@ -1485,6 +1488,10 @@ interface Argument { value: any; } +interface TxHashAttribute extends Argument { + txAttrUsage: 'Hash1'|'Hash2'|'Hash3'|'Hash4'|'Hash5'|'Hash6'|'Hash7'|'Hash8'|'Hash9'|'Hash10'|'Hash11'|'Hash12'|'Hash13'|'Hash14'|'Hash15'; +} + type ArgumentDataType = 'String'|'Boolean'|'Hash160'|'Hash256'|'Integer'|'ByteArray'|'Array'|'Address'; interface AttachedAssets { From 3e3b1f99b4b2c92d39d845fb1f4ed7b6ed01e210 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 30 May 2019 11:55:05 +0900 Subject: [PATCH 63/96] update getBalance to only accept scriptHash for assets --- nep-dapi.mediawiki | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 1edac896..2294558e 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -393,7 +393,7 @@ Example ====getBalance==== Return balance of a specific asset for the given account. -If the asset is omited from a request to MainNet, all asset and token balances will be returned. +If the asset is omitted from a request to MainNet, all asset and token balances will be returned. '''Method Interface''' @@ -414,10 +414,7 @@ interface GetBalanceArgs { interface BalanceRequest { address: string; // Address to check balance(s) assets?: string|string[]; // Asset ID or script hash to check balance. - // Requests to "MainNet" will accept the asset symbols we well. - // Requests to non "MainNet" will just return asset balances for NEO and GAS - fetchUTXO?: boolean; - // Fetches to UTXO data for NEO and/or GAS if attribute is 'true' + fetchUTXO?: boolean; // Fetches to UTXO data for NEO and/or GAS if attribute is 'true' } @@ -454,7 +451,7 @@ interface Error { getBalance({ params: { address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru', - assets: ['NKN'] + assets: ['c36aee199dbba6c3f439983657558cfb67629599'] }, }) .then((results: BalanceResults) => { @@ -488,7 +485,7 @@ Single asset balance request sample { params: { address: 'AeysVbKWiLSuSDhg7DTzUdDyYYKfgjojru', - assets: ['NKN'] + assets: ['c36aee199dbba6c3f439983657558cfb67629599'] }, } @@ -549,7 +546,7 @@ Multiple account balances request sample }, { address: 'AbKNY45nRDy6B65YPVz1B6YXiTnzRqU2uQ', - asset: 'PHX', + asset: '1578103c13e39df15d0d29826d957e85d770d8c9', }, ] } @@ -1479,7 +1476,7 @@ interface InvokeArgs { // IMPORTANT: If provided, fee and attachedAssets will be ignored. triggerContractVerification?: boolean; // Adds the instruction to invoke the contract verification trigger - + txHashAttributes?: TxHashAttribute[]; // Adds transaction attributes for the "Hash" usage block } From 90981e07b4ca761d7266a20d620e1156f1a42b20 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 30 May 2019 11:58:55 +0900 Subject: [PATCH 64/96] update send to only accept scriptHash for assets --- nep-dapi.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 2294558e..bb3e6cd5 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1346,7 +1346,7 @@ function send({ interface SendArgs { fromAddress: string; // Address of the connected account to send the assets from toAddress: string; // Address of the receiver of the assets to be sent - asset: string; // Asset script hash to be sent. Accepts asset symbol only for "MainNet" + asset: string; // Asset script hash to be sent amount: string; // The parsed amount of the asset to be sent remark?: string; // (Optional) Description of the transaction to be made fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction @@ -1384,7 +1384,7 @@ interface Error { send({ fromAddress: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d', toAddress: 'ATaWxfUAiBcQixNPq6TvKHEHPQum9bx79d', - asset: 'GAS', + asset: '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7', amount: '0.0001', remark: 'Hash puppy clothing purchase. Invoice#abc123', fee: '0.0001' @@ -1422,7 +1422,7 @@ Upon receiving this request * Validate the inputs ** From address matches connected account ** To address is valid -** Map asset symbol to script hash of one is provided instead of script hash +** Validate asset exists ** Amount is valid value, and account has enough balance * If the "broadcastOverride" input argument is set to True, return the serialized signed transaction to the dApp * Else broadcast the RPC request From 9350ca52240899a7b8fdec1a7b1076c144cfd869 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 30 May 2019 12:00:10 +0900 Subject: [PATCH 65/96] update getBalance input formatting --- nep-dapi.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index bb3e6cd5..810e6a22 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -399,7 +399,7 @@ If the asset is omitted from a request to MainNet, all asset and token balances '''Method Interface'''
-function getBalance(args: GetBalanceArgs): Promise}>
+function getBalance(args: GetBalanceArgs): Promise
 
From 85ca5326d6b02a434887800fa756e4040011ca47 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 30 May 2019 12:02:52 +0900 Subject: [PATCH 66/96] remove verifyMessage method --- nep-dapi.mediawiki | 90 ---------------------------------------------- 1 file changed, 90 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 810e6a22..e276ea2c 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -788,96 +788,6 @@ Example -====verifyMessage==== -Returns whether the provided signature data matches the provided message and was signed by the account of the provided public key. - - -'''Method Interface''' - -
-function verifyMessage({
-  message: string,
-  data: string,
-  publicKey: string,
-}): Promise<{result: boolean}>
-
- - -'''Input arguments''' - -
-interface VerifyMessageArgs {
-  message: string; // Salt prefix + original message
-  data: string; // Signed message
-  publicKey: string; // Public key of account that signed message
-}
-
- - -'''Success return value''' - -
-interface Response {
-  result: boolean;
-}
-
- - -'''Error return value''' - -
-interface Error {
-  type: string;
-  description: string;
-  data: string;
-}
-
- - -'''Example''' - -
-verifyMessage({
-  message: '058b9e03e7154e4db1e489c99256b7faHello World!',
-  data: '0147fb89d0999e9d8a90edacfa26152fe695ec8b3770dcad522048297ab903822e12472364e254ff2e088fc3ebb641cc24722c563ff679bb1d1623d08bd5863d0d',
-  publicKey: '0241392007396d6ef96159f047967c5a61f1af0871ecf9dc82afbedb68afbb949a',
-})
-.then(({result: bool}) => {
-  console.log('Signature data matches provided message and public key: ' + result);
-})
-.catch(({type: string, description: string, data: any}) => {
-  switch(type) {
-    case NO_PROVIDER:
-      console.log('No provider available.');
-      break;
-    case CONNECTION_DENIED:
-      console.log('The user rejected the request to connect with your dApp');
-      break;
-  }
-});
-
- - -'''Provider Request Handling''' - -Upon receiving this request -* The input message should have the salt already added. -* Create the hexstring that was signed. '010001f0' + + message + '0000' -For more details, please see: -[https://docs.switcheo.network/#signing-messages-for-neo] - -* Verify that the signed data matches the provided public key and hexstring. -* Return to dapp - - -Example -
-{
-  result: true,
-}
-
- - ====getBlock==== Get information about a specific block. From 5c3e931b5ce634e264a5c6d99bc190364e534c55 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 11 Jun 2019 17:18:02 +0900 Subject: [PATCH 67/96] add invokeMulti method --- nep-dapi.mediawiki | 183 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index e276ea2c..28974fd8 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1505,6 +1505,189 @@ Example +====invokeMulti==== +Execute a multiple contract invocations in a single transaction. + + +'''Method Interface''' + +
+function invoke({
+  invokeArgs: InvokeArguments[],
+  fee?: string,
+  assetIntentOverrides?: AssetIntentOverrides,
+  network?: string,
+  broadcastOverride?: boolean,
+  txHashAttributes?: TxHashAttribute[],
+}): Promise
+
+ + +'''Input arguments''' + +
+interface InvokeArgs {
+  invokeArgs: InvokeArguments[]; List of contract invoke inputs
+
+  fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction
+  network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to.
+  broadcastOverride?: boolean; // In the case that the dApp would like to be responsible for broadcasting the signed transaction rather than the wallet provider
+
+  assetIntentOverrides?: AssetIntentOverrides;
+  // A hard override of all transaction utxo inputs and outputs.
+  // IMPORTANT: If provided, fee and attachedAssets will be ignored.
+
+  txHashAttributes?: TxHashAttribute[]; // Adds transaction attributes for the "Hash" usage block
+}
+
+interface InvokeArguments {
+  scriptHash: string; // script hash of the smart contract to invoke
+  operation: string; // operation on the smart contract to call
+  args: Argument[]; // any input arguments for the operation
+  attachedAssets?: AttachedAssets;
+  triggerContractVerification?: boolean; // Adds the instruction to invoke the contract verification trigger
+}
+
+interface Argument {
+  type: ArgumentDataType;
+  value: any;
+}
+
+interface TxHashAttribute extends Argument {
+  txAttrUsage: 'Hash1'|'Hash2'|'Hash3'|'Hash4'|'Hash5'|'Hash6'|'Hash7'|'Hash8'|'Hash9'|'Hash10'|'Hash11'|'Hash12'|'Hash13'|'Hash14'|'Hash15';
+}
+
+type ArgumentDataType = 'String'|'Boolean'|'Hash160'|'Hash256'|'Integer'|'ByteArray'|'Array'|'Address';
+
+interface AttachedAssets {
+  [asset: 'NEO'|'GAS']: string;
+}
+// KEY: Asset symbol (only NEO or GAS)
+// VALUE: Parsed amount to attach
+
+interface AssetIntentOverrides {
+  inputs: AssetInput[];
+  outputs: AssetOutput[];
+}
+
+interface AssetInput {
+  txid: string;
+  index: number;
+}
+
+interface AssetOutput {
+  asset: string;
+  address: number;
+  value: string;
+}
+
+
+ + +'''Success return value''' + +interface InvokeOutput { + txid: string; // The transaction ID of the invocation + nodeUrl?: string; // The node which the transaction was broadcast to. Returned if transaction is broadcast by wallet provider + signedTx?: string; // The serialized signed transaction. Only returned if the broadcastOverride input argument was set to True +} + + +'''Error return value''' + +
+interface Error {
+  type: string; // `NO_PROVIDER`|`CONNECTION_REFUSED`|`SEND_ERROR`|`MALFORMED_INPUT`|`CANCELED`
+  description: string;
+  data: string;
+}
+
+ + +'''Example''' + +
+invokeMulti({
+  invokeArgs: [
+    {
+      scriptHash: '505663a29d83663a838eee091249abd167e928f5',
+      operation: 'storeData',
+      arguments: [
+        {
+          type: 'string',
+          value: 'hello'
+        }
+      ],
+      attachedAssets: {
+        NEO: '100',
+        GAS: '0.0001',
+      },
+      triggerContractVerification: true,
+    },
+    {
+      scriptHash: '505663a29d83663a838eee091249abd167e928f5',
+      operation: 'purchaseTicket',
+      arguments: [
+        {
+          type: 'number',
+          value: '10'
+        }
+      ],
+    }
+  ],
+  fee: '0.001',
+  network: 'TestNet',
+  broadcastOverride: false,
+  txHashAttributes: [
+    {
+      type: 'Boolean',
+      value: true,
+      txAttrUsage: 'Hash1'
+    }
+  ]
+})
+.then(({txid, nodeUrl}: InvokeOutput) => {
+  console.log('Invoke transaction success!');
+  console.log('Transaction ID: ' + txid);
+  console.log('RPC node URL: ' + nodeUrl);
+})
+.catch(({type: string, description: string, data: any}) => {
+  switch(type) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+    case RPC_ERROR:
+      console.log('There was an error when broadcasting this transaction to the network.');
+      break;
+    case CANCELED:
+      console.log('The user has canceled this transaction.');
+      break;
+  }
+});
+
+ + +'''Provider Request Handling''' + +Upon receiving this request +* Validate and format the inputs +** Script hashes is valid +** Format parameters +*** If `byteArray`, convert to appropriate hexstring based on assumed format +* Batch invoke inputs into script, and handle assets to each invoke as outputs +* If the "broadcastOverride" input argument is set to True, return the serialized signed transaction to the dApp +* Else broadcast the RPC request +* Return the transaction Id and the url of the rpc node which the tx was broadcast to + +Example +
+{
+  txid: 'ed54fb38dff371be6e3f96e4880405758c07fe6dd1295eb136fe15f311e9ff77',
+  nodeUrl: 'http://seed7.ngd.network:10332',
+}:
+
+ + ====signMessage==== Signs a provided messaged with an account selected by user. A randomized salt prefix is added to the input string before it is signed, and it is encased in a non-executable transaction before signed. This ensures allow compatibility with Ledger devices. From bc18a72693185c6be2d6b8575d7cfc7850336dab Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 24 Jun 2019 11:36:49 +0900 Subject: [PATCH 68/96] Update nep-dapi.mediawiki --- nep-dapi.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 28974fd8..bdfd6224 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1765,7 +1765,7 @@ signMessage({ Upon receiving this request * Present the message to the user for signing * Create a randomized salt value to be prefixed to the message before signing -* Create the hexstring to be signed. '010001f0' + + salt + message + '0000' +* Create the hexstring to be signed. '010001f0' + {length of salt+message in hex} + salt + message + '0000' * Sign the hexstring value once the user confirms * Return to dapp From a04b04b282a9b832b96540e3d7af100bf69198e8 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 22 Jul 2019 17:21:29 +0900 Subject: [PATCH 69/96] Update nep-dapi.mediawiki --- nep-dapi.mediawiki | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index bdfd6224..9b714ae5 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1920,7 +1920,9 @@ enum Event { ACCOUNT_CHANGED = 'ACCOUNT_CHANGED', NETWORK_CHANGED = 'NETWORK_CHANGED', CONNECTED = 'CONNECTED', - DISCONNECTED = 'DISCONNECTED' + DISCONNECTED = 'DISCONNECTED', + BLOCK_HEIGHT_CHANGED = 'BLOCK_HEIGHT_CHANGED', + TRANSACTION_CONFIRMED = 'TRANSACTION_CONFIRMED' } @@ -1946,6 +1948,16 @@ interface Account { } +=====CONNECTED===== +On a CONNECTED event, the user has approved the connection of the dapp with one of their accounts. This will fire the first time any of one of the following methods are called from the dapp: getAccount, invoke, send. + +
+interface Account {
+  address: string; // Address of the connected account
+  label?: string; // A label the users has set to identify their wallet
+}
+
+ =====DISCONNECTED===== @@ -2038,7 +2050,9 @@ enum Event { ACCOUNT_CHANGED = 'ACCOUNT_CHANGED', NETWORK_CHANGED = 'NETWORK_CHANGED', CONNECTED = 'CONNECTED', - DISCONNECTED = 'DISCONNECTED' + DISCONNECTED = 'DISCONNECTED', + BLOCK_HEIGHT_CHANGED = 'BLOCK_HEIGHT_CHANGED', + TRANSACTION_CONFIRMED = 'TRANSACTION_CONFIRMED' } From 7691a6512ed582021962b1556cb68acb66665a22 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 22 Jul 2019 17:29:30 +0900 Subject: [PATCH 70/96] Update nep-dapi.mediawiki --- nep-dapi.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 9b714ae5..6bdb9b90 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -413,7 +413,7 @@ interface GetBalanceArgs { interface BalanceRequest { address: string; // Address to check balance(s) - assets?: string|string[]; // Asset ID or script hash to check balance. + assets?: string[]; // Asset IDs or script hashes to check balance. fetchUTXO?: boolean; // Fetches to UTXO data for NEO and/or GAS if attribute is 'true' } @@ -546,7 +546,7 @@ Multiple account balances request sample }, { address: 'AbKNY45nRDy6B65YPVz1B6YXiTnzRqU2uQ', - asset: '1578103c13e39df15d0d29826d957e85d770d8c9', + assets: ['1578103c13e39df15d0d29826d957e85d770d8c9'], }, ] } From fe914c1162006986504e14f62d00c73d6e53f1e6 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 22 Jul 2019 17:37:38 +0900 Subject: [PATCH 71/96] Update nep-dapi.mediawiki --- nep-dapi.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki index 6bdb9b90..91451ab3 100644 --- a/nep-dapi.mediawiki +++ b/nep-dapi.mediawiki @@ -1512,7 +1512,7 @@ Execute a multiple contract invocations in a single transaction. '''Method Interface'''
-function invoke({
+function invokeMulti({
   invokeArgs: InvokeArguments[],
   fee?: string,
   assetIntentOverrides?: AssetIntentOverrides,
@@ -1526,7 +1526,7 @@ function invoke({
 '''Input arguments'''
 
 
-interface InvokeArgs {
+interface InvokeMultiArgs {
   invokeArgs: InvokeArguments[]; List of contract invoke inputs
 
   fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction
@@ -1586,7 +1586,7 @@ interface AssetOutput {
 
 '''Success return value'''
 
-interface InvokeOutput {
+interface InvokeMultiOutput {
   txid: string; // The transaction ID of the invocation
   nodeUrl?: string; // The node which the transaction was broadcast to. Returned if transaction is broadcast by wallet provider
   signedTx?: string; // The serialized signed transaction. Only returned if the broadcastOverride input argument was set to True

From e4b84a9f6a6e4406811eb506cc60fc95b406a133 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Tue, 23 Jul 2019 12:16:55 +0900
Subject: [PATCH 72/96] Setting the script tx attr for invoke/multiInvoke

---
 nep-dapi.mediawiki | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index 91451ab3..e8813ba9 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -1492,6 +1492,10 @@ Upon receiving this request
 ** Script hash is valid
 ** Format parameters
 *** If `byteArray`, convert to appropriate hexstring based on assumed format
+* Set script transaction attribute 0x20 according to the following conditions
+** If triggerContractVerification is set to true, set 0x20 to scriptHash of the contract being invoked
+** If there is no fee, attachedAssets, or 'assetIntentOverrides', set 0x20 to the users address
+** If there are assetIntentOverrides but none of the inputs belong to the user address, set 0x20 to user address
 * If the "broadcastOverride" input argument is set to True, return the serialized signed transaction to the dApp
 * Else broadcast the RPC request
 * Return the transaction Id and the url of the rpc node which the tx was broadcast to
@@ -1675,6 +1679,10 @@ Upon receiving this request
 ** Format parameters
 *** If `byteArray`, convert to appropriate hexstring based on assumed format
 * Batch invoke inputs into script, and handle assets to each invoke as outputs
+* Set script transaction attribute 0x20 according to the following conditions
+** If triggerContractVerification is set to true, set 0x20 to scriptHash of the contract being invoked
+** If there is no fee, attachedAssets, or 'assetIntentOverrides', set 0x20 to the users address
+** If there are assetIntentOverrides but none of the inputs belong to the user address, set 0x20 to user address
 * If the "broadcastOverride" input argument is set to True, return the serialized signed transaction to the dApp
 * Else broadcast the RPC request
 * Return the transaction Id and the url of the rpc node which the tx was broadcast to

From bcce8596d4154ce5f034a916c78faa449006ac99 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Tue, 23 Jul 2019 12:17:43 +0900
Subject: [PATCH 73/96] Assign NEP number

---
 nep-dapi.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index e8813ba9..17523af1 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -1,5 +1,5 @@
 
-  NEP: 
+  NEP: 12
   Title: Unified dApp API for wallet providers
   Author: Nick Fujita , Matus Zamborsky 
   Type: Standard

From 16a75ca49697dced5b7587d3c52c97f61760d7de Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Tue, 23 Jul 2019 12:18:02 +0900
Subject: [PATCH 74/96] Update proposal status

---
 nep-dapi.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nep-dapi.mediawiki b/nep-dapi.mediawiki
index 17523af1..4ef25b9d 100644
--- a/nep-dapi.mediawiki
+++ b/nep-dapi.mediawiki
@@ -3,7 +3,7 @@
   Title: Unified dApp API for wallet providers
   Author: Nick Fujita , Matus Zamborsky 
   Type: Standard
-  Status: Draft
+  Status: Accepted
   Created: 2018-08-28
 
From facdc0fc06cb35a198e3734e819d79d2a82ba5cb Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Tue, 23 Jul 2019 14:17:23 +0900 Subject: [PATCH 75/96] rename file to nep-12 --- nep-dapi.mediawiki => nep-12.mediawiki | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename nep-dapi.mediawiki => nep-12.mediawiki (100%) diff --git a/nep-dapi.mediawiki b/nep-12.mediawiki similarity index 100% rename from nep-dapi.mediawiki rename to nep-12.mediawiki From 822db8e1ab132bf70d465e5385ad8395e366b86c Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 1 Aug 2019 11:28:17 +0900 Subject: [PATCH 76/96] formatting --- nep-12.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 4ef25b9d..77961e5b 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -16,7 +16,7 @@ This NEP describes a common API interface for dApps to communicate with external ===End Users=== -As dApps come into the ecosystem, there will be more concerns about the safety of user assets. If dApps all required users to input their private keys in order to use them, it just takes one malicious dApp to steal all their funds. By using a trusted wallet provider which interfaces with the various dApps in the ecosystem on their behalf, users can reduce the exposure of their private keys. This will even allow users to transact with their hardware wallets via the wallet provider, never having to reveal their private keys even to the wallet itself. +As dApps come into the ecosystem, there will be more concerns about the safety of user assets. If dApps all required users to input their private keys in order to use them, it just takes one malicious dApp to steal all their funds. By using a trusted wallet provider which interfaces with the various dApps in the ecosystem on their behalf, users can reduce the exposure of their private keys. This will even allow users to transact with their hardware wallets via the wallet provider, never having to reveal their private keys even to the wallet itself. ===dApp Developers=== From 2226b54d6c6d83ea9d4c5c07af9c3a2e684a80f9 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 1 Aug 2019 11:29:58 +0900 Subject: [PATCH 77/96] formatting --- nep-12.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 77961e5b..6fcc027a 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -20,7 +20,7 @@ As dApps come into the ecosystem, there will be more concerns about the safety o ===dApp Developers=== -One of the initial hurtles for any developer when starting to develop a dApp is to create a wallet module that will allow the user and application to interface with the NEO blockchain. While there are many quality SDKs out there such as neon-js for facilitating the communication of these requests, there are often many hurtles to successfully constructing the right combination of methods, along with input and output parsing. The issue only gets amplified when trying to integrate with hardware wallet providers such as a Ledger device. +One of the initial hurdles for any developer when starting to develop a dApp is to create a wallet module that will allow the user and application to interface with the NEO blockchain. While there are many quality SDKs out there, such as neon-js, for facilitating the communication of these requests, there are often many hurdles to successfully construct the right combination of methods, along with input and output parsing. The issue only gets amplified when trying to integrate with hardware wallet providers such as a Ledger device. While there may be several options for 3rd party wallet providers that will help them to facilitate these transactions, the is currently no common consensus on the consistency of their interfaces. With a lack of consistency in interfaces to use these wallet provider services, dApp developers will be forced to make a decision to have their platform supported by a single provider, or to double or even triple their development efforts to accommodate all the different wallet provider interfaces. This will lead to a fragmentation in the dApps ecosystem. From 79c76772b80c3bd0116bf18e9be24b5486dc64fe Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 1 Aug 2019 11:31:11 +0900 Subject: [PATCH 78/96] typo --- nep-12.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 6fcc027a..c3cff764 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -22,7 +22,7 @@ As dApps come into the ecosystem, there will be more concerns about the safety o One of the initial hurdles for any developer when starting to develop a dApp is to create a wallet module that will allow the user and application to interface with the NEO blockchain. While there are many quality SDKs out there, such as neon-js, for facilitating the communication of these requests, there are often many hurdles to successfully construct the right combination of methods, along with input and output parsing. The issue only gets amplified when trying to integrate with hardware wallet providers such as a Ledger device. -While there may be several options for 3rd party wallet providers that will help them to facilitate these transactions, the is currently no common consensus on the consistency of their interfaces. With a lack of consistency in interfaces to use these wallet provider services, dApp developers will be forced to make a decision to have their platform supported by a single provider, or to double or even triple their development efforts to accommodate all the different wallet provider interfaces. This will lead to a fragmentation in the dApps ecosystem. +While there may be several options for 3rd party wallet providers that will help them to facilitate these transactions, there is currently no common consensus on the consistency of their interfaces. With a lack of consistency in interfaces to use these wallet provider services, dApp developers will be forced to make a decision to have their platform supported by a single provider, or to double or even triple their development efforts to accommodate all the different wallet provider interfaces. This will lead to a fragmentation in the dApps ecosystem. ===Wallet providers=== From bc6001cff4fc1dca75299e34edddafdb01490c33 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 1 Aug 2019 11:32:56 +0900 Subject: [PATCH 79/96] format --- nep-12.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index c3cff764..c1916680 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -26,7 +26,7 @@ While there may be several options for 3rd party wallet providers that will help ===Wallet providers=== -Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Wallet providers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplication an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted by both the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have a unified interface for such transactions, providers can spend more time on making their individual services better for their users. +Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Wallet providers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplicate an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted by both the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have an unified interface for such transactions, providers could spend more time on making their individual services better for their users. The current list of wallet providers that can benefit from the use of this protocol are currently: * NEL Chrome extension From 13634f6332f5cd5a86a6ac44f496d6130c05a088 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 1 Aug 2019 11:35:55 +0900 Subject: [PATCH 80/96] typo --- nep-12.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index c1916680..6acc8f6b 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -44,7 +44,7 @@ Additionally, since there are a significant amount of overlap in the protocols b '''Provider Request Handling''' -Implementation details of per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface. +Implementation details per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface. ===Read Methods=== From a6e939ec83c98e3df0388c646eeff04efc8d80ae Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 1 Aug 2019 12:01:06 +0900 Subject: [PATCH 81/96] Update Implementations --- nep-12.mediawiki | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 6acc8f6b..2555917f 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -2091,8 +2091,15 @@ INSUFFICIENT_FUNDS -> Thrown when the action does not have a sufficient balance This protocol will allow dApp developers to create applications that interact with the NEO blockchain without having to be concerned about managing a full wallet within their application or the details related to handing transaction creation or broadcasting. This will also allow dApps to allow users to transact in a secure fashion that does not require sharing of their private key. -==Implementation== +==Implementations== -JS implementation to demonstrate the usage of these methods from a dapp developer. +Wallet provider implementations: -o3-dapi-neo - [https://github.com/O3Labs/o3-dapi/tree/master/packages/neo Github] +===O3=== +[https://o3.network O3 Wallet] +[https://docs.o3.network/neoDapi/ dAPI Documentation] +[https://github.com/O3Labs/o3-dapi/tree/master/packages/neo Client JS Package (NPM/CDN)] + +===NEL=== +[https://github.com/NewEconoLab/TeemoWallet TeemoWallet] +[https://dapi.nel.group dAPI Documentation] From d3a24bb6dc97993e2bdb32073ab892d8ce957700 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 1 Aug 2019 12:02:41 +0900 Subject: [PATCH 82/96] Update nep-12.mediawiki --- nep-12.mediawiki | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 2555917f..e55e459f 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -2097,9 +2097,12 @@ Wallet provider implementations: ===O3=== [https://o3.network O3 Wallet] + [https://docs.o3.network/neoDapi/ dAPI Documentation] + [https://github.com/O3Labs/o3-dapi/tree/master/packages/neo Client JS Package (NPM/CDN)] ===NEL=== [https://github.com/NewEconoLab/TeemoWallet TeemoWallet] + [https://dapi.nel.group dAPI Documentation] From 05d126b104722fd4b9b64af5a40417b6183d459d Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 1 Aug 2019 12:11:30 +0900 Subject: [PATCH 83/96] Update dApp implementations --- nep-12.mediawiki | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index e55e459f..3e87193c 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -2091,9 +2091,7 @@ INSUFFICIENT_FUNDS -> Thrown when the action does not have a sufficient balance This protocol will allow dApp developers to create applications that interact with the NEO blockchain without having to be concerned about managing a full wallet within their application or the details related to handing transaction creation or broadcasting. This will also allow dApps to allow users to transact in a secure fashion that does not require sharing of their private key. -==Implementations== - -Wallet provider implementations: +==Wallet Provider Implementations== ===O3=== [https://o3.network O3 Wallet] @@ -2106,3 +2104,27 @@ Wallet provider implementations: [https://github.com/NewEconoLab/TeemoWallet TeemoWallet] [https://dapi.nel.group dAPI Documentation] + +==dApp Client Integrations== + +[https://switcheo.exchange/markets/NEX_NEO?ref=o3.network Switcheo] + +[https://store.neoeconomy.io/?ref=o3 NEO Economy Store] + +[http://dgamemaker.io/presale/ Decentralized Game Maker] + +[https://neo.alchemint.io/o3 Alchemint] + +[https://www.ftwlotto.com/?provider=o3 FTW] + +[https://neo.blocklords.io/?referalLink=AYWoyNjQwpLr1Ni7EC4HR5mQfrrRtqyPi4-1455 BLOCKLORDS] + +[https://blockchaincuties.com/neopresalestore?utm_source=o3wallet&utm_medium=referral BlockChain Cuties] + +[https://swap.o3.app/ O3 Swap] + +[https://utxo-manager.o3.app/ UTXO Manager] + +[https://buy.o3.network/ O3 Fiat Gateway] + +[https://neodapitestbed.o3.app/ NEO dAPI Testbed] From afb7851a623c2428774243a6af9221a887c33a56 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Thu, 1 Aug 2019 12:39:28 +0900 Subject: [PATCH 84/96] Update nep-12.mediawiki --- nep-12.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 3e87193c..0a618415 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -2103,7 +2103,7 @@ This protocol will allow dApp developers to create applications that interact wi ===NEL=== [https://github.com/NewEconoLab/TeemoWallet TeemoWallet] -[https://dapi.nel.group dAPI Documentation] +[https://dapi.nel.group/en/#neo-dapi-introduction dAPI Documentation] ==dApp Client Integrations== From eef71bf5513691be53c2965f7c8623c1f298151a Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 5 Aug 2019 12:07:57 +0900 Subject: [PATCH 85/96] Update nep-12.mediawiki --- nep-12.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 0a618415..ba19a0a9 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -314,7 +314,7 @@ Example ====getPublicKey==== -Return the public key of the Account that is currently connected to the dApp. +Return the public key, in hexstring format, of the Account that is currently connected to the dApp. '''Method Interface''' @@ -334,7 +334,7 @@ None
 interface Account {
   address: string; // Address of the connected account
-  publicKey: string; // Public key of the connected account
+  publicKey: string; // Public key of the connected account, in hexstring format
 }
 
@@ -379,7 +379,7 @@ getPublicKey() '''Provider Request Handling''' Upon receiving this request, return: -- The address and public key of account currently selected by the user in the wallet interface +- The address and public key of account currently selected by the user in the wallet interface, in hexstring format Example

From 81a4e45ff8f27201594d7de0036178b063b08122 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Mon, 5 Aug 2019 12:10:21 +0900
Subject: [PATCH 86/96] Update nep-12.mediawiki

---
 nep-12.mediawiki | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nep-12.mediawiki b/nep-12.mediawiki
index ba19a0a9..db87bb2c 100644
--- a/nep-12.mediawiki
+++ b/nep-12.mediawiki
@@ -256,7 +256,7 @@ None
 
 
 interface Account {
-  address: string; // Address of the connected account
+  address: string; // Address of the connected account, Base58 string format
   label?: string; // A label the users has set to identify their wallet
 }
 
@@ -333,7 +333,7 @@ None
 interface Account {
-  address: string; // Address of the connected account
+  address: string; // Address of the connected account, Base58 string format
   publicKey: string; // Public key of the connected account, in hexstring format
 }
 
From b6b8523912711e2f095fec79778e3b69f7d0525a Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 5 Aug 2019 12:46:24 +0900 Subject: [PATCH 87/96] Update nep-12.mediawiki --- nep-12.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index db87bb2c..e3a2d60c 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -606,7 +606,7 @@ function getStorage({ scriptHash: string, key: string, network?: string }): Prom
 interface GetStorageArgs {
-  scriptHash: string; // script hash of the smart contract to invoke a read on
+  scriptHash: string; // script hash of the smart contract to invoke a read on, in hexstring format
   key: string; // key of the storage value to retrieve from the contract
   network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to.
 }

From b55f5e4455785a35a5cde0ab28e35afe80215b46 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Mon, 5 Aug 2019 12:49:53 +0900
Subject: [PATCH 88/96] Update nep-12.mediawiki

---
 nep-12.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nep-12.mediawiki b/nep-12.mediawiki
index e3a2d60c..71834c4b 100644
--- a/nep-12.mediawiki
+++ b/nep-12.mediawiki
@@ -671,7 +671,7 @@ Upon receiving this request
 Example
 
 {
-  result: 'hello world'
+  result: '68656c6c6f20776f726c64'
 }
 
From 6d44a654b4fa9de685367911a85b09eee7cd2e23 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 5 Aug 2019 13:03:12 +0900 Subject: [PATCH 89/96] Update nep-12.mediawiki --- nep-12.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 71834c4b..18be873c 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -1006,7 +1006,7 @@ getTransaction({ network: 'TestNet' }) .then((result: Object) => { - console.log('Transaction details: ' + JSON.stringigy(result)); + console.log('Transaction details: ' + JSON.stringify(result)); }) .catch(({type: string, description: string, data: any}) => { switch(type) { From e076f8a5a8aca24d295f855135e63eda7c29edf7 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Mon, 5 Aug 2019 13:10:14 +0900 Subject: [PATCH 90/96] Update nep-12.mediawiki --- nep-12.mediawiki | 1 - 1 file changed, 1 deletion(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 18be873c..d66d6f2e 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -1093,7 +1093,6 @@ interface TransactionInputArgs {
 export interface ApplicationLog {
   txid: string;
-  blockindex: number;
   executions: ExecutionDetails[];
 }
 

From 5c10fc93cdf48c4d8aaca19d19b75798d26802e0 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Mon, 5 Aug 2019 14:33:18 +0900
Subject: [PATCH 91/96] Update nep-12.mediawiki

---
 nep-12.mediawiki | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nep-12.mediawiki b/nep-12.mediawiki
index d66d6f2e..832caa5d 100644
--- a/nep-12.mediawiki
+++ b/nep-12.mediawiki
@@ -1098,7 +1098,7 @@ export interface ApplicationLog {
 
 interface ExecutionDetails {
   trigger: string;
-  contract: string;
+  contract: string; // Transaction execution Script Hash
   vmstate: string;
   gas_consumed: string;
   stack: Argument[];
@@ -1106,7 +1106,7 @@ interface ExecutionDetails {
 }
 
 interface Notification {
-  contract: string;
+  contract: string; // Contract Hash where the transaction execution notice is located
   state: {
     type: 'Array';
     value: Argument[];

From de16d12c5970da57dcb15acc3f123fb63be9dd78 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Mon, 5 Aug 2019 14:45:44 +0900
Subject: [PATCH 92/96] Update nep-12.mediawiki

---
 nep-12.mediawiki | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nep-12.mediawiki b/nep-12.mediawiki
index 832caa5d..1c5f50dc 100644
--- a/nep-12.mediawiki
+++ b/nep-12.mediawiki
@@ -1407,11 +1407,11 @@ interface AttachedAssets {
 // VALUE: Parsed amount to attach
 
 interface AssetIntentOverrides {
-  inputs: AssetInput[];
+  inputs: UTXOAssetInput[];
   outputs: AssetOutput[];
 }
 
-interface AssetInput {
+interface UTXOAssetInput {
   txid: string;
   index: number;
 }

From a9f3465c2570c3bceb739d7894b4f5d2981c3946 Mon Sep 17 00:00:00 2001
From: Nick Fujita 
Date: Mon, 5 Aug 2019 14:49:02 +0900
Subject: [PATCH 93/96] Update nep-12.mediawiki

---
 nep-12.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nep-12.mediawiki b/nep-12.mediawiki
index 1c5f50dc..5590ec38 100644
--- a/nep-12.mediawiki
+++ b/nep-12.mediawiki
@@ -1722,7 +1722,7 @@ interface SignedMessage {
   publicKey: string; // Public key of account that signed message
   message: string; // Original message signed
   salt: string; // Salt added to original message as prefix, before signing
-  data; string; // Signed message
+  data: string; // Signed message
 }
 
From 14aed5d0e1712784b37128225ddad810a69e5b50 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Fri, 9 Aug 2019 14:34:39 +0900 Subject: [PATCH 94/96] Add getBlockHeight --- nep-12.mediawiki | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 5590ec38..daee2283 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -930,6 +930,85 @@ Example
+====getBlockHeight==== +Get the height of the current block. + + +'''Method Interface''' + +
+function getBlockHeight({
+  network?: string
+}): Promise<{result: BlockHeight}>
+
+ + +'''Input arguments''' + +
+interface GetBlockHeightInputArgs {
+  network?: string;
+}
+
+ + +'''Success return value''' + +
+interface BlockHeight {
+  result: number // Block height
+}
+
+ + +'''Error return value''' + +
+interface Error {
+  type: string;
+  description: string;
+  data: string;
+}
+
+ + +'''Example''' + +
+getBlockHeight({
+  network: 'TestNet'
+})
+.then((res: {result: number}) => {
+  console.log('Block height: ' + res.result);
+})
+.catch(({type: string, description: string, data: any}) => {
+  switch(type) {
+    case NO_PROVIDER:
+      console.log('No provider available.');
+      break;
+   case RPC_ERROR:
+    console.log('There was an error when broadcasting this transaction to the network.');
+    break;
+  }
+});
+
+ + +'''Provider Request Handling''' + +Upon receiving this request +* Broadcast the RPC request +* Return the RPC response results + + +Example +
+{
+  "result": 2619690
+}
+
+ + ====getTransaction==== Get information about a specific transaction. From a18ddfa7a840aa2b94c9839036994d428930a6d2 Mon Sep 17 00:00:00 2001 From: Nick Fujita Date: Fri, 9 Aug 2019 14:43:32 +0900 Subject: [PATCH 95/96] Add spec for versioning client integration modules --- nep-12.mediawiki | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index daee2283..4e078233 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -46,6 +46,10 @@ Additionally, since there are a significant amount of overlap in the protocols b Implementation details per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface. +''Wallet Provider dAPI Client Integration Package Versioning``` + +Providers of client packages for dApps shall provide versioned integration packages which facilitate the communication of these messages back to supported wallet providers. It is crutial that these packages be versioned in order to protect the dApps from potential future updates to the interface. In this way, a dApp should be able to use a fixed version of the dAPI method interfaces as long as it's supported by the wallet provider. Wallet providers should look to provide support for legacy version of client packages provided starting from the time the spec for this NEP has been finalized and merged. + ===Read Methods=== ====getProvider==== From e300825a15ccfc0b9ab820cef0d10b2ee0049f82 Mon Sep 17 00:00:00 2001 From: Albert Date: Sun, 11 Aug 2019 18:40:50 +0800 Subject: [PATCH 96/96] Fix grammar & vocab --- nep-12.mediawiki | 64 ++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/nep-12.mediawiki b/nep-12.mediawiki index 4e078233..68c51b05 100644 --- a/nep-12.mediawiki +++ b/nep-12.mediawiki @@ -26,7 +26,7 @@ While there may be several options for 3rd party wallet providers that will help ===Wallet providers=== -Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Wallet providers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplicate an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted by both the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have an unified interface for such transactions, providers could spend more time on making their individual services better for their users. +Each wallet provider, when deciding on supporting dApps to utilize their services as an authentication mechanism will be faced with a decision on how to implement an API to communicate with the dApps. Wallet providers can choose to create their own API from scratch, create their own version of existing projects, or aim to directly duplicate an existing API. In the case that the provider decides to make their own API interface from scratch, and try to promote dApps to use it, time and effort will inevitably be wasted by both the provider and competing providers on getting dApp developers on board with using their custom communication interface. If we have a unified interface for such transactions, providers could spend more time on making their individual services better for their users. The current list of wallet providers that can benefit from the use of this protocol are currently: * NEL Chrome extension @@ -35,25 +35,25 @@ The current list of wallet providers that can benefit from the use of this proto * NEX Chrome extension * O3 dApps browser -Each wallet provider has their own value proposition to it's users beyond the interface from this protocol itself, so it seems that formalizing it would be a net positive for all. +Each wallet provider has its own value proposition to its users beyond the interface from this protocol itself, so it seems that formalizing it would be a net positive for all. -Additionally, since there are a significant amount of overlap in the protocols between NEO and Ontology for sending assets, and interacting with contract on NeoVM, this proposal is a joint effort with [https://github.com/ontio/OEPs/pull/8 OEP6]. Since there are differences in the two platforms, the result of these proposals will not be identical, nor should they be, but getting as much overlap as possible will help to simplify cross-chain interactions for both platforms. +Additionally, since there is a significant amount of overlap in the protocols between NEO and Ontology for sending assets, and interacting with a contract on NeoVM, this proposal is a joint effort with [https://github.com/ontio/OEPs/pull/8 OEP6]. Since there are differences in the two platforms, the result of these proposals will not be identical, nor should they be, but getting as much overlap as possible will help to simplify cross-chain interactions for both platforms. ==Specification== '''Provider Request Handling''' -Implementation details per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transaction on their behalf, or a certain subset of transaction types. Below are basic guidelines for general handling of requests from dApps via the protocol interface. +Implementation details per dApp domain handling will be left to the discretion of the wallet provider. Providers can choose to allow users to trust certain dApps to automatically execute transactions on their behalf, or a certain subset of transaction types. Below are basic guidelines for the general handling of requests from dApps via the protocol interface. ''Wallet Provider dAPI Client Integration Package Versioning``` -Providers of client packages for dApps shall provide versioned integration packages which facilitate the communication of these messages back to supported wallet providers. It is crutial that these packages be versioned in order to protect the dApps from potential future updates to the interface. In this way, a dApp should be able to use a fixed version of the dAPI method interfaces as long as it's supported by the wallet provider. Wallet providers should look to provide support for legacy version of client packages provided starting from the time the spec for this NEP has been finalized and merged. +Providers of client packages for dApps shall provide versioned integration packages which facilitate the communication of these messages back to supported wallet providers. It is crucial that these packages be versioned in order to protect the dApps from potential future updates to the interface. In this way, a dApp should be able to use a fixed version of the dAPI method interfaces as long as it's supported by the wallet provider. Wallet providers should look to provide support for legacy versions of client packages provided starting from the time the spec for this NEP has been finalized and merged. ===Read Methods=== ====getProvider==== -Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. +Returns information about the dAPI provider, including who this provider is, the version of their dAPI, and the NEP that the interface is compatible with. '''Method Interface''' @@ -228,8 +228,8 @@ getNetworks() '''Provider Request Handling''' Upon receiving this request, return: -- The list of NEO networks that the wallet is able to connect to. The return values will be used by the dapp developer to communicate to which network they would like their request to be directed to. The wallet provider will be responsible for the logistics of which node to submit any request to for each network alias provided. -- The wallet provider is to also return the default network that the wallet UI is currently set to by user. +- The list of NEO networks that the wallet is able to connect to. The return values will be used by the dApp developer to communicate to which network they would like their request to be directed to. The wallet provider will be responsible for the logistics of which node to submit any request to for each network alias provided. +- The wallet provider is to also return the default network that the wallet UI is currently set to by the user. Example
@@ -306,7 +306,7 @@ getAccount()
 '''Provider Request Handling'''
 
 Upon receiving this request, return:
-- The address and label of account currently selected by the user in the wallet interface
+- The address and label of the account currently selected by the user in the wallet interface
 
 Example
 
@@ -383,7 +383,7 @@ getPublicKey()
 '''Provider Request Handling'''
 
 Upon receiving this request, return:
-- The address and public key of account currently selected by the user in the wallet interface, in hexstring format
+- The address and public key of the account currently selected by the user in the wallet interface, in hexstring format
 
 Example
 
@@ -412,7 +412,7 @@ function getBalance(args: GetBalanceArgs): Promise
 
 interface GetBalanceArgs {
   params: BalanceRequest|BalanceRequest[];
-  network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to.
+  network?: string - Network to submit this request to. If omitted, it will default to the network the wallet is currently set to.
 }
 
 interface BalanceRequest {
@@ -592,7 +592,7 @@ Multiple account balances request sample
 '''Provider Request Handling'''
 
 Upon receiving this request, fetch the latest balance(s) for each given account, for the specific asset if applicable.
-Typechecking will be required on the input argument, as it can be eather a single BalanceRequest object, or an array of BalanceRequest objects. In the case where a specific asset is not provided to check the balance for, the wallet provider will fetch balances for all assets and tokens for that account.
+Typechecking will be required on the input argument, as it can be either a single BalanceRequest object or an array of BalanceRequest objects. In the case where a specific asset is not provided to check the balance for, the wallet provider will fetch balances for all assets and tokens for that account.
 
 
 ====getStorage====
@@ -612,7 +612,7 @@ function getStorage({ scriptHash: string, key: string, network?: string }): Prom
 interface GetStorageArgs {
   scriptHash: string; // script hash of the smart contract to invoke a read on, in hexstring format
   key: string; // key of the storage value to retrieve from the contract
-  network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to.
+  network?: string - Network to submit this request to. If omitted, it will default to the network the wallet is currently set to.
 }
 
@@ -702,7 +702,7 @@ interface InvokeReadArgs { scriptHash: string; // script hash of the smart contract to invoke a read on operation: string; // operation on the smart contract to call args: Argument[]; // any input arguments for the operation - network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to. + network?: string - Network to submit this request to. If omitted, it will default to the network the wallet is currently set to. } interface Argument { @@ -1342,7 +1342,7 @@ interface SendArgs { amount: string; // The parsed amount of the asset to be sent remark?: string; // (Optional) Description of the transaction to be made fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction - network?: string; // Network to submit this request to. If omitted, will default to network the wallet is currently set to. + network?: string; // Network to submit this request to. If omitted, it will default to the network the wallet is currently set to. broadcastOverride?: boolean; // In the case that the dApp would like to be responsible for broadcasting the signed transaction rather than the wallet provider }
@@ -1353,7 +1353,7 @@ interface SendArgs {
 interface SendOutput {
   txid: string; // The transaction ID of the send invocation
-  nodeUrl?: string; // The node which the transaction was broadcast to. Returned if transaction is broadcast by wallet provider
+  nodeUrl?: string; // The node which the transaction was broadcast to. Returned if the transaction is broadcast by a wallet provider
   signedTx?: string; // The serialized signed transaction. Only returned if the broadcastOverride input argument was set to True
 }
 
@@ -1415,7 +1415,7 @@ Upon receiving this request ** From address matches connected account ** To address is valid ** Validate asset exists -** Amount is valid value, and account has enough balance +** Amount is a valid value, and account has enough balance * If the "broadcastOverride" input argument is set to True, return the serialized signed transaction to the dApp * Else broadcast the RPC request * Return the transaction Id and the url of the rpc node which the tx was broadcast to @@ -1459,7 +1459,7 @@ interface InvokeArgs { operation: string; // operation on the smart contract to call args: Argument[]; // any input arguments for the operation fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction - network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to. + network?: string - Network to submit this request to. If omitted, it will default to the network the wallet is currently set to. attachedAssets?: AttachedAssets; broadcastOverride?: boolean; // In the case that the dApp would like to be responsible for broadcasting the signed transaction rather than the wallet provider @@ -1512,7 +1512,7 @@ interface AssetOutput { interface InvokeOutput { txid: string; // The transaction ID of the invocation - nodeUrl?: string; // The node which the transaction was broadcast to. Returned if transaction is broadcast by wallet provider + nodeUrl?: string; // The node which the transaction was broadcast to. Returned if the transaction is broadcast by a wallet provider signedTx?: string; // The serialized signed transaction. Only returned if the broadcastOverride input argument was set to True } @@ -1616,7 +1616,7 @@ interface InvokeMultiArgs { invokeArgs: InvokeArguments[]; List of contract invoke inputs fee?: string; // (Optional) The parsed amount of network fee (in GAS) to include with transaction - network?: string - Network to submit this request to. If omitted, will default to network the wallet is currently set to. + network?: string - Network to submit this request to. If omitted, it will default to the network the wallet is currently set to. broadcastOverride?: boolean; // In the case that the dApp would like to be responsible for broadcasting the signed transaction rather than the wallet provider assetIntentOverrides?: AssetIntentOverrides; @@ -1674,7 +1674,7 @@ interface AssetOutput { interface InvokeMultiOutput { txid: string; // The transaction ID of the invocation - nodeUrl?: string; // The node which the transaction was broadcast to. Returned if transaction is broadcast by wallet provider + nodeUrl?: string; // The node which the transaction was broadcast to. Returned if the transaction is broadcast by a wallet provider signedTx?: string; // The serialized signed transaction. Only returned if the broadcastOverride input argument was set to True } @@ -1760,7 +1760,7 @@ Upon receiving this request ** Script hashes is valid ** Format parameters *** If `byteArray`, convert to appropriate hexstring based on assumed format -* Batch invoke inputs into script, and handle assets to each invoke as outputs +* Batch invoke inputs into script and handle assets to each invoke as outputs * Set script transaction attribute 0x20 according to the following conditions ** If triggerContractVerification is set to true, set 0x20 to scriptHash of the contract being invoked ** If there is no fee, attachedAssets, or 'assetIntentOverrides', set 0x20 to the users address @@ -1857,7 +1857,7 @@ Upon receiving this request * Create a randomized salt value to be prefixed to the message before signing * Create the hexstring to be signed. '010001f0' + {length of salt+message in hex} + salt + message + '0000' * Sign the hexstring value once the user confirms -* Return to dapp +* Return to dApp For more details, please see: [https://docs.switcheo.network/#signing-messages-for-neo] @@ -1873,7 +1873,7 @@ Example
====deploy==== -Will deploy a compiled smart contract to the blockchain with the provided input parameters. The GAS cost for deploying the contract will be calculated by the provider, and displayed to the user upon tx acceptance or rejection. +Will deploy a compiled smart contract to the blockchain with the provided input parameters. The GAS cost for deploying the contract will be calculated by the provider and displayed to the user upon tx acceptance or rejection. '''Method Interface''' @@ -2018,7 +2018,7 @@ enum Event { =====READY===== -On a READY event, the callback will fire with a single argument with information about the wallet provider. At any time a READY event listener is added, it will immidiately be called if the provider is already in a ready state. This provides a single flow for dapp developers since this listener should start any and all interactions with the dapi protocol. +On a READY event, the callback will fire with a single argument with information about the wallet provider. At any time a READY event listener is added, it will immediately be called if the provider is already in a ready state. This provides a single flow for dApp developers since this listener should start any and all interactions with the dAPI protocol.
 interface Provider {
   name: string;
@@ -2030,7 +2030,7 @@ interface Provider {
 
 =====ACCOUNT_CHANGED=====
 
-On a ACCOUNT_CHANGED event, the callback will fire with a single argument of the new account. This occurs when an account is already connected to the dapp, and the user has changed the connected account from the dapi provider side.
+On a ACCOUNT_CHANGED event, the callback will fire with a single argument of the new account. This occurs when an account is already connected to the dApp, and the user has changed the connected account from the dAPI provider side.
 
 interface Account {
   address: string; // Address of the connected account
@@ -2039,7 +2039,7 @@ interface Account {
 
=====CONNECTED===== -On a CONNECTED event, the user has approved the connection of the dapp with one of their accounts. This will fire the first time any of one of the following methods are called from the dapp: getAccount, invoke, send. +On a CONNECTED event, the user has approved the connection of the dApp with one of their accounts. This will fire the first time any of one of the following methods are called from the dApp: getAccount, invoke, send.
 interface Account {
@@ -2051,7 +2051,7 @@ interface Account {
 
 =====DISCONNECTED=====
 
-On a DISCONNECTED event, the account connected to the dapp via the dapi provider has been disconnected (logged out).
+On a DISCONNECTED event, the account connected to the dApp via the dAPI provider has been disconnected (logged out).
 
 
 =====NETWORK_CHANGED=====
@@ -2102,7 +2102,7 @@ Example:
 
 =====TRANSACTION_CONFIRMED=====
 
-On a TRANSACTION_CONFIRMED event, a previously broadcast transaction via the dapi has been confirmed by the blockchain.
+On a TRANSACTION_CONFIRMED event, a previously broadcast transaction via the dAPI has been confirmed by the blockchain.
 
 
 interface BlockHeightChanged {
@@ -2148,7 +2148,7 @@ enum Event {
 
 ===Error handling===
 
-All methods return a promise which will result in a resolve or reject. In the case of a rejection, the return argument will be an object formatted with standard fields for the type of error, a brief description, and any raw error data.
+All methods return a promise which will resolve or reject. In the case of a rejection, the return argument will be an object formatted with standard fields for the type of error, a brief description, and any raw error data.
 
 
 interface Error {
@@ -2161,10 +2161,10 @@ interface Error {
 Common error definitions
 
 NO_PROVIDER -> Thrown when there is no interface capable of interacting with NEO blockchain
-CONNECTION_DENIED -> Thrown when API provider refuses to execute a transaction (e.g. trying to execute a transaction on an unavialable network)
+CONNECTION_DENIED -> Thrown when API provider refuses to execute a transaction (e.g. trying to execute a transaction on an unavailable network)
 RPC_ERROR -> Thrown when a command relying on RPC connection to a network node fails
 MALFORMED_INPUT -> Thrown when an input such as the address is not a valid NEO address
-CANCELED -> Thrown when a user cancels, or refuses the dapps request
+CANCELED -> Thrown when a user cancels or refuses the dApp's request
 INSUFFICIENT_FUNDS -> Thrown when the action does not have a sufficient balance