diff --git a/README.md b/README.md
index 0d42d411..536b8708 100644
--- a/README.md
+++ b/README.md
@@ -65,7 +65,7 @@ This repository includes all relevant Sapphire and dependencies organized into
the following directories:
- [`clients`](./clients): the Go, Python and JavaScript/TypeScript clients
-- [`contracts`](./contracts): Sapphire and [OPL](https://docs.oasis.io/dapp/opl/) smart contracts
+- [`contracts`](./contracts): Sapphire and [OPL](https://docs.oasis.io/build/opl/) smart contracts
- [`docs`](./docs): topic-oriented Sapphire documentation
- [`examples`](./examples/): sample code snippets in popular Ethereum
development environments
@@ -76,7 +76,7 @@ development environments
## Documentation
The Sapphire documentation is deployed as part of the official
-[Oasis documentation](https://docs.oasis.io/dapp/sapphire/). To make changes
+[Oasis documentation](https://docs.oasis.io/build/sapphire/). To make changes
visible on the docs website:
1. Merge any changes in the `docs` folder to the `main` branch.
diff --git a/clients/go/README.md b/clients/go/README.md
index b7db4857..e8d36a16 100644
--- a/clients/go/README.md
+++ b/clients/go/README.md
@@ -6,7 +6,7 @@
style.
[@oasisprotocol/sapphire-paratime]: https://pkg.go.dev/github.com/oasisprotocol/sapphire-paratime/go/
-[Sapphire ParaTime]: https://docs.oasis.io/dapp/sapphire
+[Sapphire ParaTime]: https://docs.oasis.io/build/sapphire
## Building
@@ -96,5 +96,5 @@ _ = c.SendTransaction(ctx, signedTx)
## See Also
- [Oasis Testnet Faucet](https://faucet.testnet.oasis.io/)
-- [Creating dapps for Sapphire](https://docs.oasis.io/dapp/sapphire/quickstart)
+- [Creating dapps for Sapphire](https://docs.oasis.io/build/sapphire/quickstart)
- [How to Transfer ROSE into an EVM ParaTime](https://docs.oasis.io/general/manage-tokens/how-to-transfer-rose-into-paratime/)
diff --git a/clients/js/README.md b/clients/js/README.md
index dd04d4fd..3093dacd 100644
--- a/clients/js/README.md
+++ b/clients/js/README.md
@@ -11,7 +11,7 @@ The Sapphire wrapper with automatically encrypt the `eth_call`, `eth_estimateGas
and `eth_signTransaction` JSON-RPC calls
[@oasisprotocol/sapphire-paratime]: https://www.npmjs.com/package/@oasisprotocol/sapphire-paratime
-[sapphire paratime]: https://docs.oasis.io/dapp/sapphire/
+[sapphire paratime]: https://docs.oasis.io/build/sapphire/
_If your dapp doesn't port in under 10 minutes, it's a bug!_
If you have more than a little trouble, please file an issue.
@@ -59,5 +59,5 @@ signed queries manually using the `overrides` parameter to `SignedCallDataPack.m
## See Also
- [Oasis Testnet Faucet](https://faucet.testnet.oasis.io/)
-- [Creating dapps for Sapphire](https://docs.oasis.io/dapp/sapphire/quickstart)
+- [Creating dapps for Sapphire](https://docs.oasis.io/build/sapphire/quickstart)
- [How to Transfer ROSE into an EVM ParaTime](https://docs.oasis.io/general/manage-tokens/how-to-transfer-rose-into-paratime/)
diff --git a/contracts/README.md b/contracts/README.md
index 1a55d8c8..364cccd4 100644
--- a/contracts/README.md
+++ b/contracts/README.md
@@ -34,8 +34,8 @@ contract RandomNumber {
## Documentation
-See the user's guide for [Sapphire](https://docs.oasis.io/dapp/sapphire/) and
-[OPL](https://docs.oasis.io/dapp/opl/).
+See the user's guide for [Sapphire](https://docs.oasis.io/build/sapphire/) and
+[OPL](https://docs.oasis.io/build/opl/).
The generated API reference is hosted at
[api.docs.oasis.io](https://api.docs.oasis.io/sol/sapphire-contracts).
diff --git a/docs/README.mdx b/docs/README.mdx
index 62247cf9..6a252286 100644
--- a/docs/README.mdx
+++ b/docs/README.mdx
@@ -19,6 +19,7 @@ crypto gaming
### Getting Started
Develop and deploy a dApp on Sapphire:
+
- follow along with a video walkthrough via [quickstart][quickstart]
- start with a working dApp [demo][demo]
- explore showcase dApps deployed on Sapphire on the [playground][playground]
@@ -29,16 +30,18 @@ Develop and deploy a dApp on Sapphire:
### Understanding EVM compatibility
-Get to know the differences between Sapphire and Ethereum, and learn about
-the high level concepts of developing a confidential smart contract with our
-[guide][guide].
+Get to know the differences between [Sapphire and Ethereum], and learn about
+the high level [concepts] of developing DApps.
-[guide]: ./guide.mdx
+[Sapphire and Ethereum]: ./ethereum.md
+[concepts]: ./build/concept.mdx
### Building on Sapphire
Take your existing dApp building knowledge and add Sapphire with our developer
-[cheatsheet](./images/cheatsheet.pdf).
+[cheatsheet](./images/cheatsheet.pdf) or visit the [build] chapter.
+
+[build]: ./build/README.mdx
### Network Information
@@ -59,5 +62,5 @@ Visit the [faucet][faucet] to obtain testnet tokens for development purposes.
findSidebarItem('/node/run-your-node/paratime-node'),
findSidebarItem('/node/run-your-node/paratime-client-node'),
findSidebarItem('/node/web3'),
- findSidebarItem('/dapp/tools/other-paratimes/'),
+ findSidebarItem('/build/tools/other-paratimes/'),
]} />
diff --git a/docs/build/README.mdx b/docs/build/README.mdx
new file mode 100644
index 00000000..dc39d87e
--- /dev/null
+++ b/docs/build/README.mdx
@@ -0,0 +1,76 @@
+---
+description: Build DApps on Sapphire
+---
+
+# Build
+
+As Sapphire is EVM-compatible, you can use the same dev tooling as you would
+when building on Ethereum. Additionally, we build tools to support you in
+creating secure and confidential DApps.
+
+Feel free to check out the [concept] page to get a better understanding of the
+transaction flow and the contract state.
+
+[concept]: ./concept.mdx
+
+## Contract Development
+
+Sapphire is programmable using any language that targets the EVM, such as Solidity,
+Fe or Vyper. If you prefer to use an Ethereum framework like Hardhat or Foundry,
+you can also use those with Sapphire; all you need to do is set your Web3 gateway URL.
+You can find the details of the Oasis Sapphire Web3 endpoints
+[here](../network.mdx#rpc-endpoints).
+
+
+### Development Environments
+
+- [Build with Hardhat]
+- [Build with Foundry]
+
+[Build with Hardhat]: ./hardhat.md
+[Build with Foundry]: ./foundry.md
+
+### Features
+
+- [Deployment and Proxies][deployment]
+- [Gasless and Onchain Signing][gasless]
+- [Security considerations][security]
+- [View-call authentication][view-call]
+- [Randomness, Subcalls and More Precompiles][sapphire-contracts]
+
+[deployment]: ./deployment.md
+[gasless]: ./gasless.md
+[security]: ./security.md
+[view-call]: ./authentication.md
+[sapphire-contracts]: https://api.docs.oasis.io/sol/sapphire-contracts
+
+## Frontend Development
+
+We support the common frontend libraries:
+
+- [Ethers v6][ethers]
+- [Viem][viem]
+- [Wagmi][wagmi]
+
+[ethers]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/integrations/ethers-v6
+[viem]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/integrations/viem-v2
+[wagmi]:https://github.com/oasisprotocol/sapphire-paratime/tree/main/integrations/wagmi-2
+
+## Backend Development
+
+If you want to connect and execute transactions from your backend, visit our
+[clients] chapter to see what other languages we support
+
+[clients]: clients.md
+
+## Examples
+
+See our [examples] page for demo DApps that bring all the above together.
+
+[examples]: ../examples.mdx
+
+Should you have any questions or ideas to share, feel free to reach out to us
+on [discord and other social media channels][social-media].
+
+[social-media]: https://github.com/oasisprotocol/docs/blob/main/docs/get-involved/README.md#social-media-channels
+
diff --git a/docs/authentication.md b/docs/build/authentication.md
similarity index 99%
rename from docs/authentication.md
rename to docs/build/authentication.md
index a4f61e01..518d31c3 100644
--- a/docs/authentication.md
+++ b/docs/build/authentication.md
@@ -74,7 +74,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
+ * `true`, if called via transaction
## Caching Signed Queries
diff --git a/docs/browser.md b/docs/build/browser.md
similarity index 92%
rename from docs/browser.md
rename to docs/build/browser.md
index a0ec76e1..18b3a018 100644
--- a/docs/browser.md
+++ b/docs/build/browser.md
@@ -44,12 +44,11 @@ access them!**
The contract in the Hardhat boilerplate is ERC-20-compatible and emits the
`transfer` event. If your wish to preserve confidentiality, you can comment
-out [line 66]. Read [the guide](guide.mdx#contract-logs) to learn more.
+out [line 66]. Read the [concept] chapter to learn more.
:::
-[`wagmi`]: https://wagmi.sh/
-[`viem`]: https://viem.sh/
+[concept]: ./concept.mdx#contract-logs
## Signing Sapphire Calls and Transactions in Browser
@@ -155,7 +154,7 @@ npm run start
If all goes well the web server will spin up and your browser should
automatically open `http://localhost:3000`.
-![Hardhat boilerplate frontend](images/hardhat-boilerplate-frontend1.png)
+![Hardhat boilerplate frontend](../images/hardhat-boilerplate-frontend1.png)
Go ahead and connect the wallet. If you haven't done it yet, you will have
to add the [Sapphire ParaTime Testnet network to your
@@ -163,13 +162,13 @@ Metamask][sapphire-testnet]. Once connected, the frontend will make an unsigned
call to the `balanceOf` view and show you the amount of `MHT`s in your selected
Metamask account.
-![MHT balance of your account](images/hardhat-boilerplate-frontend2.png)
+![MHT balance of your account](../images/hardhat-boilerplate-frontend2.png)
Next, let's transfer some `MHT`s. Fill in the amount, the address and hit the
*Transfer* button. Metamask will show you the popup to sign and submit the
transfer transaction. Once confirmed, Metamask will both **sign and encrypt** the transaction.
-![Sign and encrypt the transfer transaction](images/hardhat-boilerplate-frontend3.png)
+![Sign and encrypt the transfer transaction](../images/hardhat-boilerplate-frontend3.png)
Once the transaction is processed, you will get a notification from Metamask
and the balance in the dApp will be updated.
@@ -207,14 +206,13 @@ we recommend that you check out the official [Oasis starter] files.
:::
[block explorer]: https://explorer.oasis.io/testnet/sapphire/tx/0x3303dea5d48291d1564cad573f21fc71fcbdc2b862e17e056287fd9207e3bc53
-[guide-transaction-calls]: guide.mdx#transactions--calls
+[guide-transaction-calls]: ./concept.mdx#transactions--calls
[Hardhat boilerplate repo]: https://github.com/NomicFoundation/hardhat-boilerplate
[Hardhat boilerplate]: https://hardhat.org/tutorial/boilerplate-project
-[Hardhat tutorial]: https://hardhat.org/tutorial
[line 66]: https://github.com/NomicFoundation/hardhat-boilerplate/blob/13bd712c1285b2de572f14d20e6a750ae08565c0/contracts/Token.sol#L66
-[quickstart]: quickstart.mdx#add-the-sapphire-testnet-to-hardhat
-[sapphire-testnet]: ./network.mdx#rpc-endpoints
+[quickstart]: ../quickstart.mdx#add-the-sapphire-testnet-to-hardhat
+[sapphire-testnet]: ../network.mdx#rpc-endpoints
[Sapphire ParaTime examples]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/examples/hardhat-boilerplate
[social-media]: https://github.com/oasisprotocol/docs/blob/main/docs/get-involved/README.md#social-media-channels
[pnpm]: https://pnpm.io
-[TEST tokens]: quickstart.mdx#get-some-sapphire-testnet-tokens
+[TEST tokens]: ../quickstart.mdx#get-some-sapphire-testnet-tokens
diff --git a/docs/build/clients.md b/docs/build/clients.md
new file mode 100644
index 00000000..e9b0335d
--- /dev/null
+++ b/docs/build/clients.md
@@ -0,0 +1,15 @@
+---
+description: Different clients of Sapphire
+---
+
+# Clients
+
+Sapphire has three clients in different programming languages:
+
+- Sapphire [JS]
+- Sapphire [Go]
+- Sapphire [Py]
+
+[JS]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/clients/js/README.md
+[Go]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/clients/go/README.md
+[Py]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/clients/py/README.md
diff --git a/docs/build/concept.mdx b/docs/build/concept.mdx
new file mode 100644
index 00000000..b0567865
--- /dev/null
+++ b/docs/build/concept.mdx
@@ -0,0 +1,100 @@
+---
+description: Sapphire concepts
+---
+
+import DocCard from '@theme/DocCard';
+import {findSidebarItem} from '@site/src/sidebarUtils';
+
+# Concept
+
+### Transactions & Calls
+
+{/*-- https://github.com/oasisprotocol/docs/blob/455980674563cad92ff1e1b62a7a5f2d4d6809f0/docs/general/images/architecture/client-km-compute.svg -->*/}
+![Client, Key Manager, Compute Node diagram](../../../general/images/architecture/client-km-compute.svg)
+
+The figure above illustrates the flow of a **confidential smart contract
+transaction** on Sapphire.
+
+Transactions and calls must be encrypted and signed for maximum security.
+The [@oasisprotocol/sapphire-paratime] npm package will make your life
+easy. It'll handle cryptography and signing for you.
+
+You should be aware that taking actions based on the value of private data may
+**leak the private data through side channels** like time spent, gas use and
+accessed memory locations. If you need to branch on private data, you should in
+most cases ensure that both branches exhibit the same time/gas and storage
+patterns.
+
+You can also make **confidential smart contract calls** on Sapphire. If you
+use `msg.sender` for access control in your contract, the call **must be
+signed**, otherwise `msg.sender` will be zeroed. On the other hand, set the
+`from` address to all zeros, if you want to avoid annoying signature popups in
+the user's wallet for calls that do not need to be signed. The JS library will
+do this for you.
+
+:::note
+
+Inside the smart contract code, there is no way of knowing whether the
+client's call data were originally encrypted or not.
+
+:::
+
+
+ Detailed confidential smart contract transaction flow on Sapphire
+
+![Diagram of the detailed confidential smart contract transaction flow on Sapphire](../diagrams/c10l-smart-contract-tx.mmd.svg)
+
+
+
+
+ Detailed confidential smart contract call flow on Sapphire
+
+![Diagram of the detailed confidential smart contract call flow on Sapphire](../diagrams/c10l-smart-contract-call.mmd.svg)
+
+
+
+### Contract State
+
+The Sapphire state model is like Ethereum's except for all state being encrypted
+and not accessible to anyone except the contract. The contract, executing in an
+active (attested) Oasis compute node is the only entity that can request its
+state encryption key from the Oasis key manager. Both the keys and values of the
+items stored in state are encrypted, but the **size of either is not hidden**. Your
+app may need to pad state items to a constant length, or use other obfuscation.
+Observers may also be able to infer computation based on storage access patterns,
+so you may need to obfuscate that, too. See [Security chapter] for more
+recommendations.
+
+[Security chapter]: ./security.md#storage-access-patterns
+
+:::danger Contract state leaks a fine-grained access pattern
+
+Contract state is backed by an encrypted key-value store. However, the trace of
+encrypted records is leaked to the compute node. As a concrete example, an ERC-20
+token transfer would leak which encrypted record is for the sender's account
+balance and which is for the receiver's account balance. Such a token would be
+traceable from sender address to receiver address. Obfuscating the storage access
+patterns may be done by using an ORAM implementation.
+
+:::
+
+Contract state may be made available to third parties through logs/events, or
+explicit getters.
+
+### Contract Logs
+
+Contract logs/events (e.g., those emitted by the Solidity `emit` keyword)
+are exactly like Ethereum. Data contained in events is *not* encrypted.
+Precompiled contracts are available to help you encrypt data that you can
+then pack into an event, however.
+
+:::danger Unmodified contracts may leak state through logs
+
+Base contracts like those provided by OpenZeppelin often emit logs containing
+private information. If you don't know they're doing that, you might undermine
+the confidentiality of your state. As a concrete example, the ERC-20 spec
+requires implementers to emit an `event Transfer(from, to, amount)`, which is
+obviously problematic if you're writing a confidential token. What you can
+do instead is fork that contract and remove the offending emissions.
+
+:::
diff --git a/docs/deployment.md b/docs/build/deployment.md
similarity index 100%
rename from docs/deployment.md
rename to docs/build/deployment.md
diff --git a/docs/build/foundry.md b/docs/build/foundry.md
new file mode 100644
index 00000000..bb14e68b
--- /dev/null
+++ b/docs/build/foundry.md
@@ -0,0 +1,21 @@
+---
+description: Use Sapphire with Foundry
+---
+
+# Foundry
+
+:::caution Under Construction
+
+This page is **under construction**. Content may be incomplete or subject to
+change.
+
+:::
+
+Foundry is a fast, portable, and modular framework designed to streamline
+Solidity development and testing by providing a robust set of tools for
+compiling, deploying, and verifying smart contracts.
+
+If you’re hearing about Foundry for the first time, make sure to check out the
+official [Foundry documentation].
+
+[Foundry documentation]: https://book.getfoundry.sh/
diff --git a/docs/gasless.md b/docs/build/gasless.md
similarity index 98%
rename from docs/gasless.md
rename to docs/build/gasless.md
index 0a1cbf91..09e7a9d9 100644
--- a/docs/gasless.md
+++ b/docs/build/gasless.md
@@ -40,7 +40,7 @@ checks whether the transaction is valid, wraps it into a meta-transaction
in [EIP-155] format. These steps are executed as a confidential call. Finally,
the user submits the generated transaction to the network.
-![Diagram of the On-Chain Signing](images/gasless-on-chain-signer.svg)
+![Diagram of the On-Chain Signing](../images/gasless-on-chain-signer.svg)
### EIP155Signer
@@ -258,7 +258,6 @@ creators can close the poll.
[demo-voting]: https://github.com/oasisprotocol/demo-voting
[demo-voting-playground]: https://playground.oasis.io/demo-voting
-[dao-opl]: https://github.com/oasisprotocol/docs/blob/main/docs/dapp/opl/host.md
[EIP-155]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
## Gas Station Network
@@ -267,7 +266,7 @@ creators can close the poll.
Sapphire in a forked `@oasislabs/opengsn-cli` package. The diagram below
illustrates a flow for signing a transaction by using a GSN[^1].
-![Diagram of the Gas Station Network Flow](images/gasless-gsn-flow.jpg)
+![Diagram of the Gas Station Network Flow](../images/gasless-gsn-flow.jpg)
[^1]: The GSN flow diagram is courtesy of [OpenGSN documentation][opengsn-docs].
@@ -361,6 +360,7 @@ requests and forward them to the relay hub on Sapphire Testnet.
We can test whether a relayed request can be forwarded and processed correctly.
Scroll up to find the GSN deployment response and use the following parameters:
+
- `Forwarder` as `--to`,
- `Paymaster` as `--paymaster`,
- your account address as `--from`
diff --git a/docs/build/hardhat.md b/docs/build/hardhat.md
new file mode 100644
index 00000000..02d295d1
--- /dev/null
+++ b/docs/build/hardhat.md
@@ -0,0 +1,109 @@
+---
+description: Use Sapphire with hardhat
+---
+
+# Hardhat
+
+Hardhat is a versatile development environment for Ethereum, designed to
+streamline tasks like compiling, testing, and deploying smart contracts. It
+offers a modular toolkit and an intuitive workflow that helps developers focus
+on building robust decentralized applications.
+
+If you’re reading about Hardhat for the first time, be sure to explore the
+official [Hardhat documentation] for more in-depth information.
+
+[Hardhat documentation]: https://hardhat.org/docs
+
+## Quickstart
+
+Our [Quickstart] chapter is the best way to start building on Oasis Sapphire.
+It guides you through setting up your environment and deploying your first
+contract using Hardhat. You'll quickly learn the basics of Hardhat while
+exploring Sapphire's privacy-preserving features.
+
+Check out the [Quickstart] to begin your journey!
+
+## Local Development and Testing
+
+For local development and testing, Oasis provides a Docker container that
+simulates the Sapphire blockchain. This setup works similarly to the Hardhat
+Node, allowing you to interact with a local instance of the Sapphire ParaTime
+for fast, iterative development.
+
+To learn how to set up and use the local Sapphire environment, check out the
+[Localnet] chapter under the Tools section of the documentation. It provides
+detailed instructions on configuring and running the local blockchain, making
+it easy to test and debug your contracts before deploying them to a live
+network.
+
+### Localnet Hardhat config
+
+To use the Localnet with Hardhat, add the network as follows:
+
+```js title="hardhat.config.ts"
+ import { HardhatUserConfig } from "hardhat/config";
+ import "@nomicfoundation/hardhat-toolbox";
+
+ //accounts script
+const TEST_HDWALLET = {
+ mnemonic: "test test test test test test test test test test test junk",
+ path: "m/44'/60'/0'/0",
+ initialIndex: 0,
+ count: 20,
+ passphrase: "",
+};
+const accounts = process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : TEST_HDWALLET;
+
+ const config: HardhatUserConfig = {
+ solidity: "0.8.19",
+ // highlight-start
+ networks: {
+ 'sapphire-localnet': {
+ url: "http://localhost:8545", // Localnet RPC URL
+ chainId: 23294, // Sapphire Localnet chain ID
+ accounts
+ },
+ },
+ // highlight-end
+ };
+```
+
+You can now use the standard test accounts to run your Hardhat tests:
+
+ ```shell
+npx hardhat test --network sapphire-localnet
+```
+
+## Hardhat Provider
+
+The `@oasisprotocol/sapphire-hardhat` package provides a custom Hardhat
+provider that enables encrypted transactions when working with Oasis Sapphire.
+This makes it easy to test and run tasks involving confidential smart contracts
+directly within your Hardhat setup.
+
+### Installation
+
+To add the provider to your project, run:
+
+ ```shell npm2yarn
+ npm install -D @oasisprotocol/sapphire-hardhat
+ ```
+
+Next, import it in your `hardhat.config.ts` above the rest of your plugins so
+that the provider gets wrapped before anything else starts to use it.
+
+```js
+// ESM
+import '@oasisprotocol/sapphire-hardhat';
+
+// CommonJS
+require('@oasisprotocol/sapphire-hardhat');
+
+/** All other plugins must go below this one! **/
+```
+
+The Hardhat Ethers provider is now wrapped for Sapphire and will encrypt your
+transactions on use.
+
+[Quickstart]: ../quickstart.mdx
+[Localnet]: https://github.com/oasisprotocol/docs/blob/main/docs/build/tools/localnet.mdx
diff --git a/docs/security.md b/docs/build/security.md
similarity index 100%
rename from docs/security.md
rename to docs/build/security.md
diff --git a/docs/ethereum.md b/docs/ethereum.md
new file mode 100644
index 00000000..da872204
--- /dev/null
+++ b/docs/ethereum.md
@@ -0,0 +1,89 @@
+---
+description: Differences to Ethereum
+---
+
+# Sapphire vs Ethereum
+
+Sapphire is generally compatible with Ethereum, the EVM, and all the user and
+developer tooling that you are used to. In addition to confidentiality
+features, you get a few extra benefits including the ability to **generate
+private entropy**, and **make signatures on-chain**. An example of a dApp that
+uses both is an HSM contract that generates an Ethereum wallet and signs
+transactions sent to it via transactions.
+
+There are also a few breaking changes compared to Ethereum though, but we think
+that you'll quickly grasp them:
+
+ - [Encrypted Contract State](#encrypted-contract-state)
+ - [End-to-End Encrypted Transactions and Calls](#end-to-end-encrypted-transactions-and-calls)
+ - [`from` Address is Zero for Unsigned Calls](#from-address-is-zero-for-unsigned-calls)
+ - [Override `receive` and `fallback` when Funding the Contract](#override-receive-and-fallback-when-funding-the-contract)
+ - [Instant Finality](#instant-finality)
+
+Read below to learn more about them. Otherwise, Sapphire is like Emerald, a
+fast, cheap Ethereum.
+
+## Encrypted Contract State
+
+The contract state is only visible to the contract that wrote it. With respect
+to the contract API, it's as if all state variables are declared as `private`,
+but with the further restriction that not even full nodes can read the values.
+Public or access-controlled values are provided instead through explicit
+getters.
+
+Calling `eth_getStorageAt()` will return zero.
+
+## End-to-End Encrypted Transactions and Calls
+
+Transactions and calls are end-to-end encrypted into the contract. Only the
+caller and the contract can see the data sent to/received from the ParaTime.
+This ends up defeating some utility of block explorers, however.
+
+The status of the transaction is public and so are the error code, the revert
+message and logs (emitted events).
+
+## `from` Address is Zero for Unsigned Calls
+
+The `from` address using of calls is derived from a signature attached to the
+call. Unsigned calls have their sender set to the zero address. This allows
+contract authors to write getters that release secrets to authenticated callers
+(e.g. by checking the `msg.sender` value), but without requiring a transaction
+to be posted on-chain.
+
+## Override `receive` and `fallback` when Funding the Contract
+
+In Ethereum, you can fund a contract by sending Ether along the transaction in
+two ways:
+
+1. a transaction must call a *payable* function in the contract, or
+2. not calling any specific function (i.e. empty *calldata*). In this case,
+ the payable `receive()` and/or `fallback()` functions need to be defined in
+ the contract. If no such functions exist, the transaction will revert.
+
+The behavior described above is the same in Sapphire when using EVM transactions
+to fund a contract.
+
+However, the Oasis Network also uses [Oasis-native transactions] such as a
+deposit to a ParaTime account or a transfer. In this case, **you will be able to
+fund the contract's account even though the contract may not implement payable
+`receive()` or `fallback()`!** Or, if these functions do exist, **they will not
+be triggered**. You can send such Oasis-native transactions by using the [Oasis
+CLI] for example.
+
+[Oasis-native transactions]: https://github.com/oasisprotocol/docs/blob/main/docs/general/manage-tokens/README.mdx
+[Oasis CLI]: https://github.com/oasisprotocol/cli/blob/master/docs/README.md
+
+## Instant Finality
+
+The Oasis Network is a proof of stake network where 2/3+ of the validator nodes
+need to verify each block in order to consider it final. However, in Ethereum
+the signatures of those validator nodes can be submitted minutes after the block
+is proposed, which makes the block proposal mechanism independent of the
+validation, but adds uncertainty if and when will the proposed block actually be
+finalized.
+
+In the Oasis Network, the 2/3+ of signatures need to be provided immediately
+after the block is proposed and **the network will halt, until the required
+number signatures are provided**. This means that you can rest assured that any
+validated block is final. As a consequence, the cross-chain bridges are more
+responsive yet safe on the Oasis Network.
diff --git a/docs/examples.mdx b/docs/examples.mdx
new file mode 100644
index 00000000..6d2e93ff
--- /dev/null
+++ b/docs/examples.mdx
@@ -0,0 +1,54 @@
+---
+description: Examples build with Sapphire
+---
+
+# Examples
+
+## Randomness
+
+:::info [Example Oasis Swag Wheel][rng-example]
+
+[Example dapp][rng-example] which uses onchain RNG to determine which Swag a participant wins.
+
+:::
+
+## Confidential Voting
+
+:::info [Example VoTEE][votee-example]
+
+[Voting example][votee-example] to vote for the favorite Oasis mascot, see also [voTEE.oasis.io].
+
+:::
+
+:::info [Example Blockvote][voting-example]
+
+[Example][voting-example] for general confidential and gasless voting, see also [vote.oasis.io].
+
+:::
+
+## SIWE
+
+:::info [Example SIWE][siwe-example]
+
+Sign in with Ethereum (SIWE) [example dapp][siwe-example].
+
+:::
+
+## Onchain signing
+
+:::info [Example Onchain signing][onchain-signer]
+
+Onchain transaction generation and signing [example][onchain-signer].
+
+:::
+
+Find more examples on [playground.oasis.io].
+
+[rng-example]: https://github.com/oasisprotocol/demo-oasisswag
+[voting-example]: https://github.com/oasisprotocol/dapp-blockvote
+[vote.oasis.io]: https://vote.oasis.io
+[votee-example]: https://github.com/oasisprotocol/dapp-votee
+[voTEE.oasis.io]: https://votee.oasis.io
+[siwe-example]: https://github.com/oasisprotocol/demo-starter/tree/matevz/sapphire-paratime-2.0
+[onchain-signer]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/examples/onchain-signer
+[playground.oasis.io]: https://playground.oasis.io
diff --git a/docs/guide.mdx b/docs/guide.mdx
deleted file mode 100644
index 7fe58204..00000000
--- a/docs/guide.mdx
+++ /dev/null
@@ -1,291 +0,0 @@
----
-description: Guide to creating secure dApps on Sapphire
----
-
-import DocCard from '@theme/DocCard';
-import {findSidebarItem} from '@site/src/sidebarUtils';
-
-# Guide
-
-This page mainly describes the differences between Sapphire and Ethereum
-since there are a number of excellent tutorials on developing for Ethereum.
-If you don't know where to begin, the [Hardhat tutorial] and the
-[Solidity docs] are great places to start. You can continue following this
-guide once you've set up your development environment and have deployed your
-contract to a non-confidential EVM network (e.g. Sepolia).
-
-
-[Hardhat tutorial]: https://hardhat.org/tutorial
-[Solidity docs]: https://docs.soliditylang.org/en/v0.8.15/solidity-by-example.html
-
-## Oasis Consensus Layer and Sapphire ParaTime
-
-The Oasis Network consists of the consensus layer and a number of ParaTimes.
-ParaTimes are independent replicated state machines that settle transactions
-using the consensus layer (to learn more, check the [Oasis Network
-Overview][overview chapter]). Sapphire is a ParaTime which implements the
-Ethereum Virtual Machine (EVM).
-
-The minimum and also expected block time in Sapphire is **6 seconds**. Any
-Sapphire transaction will require at least this amount of time to be executed,
-and probably no more.
-
-ParaTimes, Sapphire included, are not allowed to directly access your tokens
-stored in consensus layer accounts. You will need to _deposit_ tokens from your
-consensus account to Sapphire. Consult the [Manage your
-Tokens][how-to-deposit-rose] chapter to learn more.
-
-
-[overview chapter]: https://github.com/oasisprotocol/docs/blob/main/docs/general/oasis-network/README.mdx
-[how-to-deposit-rose]: https://github.com/oasisprotocol/docs/blob/main/docs/general/manage-tokens/README.mdx#rose-and-the-paratimes
-[Testnet faucet]: https://faucet.testnet.oasis.io/
-
-## Testnet and Mainnet
-
-Sapphire is deployed on Testnet and Mainnet chains. Testnet should be
-considered unstable software and may also have its state wiped at any time. As
-the name implies, only use Testnet for testing unless you're testing how
-angry your users get when state is wiped.
-
-:::danger Never deploy production services on Testnet
-
-Because Testnet state can be wiped in the future, you should **never** deploy a
-production service on Testnet! Just don't do it!
-
-Also note that while Testnet does use proper TEEs, due to experimental
-software and different security parameters, **confidentiality of Sapphire on
-Testnet is not guaranteed** -- all transactions and state published on the
-Sapphire Testnet should be considered public.
-
-:::
-
-:::tip
-
-For testing purposes, visit our [Testnet faucet] to obtain some TEST which you
-can then use on the Sapphire Testnet to pay for gas fees. The faucet supports
-sending TEST both to your consensus layer address or to your address inside the
-ParaTime.
-
-:::
-
-[network-parameters]: https://github.com/oasisprotocol/docs/blob/main/docs/node/mainnet/README.md
-[Testnet]: https://github.com/oasisprotocol/docs/blob/main/docs/node/testnet/README.md
-
-## Localnet
-
-For development and testing, you can run a local [instance][localnet] of the
-entire Sapphire stack.
-
-[localnet]: https://github.com/oasisprotocol/docs/blob/main/docs/dapp/tools/localnet.mdx
-
-## Sapphire vs Ethereum
-
-Sapphire is generally compatible with Ethereum, the EVM, and all the user and
-developer tooling that you are used to. In addition to confidentiality
-features, you get a few extra benefits including the ability to **generate
-private entropy**, and **make signatures on-chain**. An example of a dApp that
-uses both is an HSM contract that generates an Ethereum wallet and signs
-transactions sent to it via transactions.
-
-There are also a few breaking changes compared to Ethereum though, but we think
-that you'll quickly grasp them:
-
-- [Encrypted Contract State](#encrypted-contract-state)
-- [End-to-End Encrypted Transactions and Calls](#end-to-end-encrypted-transactions-and-calls)
-- [`from` Address is Zero for Unsigned Calls](#from-address-is-zero-for-unsigned-calls)
-- [Override `receive` and `fallback` when Funding the Contract](#override-receive-and-fallback-when-funding-the-contract)
-- [Instant Finality](#instant-finality)
-
-Read below to learn more about them. Otherwise, Sapphire is like Emerald, a
-fast, cheap Ethereum.
-
-### Encrypted Contract State
-
-The contract state is only visible to the contract that wrote it. With respect
-to the contract API, it's as if all state variables are declared as `private`,
-but with the further restriction that not even full nodes can read the values.
-Public or access-controlled values are provided instead through explicit
-getters.
-
-Calling `eth_getStorageAt()` will return zero.
-
-### End-to-End Encrypted Transactions and Calls
-
-Transactions and calls are end-to-end encrypted into the contract. Only the
-caller and the contract can see the data sent to/received from the ParaTime.
-This ends up defeating some utility of block explorers, however.
-
-The status of the transaction is public and so are the error code, the revert
-message and logs (emitted events).
-
-### `from` Address is Zero for Unsigned Calls
-
-The `from` address using of calls is derived from a signature attached to the
-call. Unsigned calls have their sender set to the zero address. This allows
-contract authors to write getters that release secrets to authenticated callers
-(e.g. by checking the `msg.sender` value), but without requiring a transaction
-to be posted on-chain.
-
-### Override `receive` and `fallback` when Funding the Contract
-
-In Ethereum, you can fund a contract by sending Ether along the transaction in
-two ways:
-
-1. a transaction must call a *payable* function in the contract, or
-2. not calling any specific function (i.e. empty *calldata*). In this case,
- the payable `receive()` and/or `fallback()` functions need to be defined in
- the contract. If no such functions exist, the transaction will revert.
-
-The behavior described above is the same in Sapphire when using EVM transactions
-to fund a contract.
-
-However, the Oasis Network also uses [Oasis-native transactions] such as a
-deposit to a ParaTime account or a transfer. In this case, **you will be able to
-fund the contract's account even though the contract may not implement payable
-`receive()` or `fallback()`!** Or, if these functions do exist, **they will not
-be triggered**. You can send such Oasis-native transactions by using the [Oasis
-CLI] for example.
-
-[Oasis-native transactions]: https://github.com/oasisprotocol/docs/blob/main/docs/general/manage-tokens/README.mdx
-[Oasis CLI]: https://github.com/oasisprotocol/cli/blob/master/docs/README.md
-
-### Instant Finality
-
-The Oasis Network is a proof of stake network where 2/3+ of the validator nodes
-need to verify each block in order to consider it final. However, in Ethereum
-the signatures of those validator nodes can be submitted minutes after the block
-is proposed, which makes the block proposal mechanism independent of the
-validation, but adds uncertainty if and when will the proposed block actually be
-finalized.
-
-In the Oasis Network, the 2/3+ of signatures need to be provided immediately
-after the block is proposed and **the network will halt, until the required
-number signatures are provided**. This means that you can rest assured that any
-validated block is final. As a consequence, the cross-chain bridges are more
-responsive yet safe on the Oasis Network.
-
-## Integrating Sapphire
-
-Once ROSE tokens are [deposited into Sapphire][how-to-deposit-rose], it should
-be painless for users to begin using dApps. To achieve this ideal user
-experience, we have to modify the dApp a little, but it's made simple by our
-compatibility library, [@oasisprotocol/sapphire-paratime].
-
-There are compatibility layers in other languages, which may be found in [the repo].
-
-[@oasisprotocol/sapphire-paratime]: https://www.npmjs.com/package/@oasisprotocol/sapphire-paratime
-[the repo]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/clients
-
-## Writing Secure dApps
-
-### Wallets
-
-Sapphire is compatible with popular self-custodial wallets including MetaMask,
-Ledger, Brave, and so forth. You can also use libraries like Ethers, Viem, and Wagmi
-to create programmatic wallets. In general, if it generates secp256k1 signatures,
-it'll work just fine.
-
-### Languages & Frameworks
-
-Sapphire is programmable using any language that targets the EVM, such as Solidity,
-Fe or Vyper. If you prefer to use an Ethereum framework like Hardhat or Foundry,
-you can also use those with Sapphire; all you need to do is set your Web3 gateway URL.
-You can find the details of the Oasis Sapphire Web3 endpoints
-[here](https://github.com/oasisprotocol/docs/blob/main/docs/dapp/sapphire/network.mdx#rpc-endpoints).
-
-### Transactions & Calls
-
-
-![Client, Key Manager, Compute Node diagram](../../general/images/architecture/client-km-compute.svg)
-
-The figure above illustrates the flow of a **confidential smart contract
-transaction** on Sapphire.
-
-Transactions and calls must be encrypted and signed for maximum security.
-The [@oasisprotocol/sapphire-paratime] npm package will make your life
-easy. It'll handle cryptography and signing for you.
-
-You should be aware that taking actions based on the value of private data may
-**leak the private data through side channels** like time spent, gas use and
-accessed memory locations. If you need to branch on private data, you should in
-most cases ensure that both branches exhibit the same time/gas and storage
-patterns.
-
-You can also make **confidential smart contract calls** on Sapphire. If you
-use `msg.sender` for access control in your contract, the call **must be
-signed**, otherwise `msg.sender` will be zeroed. On the other hand, set the
-`from` address to all zeros, if you want to avoid annoying signature popups in
-the user's wallet for calls that do not need to be signed. The JS library will
-do this for you.
-
-:::note
-
-Inside the smart contract code, there is no way of knowing whether the
-client's call data were originally encrypted or not.
-
-:::
-
-
- Detailed confidential smart contract transaction flow on Sapphire
-
-![Diagram of the detailed confidential smart contract transaction flow on Sapphire](diagrams/c10l-smart-contract-tx.mmd.svg)
-
-
-
-
- Detailed confidential smart contract call flow on Sapphire
-
-![Diagram of the detailed confidential smart contract call flow on Sapphire](diagrams/c10l-smart-contract-call.mmd.svg)
-
-
-
-### Contract State
-
-The Sapphire state model is like Ethereum's except for all state being encrypted
-and not accessible to anyone except the contract. The contract, executing in an
-active (attested) Oasis compute node is the only entity that can request its
-state encryption key from the Oasis key manager. Both the keys and values of the
-items stored in state are encrypted, but the **size of either is not hidden**. Your
-app may need to pad state items to a constant length, or use other obfuscation.
-Observers may also be able to infer computation based on storage access patterns,
-so you may need to obfuscate that, too. See [Security chapter] for more
-recommendations.
-
-[Security chapter]: ./security.md#storage-access-patterns
-
-:::danger Contract state leaks a fine-grained access pattern
-
-Contract state is backed by an encrypted key-value store. However, the trace of
-encrypted records is leaked to the compute node. As a concrete example, an ERC-20
-token transfer would leak which encrypted record is for the sender's account
-balance and which is for the receiver's account balance. Such a token would be
-traceable from sender address to receiver address. Obfuscating the storage access
-patterns may be done by using an ORAM implementation.
-
-:::
-
-Contract state may be made available to third parties through logs/events, or
-explicit getters.
-
-### Contract Logs
-
-Contract logs/events (e.g., those emitted by the Solidity `emit` keyword)
-are exactly like Ethereum. Data contained in events is *not* encrypted.
-Precompiled contracts are available to help you encrypt data that you can
-then pack into an event, however.
-
-:::danger Unmodified contracts may leak state through logs
-
-Base contracts like those provided by OpenZeppelin often emit logs containing
-private information. If you don't know they're doing that, you might undermine
-the confidentiality of your state. As a concrete example, the ERC-20 spec
-requires implementers to emit an `event Transfer(from, to, amount)`, which is
-obviously problematic if you're writing a confidential token. What you can
-do instead is fork that contract and remove the offending emissions.
-
-:::
-
-## See also
-
-
-
diff --git a/docs/network.mdx b/docs/network.mdx
index 88b005b3..1403ef1a 100644
--- a/docs/network.mdx
+++ b/docs/network.mdx
@@ -15,9 +15,20 @@ import {AddSapphireToMetaMask as S, AddSapphireTestnetToMetaMask as ST} from '@s
| Chain ID | Hex:`0x5afe`
Decimal: `23294` | Hex:`0x5aff`
Decimal: `23295` | Hex:`0x5afd`
Decimal: `23293` |
| Tools | | [Testing token Faucet][faucet] | [Local development Docker image][localnet] |
+:::danger Never deploy production services on Testnet
+
+Because Testnet state can be wiped in the future, you should **never** deploy a
+production service on Testnet! Just don't do it!
+
+Also note that while Testnet does use proper TEEs, due to experimental
+software and different security parameters, **confidentiality of Sapphire on
+Testnet is not guaranteed** -- all transactions and state published on the
+Sapphire Testnet should be considered public.
+
+:::
[faucet]: https://faucet.testnet.oasis.io/
-[localnet]: https://github.com/oasisprotocol/docs/blob/main/docs/dapp/tools/localnet.mdx
+[localnet]: https://github.com/oasisprotocol/docs/blob/main/docs/build/tools/localnet.mdx
## RPC Endpoints
@@ -62,7 +73,7 @@ dedicated RPC endpoints, consider the following providers (in alphabetic order):
| Name (Provider) | Mainnet URL | Testnet URL | EIP-3091 compatible |
|-----------------------------------------------|--------------------------------------------|--------------------------------------------|---------------------|
-| Oasis Explorer ([Oasis Protocol Foundation]) | https://explorer.oasis.io/mainnet/sapphire | https://explorer.oasis.io/testnet/sapphire | Yes |
+| Oasis Explorer ([Oasis Protocol Foundation]) | `https://explorer.oasis.io/mainnet/sapphire` | `https://explorer.oasis.io/testnet/sapphire` | Yes |
| Oasis Scan ([Bit Cat]) | [https://www.oasisscan.com/paratimes/000…279](https://www.oasisscan.com/paratimes/000000000000000000000000000000000000000000000000f80306c9858e7279) | [https://testnet.oasisscan.com/paratimes/000…f6c](https://testnet.oasisscan.com/paratimes/000000000000000000000000000000000000000000000000a6d1e3ebf60dff6c) | No |
[Bit Cat]: https://www.bitcat365.com/
diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx
index 234934ee..36368bb7 100644
--- a/docs/quickstart.mdx
+++ b/docs/quickstart.mdx
@@ -26,7 +26,7 @@ One simple-but-useful dApp that takes advantage of confidentiality is a
data trove) if the operator fails to re-up before too long.
Let's make it happen!
-[higher level of security]: guide.mdx#writing-secure-dapps
+[higher level of security]: ./build/README.mdx
[dead person's switch]: https://en.wikipedia.org/wiki/Dead_man%27s_switch
### Init a new Hardhat project
@@ -154,9 +154,9 @@ The secret ingredient is brussels sprouts
## All done!
-Congratulations, you made it through the Sapphire tutorial! If you have any
-questions, please check out the [guide] and join the discussion on the
-[#sapphire-paratime Discord channel][social-media].
+Congratulations, you made it through the Sapphire tutorial! If you want to dive
+deeper, please check out the [build] chapter and join the discussion on the
+[#dev-central Discord channel][social-media].
Best of luck on your future forays into confidentiality!
@@ -188,11 +188,11 @@ official [Oasis starter project for Go] and the [Oasis starter project for Pytho
## See also
-
+
[social-media]: https://github.com/oasisprotocol/docs/blob/main/docs/get-involved/README.md#social-media-channels
-[guide]: guide.mdx
+[build]: ./build/README.mdx
[hardhat-example]: https://github.com/oasisprotocol/sapphire-paratime/blob/stable/clients/js/1.x/examples/hardhat
[`@oasisprotocol/sapphire-hardhat`]: https://www.npmjs.com/package/@oasisprotocol/sapphire-hardhat