diff --git a/docs/guides/typed-data.md b/docs/guides/typed-data.md new file mode 100644 index 0000000000..7cdee49f40 --- /dev/null +++ b/docs/guides/typed-data.md @@ -0,0 +1,45 @@ +# Typed data hashing and signing + +## Common structure + +The whole idea is heavily inspired by [EIP-712](https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator). To get a signature needed to calculate `hash(hash(domain), hash(aci), hash(data))`. + +`hash` function is `blake2b`. + +`domain` is a record containing not required properties: +- `name` as string, +- `version` as integer, +- `networkId` as string, +- `contractAddress` as ct-encoded string. + +`aci` is part of a complete contract ACI. It defines a type of data to sign. For example, the ACI +```json +{ + "record": [ + { "name": "foo", "type": "string" }, + { "name": "bar", "type": "int" } + ] +} +``` +would correspond to the data +```json +{ "foo": "test", "bar": 42 } +``` + +`domain` and `data` are fate-encoded before hashing. `aci` is prepared for hashing according to [RFC8785](https://tools.ietf.org/html/rfc8785). + +## Implementation + +- [encodeFateValue](https://github.com/aeternity/aepp-sdk-js/blob/08ea28a8ee12abb4d5f1be36fa7ccc63bc217f05/src/utils/typed-data.ts#L41-L49) -- use to generate the first argument for `signTypedData`; +- [AccountBase::signTypedData](https://github.com/aeternity/aepp-sdk-js/blob/08ea28a8ee12abb4d5f1be36fa7ccc63bc217f05/src/account/Base.ts#L63-L70) -- calculates signature, supported in MemoryAccount and in aepp-wallet connection; + +- [hashTypedData](https://github.com/aeternity/aepp-sdk-js/blob/08ea28a8ee12abb4d5f1be36fa7ccc63bc217f05/src/utils/typed-data.ts#L84-L90) -- calculates the overall hash of typed data to sign; +- [decodeFateValue](https://github.com/aeternity/aepp-sdk-js/blob/08ea28a8ee12abb4d5f1be36fa7ccc63bc217f05/src/utils/typed-data.ts#L52-L60) -- use to preview data to sign on wallet side; +- [hashJson](https://github.com/aeternity/aepp-sdk-js/blob/08ea28a8ee12abb4d5f1be36fa7ccc63bc217f05/src/utils/typed-data.ts#L13-L15) -- deterministic hashing of an arbitrary JS value, used to calculate `hash(aci)`; +- [hashDomain](https://github.com/aeternity/aepp-sdk-js/blob/08ea28a8ee12abb4d5f1be36fa7ccc63bc217f05/src/utils/typed-data.ts#L65-L82) -- use for debugging or to prepare the hash value for smart contract. + +## Examples + +- [signing and verifying on aepp side](https://github.com/aeternity/aepp-sdk-js/blob/08ea28a8ee12abb4d5f1be36fa7ccc63bc217f05/examples/browser/aepp/src/TypedData.vue) +- [signing confirmation on wallet side](https://github.com/aeternity/aepp-sdk-js/blob/08ea28a8ee12abb4d5f1be36fa7ccc63bc217f05/examples/browser/wallet-iframe/src/App.vue#L105-L111) +- [verifying a signature on contract side](https://github.com/aeternity/aepp-sdk-js/blob/08ea28a8ee12abb4d5f1be36fa7ccc63bc217f05/test/integration/typed-data.ts#L97-L127) diff --git a/mkdocs.yml b/mkdocs.yml index df284c1748..2d02f3f0f0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -58,6 +58,7 @@ nav: - guides/batch-requests.md - guides/error-handling.md - guides/low-vs-high-usage.md + - guides/typed-data.md - Wallet interaction: - guides/connect-aepp-to-wallet.md - guides/build-wallet.md