From 8cc121963c1dbfead051579fd306723009fc4c9c Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Tue, 25 Jul 2023 10:13:53 +0100 Subject: [PATCH 01/28] sapphire: initial notes on authenticated calls & contract authentication --- docs/dapp/sapphire/authentication.md | 140 +++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 docs/dapp/sapphire/authentication.md diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md new file mode 100644 index 0000000000..0798c492e0 --- /dev/null +++ b/docs/dapp/sapphire/authentication.md @@ -0,0 +1,140 @@ +--- +description: Authenticate users with your confidential contracts +--- + +# View-Call Authentication + +User impersonation on Ethereum and other 'Transparent EVMs' isn't a problem because everybody can see all data, however with the Sapphire confidential EVM it is necessary to prevent contracts from revealing confidential information to the wrong person so it cannot allow impersonation. + +When `eth_call` is used to query a contract's `view` function the `msg.sender` parameter is set to `address(0x0)` because it is unauthenticated and anonymous. + +When a transaction is submitted it is signed by a keypair, and thus costs gas and can make state updates so `msg.sender` is set to the signing account. + +Intra-contract calls always set `msg.sender` appropriately, if a contract calls another contract in a way which could reveal sensitive information, the calling contract must implement access control or authentication. + +When `sapphire.wrap` is used to automatically end-to-end encrypt calls to Sapphire. However, once the Sapphire wrapper is requested to sign a transaction (thus attaching the provider to a signer, or converting it into one) then subsequent `view` calls via `eth_call` will be automatically signed, these are called 'Signed Queries' meaning `msg.sender` will be set to the signing account. + +However, this may not be an ideal user experience and can result in frequent pop-ups requesting they sign queries which wouldn't normally require any interaction on Transparent EVMs. + +```solidity +contract Example { + address owner; + constructor () { + owner = msg.sender; + } + function isOwner () public view returns (bool) { + return msg.sender == owner; + } +} +``` + +In the sample above, calling `isOwner` returns: + + * `false`, for `eth_call` + * `false`, with `sapphire.wrap` but without an attached signer + * `true`, with `sapphire.wrap` and an attached signer + * `true`, if called via the contract which created it + +## Sign-in with EIP-712 + +One strategy which can be used to reduce the number of transaction signing prompts when a user interacts with contracts via a dApp is to use EIP-712 to 'Sign-in', in combination with using two wrapped providers: + + 1. Perform encrypted but unauthenticated view calls + 2. Performing encrypted and authenticated transactions (or view calls), where the user will be prompted to sign each action. + +The code sample below uses an `authenticated` modifier to verify the sign-in + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +struct SignatureRSV { + bytes32 r; + bytes32 s; + uint256 v; +} + +contract SignInExample { + bytes32 public constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + string public constant SIGNIN_TYPE = "SignIn(address user, uint32 time)"; + bytes32 public constant SIGNIN_TYPEHASH = keccak256(bytes(SIGNIN_TYPE)); + bytes32 public immutable DOMAIN_SEPARATOR; + + constructor () { + DOMAIN_SEPARATOR = keccak256(abi.encode( + EIP712_DOMAIN_TYPEHASH, + keccak256("Example.SignIn"), + keccak256("1"), + block.chainid, + address(this) + )); + } + + struct SignIn { + address user; + uint32 time; + SignatureRSV rsv; + } + + modifier authenticated(SignIn calldata auth) + { + // Must be signed within 24 hours ago + require( auth.time > (block.timestamp - (60*60*24)) ); + + // Validate EIP-712 sign-in authentication + bytes32 authdataDigest = keccak256(abi.encodePacked( + "\x19\x01", + DOMAIN_SEPARATOR, + keccak256(abi.encode( + SIGNIN_TYPEHASH, + auth.user, + auth.time + )) + )); + + require( auth.user == ecrecover(authdataDigest, uint8(auth.rsv.v), auth.rsv.r, auth.rsv.s), "Invalid Sign-In" ); + + _; + } + + function authenticatedViewCall( + SignIn calldata auth, + ... args + ) + external view + authenticated(auth) + returns (bytes memory output) + { + // Use `auth.user` instead of `msg.sender` + } +} +``` + +Then the frontend dApp can request the user to sign-in using EIP-712, you may wish to add additional parameters which are authenticated such as the domain name. The following code example uses Ethers: + +```typescript +const time = new Date().getTime(); +const user = await eth.signer.getAddress(); + +// Ask user to 'Sign-In' every 24 hours +const signature = await eth.signer._signTypedData({ + name: "Example.SignIn", + version: "1", + chainId: import.meta.env.CHAINID, + verifyingContract: contract.address +}, { + SignIn: [ + { name: 'user', type: "address" }, + { name: 'time', type: 'uint32' }, + ] +}, { + user: user, + time: time +}); +const rsv = ethers.utils.splitSignature(signature); +const auth = {user, time, rsv}; +// TODO: cache the result + +// Then in future, authenticated view calls can be performed using the authenticated data +await contract.authenticatedViewCall(auth, ...args); +``` \ No newline at end of file From 8e75004126d08ec6573dac250277f3dd62683260 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Tue, 25 Jul 2023 11:09:35 +0100 Subject: [PATCH 02/28] sapphire: improved authentication verbiage --- docs/dapp/sapphire/authentication.md | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 0798c492e0..66c9573e0b 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -4,17 +4,24 @@ description: Authenticate users with your confidential contracts # View-Call Authentication -User impersonation on Ethereum and other 'Transparent EVMs' isn't a problem because everybody can see all data, however with the Sapphire confidential EVM it is necessary to prevent contracts from revealing confidential information to the wrong person so it cannot allow impersonation. +User impersonation on Ethereum and other 'Transparent EVMs' isn't a problem because everybody can see all data, however with the Sapphire confidential EVM it is necessary to prevent contracts from revealing confidential information to the wrong person - for this reason we cannot allow arbitrary impersonation of any `msg.sender`. -When `eth_call` is used to query a contract's `view` function the `msg.sender` parameter is set to `address(0x0)` because it is unauthenticated and anonymous. +There are four types of contract calls: -When a transaction is submitted it is signed by a keypair, and thus costs gas and can make state updates so `msg.sender` is set to the signing account. + 1. Contract to Contract calls + 2. Unauthenticted view calls (Queries) + 3. Authenticated view calls (Signed Queries) + 4. Transactions (authenticated by signature) + +By default all `eth_call` queries used to invoke contract functions have the `msg.sender` parameter is set to `address(0x0)`. And when a transaction is submitted it is signed by a keypair (thus costs gas and can make state updates) the `msg.sender` will be set to the signing account. Intra-contract calls always set `msg.sender` appropriately, if a contract calls another contract in a way which could reveal sensitive information, the calling contract must implement access control or authentication. -When `sapphire.wrap` is used to automatically end-to-end encrypt calls to Sapphire. However, once the Sapphire wrapper is requested to sign a transaction (thus attaching the provider to a signer, or converting it into one) then subsequent `view` calls via `eth_call` will be automatically signed, these are called 'Signed Queries' meaning `msg.sender` will be set to the signing account. +## Sapphire Wrapper + +The Ethereum provider wrapper provided by the @oasisprotocol/sapphire-paratime `sapphire.wrap` function will automatically end-to-end encrypt calldata when interacting with contracts on Sapphire, this is an easy way to ensure the calldata of your dApp transactions remain confidential - although the `from`, `to`, and `gasprice` parameters are not encrypted. -However, this may not be an ideal user experience and can result in frequent pop-ups requesting they sign queries which wouldn't normally require any interaction on Transparent EVMs. +However, once the Sapphire wrapper is requested to sign a transaction (thus attaching the provider to a signer, or converting it into one) then subsequent `view` calls via `eth_call` will be automatically signed, these are called 'Signed Queries' meaning `msg.sender` will be set to the signing account. This may not be an ideal user experience and can result in frequent pop-ups requesting they sign queries which wouldn't normally require any interaction on Transparent EVMs. ```solidity contract Example { @@ -28,7 +35,7 @@ contract Example { } ``` -In the sample above, calling `isOwner` returns: +In the sample above, assuming we're calling from the same contract or account which created the contract, calling `isOwner` will return: * `false`, for `eth_call` * `false`, with `sapphire.wrap` but without an attached signer @@ -37,10 +44,12 @@ In the sample above, calling `isOwner` returns: ## Sign-in with EIP-712 -One strategy which can be used to reduce the number of transaction signing prompts when a user interacts with contracts via a dApp is to use EIP-712 to 'Sign-in', in combination with using two wrapped providers: +One strategy which can be used to reduce the number of transaction signing prompts when a user interacts with contracts via a dApp is to use EIP-712 to 'Sign-in' once per day (or per-session), in combination with using two wrapped providers: + + 1. Provider to perform encrypted but unauthenticated view calls + 2. Another provider to perform encrypted and authenticated transactions (or view calls), where the user will be prompted to sign each action. - 1. Perform encrypted but unauthenticated view calls - 2. Performing encrypted and authenticated transactions (or view calls), where the user will be prompted to sign each action. +The two-provider pattern, in conjunction with a daily EIP-712 sign-in prompt ensures all transactions are end-to-end encrypted and the contract can authenticate users in view calls without frequent annoying popups. The code sample below uses an `authenticated` modifier to verify the sign-in From ec319e8f13bcf512aceadc92b7e1fc6385fb0266 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Tue, 25 Jul 2023 11:43:32 +0100 Subject: [PATCH 03/28] sapphire: added hyperlink to sapphire-paratime NPM package. --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 66c9573e0b..1abe908a59 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -19,7 +19,7 @@ Intra-contract calls always set `msg.sender` appropriately, if a contract calls ## Sapphire Wrapper -The Ethereum provider wrapper provided by the @oasisprotocol/sapphire-paratime `sapphire.wrap` function will automatically end-to-end encrypt calldata when interacting with contracts on Sapphire, this is an easy way to ensure the calldata of your dApp transactions remain confidential - although the `from`, `to`, and `gasprice` parameters are not encrypted. +The Ethereum provider wrapper provided by the [@oasisprotocol/sapphire-paratime](https://www.npmjs.com/package/@oasisprotocol/sapphire-paratime) `sapphire.wrap` function will automatically end-to-end encrypt calldata when interacting with contracts on Sapphire, this is an easy way to ensure the calldata of your dApp transactions remain confidential - although the `from`, `to`, and `gasprice` parameters are not encrypted. However, once the Sapphire wrapper is requested to sign a transaction (thus attaching the provider to a signer, or converting it into one) then subsequent `view` calls via `eth_call` will be automatically signed, these are called 'Signed Queries' meaning `msg.sender` will be set to the signing account. This may not be an ideal user experience and can result in frequent pop-ups requesting they sign queries which wouldn't normally require any interaction on Transparent EVMs. From 42f6187911ef9d1193990147a18e596c9e85b2de Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Fri, 28 Jul 2023 12:53:52 +0100 Subject: [PATCH 04/28] sapphire/authentication: added EIP-712 link and side-menu item --- docs/dapp/sapphire/authentication.md | 5 +++-- sidebarDapp.js | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 1abe908a59..30f15bd008 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -44,10 +44,11 @@ In the sample above, assuming we're calling from the same contract or account wh ## Sign-in with EIP-712 -One strategy which can be used to reduce the number of transaction signing prompts when a user interacts with contracts via a dApp is to use EIP-712 to 'Sign-in' once per day (or per-session), in combination with using two wrapped providers: +One strategy which can be used to reduce the number of transaction signing prompts when a user interacts with contracts via a dApp is to use [EIP-712](https://eips.ethereum.org/EIPS/eip-712) to 'Sign-in' once per day (or per-session), in combination with using two wrapped providers: 1. Provider to perform encrypted but unauthenticated view calls - 2. Another provider to perform encrypted and authenticated transactions (or view calls), where the user will be prompted to sign each action. + 2. Another provider to perform encrypted and authenticated transactions (or view calls) + - The user will be prompted to sign each action. The two-provider pattern, in conjunction with a daily EIP-712 sign-in prompt ensures all transactions are end-to-end encrypted and the contract can authenticate users in view calls without frequent annoying popups. diff --git a/sidebarDapp.js b/sidebarDapp.js index 49d30874d6..fc43e9936c 100644 --- a/sidebarDapp.js +++ b/sidebarDapp.js @@ -20,6 +20,7 @@ const sidebars = { 'dapp/sapphire/guide', 'dapp/sapphire/browser', 'dapp/sapphire/precompiles', + 'dapp/sapphire/authentication', 'dapp/sapphire/addresses', ], }, From 583057be28311a307538ad73ad6f7becd852dce2 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Mon, 31 Jul 2023 20:28:42 +0100 Subject: [PATCH 05/28] sapphire/authentication: feedback from aefhm --- docs/dapp/sapphire/authentication.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 30f15bd008..5106607732 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -4,7 +4,7 @@ description: Authenticate users with your confidential contracts # View-Call Authentication -User impersonation on Ethereum and other 'Transparent EVMs' isn't a problem because everybody can see all data, however with the Sapphire confidential EVM it is necessary to prevent contracts from revealing confidential information to the wrong person - for this reason we cannot allow arbitrary impersonation of any `msg.sender`. +User impersonation on Ethereum and other 'Transparent EVMs' isn't a problem because **everybody** can see **all** data however the Sapphire confidential EVM prevents contracts from revealing confidential information to the wrong party (account or contract) - for this reason we cannot allow arbitrary impersonation of any `msg.sender`. There are four types of contract calls: @@ -21,7 +21,7 @@ Intra-contract calls always set `msg.sender` appropriately, if a contract calls The Ethereum provider wrapper provided by the [@oasisprotocol/sapphire-paratime](https://www.npmjs.com/package/@oasisprotocol/sapphire-paratime) `sapphire.wrap` function will automatically end-to-end encrypt calldata when interacting with contracts on Sapphire, this is an easy way to ensure the calldata of your dApp transactions remain confidential - although the `from`, `to`, and `gasprice` parameters are not encrypted. -However, once the Sapphire wrapper is requested to sign a transaction (thus attaching the provider to a signer, or converting it into one) then subsequent `view` calls via `eth_call` will be automatically signed, these are called 'Signed Queries' meaning `msg.sender` will be set to the signing account. This may not be an ideal user experience and can result in frequent pop-ups requesting they sign queries which wouldn't normally require any interaction on Transparent EVMs. +However, if the Sapphire wrapper has been attached to a signer then subsequent `view` calls via `eth_call` will be request that the user sign them (e.g. a MetaMask popup), these are called 'Signed Queries' meaning `msg.sender` will be set to the signing account and can be used for authentication or to implement access control. This may add friction to the end-user experience and can result in frequent pop-ups requesting they sign queries which wouldn't normally require any interaction on Transparent EVMs. ```solidity contract Example { @@ -138,12 +138,12 @@ const signature = await eth.signer._signTypedData({ { name: 'time', type: 'uint32' }, ] }, { - user: user, + user, time: time }); const rsv = ethers.utils.splitSignature(signature); const auth = {user, time, rsv}; -// TODO: cache the result +// The `auth` variable can then be cached // Then in future, authenticated view calls can be performed using the authenticated data await contract.authenticatedViewCall(auth, ...args); From d13bae59ebb309891c7a68999aa3d17e19fd15b3 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 2 Aug 2023 23:50:42 +0100 Subject: [PATCH 06/28] sapphire/authentication: suggestions from Matevz --- docs/dapp/sapphire/authentication.md | 84 +++++++++++++++++++++------- sidebarDapp.js | 2 +- 2 files changed, 66 insertions(+), 20 deletions(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 5106607732..b6143d5f53 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -4,24 +4,55 @@ description: Authenticate users with your confidential contracts # View-Call Authentication -User impersonation on Ethereum and other 'Transparent EVMs' isn't a problem because **everybody** can see **all** data however the Sapphire confidential EVM prevents contracts from revealing confidential information to the wrong party (account or contract) - for this reason we cannot allow arbitrary impersonation of any `msg.sender`. +User impersonation on Ethereum and other "Transparent EVMs" isn't a problem +because **everybody** can see **all** data however the Sapphire confidential +EVM prevents contracts from revealing confidential information to the wrong +party (account or contract) - for this reason we cannot allow arbitrary +impersonation of any `msg.sender`. There are four types of contract calls: - 1. Contract to Contract calls - 2. Unauthenticted view calls (Queries) + 1. Contract to Contract calls (also known as *internal calls*) + 2. Unauthenticted view calls (Queries using `eth_call`) 3. Authenticated view calls (Signed Queries) 4. Transactions (authenticated by signature) -By default all `eth_call` queries used to invoke contract functions have the `msg.sender` parameter is set to `address(0x0)`. And when a transaction is submitted it is signed by a keypair (thus costs gas and can make state updates) the `msg.sender` will be set to the signing account. +By default all `eth_call` queries used to invoke contract functions have the +`msg.sender` parameter is set to `address(0x0)`. And when a transaction is +submitted it is signed by a keypair (thus costs gas and can make state updates) +the `msg.sender` will be set to the signing account. -Intra-contract calls always set `msg.sender` appropriately, if a contract calls another contract in a way which could reveal sensitive information, the calling contract must implement access control or authentication. +Intra-contract calls always set `msg.sender` appropriately, if a contract calls +another contract in a way which could reveal sensitive information, the calling +contract must implement access control or authentication. ## Sapphire Wrapper -The Ethereum provider wrapper provided by the [@oasisprotocol/sapphire-paratime](https://www.npmjs.com/package/@oasisprotocol/sapphire-paratime) `sapphire.wrap` function will automatically end-to-end encrypt calldata when interacting with contracts on Sapphire, this is an easy way to ensure the calldata of your dApp transactions remain confidential - although the `from`, `to`, and `gasprice` parameters are not encrypted. +The Ethereum provider wrapper provided by the [@oasisprotocol/sapphire-paratime][sp-npm] +`sapphire.wrap` function will automatically end-to-end encrypt calldata when +interacting with contracts on Sapphire, this is an easy way to ensure the +calldata of your dApp transactions remain confidential - although the `from`, +`to`, and `gasprice` parameters are not encrypted. -However, if the Sapphire wrapper has been attached to a signer then subsequent `view` calls via `eth_call` will be request that the user sign them (e.g. a MetaMask popup), these are called 'Signed Queries' meaning `msg.sender` will be set to the signing account and can be used for authentication or to implement access control. This may add friction to the end-user experience and can result in frequent pop-ups requesting they sign queries which wouldn't normally require any interaction on Transparent EVMs. +[sp-npm]: https://www.npmjs.com/package/@oasisprotocol/sapphire-paratime + +:::tip Unauthenticated calls and Encryption + +Although the calls may be unauthenticated, they can still be encrypted! + +::: + + +However, if the Sapphire wrapper has been attached to a signer then subsequent +view calls via `eth_call` will be request that the user sign them (e.g. a +MetaMask popup), these are called "Signed Queries" meaning `msg.sender` will be +set to the signing account and can be used for authentication or to implement +access control. This may add friction to the end-user experience and can result +in frequent pop-ups requesting they sign queries which wouldn't normally require +any interaction on Transparent EVMs. + +Let's see how Sapphire interprets different contract calls. Suppose the +following solidity code: ```solidity contract Example { @@ -35,7 +66,8 @@ contract Example { } ``` -In the sample above, assuming we're calling from the same contract or account which created the contract, calling `isOwner` will return: +In the sample above, assuming we're calling from the same contract or account +which created the contract, calling `isOwner` will return: * `false`, for `eth_call` * `false`, with `sapphire.wrap` but without an attached signer @@ -44,15 +76,22 @@ In the sample above, assuming we're calling from the same contract or account wh ## Sign-in with EIP-712 -One strategy which can be used to reduce the number of transaction signing prompts when a user interacts with contracts via a dApp is to use [EIP-712](https://eips.ethereum.org/EIPS/eip-712) to 'Sign-in' once per day (or per-session), in combination with using two wrapped providers: +One strategy which can be used to reduce the number of transaction signing +prompts when a user interacts with contracts via a dApp is to use +[EIP-712][eip-712] to "Sign-in" once per day (or per-session), in combination +with using two wrapped providers: + +[eip-712]: https://eips.ethereum.org/EIPS/eip-712 1. Provider to perform encrypted but unauthenticated view calls 2. Another provider to perform encrypted and authenticated transactions (or view calls) - The user will be prompted to sign each action. -The two-provider pattern, in conjunction with a daily EIP-712 sign-in prompt ensures all transactions are end-to-end encrypted and the contract can authenticate users in view calls without frequent annoying popups. +The two-provider pattern, in conjunction with a daily EIP-712 sign-in prompt +ensures all transactions are end-to-end encrypted and the contract can +authenticate users in view calls without frequent annoying popups. -The code sample below uses an `authenticated` modifier to verify the sign-in +The code sample below uses an `authenticated` modifier to verify the sign-in: ```solidity // SPDX-License-Identifier: UNLICENSED @@ -73,7 +112,7 @@ contract SignInExample { constructor () { DOMAIN_SEPARATOR = keccak256(abi.encode( EIP712_DOMAIN_TYPEHASH, - keccak256("Example.SignIn"), + keccak256("SignInExample.SignIn"), keccak256("1"), block.chainid, address(this) @@ -88,10 +127,10 @@ contract SignInExample { modifier authenticated(SignIn calldata auth) { - // Must be signed within 24 hours ago + // Must be signed within 24 hours ago. require( auth.time > (block.timestamp - (60*60*24)) ); - // Validate EIP-712 sign-in authentication + // Validate EIP-712 sign-in authentication. bytes32 authdataDigest = keccak256(abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR, @@ -102,7 +141,10 @@ contract SignInExample { )) )); - require( auth.user == ecrecover(authdataDigest, uint8(auth.rsv.v), auth.rsv.r, auth.rsv.s), "Invalid Sign-In" ); + address recovered_address = ecrecover( + authdataDigest, uint8(auth.rsv.v), auth.rsv.r, auth.rsv.s); + + require( auth.user == recovered_address, "Invalid Sign-In" ); _; } @@ -120,15 +162,18 @@ contract SignInExample { } ``` -Then the frontend dApp can request the user to sign-in using EIP-712, you may wish to add additional parameters which are authenticated such as the domain name. The following code example uses Ethers: +With the above contract code deployed, let's look at the frontend dApp and how +it can request the user to sign-in using EIP-712. You may wish to add additional +parameters which are authenticated such as the domain name. The following code +example uses Ethers: ```typescript const time = new Date().getTime(); const user = await eth.signer.getAddress(); -// Ask user to 'Sign-In' every 24 hours +// Ask user to "Sign-In" every 24 hours const signature = await eth.signer._signTypedData({ - name: "Example.SignIn", + name: "SignInExample.SignIn", version: "1", chainId: import.meta.env.CHAINID, verifyingContract: contract.address @@ -145,6 +190,7 @@ const rsv = ethers.utils.splitSignature(signature); const auth = {user, time, rsv}; // The `auth` variable can then be cached -// Then in future, authenticated view calls can be performed using the authenticated data +// Then in future, authenticated view calls can be performed by +// passing auth without further user interaction authenticated data await contract.authenticatedViewCall(auth, ...args); ``` \ No newline at end of file diff --git a/sidebarDapp.js b/sidebarDapp.js index fc43e9936c..e13513ec68 100644 --- a/sidebarDapp.js +++ b/sidebarDapp.js @@ -19,8 +19,8 @@ const sidebars = { 'dapp/sapphire/quickstart', 'dapp/sapphire/guide', 'dapp/sapphire/browser', - 'dapp/sapphire/precompiles', 'dapp/sapphire/authentication', + 'dapp/sapphire/precompiles', 'dapp/sapphire/addresses', ], }, From 66623ed9eb38d4d756e09c921c3b7a6a1b42510c Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Fri, 4 Aug 2023 14:50:28 +0100 Subject: [PATCH 07/28] sapphire/authentication: changed order of paragraphs --- docs/dapp/sapphire/authentication.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index b6143d5f53..db77fe9c0c 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -17,15 +17,15 @@ There are four types of contract calls: 3. Authenticated view calls (Signed Queries) 4. Transactions (authenticated by signature) +Intra-contract calls always set `msg.sender` appropriately, if a contract calls +another contract in a way which could reveal sensitive information, the calling +contract must implement access control or authentication. + By default all `eth_call` queries used to invoke contract functions have the `msg.sender` parameter is set to `address(0x0)`. And when a transaction is submitted it is signed by a keypair (thus costs gas and can make state updates) the `msg.sender` will be set to the signing account. -Intra-contract calls always set `msg.sender` appropriately, if a contract calls -another contract in a way which could reveal sensitive information, the calling -contract must implement access control or authentication. - ## Sapphire Wrapper The Ethereum provider wrapper provided by the [@oasisprotocol/sapphire-paratime][sp-npm] From 8f18d71e72493dd94401a6dbbebad087677d992f Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Mon, 7 Aug 2023 17:51:11 +0100 Subject: [PATCH 08/28] sapphire/authentication: add notes about cached signed queries --- docs/dapp/sapphire/authentication.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index db77fe9c0c..f572af74ba 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -42,7 +42,6 @@ Although the calls may be unauthenticated, they can still be encrypted! ::: - However, if the Sapphire wrapper has been attached to a signer then subsequent view calls via `eth_call` will be request that the user sign them (e.g. a MetaMask popup), these are called "Signed Queries" meaning `msg.sender` will be @@ -74,7 +73,18 @@ which created the contract, calling `isOwner` will return: * `true`, with `sapphire.wrap` and an attached signer * `true`, if called via the contract which created it -## Sign-in with EIP-712 +## Caching Signed Queries + +When using "Signed Queries" the blockchain will be queried each time, however +the Sapphire wrapper will cache signatures for signed queries with the same +parameters to avoid asking the user to sign the same thing multiple times. + +Behind the scenes the signed queries use a "leash" to specify validity conditions +so the query can only be performed within a block and account `nonce` range. +These parameters are visible in the EIP-712 popup signed by the user. Queries +with the same parameters will use the same leash. + +## Daily Sign-in with EIP-712 One strategy which can be used to reduce the number of transaction signing prompts when a user interacts with contracts via a dApp is to use From f84db5e2e214db3d4dc7eccaf9f435c4f7a60c58 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 9 Aug 2023 12:51:00 +0100 Subject: [PATCH 09/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index f572af74ba..6a326590e5 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -72,6 +72,7 @@ which created the contract, calling `isOwner` will return: * `false`, with `sapphire.wrap` but without an attached signer * `true`, with `sapphire.wrap` and an attached signer * `true`, if called via the contract which created it +* `true`, if called via transaction ## Caching Signed Queries From 191172bd4f5bff1620c80f2df420bcc982a7e81d Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:18:14 +0100 Subject: [PATCH 10/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 6a326590e5..5cb5786693 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -85,7 +85,7 @@ so the query can only be performed within a block and account `nonce` range. These parameters are visible in the EIP-712 popup signed by the user. Queries with the same parameters will use the same leash. -## Daily Sign-in with EIP-712 +## Daily Sign-In with EIP-712 One strategy which can be used to reduce the number of transaction signing prompts when a user interacts with contracts via a dApp is to use From 25bee5c03bcd49fe0d1cda7cc5fc83ec50a05892 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:18:23 +0100 Subject: [PATCH 11/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 5cb5786693..5380b27d82 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -10,7 +10,7 @@ EVM prevents contracts from revealing confidential information to the wrong party (account or contract) - for this reason we cannot allow arbitrary impersonation of any `msg.sender`. -There are four types of contract calls: +In Sapphire, there are four types of contract calls: 1. Contract to Contract calls (also known as *internal calls*) 2. Unauthenticted view calls (Queries using `eth_call`) From 4161625f824f312084865060e92a6f90e0383ecd Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:18:32 +0100 Subject: [PATCH 12/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 5380b27d82..4a3d6b47d8 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -12,7 +12,7 @@ impersonation of any `msg.sender`. In Sapphire, there are four types of contract calls: - 1. Contract to Contract calls (also known as *internal calls*) + 1. Contract to contract calls (also known as *internal calls*) 2. Unauthenticted view calls (Queries using `eth_call`) 3. Authenticated view calls (Signed Queries) 4. Transactions (authenticated by signature) From bcd2ea3840dbe7d257a8c97fa38549d77bdded47 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:18:40 +0100 Subject: [PATCH 13/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 4a3d6b47d8..5ba95a9a42 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -13,7 +13,7 @@ impersonation of any `msg.sender`. In Sapphire, there are four types of contract calls: 1. Contract to contract calls (also known as *internal calls*) - 2. Unauthenticted view calls (Queries using `eth_call`) + 2. Unauthenticted view calls (queries using `eth_call`) 3. Authenticated view calls (Signed Queries) 4. Transactions (authenticated by signature) From 365c51f7adc70a0933b70b2c6c1a2c57d52510ad Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:18:48 +0100 Subject: [PATCH 14/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 5ba95a9a42..9ad98352c8 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -14,7 +14,7 @@ In Sapphire, there are four types of contract calls: 1. Contract to contract calls (also known as *internal calls*) 2. Unauthenticted view calls (queries using `eth_call`) - 3. Authenticated view calls (Signed Queries) + 3. Authenticated view calls (signed queries) 4. Transactions (authenticated by signature) Intra-contract calls always set `msg.sender` appropriately, if a contract calls From 080447e53ec345f97d894b987542618db83bb2ae Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:18:58 +0100 Subject: [PATCH 15/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 9ad98352c8..e4b3de91a5 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -76,7 +76,7 @@ which created the contract, calling `isOwner` will return: ## Caching Signed Queries -When using "Signed Queries" the blockchain will be queried each time, however +When using signed queries the blockchain will be queried each time, however the Sapphire wrapper will cache signatures for signed queries with the same parameters to avoid asking the user to sign the same thing multiple times. From f6fc78897fdd919b798784afdf8611e5362a0e17 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:19:14 +0100 Subject: [PATCH 16/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index e4b3de91a5..9a13017e57 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -89,7 +89,7 @@ with the same parameters will use the same leash. One strategy which can be used to reduce the number of transaction signing prompts when a user interacts with contracts via a dApp is to use -[EIP-712][eip-712] to "Sign-in" once per day (or per-session), in combination +[EIP-712][eip-712] to "sign-in" once per day (or per-session), in combination with using two wrapped providers: [eip-712]: https://eips.ethereum.org/EIPS/eip-712 From 170ea8973e3055673c12744570e5e53eea7f3e34 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:29:12 +0100 Subject: [PATCH 17/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 9a13017e57..13e017a292 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -22,7 +22,9 @@ another contract in a way which could reveal sensitive information, the calling contract must implement access control or authentication. By default all `eth_call` queries used to invoke contract functions have the -`msg.sender` parameter is set to `address(0x0)`. And when a transaction is +`msg.sender` parameter set to `address(0x0)`. In contrast, authenticated calls are +signed by a keypair and will have the `msg.sender` parameter correctly initialized +(more on that later). Also, when a transaction is submitted it is signed by a keypair (thus costs gas and can make state updates) the `msg.sender` will be set to the signing account. From 8700eb507dffe444c73f42e47bf537743486aa16 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:29:30 +0100 Subject: [PATCH 18/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 13e017a292..2eb2dc0824 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -26,7 +26,7 @@ By default all `eth_call` queries used to invoke contract functions have the signed by a keypair and will have the `msg.sender` parameter correctly initialized (more on that later). Also, when a transaction is submitted it is signed by a keypair (thus costs gas and can make state updates) -the `msg.sender` will be set to the signing account. +and the `msg.sender` will be set to the signing account. ## Sapphire Wrapper From 78381b1870855d9386b052f0e2a52820a48afaab Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:29:54 +0100 Subject: [PATCH 19/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 2eb2dc0824..8c9212fd06 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -30,7 +30,7 @@ and the `msg.sender` will be set to the signing account. ## Sapphire Wrapper -The Ethereum provider wrapper provided by the [@oasisprotocol/sapphire-paratime][sp-npm] +The [@oasisprotocol/sapphire-paratime][sp-npm] Ethereum provider wrapper `sapphire.wrap` function will automatically end-to-end encrypt calldata when interacting with contracts on Sapphire, this is an easy way to ensure the calldata of your dApp transactions remain confidential - although the `from`, From 2fd74abd797193e27014d638dd3a4d87de5ad86e Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:39:54 +0100 Subject: [PATCH 20/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 8c9212fd06..1beeca2ba5 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -31,7 +31,7 @@ and the `msg.sender` will be set to the signing account. ## Sapphire Wrapper The [@oasisprotocol/sapphire-paratime][sp-npm] Ethereum provider wrapper -`sapphire.wrap` function will automatically end-to-end encrypt calldata when +`sapphire.wrap` function will **automatically end-to-end encrypt calldata** when interacting with contracts on Sapphire, this is an easy way to ensure the calldata of your dApp transactions remain confidential - although the `from`, `to`, and `gasprice` parameters are not encrypted. From e83da7066ec39927382ce4c69d3540b2377fcfc9 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:40:11 +0100 Subject: [PATCH 21/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 1beeca2ba5..c476d9690a 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -45,7 +45,7 @@ Although the calls may be unauthenticated, they can still be encrypted! ::: However, if the Sapphire wrapper has been attached to a signer then subsequent -view calls via `eth_call` will be request that the user sign them (e.g. a +view calls via `eth_call` will request that the user signs them (e.g. a MetaMask popup), these are called "Signed Queries" meaning `msg.sender` will be set to the signing account and can be used for authentication or to implement access control. This may add friction to the end-user experience and can result From 49e898a1ed565fc52ce2ec7ec4b904bef41198b3 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:40:21 +0100 Subject: [PATCH 22/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index c476d9690a..07ae147833 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -46,7 +46,7 @@ Although the calls may be unauthenticated, they can still be encrypted! However, if the Sapphire wrapper has been attached to a signer then subsequent view calls via `eth_call` will request that the user signs them (e.g. a -MetaMask popup), these are called "Signed Queries" meaning `msg.sender` will be +MetaMask popup), these are called **signed queries** meaning `msg.sender` will be set to the signing account and can be used for authentication or to implement access control. This may add friction to the end-user experience and can result in frequent pop-ups requesting they sign queries which wouldn't normally require From d5c5f9ad0b32d3a3570fddf8898e8fe2db17585f Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:33:56 +0100 Subject: [PATCH 23/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 07ae147833..159dfde322 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -170,7 +170,7 @@ contract SignInExample { authenticated(auth) returns (bytes memory output) { - // Use `auth.user` instead of `msg.sender` + // Use `auth.user` instead of `msg.sender`! } } ``` From d67b20e06f7ce2a408e5ffd72111ab21aceb8be3 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:34:05 +0100 Subject: [PATCH 24/28] Update docs/dapp/sapphire/authentication.md Co-authored-by: Xi Zhang --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 159dfde322..98bfa25693 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -203,7 +203,7 @@ const rsv = ethers.utils.splitSignature(signature); const auth = {user, time, rsv}; // The `auth` variable can then be cached -// Then in future, authenticated view calls can be performed by +// Then in the future, authenticated view calls can be performed by // passing auth without further user interaction authenticated data await contract.authenticatedViewCall(auth, ...args); ``` \ No newline at end of file From 1e73595c410bc793c7de08d8fbd70b9655133874 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:34:18 +0100 Subject: [PATCH 25/28] Update docs/dapp/sapphire/authentication.md Co-authored-by: Xi Zhang --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 98bfa25693..9e6f49e9b9 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -45,7 +45,7 @@ Although the calls may be unauthenticated, they can still be encrypted! ::: However, if the Sapphire wrapper has been attached to a signer then subsequent -view calls via `eth_call` will request that the user signs them (e.g. a +view calls via `eth_call` will request that the user sign them (e.g. a MetaMask popup), these are called **signed queries** meaning `msg.sender` will be set to the signing account and can be used for authentication or to implement access control. This may add friction to the end-user experience and can result From d2d659146b7bf5f53ed6559bda741bd8696addb6 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:34:28 +0100 Subject: [PATCH 26/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 9e6f49e9b9..8b2230eef3 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -184,7 +184,7 @@ example uses Ethers: const time = new Date().getTime(); const user = await eth.signer.getAddress(); -// Ask user to "Sign-In" every 24 hours +// Ask user to "Sign-In" every 24 hours. const signature = await eth.signer._signTypedData({ name: "SignInExample.SignIn", version: "1", From dba0d024d7bd1989dc90200cc3920c41cbee4995 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:34:36 +0100 Subject: [PATCH 27/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 8b2230eef3..14c9bf0620 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -201,7 +201,7 @@ const signature = await eth.signer._signTypedData({ }); const rsv = ethers.utils.splitSignature(signature); const auth = {user, time, rsv}; -// The `auth` variable can then be cached +// The `auth` variable can then be cached. // Then in the future, authenticated view calls can be performed by // passing auth without further user interaction authenticated data From 915855890dc23b6ad3de70de1c173e0dbba8e672 Mon Sep 17 00:00:00 2001 From: CedarMist <134699267+CedarMist@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:34:47 +0100 Subject: [PATCH 28/28] Update docs/dapp/sapphire/authentication.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matevž Jekovec --- docs/dapp/sapphire/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dapp/sapphire/authentication.md b/docs/dapp/sapphire/authentication.md index 14c9bf0620..218a612549 100644 --- a/docs/dapp/sapphire/authentication.md +++ b/docs/dapp/sapphire/authentication.md @@ -204,6 +204,6 @@ const auth = {user, time, rsv}; // The `auth` variable can then be cached. // Then in the future, authenticated view calls can be performed by -// passing auth without further user interaction authenticated data +// passing auth without further user interaction authenticated data. await contract.authenticatedViewCall(auth, ...args); ``` \ No newline at end of file