From a99199bddb6ba4155b97c4d965f698389b46365b Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 3 Aug 2018 13:20:18 +0200 Subject: [PATCH 01/60] initial OEP-5 --- OEP-5/OEP-2.1.mediawiki | 164 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 OEP-5/OEP-2.1.mediawiki diff --git a/OEP-5/OEP-2.1.mediawiki b/OEP-5/OEP-2.1.mediawiki new file mode 100644 index 0000000..1168833 --- /dev/null +++ b/OEP-5/OEP-2.1.mediawiki @@ -0,0 +1,164 @@ +
+  OEP: 5
+  Title: DApp web API
+  Author: Matus Zamborsky 
+  Type: Meta
+  Status: Draft
+  Created: 2018-08-03
+
+ +==Abstract== + +A method is proposed for authentication of user in off-chain communication. This method is a part of verifiable claim online requesting, but can be used in other scenarios where Service provider needs to authenticate the user prior providing the service. This method is based on the cryptographic principles and data structures of JWT tokens. + +==Motivation== + +Currently there is no recommended or established way of authenticating user in off-chain communication. A typical use case is requesting verifiable claim. Main motivation is to guide implementators of services interacting with ONT ID identity to use common principles and to prevent implementations which are not secure. + +==Specification== + +This proposal makes use of the following functions and definitions: + +*'''Requester''', an user wanting to prove his ONT ID ownership and requesting a service. In the context of this proposal, requester is combination of an user and an user agent application which handles credentials of the user and the communication protocol. +*'''Service provider (SeP)''', a provider of some service (e.g.: Issuer is issuing verifiable claims). +*'''Off-chain communication''', an online communication between entities which take place outside the blockchain. +*'''Signature''', a cryptographic signature of unsigned data using one of the supported signature schemes. +*'''Signature scheme''', a concrete selection of hashing function and signature algorithm used. +*'''PublicKeyId''', the ID of a signature public key. +*'''GetPublicKeyStatus''', a method of ONT ID smart contract to retrieve the public key and its status by its id. +*'''JWT Token''', a JSON object that is defined in [https://tools.ietf.org/html/rfc7519 RFC 7519] as a safe way to disclose a set of information between two parties. +*'''JWS Signature''', a standard defined for signing arbitrary JSON objects defined in [https://tools.ietf.org/html/rfc7515 RFC 7515]. +*'''A || B''', a string concatenation of two values A and B. + +===General verification process=== +#Requester prepares the request. +#Requester signs and sends a request to Service provider. +#SeP requests status of declared public key from blockchain. +#SeP validates if the key is not revoked and verifies the signature. + +===Preparation of the request=== +Verifiable claim request is represented similarly to the claim itself, as a signed JWT token. Basic structure of the token consists of three parts: Header, Payload and Signature. The standard JWT attributes are reused as much as possible and in special cases custom attributes are defined. + +====Header==== +Header of the request specifies the signature scheme employed and public key used to verify the signature. + +
+{
+  "alg": "ES256",
+  "typ": "JWT",
+  "kid": "did:ont:TRAtosUZHNSiLhzBdHacyxMX4Bg3cjWy3r#keys-1"
+}
+
+ +* '''typ''' attribute is always JWT. +* '''alg''' attribute identifies the signature scheme used to secure the JWT token. A list of supported values is based on IANA "JSON Web Signature and Encryption Algorithms" registry and can be found [[#supported-signature-schemes|here]]. +* '''kid''' attribute refers to the public key used for signature verification. It has the form of Public Key Id as defined in ONT ID specification. + +====Payload==== +Payload is the main part of the request. It contains necessary information about requester and SeP and also all the information the requester wants to disclose to the SeP. + +
+{
+  "iss": "did:ont:TRAtosUZHNSiLhzBdHacyxMX4Bg3cjWy3r",
+  "sub": "did:ont:SI59Js0zpNSiPOzBdB5cyxu80BO3cjGT70",
+  "iat": 1525465044,
+  "exp": 1530735444,
+  "data": {
+    ...
+  }
+}
+
+ +* '''iss''' attribute refers to the ONT ID of requester and has the form of ONT ID. +* '''sub''' attribute refers to the ONT ID of SeP and has the form of ONT ID. +* '''iat''' attribute marks the time the token was created and has the format of unix timestamp. +* '''exp''' attribute marks the expiration time of the token and has the format of unix timestamp. +* '''data''' attribute is the root of custom request object. It contains the information to disclose. + +===Signing the request=== +After constructing Header and Payload of the request, Signature part is computed according to JWS standard. Full description can be found in [https://tools.ietf.org/html/rfc7515#section-5.1 RFC 7515 Section 5.1]. The simplified version is as follows: + +* Compute the signing input as serialization of Header and Payload according to JWS specification. +
+  BASE64URL(Header) || '.' || BASE64URL(Payload)
+
+* Compute the JWS Signature in the manner defined for the particular signature scheme being used over the signing input. +* Encode the signature +
+  BASE64URL(Signature)
+
+* Create the signed JWT token using JWS Compact Serialization +
+  BASE64URL(Header) || '.' || BASE64URL(Payload) || '.' || BASE64URL(Signature)
+
+ +===Sending the request=== +After constructing whole request, it should be transferred to the SeP in a secure way, because it might contain private information about requester as part of the payload. + +Most widespread method will be transferring the request as POST body over HTTPS protocol. Another important method will be inter-application communication on mobile devices where requester is on one side, and SeP is another mobile application. + +===Verification of request=== +Before SeP provides the service, it must verify the signature and authorize the requester. To do so, it must: + +* Deserialize the request +* Request status of declared Public Key +* Validate Signature +* Determine the ONT ID of requester + +====Deserialization==== +The process of deserialization is exactly opposite of the serialization steps. Therefore the first step is to divide the encoded request by separator '.' into BASE64URL encoded Header, Payload and Signature. After that it must decode the BASE64URL encoding. + +====Requesting status of public Key==== +Public key used during signing process is stored in attribute '''kid''' in the Header. SeP will preferably use one of the SDKs for communicating with Ontology blockchain to retrieve Public key status for declared Public key and check if it is not revoked. + +
+  Status = GetPublicKeyStatus(kid)
+
+ +If SeP is not able to retrieve Public key status or the status is revoked, then the identity is not verified and SeP must not proceed. + +====Validating of Signature==== +Validation of signature will ensure, that the request was not forged and nobody tampered with the Request. Signature is validated according to JWS standard. Full description can be found in [https://tools.ietf.org/html/rfc7515#section-5.2 RFC 7515 Section 5.2]. The simplified version is as follows: + +* Compute the signing input as serialization of Header and Payload according to JWS specification. +
+  BASE64URL(Header) || '.' || BASE64URL(Payload)
+
+* Validate the JWS Signature against the JWS signing input in the manner defined for the particular signature scheme being used. + +If the signature is not valid, then the identity is not verified and SeP must not proceed. + +====Determining the ONT ID of requester==== +Final step in verification of the requester is determining if declared public key in Header attribute '''kid''' belongs to proclaimed issuer of the request in Payload attribute '''iss'''. This is straightforward process, because the '''kid''' has a form of #keys-. Therefore a check if the '''kid''' attribute starts with '''iss''' attribute is sufficient. + +If the check passed, the Service provider has authenticated the Requester and verified that he is the owner of the ONT ID and can proceed. + +Otherwise the identity is not verified and SeP must not proceed. + +===Supported signature schemes=== +*'''ES224''' - ECDSA with SHA224, +*'''ES256''' - ECDSA with SHA256, +*'''ES384''' - ECDSA with SHA384, +*'''ES512''' - ECDSA with SHA512, +*'''ES3-224''' - ECDSA with SHA3 224 +*'''ES3-256''' - ECDSA with SHA3 256 +*'''ES3-384''' - ECDSA with SHA3 384 +*'''ES3-512''' - ECDSA with SHA3 512 +*'''ER160''' - ECDSA with RIPEMD160 +*'''SM''' - SM2 with SM3 +*'''EDS512''' - EDDSA with SHA256 + +==Rationale== + +'''''User story:''' As a Service Provider, I need to check if the Requester is really who he claims to be, before providing the service.'' + +or more specifically + +'''''User story:''' As a Trust Anchor who would like to issue a verifiable claim, I need to check if the Requester is really who he claims to be.'' + +==Test Cases== +backslash47/ontology-ts-sdk - https://github.com/backslash47/ontology-ts-sdk/blob/oep-verify-impl/test/webRequest.test.ts + +==Implementation== + +backslash47/ontology-ts-sdk - https://github.com/backslash47/ontology-ts-sdk/blob/oep-verify-impl/src/web/webRequest.ts From 8de3d742ac7c08c81f844a3e953216da7ec57b1e Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 3 Aug 2018 13:22:37 +0200 Subject: [PATCH 02/60] rename --- OEP-5/{OEP-2.1.mediawiki => OEP-5.mediawiki} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename OEP-5/{OEP-2.1.mediawiki => OEP-5.mediawiki} (100%) diff --git a/OEP-5/OEP-2.1.mediawiki b/OEP-5/OEP-5.mediawiki similarity index 100% rename from OEP-5/OEP-2.1.mediawiki rename to OEP-5/OEP-5.mediawiki From cb088f1a6b5e15baae6659aa972c2c459dce7737 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 3 Aug 2018 13:46:37 +0200 Subject: [PATCH 03/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 147 ++---------------------------------------- 1 file changed, 6 insertions(+), 141 deletions(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index 1168833..6f978e3 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -1,6 +1,6 @@
   OEP: 5
-  Title: DApp web API
+  Title: dApp web API
   Author: Matus Zamborsky 
   Type: Meta
   Status: Draft
@@ -9,156 +9,21 @@
 
 ==Abstract==
 
-A method is proposed for authentication of user in off-chain communication. This method is a part of verifiable claim online requesting, but can be used in other scenarios where Service provider needs to authenticate the user prior providing the service. This method is based on the cryptographic principles and data structures of JWT tokens.
+An Javascript API is proposed for dApps development. This API allows dApps to communicate with Ontology blockchain and make requests for transfers, ONT ID registration and others without requiring users to trust the dApp itself. The trust issue is shifted to the API implementation provider.
 
 ==Motivation==
 
-Currently there is no recommended or established way of authenticating  user in off-chain communication. A typical use case is requesting verifiable claim. Main motivation is to guide implementators of services interacting with ONT ID identity to use common principles and to prevent implementations which are not secure. 
+Currently a dApp will use one of the SDKs (Typescript, Java, Python, ...) to communicate with Ontology network. This setup has two main disadvantages:
 
-==Specification==
-
-This proposal makes use of the following functions and definitions:
-
-*'''Requester''', an user wanting to prove his ONT ID ownership and requesting a service. In the context of this proposal, requester is combination of an user and an user agent application which handles credentials of the user and the communication protocol.
-*'''Service provider (SeP)''', a provider of some service (e.g.: Issuer is issuing verifiable claims).
-*'''Off-chain communication''', an online communication between entities which take place outside the blockchain.
-*'''Signature''', a cryptographic signature of unsigned data using one of the supported signature schemes.
-*'''Signature scheme''', a concrete selection of hashing function and signature algorithm used. 
-*'''PublicKeyId''', the ID of a signature public key.
-*'''GetPublicKeyStatus''', a method of ONT ID smart contract to retrieve the public key and its status by its id.
-*'''JWT Token''', a JSON object that is defined in [https://tools.ietf.org/html/rfc7519 RFC 7519] as a safe way to disclose a set of information between two parties.
-*'''JWS Signature''', a standard defined for signing arbitrary JSON objects defined in [https://tools.ietf.org/html/rfc7515 RFC 7515].
-*'''A || B''', a string concatenation of two values A and B.
-
-===General verification process===
-#Requester prepares the request.
-#Requester signs and sends a request to Service provider.
-#SeP requests status of declared public key from blockchain.
-#SeP validates if the key is not revoked and verifies the signature.
-
-===Preparation of the request===
-Verifiable claim request is represented similarly to the claim itself, as a signed JWT token. Basic structure of the token consists of three parts: Header, Payload and Signature. The standard JWT attributes are reused as much as possible and in special cases custom attributes are defined.
-
-====Header====
-Header of the request specifies the signature scheme employed and public key used to verify the signature.
-
-
-{
-  "alg": "ES256",
-  "typ": "JWT",
-  "kid": "did:ont:TRAtosUZHNSiLhzBdHacyxMX4Bg3cjWy3r#keys-1"
-}
-
- -* '''typ''' attribute is always JWT. -* '''alg''' attribute identifies the signature scheme used to secure the JWT token. A list of supported values is based on IANA "JSON Web Signature and Encryption Algorithms" registry and can be found [[#supported-signature-schemes|here]]. -* '''kid''' attribute refers to the public key used for signature verification. It has the form of Public Key Id as defined in ONT ID specification. - -====Payload==== -Payload is the main part of the request. It contains necessary information about requester and SeP and also all the information the requester wants to disclose to the SeP. - -
-{
-  "iss": "did:ont:TRAtosUZHNSiLhzBdHacyxMX4Bg3cjWy3r",
-  "sub": "did:ont:SI59Js0zpNSiPOzBdB5cyxu80BO3cjGT70",
-  "iat": 1525465044,
-  "exp": 1530735444,
-  "data": {
-    ...
-  }
-}
-
- -* '''iss''' attribute refers to the ONT ID of requester and has the form of ONT ID. -* '''sub''' attribute refers to the ONT ID of SeP and has the form of ONT ID. -* '''iat''' attribute marks the time the token was created and has the format of unix timestamp. -* '''exp''' attribute marks the expiration time of the token and has the format of unix timestamp. -* '''data''' attribute is the root of custom request object. It contains the information to disclose. - -===Signing the request=== -After constructing Header and Payload of the request, Signature part is computed according to JWS standard. Full description can be found in [https://tools.ietf.org/html/rfc7515#section-5.1 RFC 7515 Section 5.1]. The simplified version is as follows: - -* Compute the signing input as serialization of Header and Payload according to JWS specification. -
-  BASE64URL(Header) || '.' || BASE64URL(Payload)
-
-* Compute the JWS Signature in the manner defined for the particular signature scheme being used over the signing input. -* Encode the signature -
-  BASE64URL(Signature)
-
-* Create the signed JWT token using JWS Compact Serialization -
-  BASE64URL(Header) || '.' || BASE64URL(Payload) || '.' || BASE64URL(Signature)
-
- -===Sending the request=== -After constructing whole request, it should be transferred to the SeP in a secure way, because it might contain private information about requester as part of the payload. - -Most widespread method will be transferring the request as POST body over HTTPS protocol. Another important method will be inter-application communication on mobile devices where requester is on one side, and SeP is another mobile application. - -===Verification of request=== -Before SeP provides the service, it must verify the signature and authorize the requester. To do so, it must: - -* Deserialize the request -* Request status of declared Public Key -* Validate Signature -* Determine the ONT ID of requester - -====Deserialization==== -The process of deserialization is exactly opposite of the serialization steps. Therefore the first step is to divide the encoded request by separator '.' into BASE64URL encoded Header, Payload and Signature. After that it must decode the BASE64URL encoding. - -====Requesting status of public Key==== -Public key used during signing process is stored in attribute '''kid''' in the Header. SeP will preferably use one of the SDKs for communicating with Ontology blockchain to retrieve Public key status for declared Public key and check if it is not revoked. - -
-  Status = GetPublicKeyStatus(kid)
-
- -If SeP is not able to retrieve Public key status or the status is revoked, then the identity is not verified and SeP must not proceed. +1. User of the dApp will have to trust with his private keys to the dApp developer and that information about transfers mediated through the dApp are legitimate. -====Validating of Signature==== -Validation of signature will ensure, that the request was not forged and nobody tampered with the Request. Signature is validated according to JWS standard. Full description can be found in [https://tools.ietf.org/html/rfc7515#section-5.2 RFC 7515 Section 5.2]. The simplified version is as follows: +2. Although the SDKs are very powerful, they are hard to use. A more streamlined API will allow developers to focus on the application itself. -* Compute the signing input as serialization of Header and Payload according to JWS specification. -
-  BASE64URL(Header) || '.' || BASE64URL(Payload)
-
-* Validate the JWS Signature against the JWS signing input in the manner defined for the particular signature scheme being used. - -If the signature is not valid, then the identity is not verified and SeP must not proceed. - -====Determining the ONT ID of requester==== -Final step in verification of the requester is determining if declared public key in Header attribute '''kid''' belongs to proclaimed issuer of the request in Payload attribute '''iss'''. This is straightforward process, because the '''kid''' has a form of #keys-. Therefore a check if the '''kid''' attribute starts with '''iss''' attribute is sufficient. - -If the check passed, the Service provider has authenticated the Requester and verified that he is the owner of the ONT ID and can proceed. - -Otherwise the identity is not verified and SeP must not proceed. - -===Supported signature schemes=== -*'''ES224''' - ECDSA with SHA224, -*'''ES256''' - ECDSA with SHA256, -*'''ES384''' - ECDSA with SHA384, -*'''ES512''' - ECDSA with SHA512, -*'''ES3-224''' - ECDSA with SHA3 224 -*'''ES3-256''' - ECDSA with SHA3 256 -*'''ES3-384''' - ECDSA with SHA3 384 -*'''ES3-512''' - ECDSA with SHA3 512 -*'''ER160''' - ECDSA with RIPEMD160 -*'''SM''' - SM2 with SM3 -*'''EDS512''' - EDDSA with SHA256 +==Specification== ==Rationale== -'''''User story:''' As a Service Provider, I need to check if the Requester is really who he claims to be, before providing the service.'' - -or more specifically - -'''''User story:''' As a Trust Anchor who would like to issue a verifiable claim, I need to check if the Requester is really who he claims to be.'' - ==Test Cases== -backslash47/ontology-ts-sdk - https://github.com/backslash47/ontology-ts-sdk/blob/oep-verify-impl/test/webRequest.test.ts ==Implementation== -backslash47/ontology-ts-sdk - https://github.com/backslash47/ontology-ts-sdk/blob/oep-verify-impl/src/web/webRequest.ts From ea2a354a06fbdcfc5ea2cc3147ed566e0e272666 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 09:11:34 +0200 Subject: [PATCH 04/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index 6f978e3..992fd31 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -1,6 +1,6 @@
   OEP: 5
-  Title: dApp web API
+  Title: dApp web API (dAPI)
   Author: Matus Zamborsky 
   Type: Meta
   Status: Draft
@@ -9,18 +9,39 @@
 
 ==Abstract==
 
-An Javascript API is proposed for dApps development. This API allows dApps to communicate with Ontology blockchain and make requests for transfers, ONT ID registration and others without requiring users to trust the dApp itself. The trust issue is shifted to the API implementation provider.
+A Javascript API is proposed for dApps development. This dAPI allows dApps to communicate with Ontology blockchain and make requests for transfers, ONT ID registration and others, without requiring users to trust the dApp itself. The issue of trust is shifted to the dAPI provider.
 
 ==Motivation==
 
 Currently a dApp will use one of the SDKs (Typescript, Java, Python, ...) to communicate with Ontology network. This setup has two main disadvantages:
 
-1. User of the dApp will have to trust with his private keys to the dApp developer and that information about transfers mediated through the dApp are legitimate.
+1. User of the dApp will have to trust the dApp developer with his private keys and that information about transfers mediated through the dApp are legitimate.
 
 2. Although the SDKs are very powerful, they are hard to use. A more streamlined API will allow developers to focus on the application itself.
 
 ==Specification==
 
+This proposal makes use of the following functions and definitions:
+
+*'''SDK''', a software development kit implementing low level communication with the network and providing high level interface for dApps.
+
+*'''dApp''', an application with decentralized characteristics running in web environment. The application uses Ontology network for value transfers, contracts enforcing and identification between participants.
+
+*'''dAPI''', the API for dApps this OEP is proposing.
+
+*'''dAPI provider''', an implementation of the dAPI in the form of web browser plugin or other means, where a user interaction with the provider can be injected into api call workflow (e.g.: confirming transfer)
+
+===dAPI grouping===
+Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these groups:
+
+* '''Network''', a thin wrapper around the Ontology Node Websocket API, masking the complexity of websockets with Request-Response facade.
+
+* '''Runtime''', a main point of integration with the dAPI provider, where the issue of trust is shifted from dApp to dApp provider.
+
+* '''Smart contract''', a high level wrapper around the Smart Contract invocation and deployment.
+
+* '''Utils''', a group of utility function for encoding and decoding the data from/to blockchain.
+
 ==Rationale==
 
 ==Test Cases==

From 48a514cbcce849ce9b2f1e7904febbb090e529be Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Mon, 6 Aug 2018 09:20:42 +0200
Subject: [PATCH 05/60] Update OEP-5.mediawiki

---
 OEP-5/OEP-5.mediawiki | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki
index 992fd31..80d4060 100644
--- a/OEP-5/OEP-5.mediawiki
+++ b/OEP-5/OEP-5.mediawiki
@@ -42,6 +42,14 @@ Although this proposal is bringing clear and simple API for the dApps, the indiv
 
 * '''Utils''', a group of utility function for encoding and decoding the data from/to blockchain.
 
+===Network===
+
+```ruby
+require 'redcarpet'
+markdown = Redcarpet.new("Hello World!")
+puts markdown.to_html
+```
+
 ==Rationale==
 
 ==Test Cases==

From a16f27c3b37ff53476233eb93b0952b1d368856d Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Mon, 6 Aug 2018 09:25:20 +0200
Subject: [PATCH 06/60] Update OEP-5.mediawiki

---
 OEP-5/OEP-5.mediawiki | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki
index 80d4060..d2e1786 100644
--- a/OEP-5/OEP-5.mediawiki
+++ b/OEP-5/OEP-5.mediawiki
@@ -44,11 +44,6 @@ Although this proposal is bringing clear and simple API for the dApps, the indiv
 
 ===Network===
 
-```ruby
-require 'redcarpet'
-markdown = Redcarpet.new("Hello World!")
-puts markdown.to_html
-```
 
 ==Rationale==
 

From 413d9bd40bc182470323769090c48d6f93c77cdf Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Mon, 6 Aug 2018 09:40:54 +0200
Subject: [PATCH 07/60] Update OEP-5.mediawiki

---
 OEP-5/OEP-5.mediawiki | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki
index d2e1786..02406bd 100644
--- a/OEP-5/OEP-5.mediawiki
+++ b/OEP-5/OEP-5.mediawiki
@@ -20,7 +20,9 @@ Currently a dApp will use one of the SDKs (Typescript, Java, Python, ...) to com
 2. Although the SDKs are very powerful, they are hard to use. A more streamlined API will allow developers to focus on the application itself.
 
 ==Specification==
+API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To preciselly describe the structure of those objects, we'd chosen Typescript syntax.
 
+===Definitions===
 This proposal makes use of the following functions and definitions:
 
 *'''SDK''', a software development kit implementing low level communication with the network and providing high level interface for dApps.
@@ -31,10 +33,12 @@ This proposal makes use of the following functions and definitions:
 
 *'''dAPI provider''', an implementation of the dAPI in the form of web browser plugin or other means, where a user interaction with the provider can be injected into api call workflow (e.g.: confirming transfer)
 
+
+
 ===dAPI grouping===
 Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these groups:
 
-* '''Network''', a thin wrapper around the Ontology Node Websocket API, masking the complexity of websockets with Request-Response facade.
+* '''Network''', a thin wrapper around the Ontology Node API, masking the complexity of rpc/rest calls and websockets with Request-Response facade.
 
 * '''Runtime''', a main point of integration with the dAPI provider, where the issue of trust is shifted from dApp to dApp provider.
 
@@ -43,7 +47,20 @@ Although this proposal is bringing clear and simple API for the dApps, the indiv
 * '''Utils''', a group of utility function for encoding and decoding the data from/to blockchain.
 
 ===Network===
+A network API consists of:
 
+
+function getGenerateBlockTime(): Promise
+function getNodeCount(): Promise
+function getBlockHeight(): Promise
+function getMerkleProof(txHash: string): Promise
+function getStorage(constractAddress: string, key: string): Promise
+function getAllowance(asset: Asset, fromAddress: string, toAddress: string): Promise
+function getBlock(block: number | string): Promise
+function getTransaction(txHash: string): Promise
+function getNetwork(): Network
+function getBalance(address: string, asset: Asset): Promise
+
==Rationale== From 6080f90fe579c8ebd65e6fa7c7fabd2e027bd2e6 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 09:53:58 +0200 Subject: [PATCH 08/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index 02406bd..bc75987 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -20,9 +20,6 @@ Currently a dApp will use one of the SDKs (Typescript, Java, Python, ...) to com 2. Although the SDKs are very powerful, they are hard to use. A more streamlined API will allow developers to focus on the application itself. ==Specification== -API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To preciselly describe the structure of those objects, we'd chosen Typescript syntax. - -===Definitions=== This proposal makes use of the following functions and definitions: *'''SDK''', a software development kit implementing low level communication with the network and providing high level interface for dApps. @@ -33,8 +30,6 @@ This proposal makes use of the following functions and definitions: *'''dAPI provider''', an implementation of the dAPI in the form of web browser plugin or other means, where a user interaction with the provider can be injected into api call workflow (e.g.: confirming transfer) - - ===dAPI grouping=== Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these groups: @@ -46,10 +41,16 @@ Although this proposal is bringing clear and simple API for the dApps, the indiv * '''Utils''', a group of utility function for encoding and decoding the data from/to blockchain. +===Complex structures=== +API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To preciselly describe the structure of those objects, we'd chosen Typescript syntax. + ===Network=== A network API consists of:
+type Network = 'MAIN' | 'TEST' | 'PRIVATE';
+type Asset = 'ont' | 'ong';
+
 function getGenerateBlockTime(): Promise
 function getNodeCount(): Promise
 function getBlockHeight(): Promise
@@ -59,9 +60,11 @@ function getAllowance(asset: Asset, fromAddress: string, toAddress: string): Pro
 function getBlock(block: number | string): Promise
 function getTransaction(txHash: string): Promise
 function getNetwork(): Network
-function getBalance(address: string, asset: Asset): Promise
+function getBalance(address: string): Promise
 
+For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. '''BigNumber''' corresponds to a implementation of BigNumbers. + ==Rationale== ==Test Cases== From a5b8409118100ffa0665d9708acab76353644901 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 10:12:26 +0200 Subject: [PATCH 09/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index bc75987..4887e03 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -65,6 +65,29 @@ function getBalance(address: string): Promise For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. '''BigNumber''' corresponds to a implementation of BigNumbers. +===Runtime=== +A runtime API consists of: + +
+type Asset = 'ont' | 'ong';
+
+interface OntIdAttribute {
+    key: string;
+    type: string;
+    value: string;
+}
+
+function getOwnAddress(): string | null
+
+function makeTransfer(recipientAddress: string, asset: Asset, amount: BigNumber): Promise
+function withdrawOng(amount: BigNumber): Promise
+
+function registerOntId(ontId: string, publicKey: string): Promise
+function addOntIdAttributes(ontId: string, attributes: OntIdAttribute[]): Promise
+function removeOntIdAttribute(ontId: string, key: string): Promise
+
+ + ==Rationale== ==Test Cases== From af01a6e5823047d740c349f36c831685420fa0ae Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 11:05:12 +0200 Subject: [PATCH 10/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 60 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index 4887e03..3efd2dd 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -35,12 +35,23 @@ Although this proposal is bringing clear and simple API for the dApps, the indiv * '''Network''', a thin wrapper around the Ontology Node API, masking the complexity of rpc/rest calls and websockets with Request-Response facade. -* '''Runtime''', a main point of integration with the dAPI provider, where the issue of trust is shifted from dApp to dApp provider. +* '''Runtime.*''', a main point of integration with the dAPI provider, where the issue of trust is shifted from dApp to dApp provider. -* '''Smart contract''', a high level wrapper around the Smart Contract invocation and deployment. +* '''Runtime.Asset''', functions for transfering assets between user account and others. + +* '''Runtime.Identity''', functions for interacting with own ONT-ID identity. + +* '''Runtime.SmartContract''', a high level wrapper around the Smart Contract invocation and deployment. + +* '''Runtime.Message''', functions for signing arbitrary messages. * '''Utils''', a group of utility function for encoding and decoding the data from/to blockchain. +===Account/Identity management and transaction signing === +Because dAPI shifts the issue of trust from dApp to dApp provider, all account and identity management is external to the dApp. Therefore there are no methods which directly handle private keys. The dApp won't need to sign the transaction itself. + +Any time dApp makes a call that requires a private key to sign something (makeTransfer, sign), dApp provider will inform user about the action and prompt him for permission. + ===Complex structures=== API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To preciselly describe the structure of those objects, we'd chosen Typescript syntax. @@ -65,26 +76,55 @@ function getBalance(address: string): Promise For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. '''BigNumber''' corresponds to a implementation of BigNumbers. -===Runtime=== -A runtime API consists of: +===Runtime.Asset=== +A primary focus of Runtime.Asset API is to enumerate the addresses under user control and initiate a transfer of ong withdrawal. The request needs to be confirmed by the user. + +A Runtime.Asset API consists of:
 type Asset = 'ont' | 'ong';
 
+function getDefaultAddress(): string | null
+function getOwnAddresses(): string[]
+
+function makeTransfer(senderAddress: string, recipientAddress: string, asset: Asset, amount: BigNumber): Promise
+function withdrawOng(amount: BigNumber): Promise
+
+ +===Runtime.Identity=== +A primary focus of Runtime.Identity API is to enumerate the ONT-ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. + +
 interface OntIdAttribute {
     key: string;
     type: string;
     value: string;
 }
 
-function getOwnAddress(): string | null
+interface OntIdDDO {
+    ...
+}
 
-function makeTransfer(recipientAddress: string, asset: Asset, amount: BigNumber): Promise
-function withdrawOng(amount: BigNumber): Promise
+function getDefaultIdentity(): string | null
+function getOwnIdentities(): string[]
+
+function getDDO(ontId: string): Promise
+function addAttributes(ontId: string, attributes: OntIdAttribute[]): Promise
+function removeAttribute(ontId: string, key: string): Promise
+
+ +===Runtime.Message=== +This API deals with arbitrary message signing and verification. For security reasons, the API will prepend the supplied the message with known prefix or typed messages needs to be used. + +
+function signMessage(messageHash: string): Promise
+function verifyMessage(messageHash: string, signature: string): Promise
+
+function signPersonalMessage(message: string): Promise
+function verifyPersonalMessage(message: string, signature: string): Promise
 
-function registerOntId(ontId: string, publicKey: string): Promise
-function addOntIdAttributes(ontId: string, attributes: OntIdAttribute[]): Promise
-function removeOntIdAttribute(ontId: string, key: string): Promise
+function signTypedMessage(message: TypedMessage): Promise
+function verifyTypedMessage(message: TypedMessage, signature: string): Promise
 
From 5e2967d390b293b1a3cf77d6b96f8fd5bdd1c8de Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 11:51:53 +0200 Subject: [PATCH 11/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index 3efd2dd..586687e 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -1,8 +1,8 @@
-  OEP: 5
-  Title: dApp web API (dAPI)
+  OEP: 6
+  Title: API for dApps (dAPI)
   Author: Matus Zamborsky 
-  Type: Meta
+  Type: Standard
   Status: Draft
   Created: 2018-08-03
 
From e1ae510581aa7b91eba57323ee8fb771eb560e43 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 11:55:18 +0200 Subject: [PATCH 12/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index 586687e..ad0cbe8 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -55,13 +55,25 @@ Any time dApp makes a call that requires a private key to sign something (makeTr ===Complex structures=== API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To preciselly describe the structure of those objects, we'd chosen Typescript syntax. -===Network=== -A network API consists of: -
 type Network = 'MAIN' | 'TEST' | 'PRIVATE';
 type Asset = 'ont' | 'ong';
 
+interface OntIdAttribute {
+    key: string;
+    type: string;
+    value: string;
+}
+
+interface OntIdDDO {
+    ...
+}
+
+ +===Network=== +A network API consists of: + +
 function getGenerateBlockTime(): Promise
 function getNodeCount(): Promise
 function getBlockHeight(): Promise
@@ -81,11 +93,15 @@ A primary focus of Runtime.Asset API is to enumerate the addresses under user co
 
 A Runtime.Asset API consists of:
 
+====getOwnAddresses====
 
-type Asset = 'ont' | 'ong';
+function getOwnAddresses(): string[]
+
+Returns all the addresses associated with logged in user. + +
 function getDefaultAddress(): string | null
-function getOwnAddresses(): string[]
 
 function makeTransfer(senderAddress: string, recipientAddress: string, asset: Asset, amount: BigNumber): Promise
 function withdrawOng(amount: BigNumber): Promise
@@ -95,15 +111,6 @@ function withdrawOng(amount: BigNumber): Promise
 A primary focus of Runtime.Identity API is to enumerate the ONT-ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. 
 
 
-interface OntIdAttribute {
-    key: string;
-    type: string;
-    value: string;
-}
-
-interface OntIdDDO {
-    ...
-}
 
 function getDefaultIdentity(): string | null
 function getOwnIdentities(): string[]

From 839ea4508e7f7e994b73a3a92f2d35a35d5863ab Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Mon, 6 Aug 2018 11:58:27 +0200
Subject: [PATCH 13/60] Update OEP-5.mediawiki

---
 OEP-5/OEP-5.mediawiki | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki
index ad0cbe8..25dfb9e 100644
--- a/OEP-5/OEP-5.mediawiki
+++ b/OEP-5/OEP-5.mediawiki
@@ -100,13 +100,20 @@ function getOwnAddresses(): string[]
 
 Returns all the addresses associated with logged in user.
 
+====getDefaultAddress====
 
 function getDefaultAddress(): string | null
+
+Returns currently selected address of logged in user or null if there is none. +====makeTransfer==== +
 function makeTransfer(senderAddress: string, recipientAddress: string, asset: Asset, amount: BigNumber): Promise
-function withdrawOng(amount: BigNumber): Promise
 
+Initiates a transfer of amount asset from senderAddress to recipientAddress. The senderAddress must be one of the addresses returned by getOwnAddresses + + ===Runtime.Identity=== A primary focus of Runtime.Identity API is to enumerate the ONT-ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. From 2d8cb2eb2b5c7930447f52960a8cfd7b008f8a52 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 12:00:11 +0200 Subject: [PATCH 14/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index 25dfb9e..7ba8d19 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -89,9 +89,7 @@ function getBalance(address: string): Promise For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. '''BigNumber''' corresponds to a implementation of BigNumbers. ===Runtime.Asset=== -A primary focus of Runtime.Asset API is to enumerate the addresses under user control and initiate a transfer of ong withdrawal. The request needs to be confirmed by the user. - -A Runtime.Asset API consists of: +A primary focus of Runtime.Asset API is to enumerate the addresses under user control and initiate a transfer. The request needs to be confirmed by the user. ====getOwnAddresses====

From 7a23003ac2f8eb548eee62731debd1c5bcf2b262 Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Mon, 6 Aug 2018 13:11:59 +0200
Subject: [PATCH 15/60] Update OEP-5.mediawiki

---
 OEP-5/OEP-5.mediawiki | 38 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki
index 7ba8d19..fed2b4b 100644
--- a/OEP-5/OEP-5.mediawiki
+++ b/OEP-5/OEP-5.mediawiki
@@ -109,22 +109,56 @@ Returns currently selected address of logged in user or null if there is none.
 function makeTransfer(senderAddress: string, recipientAddress: string, asset: Asset, amount: BigNumber): Promise
 
-Initiates a transfer of amount asset from senderAddress to recipientAddress. The senderAddress must be one of the addresses returned by getOwnAddresses +Initiates a transfer of amount asset from senderAddress to recipientAddress. The senderAddress must be one of the addresses returned by getOwnAddresses. ===Runtime.Identity=== A primary focus of Runtime.Identity API is to enumerate the ONT-ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. +====getOwnIdentities====
+function getOwnIdentities(): string[]
+
+ +Returns all the identites associated with logged in user. +====getDefaultIdentity==== +
 function getDefaultIdentity(): string | null
-function getOwnIdentities(): string[]
+
+Returns currently selected identity of logged in user or null if there is none. + +====getDDO==== +
 function getDDO(ontId: string): Promise
+
+ +Queries Description Object of the identity. This operation is not signed and therefore does not require user interaction. + +====getAttributes==== +
+function getAttributes(ontId: string): Promise
+
+ +Queries attributes attached to the identity. This operation is not signed and therefore does not require user interaction. + + +====addAttributes==== +
 function addAttributes(ontId: string, attributes: OntIdAttribute[]): Promise
+
+ +Adds attributes to the identity. The ontId must be one of the identities returned by getOwnIdentities. + +====removeAttributes==== +
 function removeAttribute(ontId: string, key: string): Promise
 
+Removes attribute from the identity. The ontId must be one of the identities returned by getOwnIdentities. + + ===Runtime.Message=== This API deals with arbitrary message signing and verification. For security reasons, the API will prepend the supplied the message with known prefix or typed messages needs to be used. From 62afd6db6b5359303ab09f096ac7519c9b9bb13c Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 13:33:25 +0200 Subject: [PATCH 16/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 61 ++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index fed2b4b..39ba39a 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -24,6 +24,8 @@ This proposal makes use of the following functions and definitions: *'''SDK''', a software development kit implementing low level communication with the network and providing high level interface for dApps. +*'''SHA256''', a well-known hashing algorithm that takes an arbitrary number of bytes as input and deterministically yields a 32-byte hash. + *'''dApp''', an application with decentralized characteristics running in web environment. The application uses Ontology network for value transfers, contracts enforcing and identification between participants. *'''dAPI''', the API for dApps this OEP is proposing. @@ -91,29 +93,29 @@ For further explanation about the wrapped method consult https://ontio.github.io ===Runtime.Asset=== A primary focus of Runtime.Asset API is to enumerate the addresses under user control and initiate a transfer. The request needs to be confirmed by the user. -====getOwnAddresses==== +====getOwnAccounts====
-function getOwnAddresses(): string[]
+function getOwnAccounts(): string[]
 
-Returns all the addresses associated with logged in user. +Returns all the accounts associated with logged in user. -====getDefaultAddress==== +====getDefaultAccount====
-function getDefaultAddress(): string | null
+function getDefaultAccount(): string | null
 
-Returns currently selected address of logged in user or null if there is none. +Returns currently selected account of logged in user or null if there is none. ====makeTransfer====
-function makeTransfer(senderAddress: string, recipientAddress: string, asset: Asset, amount: BigNumber): Promise
+function makeTransfer(sender: string, recipient: string, asset: Asset, amount: BigNumber): Promise
 
-Initiates a transfer of amount asset from senderAddress to recipientAddress. The senderAddress must be one of the addresses returned by getOwnAddresses. +Initiates a transfer of amount asset from sender account to recipient account. The sender must be one of the accounts returned by getOwnAccounts. ===Runtime.Identity=== -A primary focus of Runtime.Identity API is to enumerate the ONT-ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. +A primary focus of Runtime.Identity API is to enumerate the ONT ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. ====getOwnIdentities====
@@ -162,17 +164,46 @@ Removes attribute from the identity. The ontId must be one of the i
 ===Runtime.Message===
 This API deals with arbitrary message signing and verification. For security reasons, the API will prepend the supplied the message with known prefix or typed messages needs to be used.
 
+====signMessageHash====
+
+function signMessageHash(messageHash: string, accountOrIdentity: string): Promise
+
+ +Initiates signing of arbitrary messageHash by the account or identity. The accountOrIdentity '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. + +This method does not require the dApp to disclose the message itself, only the hash. + +Because malicious dApp can hash a real prepared transfer transaction and plant it for signing, that posses a risk to the user. +Therefore the hash is prepended with known string '''Ontology message:''', hashed with '''SHA-256''' and only this hash is put for signing. + +====verifyMessageHash==== +
+function verifyMessageHash(messageHash: string, accountOrIdentity: string, signature: string): Promise
+
+ +Verifies that the signature is created by the account or identity over messageHash. The accountOrIdentity '''does not''' need to be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. + +This method does not require the dApp to disclose the message itself, only the hash. + + +====signMessage====
-function signMessage(messageHash: string): Promise
-function verifyMessage(messageHash: string, signature: string): Promise
+function signMessage(message: string, accountOrIdentity: string): Promise
+
-function signPersonalMessage(message: string): Promise -function verifyPersonalMessage(message: string, signature: string): Promise +Initiates signing of text message by the account or identity. The accountOrIdentity '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. -function signTypedMessage(message: TypedMessage): Promise -function verifyTypedMessage(message: TypedMessage, signature: string): Promise +This method provide the dAPI provider with the message body, which it should display to the user prior to signing (e.g.: a contract to sign). Signing is done on '''SHA-256''' hash of the message. + +====verifyMessage==== +
+function verifyMessage(message: string, accountOrIdentity: string, signature: string): Promise
 
+Verifies that the signature is created by the account or identity over text message. The accountOrIdentity '''does not''' need to be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. + +Verification is done on '''SHA-256''' hash of the message. + ==Rationale== From e5ccd8c6b79810d26c6de56cac496c7562560e80 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 13:34:26 +0200 Subject: [PATCH 17/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index 39ba39a..ca8d1cc 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -162,7 +162,7 @@ Removes attribute from the identity. The ontId must be one of the i ===Runtime.Message=== -This API deals with arbitrary message signing and verification. For security reasons, the API will prepend the supplied the message with known prefix or typed messages needs to be used. +This API deals with arbitrary message signing and verification. ====signMessageHash====

From 496c1944b77e3be9321ce2c0cdea78a9c6d2f894 Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Mon, 6 Aug 2018 13:41:20 +0200
Subject: [PATCH 18/60] Update OEP-5.mediawiki

---
 OEP-5/OEP-5.mediawiki | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki
index ca8d1cc..2b527f6 100644
--- a/OEP-5/OEP-5.mediawiki
+++ b/OEP-5/OEP-5.mediawiki
@@ -32,24 +32,22 @@ This proposal makes use of the following functions and definitions:
 
 *'''dAPI provider''', an implementation of the dAPI in the form of web browser plugin or other means, where a user interaction with the provider can be injected into api call workflow (e.g.: confirming transfer)
 
-===dAPI grouping===
-Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these groups:
+===Components===
+Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these components:
 
 * '''Network''', a thin wrapper around the Ontology Node API, masking the complexity of rpc/rest calls and websockets with Request-Response facade.
 
-* '''Runtime.*''', a main point of integration with the dAPI provider, where the issue of trust is shifted from dApp to dApp provider.
+* '''Asset''', functions for transfering assets between user account and others.
 
-* '''Runtime.Asset''', functions for transfering assets between user account and others.
+* '''Identity''', functions for interacting with own ONT-ID identity.
 
-* '''Runtime.Identity''', functions for interacting with own ONT-ID identity.
+* '''SmartContract''', a high level wrapper around the Smart Contract invocation and deployment.
 
-* '''Runtime.SmartContract''', a high level wrapper around the Smart Contract invocation and deployment.
-
-* '''Runtime.Message''', functions for signing arbitrary messages.
+* '''Message''', functions for signing arbitrary messages.
 
 * '''Utils''', a group of utility function for encoding and decoding the data from/to blockchain.
 
-===Account/Identity management and transaction signing ===
+===Account/Identity managemen===
 Because dAPI shifts the issue of trust from dApp to dApp provider, all account and identity management is external to the dApp. Therefore there are no methods which directly handle private keys. The dApp won't need to sign the transaction itself. 
 
 Any time dApp makes a call that requires a private key to sign something (makeTransfer, sign), dApp provider will inform user about the action and prompt him for permission.
@@ -90,7 +88,7 @@ function getBalance(address: string): Promise
 
 For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. '''BigNumber''' corresponds to a implementation of BigNumbers.
 
-===Runtime.Asset===
+===Asset===
 A primary focus of Runtime.Asset API is to enumerate the addresses under user control and initiate a transfer. The request needs to be confirmed by the user.
 
 ====getOwnAccounts====
@@ -114,7 +112,7 @@ function makeTransfer(sender: string, recipient: string, asset: Asset, amount: B
 Initiates a transfer of amount asset from sender account to recipient account. The sender must be one of the accounts returned by getOwnAccounts.
 
 
-===Runtime.Identity===
+===Identity===
 A primary focus of Runtime.Identity API is to enumerate the ONT ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. 
 
 ====getOwnIdentities====
@@ -161,7 +159,7 @@ function removeAttribute(ontId: string, key: string): Promise
 Removes attribute from the identity. The ontId must be one of the identities returned by getOwnIdentities.
 
 
-===Runtime.Message===
+===Message===
 This API deals with arbitrary message signing and verification.
 
 ====signMessageHash====
@@ -183,7 +181,7 @@ function verifyMessageHash(messageHash: string, accountOrIdentity: string, signa
 
 Verifies that the signature is created by the account or identity over messageHash. The accountOrIdentity '''does not''' need to be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities.
 
-This method does not require the dApp to disclose the message itself, only the hash. 
+This method does not require the dApp to disclose the message itself, only the hash. The hash is prepended with known string '''Ontology message:''', hashed with '''SHA-256''' and only this hash is put for verification.
 
 
 ====signMessage====
@@ -204,6 +202,8 @@ Verifies that the signature is created by the account or identity o
 
 Verification is done on '''SHA-256''' hash of the message.
 
+===SmartContract===
+
 
 ==Rationale==
 

From 7ecf08ef5c896b19d3ee63f94e5bc89c3dd57b91 Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Mon, 6 Aug 2018 13:54:41 +0200
Subject: [PATCH 19/60] Update OEP-5.mediawiki

---
 OEP-5/OEP-5.mediawiki | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki
index 2b527f6..3f85bea 100644
--- a/OEP-5/OEP-5.mediawiki
+++ b/OEP-5/OEP-5.mediawiki
@@ -47,7 +47,7 @@ Although this proposal is bringing clear and simple API for the dApps, the indiv
 
 * '''Utils''', a group of utility function for encoding and decoding the data from/to blockchain.
 
-===Account/Identity managemen===
+===Account/Identity management===
 Because dAPI shifts the issue of trust from dApp to dApp provider, all account and identity management is external to the dApp. Therefore there are no methods which directly handle private keys. The dApp won't need to sign the transaction itself. 
 
 Any time dApp makes a call that requires a private key to sign something (makeTransfer, sign), dApp provider will inform user about the action and prompt him for permission.
@@ -203,7 +203,23 @@ Verifies that the signature is created by the account or identity o
 Verification is done on '''SHA-256''' hash of the message.
 
 ===SmartContract===
+The main functionality of this component is invocaction of smart contract methods.
 
+====invoke====
+
+function invoke(constract: string, method: string, parameters: Parameter[], gasPrice: BigNumber, gasLimit: BigNumber): Promise
+
+ +Initiates a method call to a smart contract with supplied parameters. +The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. + + +====invokeRead==== +
+function invokeRead(constract: string, method: string, parameters: Parameter[]): Promise
+
+ +Initiates a method call to a smart contract with supplied parameters in read only mode (preExec). This kind of method call does not write anything to blockchain and therefore does not need to be signed or paid for. It is processed without user interaction. ==Rationale== From bf664b7d59cd69384c6a773ff31f53ab68c4c91f Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 15:12:18 +0200 Subject: [PATCH 20/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 52 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index 3f85bea..048d391 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -30,7 +30,10 @@ This proposal makes use of the following functions and definitions: *'''dAPI''', the API for dApps this OEP is proposing. -*'''dAPI provider''', an implementation of the dAPI in the form of web browser plugin or other means, where a user interaction with the provider can be injected into api call workflow (e.g.: confirming transfer) +*'''dAPI provider''', an implementation of the dAPI in the form of web browser plugin or other means, where a user interaction with the provider can be injected into api call workflow (e.g.: confirming transfer). + +*'''Notify event''', an event broadcasted from smart contract execution. + ===Components=== Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these components: @@ -57,8 +60,18 @@ API specification is a complex document. Every method has some inputs and output
 type Network = 'MAIN' | 'TEST' | 'PRIVATE';
+
 type Asset = 'ont' | 'ong';
 
+enum TransactionType {
+    BookKeeper = 2,
+    Claim = 3,
+    Deploy = 208,
+    Invoke = 209,
+    Enrollment = 4,
+    Vote = 5
+}
+
 interface OntIdAttribute {
     key: string;
     type: string;
@@ -68,6 +81,16 @@ interface OntIdAttribute {
 interface OntIdDDO {
     ...
 }
+
+type EventListener = (data: any) => void;
+
+type ParameterType = 'Boolean' | 'Integer' | 'ByteArray' | 'Interface' | 'Array' | 'Struct' |
+  'Map' | 'String' | 'Int' | 'Long' | 'IntArray' | 'LongArray' | 'Address';
+
+interface Parameter {
+    value: string;
+}
+
 
===Network=== @@ -213,17 +236,40 @@ function invoke(constract: string, method: string, parameters: Parameter[], gasP Initiates a method call to a smart contract with supplied parameters. The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. +Smart code execution is two step process: + +1. The transaction is send to the network. +2. The transaction is recorded to the blockchain at a later time. + +The invoke function will finish as soon as the transaction is sent to the network. To receive useful data from method execution it is necessary to start listening for events using addEventListener. + ====invokeRead====
-function invokeRead(constract: string, method: string, parameters: Parameter[]): Promise
+function invokeRead(constract: string, method: string, parameters: Parameter[]): Promise
 
Initiates a method call to a smart contract with supplied parameters in read only mode (preExec). This kind of method call does not write anything to blockchain and therefore does not need to be signed or paid for. It is processed without user interaction. +====addEventListener==== +
+function addEventListener(listener: EventListener): void
+
+ +Starts listening for Notify events. + +====removeEventListener==== +
+function addEventListener(listener: EventListener): void
+
+ +Stops listening for Notify events. + ==Rationale== +'''''User story''''': As a '''dApp''' developer, I need to use a lightweight api for integration with Ontology network without requiring my users to share their private keys with me. + ==Test Cases== ==Implementation== - +OntologyCommunityDevelopers/ontology-plugin-wallet - https://github.com/OntologyCommunityDevelopers/ontology-plugin-wallet From 32afb1a4bd796dc3161a050fa8a695a12eb466b8 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 15:23:08 +0200 Subject: [PATCH 21/60] Update OEP-5.mediawiki --- OEP-5/OEP-5.mediawiki | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-5/OEP-5.mediawiki index 048d391..9c686e7 100644 --- a/OEP-5/OEP-5.mediawiki +++ b/OEP-5/OEP-5.mediawiki @@ -13,12 +13,14 @@ A Javascript API is proposed for dApps development. This dAPI allows dApps to co ==Motivation== -Currently a dApp will use one of the SDKs (Typescript, Java, Python, ...) to communicate with Ontology network. This setup has two main disadvantages: +Currently a dApp will use one of the SDKs (Typescript, Java, Python, ...) to communicate with Ontology network. This setup has three main disadvantages: 1. User of the dApp will have to trust the dApp developer with his private keys and that information about transfers mediated through the dApp are legitimate. 2. Although the SDKs are very powerful, they are hard to use. A more streamlined API will allow developers to focus on the application itself. +3. Hard to implement integration to external signing mechanism (e.g.: Ledger, Trezor) + ==Specification== This proposal makes use of the following functions and definitions: @@ -26,7 +28,7 @@ This proposal makes use of the following functions and definitions: *'''SHA256''', a well-known hashing algorithm that takes an arbitrary number of bytes as input and deterministically yields a 32-byte hash. -*'''dApp''', an application with decentralized characteristics running in web environment. The application uses Ontology network for value transfers, contracts enforcing and identification between participants. +*'''dApp''', an application with decentralised characteristics running in web environment. The application uses Ontology network for value transfers, contracts enforcing and identification between participants. *'''dAPI''', the API for dApps this OEP is proposing. @@ -38,9 +40,9 @@ This proposal makes use of the following functions and definitions: ===Components=== Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these components: -* '''Network''', a thin wrapper around the Ontology Node API, masking the complexity of rpc/rest calls and websockets with Request-Response facade. +* '''Network''', a thin wrapper around the Ontology Node API, masking the complexity of rpc/rest calls and web-sockets with Request-Response facade. -* '''Asset''', functions for transfering assets between user account and others. +* '''Asset''', functions for transferring assets between user account and others. * '''Identity''', functions for interacting with own ONT-ID identity. @@ -55,8 +57,10 @@ Because dAPI shifts the issue of trust from dApp to dApp provider, all account a Any time dApp makes a call that requires a private key to sign something (makeTransfer, sign), dApp provider will inform user about the action and prompt him for permission. +dApp provider can even forward the request to external signing mechanism as part of the process. This way the dApp does not need to specifically integrate with such mechanism. + ===Complex structures=== -API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To preciselly describe the structure of those objects, we'd chosen Typescript syntax. +API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To precisely describe the structure of those objects, we'd chosen Typescript syntax.
 type Network = 'MAIN' | 'TEST' | 'PRIVATE';
@@ -68,7 +72,7 @@ enum TransactionType {
     Claim = 3,
     Deploy = 208,
     Invoke = 209,
-    Enrollment = 4,
+    Enrolment = 4,
     Vote = 5
 }
 
@@ -101,7 +105,7 @@ function getGenerateBlockTime(): Promise
 function getNodeCount(): Promise
 function getBlockHeight(): Promise
 function getMerkleProof(txHash: string): Promise
-function getStorage(constractAddress: string, key: string): Promise
+function getStorage(contract: string, key: string): Promise
 function getAllowance(asset: Asset, fromAddress: string, toAddress: string): Promise
 function getBlock(block: number | string): Promise
 function getTransaction(txHash: string): Promise
@@ -143,7 +147,7 @@ A primary focus of Runtime.Identity API is to enumerate the ONT ID identities un
 function getOwnIdentities(): string[]
 
-Returns all the identites associated with logged in user. +Returns all the identities associated with logged in user. ====getDefaultIdentity====
@@ -226,11 +230,11 @@ Verifies that the signature is created by the account or identity o
 Verification is done on '''SHA-256''' hash of the message.
 
 ===SmartContract===
-The main functionality of this component is invocaction of smart contract methods.
+The main functionality of this component is invocation of smart contract methods.
 
 ====invoke====
 
-function invoke(constract: string, method: string, parameters: Parameter[], gasPrice: BigNumber, gasLimit: BigNumber): Promise
+function invoke(contract: string, method: string, parameters: Parameter[], gasPrice: BigNumber, gasLimit: BigNumber): Promise
 
Initiates a method call to a smart contract with supplied parameters. @@ -246,7 +250,7 @@ The invoke function will finish as soon as the transaction is sent ====invokeRead====
-function invokeRead(constract: string, method: string, parameters: Parameter[]): Promise
+function invokeRead(contract: string, method: string, parameters: Parameter[]): Promise
 
Initiates a method call to a smart contract with supplied parameters in read only mode (preExec). This kind of method call does not write anything to blockchain and therefore does not need to be signed or paid for. It is processed without user interaction. From 4cc6d7258583f52e992e325f8d2d15786fbfff18 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 15:24:44 +0200 Subject: [PATCH 22/60] rename OEP-5 to OEP-6 Signed-off-by: Matus Zamborsky --- OEP-5/OEP-5.mediawiki => OEP-6/OEP-6.mediawiki | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename OEP-5/OEP-5.mediawiki => OEP-6/OEP-6.mediawiki (100%) diff --git a/OEP-5/OEP-5.mediawiki b/OEP-6/OEP-6.mediawiki similarity index 100% rename from OEP-5/OEP-5.mediawiki rename to OEP-6/OEP-6.mediawiki From 233028dbb4084d69227ca416b01bc068782478bb Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 6 Aug 2018 15:56:09 +0200 Subject: [PATCH 23/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 60 ++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 9c686e7..fd51fe4 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -62,45 +62,14 @@ dApp provider can even forward the request to external signing mechanism as part ===Complex structures=== API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To precisely describe the structure of those objects, we'd chosen Typescript syntax. -
-type Network = 'MAIN' | 'TEST' | 'PRIVATE';
-
-type Asset = 'ont' | 'ong';
-
-enum TransactionType {
-    BookKeeper = 2,
-    Claim = 3,
-    Deploy = 208,
-    Invoke = 209,
-    Enrolment = 4,
-    Vote = 5
-}
-
-interface OntIdAttribute {
-    key: string;
-    type: string;
-    value: string;
-}
-
-interface OntIdDDO {
-    ...
-}
-
-type EventListener = (data: any) => void;
-
-type ParameterType = 'Boolean' | 'Integer' | 'ByteArray' | 'Interface' | 'Array' | 'Struct' |
-  'Map' | 'String' | 'Int' | 'Long' | 'IntArray' | 'LongArray' | 'Address';
-
-interface Parameter {
-    value: string;
-}
-
-
===Network=== A network API consists of:
+type Network = 'MAIN' | 'TEST' | 'PRIVATE';
+type Asset = 'ont' | 'ong';
+
 function getGenerateBlockTime(): Promise
 function getNodeCount(): Promise
 function getBlockHeight(): Promise
@@ -158,6 +127,10 @@ Returns currently selected identity of logged in user or null if there is none.
 
 ====getDDO====
 
+interface OntIdDDO {
+    ...
+}
+
 function getDDO(ontId: string): Promise
 
@@ -165,6 +138,12 @@ Queries Description Object of the identity. This operation is not signed and the ====getAttributes====
+interface OntIdAttribute {
+    key: string;
+    type: string;
+    value: string;
+}
+
 function getAttributes(ontId: string): Promise
 
@@ -234,7 +213,16 @@ The main functionality of this component is invocation of smart contract methods ====invoke====
-function invoke(contract: string, method: string, parameters: Parameter[], gasPrice: BigNumber, gasLimit: BigNumber): Promise
+type ParameterType = 'Boolean' | 'Integer' | 'ByteArray' | 'Interface' | 'Array' | 'Struct' |
+  'Map' | 'String' | 'Int' | 'Long' | 'IntArray' | 'LongArray' | 'Address';
+
+interface Parameter {
+    type: ParameterType;
+    value: string;
+}
+
+function invoke(contract: string, method: string, parameters: Parameter[], 
+  gasPrice: BigNumber, gasLimit: BigNumber): Promise
 
Initiates a method call to a smart contract with supplied parameters. @@ -257,6 +245,8 @@ Initiates a method call to a smart contract with suppl ====addEventListener====
+type EventListener = (data: any) => void;
+
 function addEventListener(listener: EventListener): void
 
From 06ae6e192a0c5516739110fa22bd787540e7bf6c Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 10 Aug 2018 12:28:14 +0200 Subject: [PATCH 24/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index fd51fe4..eed8c10 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -36,6 +36,8 @@ This proposal makes use of the following functions and definitions: *'''Notify event''', an event broadcasted from smart contract execution. +*'''NEOVM''', a lightweight virtual machine for execution of Neo/Ontology smart contracts. + ===Components=== Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these components: @@ -85,7 +87,7 @@ function getBalance(address: string): Promise For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. '''BigNumber''' corresponds to a implementation of BigNumbers. ===Asset=== -A primary focus of Runtime.Asset API is to enumerate the addresses under user control and initiate a transfer. The request needs to be confirmed by the user. +A primary focus of Asset API is to enumerate the addresses under user control and initiate a transfer. The request needs to be confirmed by the user. ====getOwnAccounts====
@@ -109,7 +111,7 @@ Initiates a transfer of amount asset from sender accou
 
 
 ===Identity===
-A primary focus of Runtime.Identity API is to enumerate the ONT ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. 
+A primary focus of Identity API is to enumerate the ONT ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. 
 
 ====getOwnIdentities====
 
@@ -243,6 +245,15 @@ function invokeRead(contract: string, method: string, parameters: Parameter[]):
 
 Initiates a method call to a smart contract with supplied parameters in read only mode (preExec). This kind of method call does not write anything to blockchain and therefore does not need to be signed or paid for. It is processed without user interaction.
 
+====deploy====
+
+function invokeRead(code: string, name: string, version: string, author: string, 
+    email: string, description: string, needStorage: boolean, gasPrice: BigNumber, gasLimit: BigNumber): Promise
+
+ +Initiates deployment of smart contract. The code parameter represents compiled code of smart contract for NEOVM. The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. + + ====addEventListener====
 type EventListener = (data: any) => void;

From 68f44dee0c3dd69a421cead111ca22007b2ff685 Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Fri, 10 Aug 2018 13:52:58 +0200
Subject: [PATCH 25/60] Add files via upload

---
 OEP-6/dAPI provider.svg | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 OEP-6/dAPI provider.svg

diff --git a/OEP-6/dAPI provider.svg b/OEP-6/dAPI provider.svg
new file mode 100644
index 0000000..e11bb8b
--- /dev/null
+++ b/OEP-6/dAPI provider.svg	
@@ -0,0 +1,2 @@
+
+
User
User
Web DApp
Web code
Web code
dAPI.js
dAPI.js
dAPI providerUI
Asset transfers
Asset transfers
Identity modification
Identity modification
Smart contract
invocation/deployment
Smart contract<br>invocation/deployment<br>
Messages
Messages<br>
Background
Ontology TS SDK
Ontology TS SDK
Wallet manager
Wallet manager
Persister
Persister
External connectors
External connectors
Web extension
messaging
Web extension<br>messaging
Ontology Network
Smart contracts
Smart contracts<br>
Accounts
Accounts<br>
Websocket
Websocket
REST
REST
Web extension messaging
Web extension messaging
Ledger/Trezor
Ledger/Trezor
REST / messaging
REST / messaging
Browser
Browser
Browser
Browser
\ No newline at end of file From 24792719e49d10137e3d791f3ffa12962573170b Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 10 Aug 2018 13:53:27 +0200 Subject: [PATCH 26/60] Rename dAPI provider.svg to architecture.svg --- OEP-6/{dAPI provider.svg => architecture.svg} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename OEP-6/{dAPI provider.svg => architecture.svg} (99%) diff --git a/OEP-6/dAPI provider.svg b/OEP-6/architecture.svg similarity index 99% rename from OEP-6/dAPI provider.svg rename to OEP-6/architecture.svg index e11bb8b..4febe2b 100644 --- a/OEP-6/dAPI provider.svg +++ b/OEP-6/architecture.svg @@ -1,2 +1,2 @@ -
User
User
Web DApp
Web code
Web code
dAPI.js
dAPI.js
dAPI providerUI
Asset transfers
Asset transfers
Identity modification
Identity modification
Smart contract
invocation/deployment
Smart contract<br>invocation/deployment<br>
Messages
Messages<br>
Background
Ontology TS SDK
Ontology TS SDK
Wallet manager
Wallet manager
Persister
Persister
External connectors
External connectors
Web extension
messaging
Web extension<br>messaging
Ontology Network
Smart contracts
Smart contracts<br>
Accounts
Accounts<br>
Websocket
Websocket
REST
REST
Web extension messaging
Web extension messaging
Ledger/Trezor
Ledger/Trezor
REST / messaging
REST / messaging
Browser
Browser
Browser
Browser
\ No newline at end of file +
User
User
Web DApp
Web code
Web code
dAPI.js
dAPI.js
dAPI providerUI
Asset transfers
Asset transfers
Identity modification
Identity modification
Smart contract
invocation/deployment
Smart contract<br>invocation/deployment<br>
Messages
Messages<br>
Background
Ontology TS SDK
Ontology TS SDK
Wallet manager
Wallet manager
Persister
Persister
External connectors
External connectors
Web extension
messaging
Web extension<br>messaging
Ontology Network
Smart contracts
Smart contracts<br>
Accounts
Accounts<br>
Websocket
Websocket
REST
REST
Web extension messaging
Web extension messaging
Ledger/Trezor
Ledger/Trezor
REST / messaging
REST / messaging
Browser
Browser
Browser
Browser
From 4c3a4eeee50199e6525efec27865837602ad957c Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 10 Aug 2018 13:55:35 +0200 Subject: [PATCH 27/60] Rename architecture.svg to OEP-6-1.svg --- OEP-6/{architecture.svg => OEP-6-1.svg} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename OEP-6/{architecture.svg => OEP-6-1.svg} (100%) diff --git a/OEP-6/architecture.svg b/OEP-6/OEP-6-1.svg similarity index 100% rename from OEP-6/architecture.svg rename to OEP-6/OEP-6-1.svg From 5141d569416cf87ca7b3511d6260abe942c7dfba Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 10 Aug 2018 13:57:10 +0200 Subject: [PATCH 28/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index eed8c10..f756830 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -270,6 +270,12 @@ function addEventListener(listener: EventListener): void Stops listening for Notify events. +==Architecture== +The interaction between dApp and Ontology network can be described with this diagram: + +[[Image:OEP-6-1.svg|Architecture]] + + ==Rationale== '''''User story''''': As a '''dApp''' developer, I need to use a lightweight api for integration with Ontology network without requiring my users to share their private keys with me. From d4c24c5273dd8202595a5e009c0c1f2bec6721bc Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 10 Aug 2018 14:15:25 +0200 Subject: [PATCH 29/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index f756830..25dcda6 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -1,6 +1,6 @@
   OEP: 6
-  Title: API for dApps (dAPI)
+  Title: API for dApps (dAPI) and communication protocol for dAPI providers
   Author: Matus Zamborsky 
   Type: Standard
   Status: Draft
@@ -9,7 +9,11 @@
 
 ==Abstract==
 
-A Javascript API is proposed for dApps development. This dAPI allows dApps to communicate with Ontology blockchain and make requests for transfers, ONT ID registration and others, without requiring users to trust the dApp itself. The issue of trust is shifted to the dAPI provider.
+This proposal has two major parts:
+
+* A Javascript API is proposed for dApps development. This dAPI allows dApps to communicate with Ontology blockchain and make requests for transfers, ONT ID registration and others, without requiring users to trust the dApp itself. The issue of trust is shifted to the dAPI provider.
+
+* A Communication protocol is proposed for dAPI provider development. This allows multiple Wallet implementators to offer the same unified service to users of dApps and prevent fragmentation of dApp development.
 
 ==Motivation==
 
@@ -275,6 +279,14 @@ The interaction between dApp and Ontology network can be described with this dia
 
 [[Image:OEP-6-1.svg|Architecture]]
 
+===Yellow parts===
+These components are external to this proposal.
+
+===Green parts===
+'''dAPI.js''' is universal implementation of this proposal for direct use by dApp developers.
+
+===Blue parts===
+These components all belongs to concrete implementation of dAPI provider. The implementation is out of scope of this proposal, but the implementator must adhere to the protocol used by dAPI.js.
 
 ==Rationale==
 

From e99c47f17ed4280cf01aab2a7a52d0b046cb114f Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Fri, 10 Aug 2018 14:17:43 +0200
Subject: [PATCH 30/60] Update OEP-6-1.svg

---
 OEP-6/OEP-6-1.svg | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OEP-6/OEP-6-1.svg b/OEP-6/OEP-6-1.svg
index 4febe2b..ce179ee 100644
--- a/OEP-6/OEP-6-1.svg
+++ b/OEP-6/OEP-6-1.svg
@@ -1,2 +1,2 @@
 
-
User
User
Web DApp
Web code
Web code
dAPI.js
dAPI.js
dAPI providerUI
Asset transfers
Asset transfers
Identity modification
Identity modification
Smart contract
invocation/deployment
Smart contract<br>invocation/deployment<br>
Messages
Messages<br>
Background
Ontology TS SDK
Ontology TS SDK
Wallet manager
Wallet manager
Persister
Persister
External connectors
External connectors
Web extension
messaging
Web extension<br>messaging
Ontology Network
Smart contracts
Smart contracts<br>
Accounts
Accounts<br>
Websocket
Websocket
REST
REST
Web extension messaging
Web extension messaging
Ledger/Trezor
Ledger/Trezor
REST / messaging
REST / messaging
Browser
Browser
Browser
Browser
+
User
User
Web DApp
Web code
Web code
dAPI.js
dAPI.js
dAPI providerUI
Asset transfers
Asset transfers
Identity modification
Identity modification
Smart contract
invocation/deployment
Smart contract<br>invocation/deployment<br>
Messages
Messages<br>
Background
Ontology TS SDK
Ontology TS SDK
Wallet manager
Wallet manager
Persister
Persister
External connectors
External connectors
Web extension
messaging
Web extension<br>messaging
Ontology Network
Smart contracts
Smart contracts<br>
Accounts
Accounts<br>
Websocket
Websocket
REST
REST
dAPI protocol
dAPI protocol
Ledger/Trezor
Ledger/Trezor
REST / messaging
REST / messaging
Browser
Browser
Browser
Browser
From d8c5e0ed4f03653d40386b830a2cb61f09d222af Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Thu, 16 Aug 2018 15:27:46 +0200 Subject: [PATCH 31/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 25dcda6..bfee4c9 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -137,7 +137,7 @@ interface OntIdDDO { ... } -function getDDO(ontId: string): Promise +function getDDO(identity: string): Promise
Queries Description Object of the identity. This operation is not signed and therefore does not require user interaction. @@ -150,7 +150,7 @@ interface OntIdAttribute { value: string; } -function getAttributes(ontId: string): Promise +function getAttributes(identity: string): Promise
Queries attributes attached to the identity. This operation is not signed and therefore does not require user interaction. @@ -158,17 +158,17 @@ Queries attributes attached to the identity. This operation is not signed and th ====addAttributes====
-function addAttributes(ontId: string, attributes: OntIdAttribute[]): Promise
+function addAttributes(identity: string, attributes: OntIdAttribute[]): Promise
 
-Adds attributes to the identity. The ontId must be one of the identities returned by getOwnIdentities. +Adds attributes to the identity. The identity must be one of the identities returned by getOwnIdentities. ====removeAttributes====
-function removeAttribute(ontId: string, key: string): Promise
+function removeAttribute(identity: string, key: string): Promise
 
-Removes attribute from the identity. The ontId must be one of the identities returned by getOwnIdentities. +Removes attribute from the identity. The identity must be one of the identities returned by getOwnIdentities. ===Message=== @@ -176,10 +176,10 @@ This API deals with arbitrary message signing and verification. ====signMessageHash====
-function signMessageHash(messageHash: string, accountOrIdentity: string): Promise
+function signMessageHash(messageHash: string, address: string): Promise
 
-Initiates signing of arbitrary messageHash by the account or identity. The accountOrIdentity '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +Initiates signing of arbitrary messageHash by the account or identity. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. This method does not require the dApp to disclose the message itself, only the hash. @@ -188,29 +188,29 @@ Therefore the hash is prepended with known string '''Ontology message:''', hashe ====verifyMessageHash====
-function verifyMessageHash(messageHash: string, accountOrIdentity: string, signature: string): Promise
+function verifyMessageHash(messageHash: string, address: string, signature: string): Promise
 
-Verifies that the signature is created by the account or identity over messageHash. The accountOrIdentity '''does not''' need to be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +Verifies that the signature is created by the account or identity over messageHash. The address '''does not''' need to be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. This method does not require the dApp to disclose the message itself, only the hash. The hash is prepended with known string '''Ontology message:''', hashed with '''SHA-256''' and only this hash is put for verification. ====signMessage====
-function signMessage(message: string, accountOrIdentity: string): Promise
+function signMessage(message: string, address: string): Promise
 
-Initiates signing of text message by the account or identity. The accountOrIdentity '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +Initiates signing of text message by the account or identity. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. This method provide the dAPI provider with the message body, which it should display to the user prior to signing (e.g.: a contract to sign). Signing is done on '''SHA-256''' hash of the message. ====verifyMessage====
-function verifyMessage(message: string, accountOrIdentity: string, signature: string): Promise
+function verifyMessage(message: string, address: string, signature: string): Promise
 
-Verifies that the signature is created by the account or identity over text message. The accountOrIdentity '''does not''' need to be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +Verifies that the signature is created by the account or identity over text message. The address '''does not''' need to be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. Verification is done on '''SHA-256''' hash of the message. @@ -227,12 +227,12 @@ interface Parameter { value: string; } -function invoke(contract: string, method: string, parameters: Parameter[], - gasPrice: BigNumber, gasLimit: BigNumber): Promise +function invoke(account: string, contract: string, method: string, parameters: Parameter[], + gasPrice: BigNumber, gasLimit: BigNumber, addresses: string[]): Promise
Initiates a method call to a smart contract with supplied parameters. -The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. +The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. The account will be set as payer of the transaction. It '''must''' be one of the accounts returned by getOwnAccounts. addresses can specify additional accounts or identites whose signature will be required. Every element '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. Smart code execution is two step process: @@ -251,11 +251,11 @@ Initiates a method call to a smart contract with suppl ====deploy====
-function invokeRead(code: string, name: string, version: string, author: string, 
+function deploy(account: string, code: string, name: string, version: string, author: string, 
     email: string, description: string, needStorage: boolean, gasPrice: BigNumber, gasLimit: BigNumber): Promise
 
-Initiates deployment of smart contract. The code parameter represents compiled code of smart contract for NEOVM. The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. +Initiates deployment of smart contract. The code parameter represents compiled code of smart contract for NEOVM. The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. The account will be set as payer of the transaction. It '''must''' be one of the accounts returned by getOwnAccounts ====addEventListener==== From 72575501b11bc50ce500d6cd2e4b7cd87af5a5da Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 17 Aug 2018 12:30:36 +0200 Subject: [PATCH 32/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 51 +++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index bfee4c9..b3d8c79 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -95,17 +95,23 @@ A primary focus of Asset API is to enumerate the addresses under user control an ====getOwnAccounts====
-function getOwnAccounts(): string[]
+function getOwnAccounts(): Promise
 
Returns all the accounts associated with logged in user. ====getDefaultAccount====
-function getDefaultAccount(): string | null
+function getDefaultAccount(): Promise
 
Returns currently selected account of logged in user or null if there is none. +====getPublicKey==== +
+function getPublicKey(account: string): Promise
+
+Returns public key corresponding to an account. The account must be one of the accounts returned by getOwnAccounts. + ====makeTransfer====
 function makeTransfer(sender: string, recipient: string, asset: Asset, amount: BigNumber): Promise
@@ -119,18 +125,24 @@ A primary focus of Identity API is to enumerate the ONT ID identities under user
 
 ====getOwnIdentities====
 
-function getOwnIdentities(): string[]
+function getOwnIdentities(): Promise
 
Returns all the identities associated with logged in user. ====getDefaultIdentity====
-function getDefaultIdentity(): string | null
+function getDefaultIdentity(): Promise
 
Returns currently selected identity of logged in user or null if there is none. +====getPublicKeys==== +
+function getPublicKeys(identity: string): Promise
+
+Returns public keys corresponding to an identity. The identity must be one of the identities returned by getOwnIdentities. This call must query blockchain by contrast to asset.getPublicKey. + ====getDDO====
 interface OntIdDDO {
@@ -184,16 +196,25 @@ Initiates signing of arbitrary messageHash by the account or identi
 This method does not require the dApp to disclose the message itself, only the hash. 
 
 Because malicious dApp can hash a real prepared transfer transaction and plant it for signing, that posses a risk to the user.
-Therefore the hash is prepended with known string '''Ontology message:''', hashed with '''SHA-256''' and only this hash is put for signing.
+Therefore the hash is prepended with known string '''Ontology message:''', and only this hash is put for signing.
 
 ====verifyMessageHash====
 
-function verifyMessageHash(messageHash: string, address: string, signature: string): Promise
+function verifyMessageHash(address: string, messageHash: string, address: string, signature: string): Promise
 
-Verifies that the signature is created by the account or identity over messageHash. The address '''does not''' need to be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +Verifies that the signature is created by the account or identity over messageHash. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. -This method does not require the dApp to disclose the message itself, only the hash. The hash is prepended with known string '''Ontology message:''', hashed with '''SHA-256''' and only this hash is put for verification. +This method does not require the dApp to disclose the message itself, only the hash. The hash is prepended with known string '''Ontology message:''' and only this hash is put for verification. + +====verifyMessageHashPk==== +
+function verifyMessageHashPk(publicKey: string, messageHash: string, address: string, signature: string): Promise
+
+ +Verifies that the signature is created by a private key corresponding to publicKey over messageHash. + +This method does not require the dApp to disclose the message itself, only the hash. The hash is prepended with known string '''Ontology message:''' and only this hash is put for verification. ====signMessage==== @@ -203,16 +224,22 @@ function signMessage(message: string, address: string): Promise Initiates signing of text message by the account or identity. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. -This method provide the dAPI provider with the message body, which it should display to the user prior to signing (e.g.: a contract to sign). Signing is done on '''SHA-256''' hash of the message. +This method provide the dAPI provider with the message body, which it should display to the user prior to signing (e.g.: a contract to sign). ====verifyMessage====
-function verifyMessage(message: string, address: string, signature: string): Promise
+function verifyMessage(address: string, message: string, address: string, signature: string): Promise
+
+ +Verifies that the signature is created by the account or identity over text message. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. + +====verifyMessagePk==== +
+function verifyMessage(publicKey: string, message: string, address: string, signature: string): Promise
 
-Verifies that the signature is created by the account or identity over text message. The address '''does not''' need to be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +Verifies that the signature is created by a private key corresponding to publicKey over text message. -Verification is done on '''SHA-256''' hash of the message. ===SmartContract=== The main functionality of this component is invocation of smart contract methods. From c2e77b73f9ae992524c97f6d194bb531643c02a1 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 17 Aug 2018 12:54:02 +0200 Subject: [PATCH 33/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 49 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index b3d8c79..9155d26 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -58,6 +58,11 @@ Although this proposal is bringing clear and simple API for the dApps, the indiv * '''Utils''', a group of utility function for encoding and decoding the data from/to blockchain. +===Asynchronicity and error handling=== +All the functions except '''Utils''' component are communicating with extension through asynchronious message channel. Therefore all the methods are returning Promises. + +The promises will be either resolved immediately if no interaction with user UI or blockchain is required or later when the user action takes place/blockchain responds. In case the call to method trigger an error, the error code is transmitted in rejected promise. Specific error codes are described with every method. + ===Account/Identity management=== Because dAPI shifts the issue of trust from dApp to dApp provider, all account and identity management is external to the dApp. Therefore there are no methods which directly handle private keys. The dApp won't need to sign the transaction itself. @@ -98,19 +103,27 @@ A primary focus of Asset API is to enumerate the addresses under user control an function getOwnAccounts(): Promise
-Returns all the accounts associated with logged in user. +Returns all the accounts associated with logged in user. + +* Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts ====getDefaultAccount====
 function getDefaultAccount(): Promise
 
-Returns currently selected account of logged in user or null if there is none. +Returns currently selected account of logged in user. + +* Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts ====getPublicKey====
 function getPublicKey(account: string): Promise
 
-Returns public key corresponding to an account. The account must be one of the accounts returned by getOwnAccounts. +Returns public key corresponding to an account. The account must be one of the accounts returned by getOwnAccounts. + +* Rejects with '''MALFORMED_ACCOUNT''' in case the account is not a valid account +* Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts +* Rejects with '''WRONG_ACCOUNT''' in case the account is not one of own accounts ====makeTransfer====
@@ -119,6 +132,10 @@ function makeTransfer(sender: string, recipient: string, asset: Asset, amount: B
 
 Initiates a transfer of amount asset from sender account to recipient account. The sender must be one of the accounts returned by getOwnAccounts.
 
+* Rejects with '''MALFORMED_ACCOUNT''' in case the sender or recipient is not a valid account
+* Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts
+* Rejects with '''WRONG_ACCOUNT''' in case the sender is not one of own accounts
+* Rejects with '''CANCELED''' in case the user cancels the request
 
 ===Identity===
 A primary focus of Identity API is to enumerate the ONT ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. 
@@ -130,18 +147,24 @@ function getOwnIdentities(): Promise
 
 Returns all the identities associated with logged in user.
 
+* Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity
+
 ====getDefaultIdentity====
 
 function getDefaultIdentity(): Promise
 
-Returns currently selected identity of logged in user or null if there is none. +Returns currently selected identity of logged in user. + +* Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity ====getPublicKeys====
 function getPublicKeys(identity: string): Promise
 
-Returns public keys corresponding to an identity. The identity must be one of the identities returned by getOwnIdentities. This call must query blockchain by contrast to asset.getPublicKey. +Returns public keys corresponding to an identity. The identity '''does not''' need to be one of the identities returned by getOwnIdentities. This call must query blockchain by contrast to asset.getPublicKey. + +* Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity ====getDDO====
@@ -152,7 +175,9 @@ interface OntIdDDO {
 function getDDO(identity: string): Promise
 
-Queries Description Object of the identity. This operation is not signed and therefore does not require user interaction. +Queries Description Object of the identity. The identity '''does not''' need to be one of the identities returned by getOwnIdentities. This operation is not signed and therefore does not require user interaction. + +* Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity ====getAttributes====
@@ -165,8 +190,9 @@ interface OntIdAttribute {
 function getAttributes(identity: string): Promise
 
-Queries attributes attached to the identity. This operation is not signed and therefore does not require user interaction. +Queries attributes attached to the identity. The identity '''does not''' need to be one of the identities returned by getOwnIdentities. This operation is not signed and therefore does not require user interaction. +* Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity ====addAttributes====
@@ -175,13 +201,20 @@ function addAttributes(identity: string, attributes: OntIdAttribute[]): Promise<
 
 Adds attributes to the identity. The identity must be one of the identities returned by getOwnIdentities.
 
+* Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity
+* Rejects with '''WRONG_IDENTITY''' in case the identity is not one of own identites
+* Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity
+
 ====removeAttributes====
 
 function removeAttribute(identity: string, key: string): Promise
 
-Removes attribute from the identity. The identity must be one of the identities returned by getOwnIdentities. +Removes attribute from the identity. The identity must be one of the identities returned by getOwnIdentities. +* Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity +* Rejects with '''WRONG_IDENTITY''' in case the identity is not one of own identites +* Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity ===Message=== This API deals with arbitrary message signing and verification. From 4db5de03496d20dbd8334292273c8d3d7c627316 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 17 Aug 2018 13:29:24 +0200 Subject: [PATCH 34/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 50 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 9155d26..78edb9f 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -121,9 +121,9 @@ function getPublicKey(account: string): Promise
Returns public key corresponding to an account. The account must be one of the accounts returned by getOwnAccounts. -* Rejects with '''MALFORMED_ACCOUNT''' in case the account is not a valid account * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts * Rejects with '''WRONG_ACCOUNT''' in case the account is not one of own accounts +* Rejects with '''MALFORMED_ACCOUNT''' in case the account is not a valid account ====makeTransfer====
@@ -132,9 +132,9 @@ function makeTransfer(sender: string, recipient: string, asset: Asset, amount: B
 
 Initiates a transfer of amount asset from sender account to recipient account. The sender must be one of the accounts returned by getOwnAccounts.
 
-* Rejects with '''MALFORMED_ACCOUNT''' in case the sender or recipient is not a valid account
 * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts
 * Rejects with '''WRONG_ACCOUNT''' in case the sender is not one of own accounts
+* Rejects with '''MALFORMED_ACCOUNT''' in case the sender or recipient is not a valid account
 * Rejects with '''CANCELED''' in case the user cancels the request
 
 ===Identity===
@@ -199,7 +199,7 @@ Queries attributes attached to the identity. The identity
 
-Adds attributes to the identity. The identity must be one of the identities returned by getOwnIdentities. +Adds attributes to the identity. The identity must be one of the identities returned by getOwnIdentities. * Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity * Rejects with '''WRONG_IDENTITY''' in case the identity is not one of own identites @@ -231,6 +231,11 @@ This method does not require the dApp to disclose the message itself, only the h Because malicious dApp can hash a real prepared transfer transaction and plant it for signing, that posses a risk to the user. Therefore the hash is prepended with known string '''Ontology message:''', and only this hash is put for signing. +* Rejects with '''NO_ADDRESS''' in case the user is not signed in or has no account or identity +* Rejects with '''WRONG_ADDRESS''' in case the address is not one of own accounts or identites +* Rejects with '''MALFORMED_ADDRESS''' in case the address is not a valid account or identity +* Rejects with '''MALFORMED_MESSAGE''' in case the message is not hex encoded + ====verifyMessageHash====
 function verifyMessageHash(address: string, messageHash: string, address: string, signature: string): Promise
@@ -240,6 +245,12 @@ Verifies that the signature is created by the account or identity o
 
 This method does not require the dApp to disclose the message itself, only the hash. The hash is prepended with known string '''Ontology message:''' and only this hash is put for verification.
 
+* Rejects with '''NO_ADDRESS''' in case the user is not signed in or has no account or identity
+* Rejects with '''WRONG_ADDRESS''' in case the address is not one of own accounts or identites
+* Rejects with '''MALFORMED_ADDRESS''' in case the address is not a valid account or identity
+* Rejects with '''MALFORMED_MESSAGE''' in case the message is not hex encoded
+* Rejects with '''MALFORMED_SIGNATURE''' in case the signature is not hex encoded
+
 ====verifyMessageHashPk====
 
 function verifyMessageHashPk(publicKey: string, messageHash: string, address: string, signature: string): Promise
@@ -249,16 +260,25 @@ Verifies that the signature is created by a private key correspondi
 
 This method does not require the dApp to disclose the message itself, only the hash. The hash is prepended with known string '''Ontology message:''' and only this hash is put for verification.
 
+* Rejects with '''MALFORMED_PUBLIC_KEY''' in case the public key is not hex encoded
+* Rejects with '''MALFORMED_MESSAGE''' in case the message is not hex encoded
+* Rejects with '''MALFORMED_SIGNATURE''' in case the signature is not hex encoded
+
 
 ====signMessage====
 
-function signMessage(message: string, address: string): Promise
+function signMessage(address: string, message: string): Promise
 
Initiates signing of text message by the account or identity. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. This method provide the dAPI provider with the message body, which it should display to the user prior to signing (e.g.: a contract to sign). +* Rejects with '''NO_ADDRESS''' in case the user is not signed in or has no account or identity +* Rejects with '''WRONG_ADDRESS''' in case the address is not one of own accounts or identites +* Rejects with '''MALFORMED_ADDRESS''' in case the address is not a valid account or identity + + ====verifyMessage====
 function verifyMessage(address: string, message: string, address: string, signature: string): Promise
@@ -266,6 +286,12 @@ function verifyMessage(address: string, message: string, address: string, signat
 
 Verifies that the signature is created by the account or identity over text message. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities.
 
+* Rejects with '''NO_ADDRESS''' in case the user is not signed in or has no account or identity
+* Rejects with '''WRONG_ADDRESS''' in case the address is not one of own accounts or identites
+* Rejects with '''MALFORMED_ADDRESS''' in case the address is not a valid account or identity
+* Rejects with '''MALFORMED_MESSAGE''' in case the message is not hex encoded
+
+
 ====verifyMessagePk====
 
 function verifyMessage(publicKey: string, message: string, address: string, signature: string): Promise
@@ -273,6 +299,9 @@ function verifyMessage(publicKey: string, message: string, address: string, sign
 
 Verifies that the signature is created by a private key corresponding to publicKey over text message. 
 
+* Rejects with '''MALFORMED_PUBLIC_KEY''' in case the public key is not hex encoded
+* Rejects with '''MALFORMED_SIGNATURE''' in case the signature is not hex encoded
+
 
 ===SmartContract===
 The main functionality of this component is invocation of smart contract methods.
@@ -301,6 +330,12 @@ Smart code execution is two step process:
 
 The invoke function will finish as soon as the transaction is sent to the network. To receive useful data from method execution it is necessary to start listening for events using addEventListener.
 
+* Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts
+* Rejects with '''WRONG_ACCOUNT''' in case the sender is not one of own accounts
+* Rejects with '''MALFORMED_ACCOUNT''' in case the account is not a valid account
+* Rejects with '''MALFORMED_CONTRACT''' in case the contract is not hex encoded contract address
+* Rejects with '''MALFORMED_ADDRESS''' in case the addresses contains at least one address which is not a valid account nor identity
+
 
 ====invokeRead====
 
@@ -309,6 +344,9 @@ function invokeRead(contract: string, method: string, parameters: Parameter[]):
 
 Initiates a method call to a smart contract with supplied parameters in read only mode (preExec). This kind of method call does not write anything to blockchain and therefore does not need to be signed or paid for. It is processed without user interaction.
 
+* Rejects with '''MALFORMED_CONTRACT''' in case the contract is not hex encoded contract address
+
+
 ====deploy====
 
 function deploy(account: string, code: string, name: string, version: string, author: string, 
@@ -317,6 +355,10 @@ function deploy(account: string, code: string, name: string, version: string, au
 
 Initiates deployment of smart contract. The code parameter represents compiled code of smart contract for NEOVM. The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. The account will be set as payer of the transaction. It '''must''' be one of the accounts returned by getOwnAccounts
 
+* Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts
+* Rejects with '''WRONG_ACCOUNT''' in case the sender is not one of own accounts
+* Rejects with '''MALFORMED_ACCOUNT''' in case the account is not a valid account
+
 
 ====addEventListener====
 

From a90c80d20032695b2288028f1f636d0c90fc2c79 Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Fri, 17 Aug 2018 14:01:47 +0200
Subject: [PATCH 35/60] Update OEP-6.mediawiki

---
 OEP-6/OEP-6.mediawiki | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki
index 78edb9f..315ffbd 100644
--- a/OEP-6/OEP-6.mediawiki
+++ b/OEP-6/OEP-6.mediawiki
@@ -30,8 +30,6 @@ This proposal makes use of the following functions and definitions:
 
 *'''SDK''', a software development kit implementing low level communication with the network and providing high level interface for dApps.
 
-*'''SHA256''', a well-known hashing algorithm that takes an arbitrary number of bytes as input and deterministically yields a 32-byte hash.
-
 *'''dApp''', an application with decentralised characteristics running in web environment. The application uses Ontology network for value transfers, contracts enforcing and identification between participants.
 
 *'''dAPI''', the API for dApps this OEP is proposing.
@@ -70,16 +68,36 @@ Any time dApp makes a call that requires a private key to sign something (makeTr
 
 dApp provider can even forward the request to external signing mechanism as part of the process. This way the dApp does not need to specifically integrate with such mechanism.
 
+===Encoding===
+The interaction with dAPI often requires specification of '''Address''', '''Identity''', '''Contract address''' or '''Public Key'''. Those concepts are represented by string representation with specific encodings.
+
+====Address====
+* 34 bytes long
+* using Base58 check encoding
+* starts with A letter
+
+====Contract address====
+* 40 bytes long
+* using Hex encoding
+
+====Identity====
+* 42 bytes long
+* using Base58 check encoding for 34 byte suffix
+* starts with 'did:ont:' prefix
+
+====Public Key=====
+* 33/35 bytes long
+* using Hex encoding
+
 ===Complex structures===
 API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To precisely describe the structure of those objects, we'd chosen Typescript syntax.
 
-
 ===Network===
 A network API consists of:
 
 
 type Network = 'MAIN' | 'TEST' | 'PRIVATE';
-type Asset = 'ont' | 'ong';
+type Asset = 'ONT' | 'ONG';
 
 function getGenerateBlockTime(): Promise
 function getNodeCount(): Promise
@@ -396,5 +414,8 @@ These components all belongs to concrete implementation of dAPI provider. The im
 
 ==Test Cases==
 
-==Implementation==
+==Implementation of dAPI.js==
+OntologyCommunityDevelopers/ontology-dapi - https://github.com/OntologyCommunityDevelopers/ontology-dapi
+
+==Implementation of dAPI provider==
 OntologyCommunityDevelopers/ontology-plugin-wallet - https://github.com/OntologyCommunityDevelopers/ontology-plugin-wallet

From 86356bc2dcd1116aab59d43abcfde4b3760cfbba Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Fri, 17 Aug 2018 14:02:37 +0200
Subject: [PATCH 36/60] Update OEP-6.mediawiki

---
 OEP-6/OEP-6.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki
index 315ffbd..9222888 100644
--- a/OEP-6/OEP-6.mediawiki
+++ b/OEP-6/OEP-6.mediawiki
@@ -85,7 +85,7 @@ The interaction with dAPI often requires specification of '''Address''', '''Iden
 * using Base58 check encoding for 34 byte suffix
 * starts with 'did:ont:' prefix
 
-====Public Key=====
+====Public Key====
 * 33/35 bytes long
 * using Hex encoding
 

From 2d6f4755dc7fc4de8c24948a8668ef7996513edf Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Fri, 17 Aug 2018 14:19:58 +0200
Subject: [PATCH 37/60] Update OEP-6-1.svg

---
 OEP-6/OEP-6-1.svg | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/OEP-6/OEP-6-1.svg b/OEP-6/OEP-6-1.svg
index ce179ee..6cf344d 100644
--- a/OEP-6/OEP-6-1.svg
+++ b/OEP-6/OEP-6-1.svg
@@ -1,2 +1,2 @@
 
-
User
User
Web DApp
Web code
Web code
dAPI.js
dAPI.js
dAPI providerUI
Asset transfers
Asset transfers
Identity modification
Identity modification
Smart contract
invocation/deployment
Smart contract<br>invocation/deployment<br>
Messages
Messages<br>
Background
Ontology TS SDK
Ontology TS SDK
Wallet manager
Wallet manager
Persister
Persister
External connectors
External connectors
Web extension
messaging
Web extension<br>messaging
Ontology Network
Smart contracts
Smart contracts<br>
Accounts
Accounts<br>
Websocket
Websocket
REST
REST
dAPI protocol
dAPI protocol
Ledger/Trezor
Ledger/Trezor
REST / messaging
REST / messaging
Browser
Browser
Browser
Browser
+
User
User
Web DApp
Web code
Web code
dAPI.js
dAPI.js
dAPI providerUI
Asset transfers
Asset transfers
Identity modification
Identity modification
Smart contract
invocation/deployment
Smart contract<br>invocation/deployment<br>
Messages
Messages<br>
Background
Ontology TS SDK
Ontology TS SDK
Wallet manager
Wallet manager
Persister
Persister
External connectors
External connectors
Web extension
messaging
Web extension<br>messaging
Content
dAPI.js content proxy
dAPI.js content proxy
dAPI protocol
dAPI protocol
Ontology Network
Smart contracts
Smart contracts<br>
Accounts
Accounts<br>
Websocket
Websocket
REST
REST
Ledger/Trezor
Ledger/Trezor
REST / messaging
REST / messaging
Browser
Browser
Browser
Browser
Window messaging
Window messaging
From 0369ed031f91d70b1dc06212bc6cc8f1e98a7174 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 17 Aug 2018 17:00:03 +0200 Subject: [PATCH 38/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 9222888..e74d949 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -104,14 +104,14 @@ function getNodeCount(): Promise function getBlockHeight(): Promise function getMerkleProof(txHash: string): Promise function getStorage(contract: string, key: string): Promise -function getAllowance(asset: Asset, fromAddress: string, toAddress: string): Promise +function getAllowance(asset: Asset, fromAddress: string, toAddress: string): Promise function getBlock(block: number | string): Promise function getTransaction(txHash: string): Promise function getNetwork(): Network function getBalance(address: string): Promise
-For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. '''BigNumber''' corresponds to a implementation of BigNumbers. +For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. ===Asset=== A primary focus of Asset API is to enumerate the addresses under user control and initiate a transfer. The request needs to be confirmed by the user. @@ -145,7 +145,7 @@ Returns public key corresponding to an account. The account -function makeTransfer(sender: string, recipient: string, asset: Asset, amount: BigNumber): Promise +function makeTransfer(sender: string, recipient: string, asset: Asset, amount: number): Promise
Initiates a transfer of amount asset from sender account to recipient account. The sender must be one of the accounts returned by getOwnAccounts. @@ -335,7 +335,7 @@ interface Parameter { } function invoke(account: string, contract: string, method: string, parameters: Parameter[], - gasPrice: BigNumber, gasLimit: BigNumber, addresses: string[]): Promise + gasPrice: number, gasLimit: number, addresses: string[]): Promise
Initiates a method call to a smart contract with supplied parameters. @@ -368,7 +368,7 @@ Initiates a method call to a smart contract with suppl ====deploy====
 function deploy(account: string, code: string, name: string, version: string, author: string, 
-    email: string, description: string, needStorage: boolean, gasPrice: BigNumber, gasLimit: BigNumber): Promise
+    email: string, description: string, needStorage: boolean, gasPrice: number, gasLimit: number): Promise
 
Initiates deployment of smart contract. The code parameter represents compiled code of smart contract for NEOVM. The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. The account will be set as payer of the transaction. It '''must''' be one of the accounts returned by getOwnAccounts From 546adb32306b71fc8d7648cf576377b9bad83809 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Fri, 17 Aug 2018 17:03:43 +0200 Subject: [PATCH 39/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index e74d949..5ea5bfd 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -343,8 +343,8 @@ The gasPrice and gasLimit are hints for the dAPI provi Smart code execution is two step process: -1. The transaction is send to the network. -2. The transaction is recorded to the blockchain at a later time. +# The transaction is send to the network. +# The transaction is recorded to the blockchain at a later time. The invoke function will finish as soon as the transaction is sent to the network. To receive useful data from method execution it is necessary to start listening for events using addEventListener. From eb6863831864ac5263992d608e3fcaac05f4c469 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Sat, 18 Aug 2018 11:22:16 +0200 Subject: [PATCH 40/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 5ea5bfd..a25df6c 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -145,10 +145,12 @@ Returns public key corresponding to an account. The account -function makeTransfer(sender: string, recipient: string, asset: Asset, amount: number): Promise +function makeTransfer(sender: string, recipient: string, asset: Asset, amount: number): Promise
-Initiates a transfer of amount asset from sender account to recipient account. The sender must be one of the accounts returned by getOwnAccounts. +Initiates a transfer of amount asset from sender account to recipient account. The sender must be one of the accounts returned by getOwnAccounts. + +Returns transaction Id. * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts * Rejects with '''WRONG_ACCOUNT''' in case the sender is not one of own accounts From 97d2f5d5b7984e8f9d9e4000896c74023aed0edb Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Sat, 18 Aug 2018 15:58:23 +0200 Subject: [PATCH 41/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index a25df6c..1c744f9 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -328,16 +328,15 @@ The main functionality of this component is invocation of smart contract methods ====invoke====
-type ParameterType = 'Boolean' | 'Integer' | 'ByteArray' | 'Interface' | 'Array' | 'Struct' |
-  'Map' | 'String' | 'Int' | 'Long' | 'IntArray' | 'LongArray' | 'Address';
+type ParameterType = 'Boolean' | 'Integer' | 'ByteArray' | 'Struct' | 'Map' | 'String';
 
 interface Parameter {
     type: ParameterType;
-    value: string;
+    value: any;
 }
 
 function invoke(account: string, contract: string, method: string, parameters: Parameter[], 
-  gasPrice: number, gasLimit: number, addresses: string[]): Promise
+  gasPrice: number, gasLimit: number, addresses: string[]): Promise
 
Initiates a method call to a smart contract with supplied parameters. From 3b6207d087799d1e47b8e0b2511dae0cacadf8dc Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Sat, 18 Aug 2018 16:44:08 +0200 Subject: [PATCH 42/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 62 ++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 1c744f9..f1374af 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -40,22 +40,6 @@ This proposal makes use of the following functions and definitions: *'''NEOVM''', a lightweight virtual machine for execution of Neo/Ontology smart contracts. - -===Components=== -Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these components: - -* '''Network''', a thin wrapper around the Ontology Node API, masking the complexity of rpc/rest calls and web-sockets with Request-Response facade. - -* '''Asset''', functions for transferring assets between user account and others. - -* '''Identity''', functions for interacting with own ONT-ID identity. - -* '''SmartContract''', a high level wrapper around the Smart Contract invocation and deployment. - -* '''Message''', functions for signing arbitrary messages. - -* '''Utils''', a group of utility function for encoding and decoding the data from/to blockchain. - ===Asynchronicity and error handling=== All the functions except '''Utils''' component are communicating with extension through asynchronious message channel. Therefore all the methods are returning Promises. @@ -92,6 +76,23 @@ The interaction with dAPI often requires specification of '''Address''', '''Iden ===Complex structures=== API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To precisely describe the structure of those objects, we'd chosen Typescript syntax. +===Components=== +Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these components: + +* '''Network''', a thin wrapper around the Ontology Node API, masking the complexity of rpc/rest calls and web-sockets with Request-Response facade. + +* '''Provider''', functions for getting information about dAPI provider + +* '''Asset''', functions for transferring assets between user account and others. + +* '''Identity''', functions for interacting with own ONT-ID identity. + +* '''SmartContract''', a high level wrapper around the Smart Contract invocation and deployment. + +* '''Message''', functions for signing arbitrary messages. + +* '''Utils''', a group of utility function for encoding and decoding the data from/to blockchain. + ===Network=== A network API consists of: @@ -113,6 +114,35 @@ function getBalance(address: string): Promise For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. +===Provider=== +A primary focus of Provider API is to check if user has installed any dAPI provider and to get information about it. + +====isInstalled==== +
+function isInstalled(): Promise
+
+ +Returns true if there is dAPI provider installed. + +====getName==== +
+function getName(): Promise
+
+ +Returns the name of the installed dAPI provider. + +* Rejects with '''NO_PROVIDER''' in case there is no dAPI provider installed. + +====getVersion==== +
+function getVersion(): Promise
+
+ +Returns the version of the installed dAPI provider. + +* Rejects with '''NO_PROVIDER''' in case there is no dAPI provider installed. + + ===Asset=== A primary focus of Asset API is to enumerate the addresses under user control and initiate a transfer. The request needs to be confirmed by the user. From b515c8df77ff9164150c4c70ebaeb54a9d6ed132 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Thu, 23 Aug 2018 08:21:10 +0200 Subject: [PATCH 43/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index f1374af..916d0bd 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -117,32 +117,21 @@ For further explanation about the wrapped method consult https://ontio.github.io ===Provider=== A primary focus of Provider API is to check if user has installed any dAPI provider and to get information about it. -====isInstalled==== +====getProvider====
-function isInstalled(): Promise
-
- -Returns true if there is dAPI provider installed. - -====getName==== -
-function getName(): Promise
-
-Returns the name of the installed dAPI provider. - -* Rejects with '''NO_PROVIDER''' in case there is no dAPI provider installed. +interface Provider { + name: string; + version: string; +} -====getVersion==== -
-function getVersion(): Promise
+function getProvider(): Promise
 
-Returns the version of the installed dAPI provider. +Returns the information about installed dAPI provider if there is one installed. * Rejects with '''NO_PROVIDER''' in case there is no dAPI provider installed. - ===Asset=== A primary focus of Asset API is to enumerate the addresses under user control and initiate a transfer. The request needs to be confirmed by the user. From b397b0a1d9ef2b71ee607db2f646beea6326a805 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Thu, 23 Aug 2018 09:11:43 +0200 Subject: [PATCH 44/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 916d0bd..73501a6 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -238,7 +238,7 @@ Queries attributes attached to the identity. The identity
-Adds attributes to the identity. The identity must be one of the identities returned by getOwnIdentities. +Adds attributes to the identity. The identity must be one of the identities returned by getOwnIdentities. Attributes with existing key will be overwritten. * Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity * Rejects with '''WRONG_IDENTITY''' in case the identity is not one of own identites From 6a86bf7f8a20a39f086338aff864a57612492aa1 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Thu, 23 Aug 2018 09:58:28 +0200 Subject: [PATCH 45/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 73501a6..75e85da 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -114,6 +114,8 @@ function getBalance(address: string): Promise For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. +TODO: copy the definition of all network api calls with inputs and outputs from ontology documentation. + ===Provider=== A primary focus of Provider API is to check if user has installed any dAPI provider and to get information about it. From 427fe9d67745ad31bbbac29dcb1f82638760ebb1 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Thu, 23 Aug 2018 10:26:54 +0200 Subject: [PATCH 46/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 75e85da..8709798 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -125,12 +125,23 @@ A primary focus of Provider API is to check if user has installed any dAPI provi interface Provider { name: string; version: string; + compatibility: string[]; } function getProvider(): Promise
-Returns the information about installed dAPI provider if there is one installed. +Returns the information about installed dAPI provider if there is one installed. compatibility refers to all OEPs this dAPI provider supports. E.g.: + +
+compatability: [
+    'OEP-6',
+    'OEP-10',
+    'OEP-29'
+]
+
+ +dAPI provider does not need to support all future OEPs concerned with dAPI. * Rejects with '''NO_PROVIDER''' in case there is no dAPI provider installed. From 4eb5a97efadde44d451574db4c76a3b4228249f9 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Thu, 23 Aug 2018 10:27:35 +0200 Subject: [PATCH 47/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 8709798..87d5203 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -422,7 +422,7 @@ Starts listening for Notify events. ====removeEventListener====
-function addEventListener(listener: EventListener): void
+function removeEventListener(listener: EventListener): void
 
Stops listening for Notify events. From 5530155b3efcca0fb9ca0a89067ac91658bdc883 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Thu, 23 Aug 2018 12:14:08 +0200 Subject: [PATCH 48/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 87d5203..48604f1 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -97,9 +97,14 @@ Although this proposal is bringing clear and simple API for the dApps, the indiv A network API consists of:
-type Network = 'MAIN' | 'TEST' | 'PRIVATE';
+type NetworkType = 'MAIN' | 'TEST' | 'PRIVATE';
 type Asset = 'ONT' | 'ONG';
 
+interface Network {
+  type: NetworkType;
+  address: string;
+}
+
 function getGenerateBlockTime(): Promise
 function getNodeCount(): Promise
 function getBlockHeight(): Promise

From 2d124946184f1b86f4a77c3affe23da38a0ca534 Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Thu, 23 Aug 2018 12:20:58 +0200
Subject: [PATCH 49/60] Update OEP-6.mediawiki

---
 OEP-6/OEP-6.mediawiki | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki
index 48604f1..1010d50 100644
--- a/OEP-6/OEP-6.mediawiki
+++ b/OEP-6/OEP-6.mediawiki
@@ -187,6 +187,8 @@ function makeTransfer(sender: string, recipient: string, asset: Asset, amount: n
 
 Initiates a transfer of amount asset from sender account to recipient account. The sender must be one of the accounts returned by getOwnAccounts. 
 
+The amount should always be an integer value. Therefore is is represented in the smallest, further non divisible units for the asset. E.g.: If the asset is ONG then the value is multiplied by 1000000000.
+
 Returns transaction Id.
 
 * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts

From f6673e6912246a9ca54a8dd54c1fe33833175f00 Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Thu, 23 Aug 2018 22:40:58 +0200
Subject: [PATCH 50/60] Update OEP-6.mediawiki

---
 OEP-6/OEP-6.mediawiki | 35 ++++++++++++++++-------------------
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki
index 1010d50..bdcf01b 100644
--- a/OEP-6/OEP-6.mediawiki
+++ b/OEP-6/OEP-6.mediawiki
@@ -374,8 +374,15 @@ interface Parameter {
     value: any;
 }
 
+type Result = string[];
+
+interface Response {
+    transaction: string;
+    results: Result[];
+}
+
 function invoke(account: string, contract: string, method: string, parameters: Parameter[], 
-  gasPrice: number, gasLimit: number, addresses: string[]): Promise
+  gasPrice: number, gasLimit: number, addresses: string[]): Promise
 
Initiates a method call to a smart contract with supplied parameters. @@ -384,9 +391,13 @@ The gasPrice and gasLimit are hints for the dAPI provi Smart code execution is two step process: # The transaction is send to the network. -# The transaction is recorded to the blockchain at a later time. +# The transaction is processed and recorded to the blockchain at a later time. + +The invoke function will finish only after the transaction is processed by the network. -The invoke function will finish as soon as the transaction is sent to the network. To receive useful data from method execution it is necessary to start listening for events using addEventListener. +Returns transaction hash and array of results. + +To output a result from smart contract, call Runtime.Notify method. For every such a call, one result will be outputed. * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts * Rejects with '''WRONG_ACCOUNT''' in case the sender is not one of own accounts @@ -402,6 +413,8 @@ function invokeRead(contract: string, method: string, parameters: Parameter[]): Initiates a method call to a smart contract with supplied parameters in read only mode (preExec). This kind of method call does not write anything to blockchain and therefore does not need to be signed or paid for. It is processed without user interaction. +Returns direct value returned by the smart contract execution. + * Rejects with '''MALFORMED_CONTRACT''' in case the contract is not hex encoded contract address @@ -418,22 +431,6 @@ Initiates deployment of smart contract. The code parameter represen * Rejects with '''MALFORMED_ACCOUNT''' in case the account is not a valid account -====addEventListener==== -
-type EventListener = (data: any) => void;
-
-function addEventListener(listener: EventListener): void
-
- -Starts listening for Notify events. - -====removeEventListener==== -
-function removeEventListener(listener: EventListener): void
-
- -Stops listening for Notify events. - ==Architecture== The interaction between dApp and Ontology network can be described with this diagram: From 6ddc5070accd4dfcb8811ec4c407bf895c2144dd Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Sun, 26 Aug 2018 08:35:25 +0200 Subject: [PATCH 51/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index bdcf01b..11dad38 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -52,6 +52,20 @@ Any time dApp makes a call that requires a private key to sign something (makeTr dApp provider can even forward the request to external signing mechanism as part of the process. This way the dApp does not need to specifically integrate with such mechanism. +dAPI providers can choose to support multiple accounts and identities. Account and identity switching is part of dAPI provider implementation. dAPI provider should share with dApp as little information about user accounts and identities as possible, because it posses a security risk. Otherwise malicious dApp can list all user accounts with balances and identities. + +====dAPI access restriction==== +Using dAPI any dApp is able to call the dAPI provider and initiate an interaction with the user (e.g.: makeTransfer). Only prerequisite is, that the user visits the dApp page. Although the user will need to confirm such an action, bothering him with this action, if he has no intention to confirm it, will hinder the experience. + +Therefore the dAPI will forward with every request the Caller object containing the url of the dApp page or id of another extension trying to communicate with dAPI provider. It is upto the dAPI provider to implement custom permission granting workflow or automatic blacklisting. + +
+interface Caller {
+  url?: string;
+  id?: string;
+}
+
+ ===Encoding=== The interaction with dAPI often requires specification of '''Address''', '''Identity''', '''Contract address''' or '''Public Key'''. Those concepts are represented by string representation with specific encodings. From 0bae06105c3075b3d0202a372b609bbbd87bdb5c Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Sun, 26 Aug 2018 09:09:45 +0200 Subject: [PATCH 52/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 157 +++++++++++------------------------------- 1 file changed, 39 insertions(+), 118 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 11dad38..c4195c0 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -165,77 +165,31 @@ dAPI provider does not need to support all future OEPs concerned with dAPI. * Rejects with '''NO_PROVIDER''' in case there is no dAPI provider installed. ===Asset=== -A primary focus of Asset API is to enumerate the addresses under user control and initiate a transfer. The request needs to be confirmed by the user. - -====getOwnAccounts==== -
-function getOwnAccounts(): Promise
-
- -Returns all the accounts associated with logged in user. - -* Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts - -====getDefaultAccount==== -
-function getDefaultAccount(): Promise
-
-Returns currently selected account of logged in user. - -* Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts - -====getPublicKey==== -
-function getPublicKey(account: string): Promise
-
-Returns public key corresponding to an account. The account must be one of the accounts returned by getOwnAccounts. - -* Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts -* Rejects with '''WRONG_ACCOUNT''' in case the account is not one of own accounts -* Rejects with '''MALFORMED_ACCOUNT''' in case the account is not a valid account +A primary focus of Asset API is to initiate a transfer. The request needs to be confirmed by the user. ====makeTransfer====
-function makeTransfer(sender: string, recipient: string, asset: Asset, amount: number): Promise
+function makeTransfer(recipient: string, asset: Asset, amount: number): Promise
 
-Initiates a transfer of amount asset from sender account to recipient account. The sender must be one of the accounts returned by getOwnAccounts. +Initiates a transfer of amount asset to recipient account. The amount should always be an integer value. Therefore is is represented in the smallest, further non divisible units for the asset. E.g.: If the asset is ONG then the value is multiplied by 1000000000. Returns transaction Id. * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts -* Rejects with '''WRONG_ACCOUNT''' in case the sender is not one of own accounts -* Rejects with '''MALFORMED_ACCOUNT''' in case the sender or recipient is not a valid account +* Rejects with '''MALFORMED_ACCOUNT''' in case the recipient is not a valid account * Rejects with '''CANCELED''' in case the user cancels the request ===Identity=== -A primary focus of Identity API is to enumerate the ONT ID identities under user control and initiate a process of adding/removing attribute from the identity. The request needs to be confirmed by the user. - -====getOwnIdentities==== -
-function getOwnIdentities(): Promise
-
- -Returns all the identities associated with logged in user. - -* Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity - -====getDefaultIdentity==== -
-function getDefaultIdentity(): Promise
-
- -Returns currently selected identity of logged in user. - -* Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity +A primary focus of Identity API is to interact with ONT ID smart contract on the blockchain. ====getPublicKeys====
 function getPublicKeys(identity: string): Promise
 
-Returns public keys corresponding to an identity. The identity '''does not''' need to be one of the identities returned by getOwnIdentities. This call must query blockchain by contrast to asset.getPublicKey. +Returns public keys corresponding to an identity. This call must query the blockchain. This operation is not signed and therefore does not require user interaction. * Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity @@ -248,7 +202,7 @@ interface OntIdDDO { function getDDO(identity: string): Promise
-Queries Description Object of the identity. The identity '''does not''' need to be one of the identities returned by getOwnIdentities. This operation is not signed and therefore does not require user interaction. +Queries Description Object of the identity. This call must query the blockchain. This operation is not signed and therefore does not require user interaction. * Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity @@ -263,41 +217,45 @@ interface OntIdAttribute { function getAttributes(identity: string): Promise
-Queries attributes attached to the identity. The identity '''does not''' need to be one of the identities returned by getOwnIdentities. This operation is not signed and therefore does not require user interaction. +Queries attributes attached to the identity. This call must query the blockchain. This operation is not signed and therefore does not require user interaction. * Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity ====addAttributes====
-function addAttributes(identity: string, attributes: OntIdAttribute[]): Promise
+function addAttributes(attributes: OntIdAttribute[]): Promise
 
-Adds attributes to the identity. The identity must be one of the identities returned by getOwnIdentities. Attributes with existing key will be overwritten. +Initiates adding of attributes to the user identity. This action needs to be confirmed by the user. Attributes with existing key will be overwritten. * Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity -* Rejects with '''WRONG_IDENTITY''' in case the identity is not one of own identites -* Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity ====removeAttributes====
-function removeAttribute(identity: string, key: string): Promise
+function removeAttribute(key: string): Promise
 
-Removes attribute from the identity. The identity must be one of the identities returned by getOwnIdentities. +Initiates removing of attribute from the user identity. This action needs to be confirmed by the user. * Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity -* Rejects with '''WRONG_IDENTITY''' in case the identity is not one of own identites -* Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity ===Message=== This API deals with arbitrary message signing and verification. ====signMessageHash====
-function signMessageHash(messageHash: string, address: string): Promise
+
+interface Signature {
+  publicKey: string;
+  data: string;
+}
+
+function signMessageHash(messageHash: string): Promise
 
-Initiates signing of arbitrary messageHash by the account or identity. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +Initiates signing of arbitrary messageHash by the user account or identity. dAPI provider should provide the user with a way for selecting which account or identity will sign the message. + +Returns the Signature object containing both the publicKey and signature data needed for signature validation. This method does not require the dApp to disclose the message itself, only the hash. @@ -305,75 +263,42 @@ Because malicious dApp can hash a real prepared transfer transaction and plant i Therefore the hash is prepended with known string '''Ontology message:''', and only this hash is put for signing. * Rejects with '''NO_ADDRESS''' in case the user is not signed in or has no account or identity -* Rejects with '''WRONG_ADDRESS''' in case the address is not one of own accounts or identites -* Rejects with '''MALFORMED_ADDRESS''' in case the address is not a valid account or identity * Rejects with '''MALFORMED_MESSAGE''' in case the message is not hex encoded ====verifyMessageHash====
-function verifyMessageHash(address: string, messageHash: string, address: string, signature: string): Promise
+function verifyMessageHash(messageHash: string, signature: Signature): Promise
 
-Verifies that the signature is created by the account or identity over messageHash. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +Verifies that the signature is valid signature of messageHash. This method does not require the dApp to disclose the message itself, only the hash. The hash is prepended with known string '''Ontology message:''' and only this hash is put for verification. -* Rejects with '''NO_ADDRESS''' in case the user is not signed in or has no account or identity -* Rejects with '''WRONG_ADDRESS''' in case the address is not one of own accounts or identites -* Rejects with '''MALFORMED_ADDRESS''' in case the address is not a valid account or identity * Rejects with '''MALFORMED_MESSAGE''' in case the message is not hex encoded -* Rejects with '''MALFORMED_SIGNATURE''' in case the signature is not hex encoded - -====verifyMessageHashPk==== -
-function verifyMessageHashPk(publicKey: string, messageHash: string, address: string, signature: string): Promise
-
- -Verifies that the signature is created by a private key corresponding to publicKey over messageHash. - -This method does not require the dApp to disclose the message itself, only the hash. The hash is prepended with known string '''Ontology message:''' and only this hash is put for verification. - -* Rejects with '''MALFORMED_PUBLIC_KEY''' in case the public key is not hex encoded -* Rejects with '''MALFORMED_MESSAGE''' in case the message is not hex encoded -* Rejects with '''MALFORMED_SIGNATURE''' in case the signature is not hex encoded - +* Rejects with '''MALFORMED_SIGNATURE''' in case the signature is not in valid format ====signMessage====
-function signMessage(address: string, message: string): Promise
+function signMessage(message: string): Promise
 
-Initiates signing of text message by the account or identity. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +Initiates signing of arbitrary message by the user account or identity. dAPI provider should provide the user with a way for selecting which account or identity will sign the message. + +Returns the Signature object containing both the publicKey and signature data needed for signature validation. This method provide the dAPI provider with the message body, which it should display to the user prior to signing (e.g.: a contract to sign). * Rejects with '''NO_ADDRESS''' in case the user is not signed in or has no account or identity -* Rejects with '''WRONG_ADDRESS''' in case the address is not one of own accounts or identites -* Rejects with '''MALFORMED_ADDRESS''' in case the address is not a valid account or identity - ====verifyMessage====
-function verifyMessage(address: string, message: string, address: string, signature: string): Promise
+function verifyMessage(message: string, signature: Signature): Promise
 
-Verifies that the signature is created by the account or identity over text message. The address '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +Verifies that the signature is valid signature of message. -* Rejects with '''NO_ADDRESS''' in case the user is not signed in or has no account or identity -* Rejects with '''WRONG_ADDRESS''' in case the address is not one of own accounts or identites -* Rejects with '''MALFORMED_ADDRESS''' in case the address is not a valid account or identity * Rejects with '''MALFORMED_MESSAGE''' in case the message is not hex encoded - - -====verifyMessagePk==== -
-function verifyMessage(publicKey: string, message: string, address: string, signature: string): Promise
-
- -Verifies that the signature is created by a private key corresponding to publicKey over text message. - -* Rejects with '''MALFORMED_PUBLIC_KEY''' in case the public key is not hex encoded -* Rejects with '''MALFORMED_SIGNATURE''' in case the signature is not hex encoded +* Rejects with '''MALFORMED_SIGNATURE''' in case the signature is not in valid format ===SmartContract=== @@ -395,12 +320,14 @@ interface Response { results: Result[]; } -function invoke(account: string, contract: string, method: string, parameters: Parameter[], - gasPrice: number, gasLimit: number, addresses: string[]): Promise +function invoke(contract: string, method: string, parameters: Parameter[], + gasPrice: number, gasLimit: number, requireIdentity: boolean): Promise
Initiates a method call to a smart contract with supplied parameters. -The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. The account will be set as payer of the transaction. It '''must''' be one of the accounts returned by getOwnAccounts. addresses can specify additional accounts or identites whose signature will be required. Every element '''must''' be one of the accounts returned by getOwnAccounts or identities returned by getOwnIdentities. +The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. It is upto the dAPI provide to allow user select the payer's account. + +In case the smart contract requires the call to be signed also by an identity, parameter requireIdentity should be set to true. Smart code execution is two step process: @@ -414,11 +341,7 @@ Returns transaction hash and array of results. To output a result from smart contract, call Runtime.Notify method. For every such a call, one result will be outputed. * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts -* Rejects with '''WRONG_ACCOUNT''' in case the sender is not one of own accounts -* Rejects with '''MALFORMED_ACCOUNT''' in case the account is not a valid account * Rejects with '''MALFORMED_CONTRACT''' in case the contract is not hex encoded contract address -* Rejects with '''MALFORMED_ADDRESS''' in case the addresses contains at least one address which is not a valid account nor identity - ====invokeRead====
@@ -434,15 +357,13 @@ Returns direct value returned by the smart contract execution.
 
 ====deploy====
 
-function deploy(account: string, code: string, name: string, version: string, author: string, 
+function deploy(code: string, name: string, version: string, author: string, 
     email: string, description: string, needStorage: boolean, gasPrice: number, gasLimit: number): Promise
 
-Initiates deployment of smart contract. The code parameter represents compiled code of smart contract for NEOVM. The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. The account will be set as payer of the transaction. It '''must''' be one of the accounts returned by getOwnAccounts +Initiates deployment of smart contract. The code parameter represents compiled code of smart contract for NEOVM. The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. It is upto the dAPI provide to allow user select the payer's account. * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts -* Rejects with '''WRONG_ACCOUNT''' in case the sender is not one of own accounts -* Rejects with '''MALFORMED_ACCOUNT''' in case the account is not a valid account ==Architecture== From 38dbf17d50362a00b5a690bfdb0cf58b0e96e007 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 27 Aug 2018 15:32:47 +0200 Subject: [PATCH 53/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index c4195c0..897511a 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -167,6 +167,13 @@ dAPI provider does not need to support all future OEPs concerned with dAPI. ===Asset=== A primary focus of Asset API is to initiate a transfer. The request needs to be confirmed by the user. +====getDefaultAccount==== +
	
+function getDefaultAccount(): Promise	
+
+Returns currently selected account of logged in user. + * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts + ====makeTransfer====
 function makeTransfer(recipient: string, asset: Asset, amount: number): Promise
@@ -185,6 +192,13 @@ Returns transaction Id.
 ===Identity===
 A primary focus of Identity API is to interact with ONT ID smart contract on the blockchain.
 
+====getDefaultIdentity====	
+
	
+function getDefaultIdentity(): Promise	
+
+ Returns currently selected identity of logged in user. + * Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity + ====getPublicKeys====
 function getPublicKeys(identity: string): Promise

From 5561f7f8b0c6b0b5156c7ec0a73b2febda6e1789 Mon Sep 17 00:00:00 2001
From: Matus Zamborsky 
Date: Tue, 28 Aug 2018 08:23:13 +0200
Subject: [PATCH 54/60] Update OEP-6.mediawiki

---
 OEP-6/OEP-6.mediawiki | 26 +++-----------------------
 1 file changed, 3 insertions(+), 23 deletions(-)

diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki
index 897511a..3115100 100644
--- a/OEP-6/OEP-6.mediawiki
+++ b/OEP-6/OEP-6.mediawiki
@@ -1,7 +1,7 @@
 
   OEP: 6
   Title: API for dApps (dAPI) and communication protocol for dAPI providers
-  Author: Matus Zamborsky 
+  Author: Matus Zamborsky , Nick Fujita 
   Type: Standard
   Status: Draft
   Created: 2018-08-03
@@ -199,14 +199,6 @@ function getDefaultIdentity(): Promise
  Returns currently selected identity of logged in user.	
  * Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity
 
-====getPublicKeys====
-
-function getPublicKeys(identity: string): Promise
-
-Returns public keys corresponding to an identity. This call must query the blockchain. This operation is not signed and therefore does not require user interaction. - -* Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity - ====getDDO====
 interface OntIdDDO {
@@ -218,20 +210,7 @@ function getDDO(identity: string): Promise
 
 Queries Description Object of the identity. This call must query the blockchain. This operation is not signed and therefore does not require user interaction.
 
-* Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity
-
-====getAttributes====
-
-interface OntIdAttribute {
-    key: string;
-    type: string;
-    value: string;
-}
-
-function getAttributes(identity: string): Promise
-
- -Queries attributes attached to the identity. This call must query the blockchain. This operation is not signed and therefore does not require user interaction. +Returns Description object of the identity. This object contains public keys and attributes of the identity. * Rejects with '''MALFORMED_IDENTITY''' in case the identity is not a valid identity @@ -253,6 +232,7 @@ Initiates removing of attribute from the user identity. This action needs to be * Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity + ===Message=== This API deals with arbitrary message signing and verification. From 5e03f82499251e724f63c49d032090ab207cb673 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Tue, 28 Aug 2018 08:25:34 +0200 Subject: [PATCH 55/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 3115100..6d4f54b 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -167,9 +167,9 @@ dAPI provider does not need to support all future OEPs concerned with dAPI. ===Asset=== A primary focus of Asset API is to initiate a transfer. The request needs to be confirmed by the user. -====getDefaultAccount==== +====getAccount====
	
-function getDefaultAccount(): Promise	
+function getAccount(): Promise	
 
Returns currently selected account of logged in user. * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts @@ -192,9 +192,9 @@ Returns transaction Id. ===Identity=== A primary focus of Identity API is to interact with ONT ID smart contract on the blockchain. -====getDefaultIdentity==== +====getIdentity====
	
-function getDefaultIdentity(): Promise	
+function getIdentity(): Promise	
 
Returns currently selected identity of logged in user. * Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity @@ -223,7 +223,7 @@ Initiates adding of attributes to the user identity. This action needs to be con * Rejects with '''NO_IDENTITY''' in case the user is not signed in or has no identity -====removeAttributes==== +====removeAttribute====
 function removeAttribute(key: string): Promise
 
From 118b07843c97927b23264d19c1448a9a547babf3 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Tue, 28 Aug 2018 12:23:20 +0200 Subject: [PATCH 56/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 6d4f54b..6ba4761 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -88,7 +88,9 @@ The interaction with dAPI often requires specification of '''Address''', '''Iden * using Hex encoding ===Complex structures=== -API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To precisely describe the structure of those objects, we'd chosen Typescript syntax. +All the functions of this dAPI, which requires arguments are using one typed argument instead of many. The reasons are better readability and future extensibility. + +API specification is a complex document. Every method has some inputs and outputs. Although we use the primitive types (numbers, strings, booleans) whenever possible, there are places where a complex object is required. To precisely describe the structure of those objects, we'd chosen Typescript-like syntax. ===Components=== Although this proposal is bringing clear and simple API for the dApps, the individual functions can be divided into these components: @@ -122,13 +124,13 @@ interface Network { function getGenerateBlockTime(): Promise function getNodeCount(): Promise function getBlockHeight(): Promise -function getMerkleProof(txHash: string): Promise -function getStorage(contract: string, key: string): Promise -function getAllowance(asset: Asset, fromAddress: string, toAddress: string): Promise -function getBlock(block: number | string): Promise -function getTransaction(txHash: string): Promise +function getMerkleProof({ txHash: string }): Promise +function getStorage({ contract: string, key: string }): Promise +function getAllowance({ asset: Asset, fromAddress: string, toAddress: string }): Promise +function getBlock({ block: number | string }): Promise +function getTransaction({ txHash: string }): Promise function getNetwork(): Network -function getBalance(address: string): Promise +function getBalance({ address: string }): Promise
For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain. @@ -176,7 +178,7 @@ Returns currently selected account of logged in user. ====makeTransfer====
-function makeTransfer(recipient: string, asset: Asset, amount: number): Promise
+function makeTransfer({ recipient: string, asset: Asset, amount: number }): Promise
 
Initiates a transfer of amount asset to recipient account. @@ -205,7 +207,7 @@ interface OntIdDDO { ... } -function getDDO(identity: string): Promise +function getDDO({ identity: string }): Promise
Queries Description Object of the identity. This call must query the blockchain. This operation is not signed and therefore does not require user interaction. @@ -216,7 +218,7 @@ Returns Description object of the identity. This object contains pu ====addAttributes====
-function addAttributes(attributes: OntIdAttribute[]): Promise
+function addAttributes({ attributes: OntIdAttribute[] }): Promise
 
Initiates adding of attributes to the user identity. This action needs to be confirmed by the user. Attributes with existing key will be overwritten. @@ -225,7 +227,7 @@ Initiates adding of attributes to the user identity. This action needs to be con ====removeAttribute====
-function removeAttribute(key: string): Promise
+function removeAttribute({ key: string }): Promise
 
Initiates removing of attribute from the user identity. This action needs to be confirmed by the user. @@ -244,7 +246,7 @@ interface Signature { data: string; } -function signMessageHash(messageHash: string): Promise +function signMessageHash({ messageHash: string }): Promise
Initiates signing of arbitrary messageHash by the user account or identity. dAPI provider should provide the user with a way for selecting which account or identity will sign the message. @@ -261,7 +263,7 @@ Therefore the hash is prepended with known string '''Ontology message:''', and o ====verifyMessageHash====
-function verifyMessageHash(messageHash: string, signature: Signature): Promise
+function verifyMessageHash({ messageHash: string, signature: Signature }): Promise
 
Verifies that the signature is valid signature of messageHash. @@ -273,7 +275,7 @@ This method does not require the dApp to disclose the message itself, only the h ====signMessage====
-function signMessage(message: string): Promise
+function signMessage({ message: string }): Promise
 
Initiates signing of arbitrary message by the user account or identity. dAPI provider should provide the user with a way for selecting which account or identity will sign the message. @@ -286,7 +288,7 @@ This method provide the dAPI provider with the message body, which it should dis ====verifyMessage====
-function verifyMessage(message: string, signature: Signature): Promise
+function verifyMessage({ message: string, signature: Signature }): Promise
 
Verifies that the signature is valid signature of message. @@ -314,8 +316,8 @@ interface Response { results: Result[]; } -function invoke(contract: string, method: string, parameters: Parameter[], - gasPrice: number, gasLimit: number, requireIdentity: boolean): Promise +function invoke({ contract: string, method: string, parameters?: Parameter[], + gasPrice?: number, gasLimit?: number, requireIdentity?: boolean }): Promise
Initiates a method call to a smart contract with supplied parameters. @@ -339,7 +341,7 @@ To output a result from smart contract, call Runtime.Notify method. For every su ====invokeRead====
-function invokeRead(contract: string, method: string, parameters: Parameter[]): Promise
+function invokeRead({ contract: string, method: string, parameters?: Parameter[] }): Promise
 
Initiates a method call to a smart contract with supplied parameters in read only mode (preExec). This kind of method call does not write anything to blockchain and therefore does not need to be signed or paid for. It is processed without user interaction. @@ -351,8 +353,8 @@ Returns direct value returned by the smart contract execution. ====deploy====
-function deploy(code: string, name: string, version: string, author: string, 
-    email: string, description: string, needStorage: boolean, gasPrice: number, gasLimit: number): Promise
+function deploy({ code: string, name?: string, version?: string, author?: string, 
+    email?: string, description?: string, needStorage?: boolean, gasPrice?: number, gasLimit?: number }): Promise
 
Initiates deployment of smart contract. The code parameter represents compiled code of smart contract for NEOVM. The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. It is upto the dAPI provide to allow user select the payer's account. From 3164a4a5c5a3b38e395a991894b2f7d504dab009 Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Wed, 29 Aug 2018 09:50:21 +0200 Subject: [PATCH 57/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 6ba4761..6758068 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -367,14 +367,14 @@ The interaction between dApp and Ontology network can be described with this dia [[Image:OEP-6-1.svg|Architecture]] -===Yellow parts=== -These components are external to this proposal. +===External components=== +Yellow colored components are external to this proposal. -===Green parts=== -'''dAPI.js''' is universal implementation of this proposal for direct use by dApp developers. +===dAPI.js=== +Green colored components represent '''dAPI.js'''. It is universal implementation of communication channel for direct use by dApp developers in web browsers. -===Blue parts=== -These components all belongs to concrete implementation of dAPI provider. The implementation is out of scope of this proposal, but the implementator must adhere to the protocol used by dAPI.js. +===dAPI provider=== +Blue colored components belong to specific implementation of dAPI provider. The implementation is out of scope of this proposal, but the implementator must adhere to the protocol used by dAPI.js. ==Rationale== From a0cf97cc7984c3cb71da21317899476c0febc66f Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Wed, 29 Aug 2018 11:20:28 +0200 Subject: [PATCH 58/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 6758068..d421e17 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -376,6 +376,11 @@ Green colored components represent '''dAPI.js'''. It is universal implementation ===dAPI provider=== Blue colored components belong to specific implementation of dAPI provider. The implementation is out of scope of this proposal, but the implementator must adhere to the protocol used by dAPI.js. +===Communication protocol=== +The communication protocol has RPC style of communication. The RPC is modeled on top of standard WebExtension message passing using runtime.sendMessage and runtime.onMessage.addListener. All the complications of WebExtension is hidden for both the '''dApp''' and '''dAPI provider''' when using dAPI.js. + +dAPI providers might use dAPI.js as the communication protocol, but they can also implement different protocols suitable for the specific environment (e.g: iOS, Android, Desktop). + ==Rationale== '''''User story''''': As a '''dApp''' developer, I need to use a lightweight api for integration with Ontology network without requiring my users to share their private keys with me. From 43e4816fb059a1c387e4bf4649836803161249bb Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Thu, 13 Sep 2018 09:06:58 +0200 Subject: [PATCH 59/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index d421e17..794b582 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -48,14 +48,14 @@ The promises will be either resolved immediately if no interaction with user UI ===Account/Identity management=== Because dAPI shifts the issue of trust from dApp to dApp provider, all account and identity management is external to the dApp. Therefore there are no methods which directly handle private keys. The dApp won't need to sign the transaction itself. -Any time dApp makes a call that requires a private key to sign something (makeTransfer, sign), dApp provider will inform user about the action and prompt him for permission. +Any time dApp makes a call that requires a private key to sign something (send, sign), dApp provider will inform user about the action and prompt him for permission. dApp provider can even forward the request to external signing mechanism as part of the process. This way the dApp does not need to specifically integrate with such mechanism. dAPI providers can choose to support multiple accounts and identities. Account and identity switching is part of dAPI provider implementation. dAPI provider should share with dApp as little information about user accounts and identities as possible, because it posses a security risk. Otherwise malicious dApp can list all user accounts with balances and identities. ====dAPI access restriction==== -Using dAPI any dApp is able to call the dAPI provider and initiate an interaction with the user (e.g.: makeTransfer). Only prerequisite is, that the user visits the dApp page. Although the user will need to confirm such an action, bothering him with this action, if he has no intention to confirm it, will hinder the experience. +Using dAPI any dApp is able to call the dAPI provider and initiate an interaction with the user (e.g.: send). Only prerequisite is, that the user visits the dApp page. Although the user will need to confirm such an action, bothering him with this action, if he has no intention to confirm it, will hinder the experience. Therefore the dAPI will forward with every request the Caller object containing the url of the dApp page or id of another extension trying to communicate with dAPI provider. It is upto the dAPI provider to implement custom permission granting workflow or automatic blacklisting. @@ -176,19 +176,19 @@ function getAccount(): Promise Returns currently selected account of logged in user. * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts -====makeTransfer==== +====send====
-function makeTransfer({ recipient: string, asset: Asset, amount: number }): Promise
+function send({ to: string, asset: Asset, amount: number }): Promise
 
-Initiates a transfer of amount asset to recipient account. +Initiates a transfer of amount asset to to account. The amount should always be an integer value. Therefore is is represented in the smallest, further non divisible units for the asset. E.g.: If the asset is ONG then the value is multiplied by 1000000000. Returns transaction Id. * Rejects with '''NO_ACCOUNT''' in case the user is not signed in or has no accounts -* Rejects with '''MALFORMED_ACCOUNT''' in case the recipient is not a valid account +* Rejects with '''MALFORMED_ACCOUNT''' in case the to is not a valid account * Rejects with '''CANCELED''' in case the user cancels the request ===Identity=== @@ -316,11 +316,11 @@ interface Response { results: Result[]; } -function invoke({ contract: string, method: string, parameters?: Parameter[], +function invoke({ scriptHash: string, operation: string, args?: Parameter[], gasPrice?: number, gasLimit?: number, requireIdentity?: boolean }): Promise
-Initiates a method call to a smart contract with supplied parameters. +Initiates a operation call to a smart contract on scriptHash address with supplied args. The gasPrice and gasLimit are hints for the dAPI provider and it should allow user to override those values before signing. It is upto the dAPI provide to allow user select the payer's account. In case the smart contract requires the call to be signed also by an identity, parameter requireIdentity should be set to true. @@ -341,10 +341,10 @@ To output a result from smart contract, call Runtime.Notify method. For every su ====invokeRead====
-function invokeRead({ contract: string, method: string, parameters?: Parameter[] }): Promise
+function invokeRead({ scriptHash: string, operation: string, args?: Parameter[] }): Promise
 
-Initiates a method call to a smart contract with supplied parameters in read only mode (preExec). This kind of method call does not write anything to blockchain and therefore does not need to be signed or paid for. It is processed without user interaction. +Initiates a operation call to a smart contract on scriptHash with supplied args in read only mode (preExec). This kind of operation call does not write anything to blockchain and therefore does not need to be signed or paid for. It is processed without user interaction. Returns direct value returned by the smart contract execution. From 46bbf73958c40e2f4f6b76ce70216a0f6588e7ef Mon Sep 17 00:00:00 2001 From: Matus Zamborsky Date: Mon, 5 Nov 2018 10:28:58 +0100 Subject: [PATCH 60/60] Update OEP-6.mediawiki --- OEP-6/OEP-6.mediawiki | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/OEP-6/OEP-6.mediawiki b/OEP-6/OEP-6.mediawiki index 794b582..ea8501b 100644 --- a/OEP-6/OEP-6.mediawiki +++ b/OEP-6/OEP-6.mediawiki @@ -131,6 +131,17 @@ function getBlock({ block: number | string }): Promise function getTransaction({ txHash: string }): Promise function getNetwork(): Network function getBalance({ address: string }): Promise +function getUnboundOng({ address: string }): Promise +function getContract({ hash: string }): Promise +function getSmartCodeEvent({ value: string | number }): Promise +function getBlockHeightByTxHash({ hash: string }): Promise +function getBlockHash({ height: number }): Promise +function getBlockTxsByHeight({ height: number }): Promise +function getGasPrice(): Promise +function getGrantOng({ address: string }): Promise +function getMempoolTxCount(): Promise +function getMempoolTxState({ hash: string }): Promise +function getVersion(): Promise
For further explanation about the wrapped method consult https://ontio.github.io/documentation/restful_api_en.html . The types '''Transaction''', '''Block''', '''MerkleProof''' and '''Balance''' corresponds to the exact object returned from Ontology blockchain.