Skip to content
This repository has been archived by the owner on Nov 11, 2022. It is now read-only.

Commit

Permalink
docs updates
Browse files Browse the repository at this point in the history
  • Loading branch information
corbanvilla committed Apr 25, 2022
1 parent 3f4d0e0 commit 3db9f67
Show file tree
Hide file tree
Showing 18 changed files with 69 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
sidebar_position: 2
label: 'Architecture'
---

# Architecture
Expand All @@ -10,6 +11,6 @@ Overview of the overall architecture of the library.

- All web3-redux data is stored under the `web3Redux` slice of the store as a normalized json store (State). The overall interface of the state can be found under [State](../web3-redux-reference/interfaces/State.md).
- [Selectors](https://github.com/reduxjs/reselect) for each [redux-orm](https://github.com/redux-orm/redux-orm) model are the preferred way to then read this data.
- Redux ORM models are meant to represent blockchain data such as [Block](../web3-redux-reference/interfaces/Block.BlockHeader.md), [Transaction](../web3-redux-reference/interfaces/Transaction.Transaction-1.md), [Contract](../web3-redux-reference/interfaces/Contract.Contract-1.md)
- State is mutated by the dispatching of Actions. Actions can be synchronous, for simple CRUD operations on the state, or asynchronous, for network fetch operations. Async actions are handled by [redux-saga](https://github.com/redux-saga/redux-saga) and will usually dispatched a new CRUD action after fetching data.
- Hooks such as `useDispatch` and `useSelector`, enable Redux components to use the React Context API to read/write to the store by combining selectors and actions.
- Redux ORM models are meant to represent blockchain data such as [Block](../web3-redux-reference/interfaces/Block.BlockHeader.md), [Transaction](../web3-redux-reference/interfaces/Transaction.Transaction-1.md), [Contract](../web3-redux-reference/interfaces/Contract.Contract-1.md).
- State is mutated by the dispatching of Actions. Actions can be synchronous (e.g. simple CRUD operations on the state) or asynchronous (e.g. network fetch operations). Async actions are handled by [redux-saga](https://github.com/redux-saga/redux-saga) and will usually dispatch a new CRUD action after fetching data.
- Hooks such as `useDispatch` and `useSelector` enable Redux components to use the React Context API to read/write to the store by combining selectors and actions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
---
label: 'Batching with HTTP'
---
# Batching with HTTP

:::warning
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
---
label: 'Batching with Multicall'
---
# Batching with Multicall

:::warning
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# Block subscription
---
label: 'Block Subscription'
---
# Block Subscription

To sync with on-chain events, it's a good idea to start a block subscription as it can be used as a reference point to keep data fresh. This is recommended but not required as some apps might use a different refresh mechanism.
The `web3-redux` block subscription hook is configured to automatically start/stop the correct subscription if the `networkId` parameter changes. Alternatively, you can use the `subscribe()/unsubscribe()` handlers for more granular control such as handling user interactions.

```typescript
//Blocks.tsx
import { Block } from '@leovigna/web3-redux';
import { Block } from '@owlprotocol/web3-redux';
const BlocksComponent = ({ networkId }) => {
const [blocks, { subscribe, unsubsribe }] = Block.useBlockSync(networkId);
};
Expand All @@ -14,7 +17,7 @@ const BlocksComponent = ({ networkId }) => {
Alternatively, if not using hooks or React in general, you can manually dispatch a block sync action and use the selector as follows:

```typescript
import { Block, Network } from '@leovigna/web3-redux';
import { Block, Network } from '@owlprotocol/web3-redux';
store.dispatch(Block.subscribe({ networkId: '1' }));
const blocks = Network.selectBlocks(store.getState());
```
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
sidebar_position: 0
label: 'Custom Redux Store'
---

# Custom Redux Store
Expand All @@ -10,7 +11,7 @@ sidebar_position: 0

## Persistence

In most situations, you will want to add web3-redux to your existing redux store. The web3Reducer MUST be stored at the `web3Redux` key in your store.
In most situations, you will want to add `web3-redux` to your existing redux store. The web3Reducer **MUST** be stored at the `web3Redux` key in your store.

```typescript
//store.ts
Expand All @@ -29,7 +30,7 @@ sagaMiddleware.run(web3Saga);
export default store;
```

Then follow the standard `react-redux` configuration [guide](https://redux.js.org/usage/configuring-your-store) to add a `Provider` component to wrap your entire React app in the redux context.
Then follow the standard `react-redux` configuration [guide](https://redux.js.org/usage/configuring-your-store) to add a `Provider` component to wrap your entire React app within the redux context.

```typescript
//index.tsx
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
sidebar_position: 1
label: 'Persistence'
---

# Persistence
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
---
label: 'Raw Event Logs'
---
# Raw Event Logs

:::warning
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
---
sidebar_position: 4
label: 'Contract Call Sync'
---

# Contract Call Sync

Web3-Redux offers enhanced customizability of contract call syncing to avoid unecessary rpc calls. Contract call syncing is achieved by refreshing contract calls based on a set of parameters.
Web3-Redux offers enhanced customizability of contract call syncing to avoid unecessary RPC calls. Contract call syncing is achieved by refreshing contract calls based on a set of parameters.

## Simple Contract Call

Expand All @@ -16,7 +17,7 @@ TODO

## Generic Sync

This type union of [Sync](../web3-redux-reference/namespaces/Sync.md#sync) and some defaults is often used as a parameter in certain hooks such as [useContractCall](../web3-redux-hooks/Contract_Data.md#usecontractcall).
This type union of [Sync](../web3-redux-reference/namespaces/Sync.md#sync) and other defaults is often used as a parameter in certain hooks such as [useContractCall](../web3-redux-hooks/Contract_Data.md#usecontractcall).

- Sync: Regular Sync middleware action.
- `"Block"`: Sync every block. Represents a [BlockSync](../web3-redux-reference/interfaces/Sync.BlockSync.md) with `matchBlockNumberModulo = 1`.
Expand All @@ -32,11 +33,11 @@ In summary, there are 4 types of contract call sync types:

- `once`: Call contract method once
- `Block`: Call contract and refresh every block.
`Event`: Call contract on
`Event`: Call contract on an event.
- `Transaction`: Call contract and refresh every time a block includes a transaction to the contract. This uses the heuristic that your contract's state only changes when transactions interact with it directly.

:::note
Both block sync, and transaction sync require an existing block subscription to be first created.
Both block sync and transaction sync require an existing block subscription to be first created.
:::

:::warning
Expand All @@ -45,7 +46,7 @@ Both block sync, and transaction sync require an existing block subscription to

## Optimizing Call Sync

By default, contracts use Transaction syncing but this can be customized for each specific contract call. This is can be a sub-optimal or even incorrect sync strategy.
By default, contracts use Transaction syncing. It can however be customized for each specific contract call. This is can be a sub-optimal or even incorrect sync strategy.

Transaction syncing can be sub-optimal if a call's return value never changes. For example, an ERC20 token's name or symbol. In this case simply disable syncing with `sync: false`.

Expand All @@ -55,17 +56,17 @@ Examples of cases where this assumption might be incorrect include:
- Contract call return value depends on block number
- Contract state can be changed by a call to some proxy contract

In these cases we recommend switching to Block syncing, which will poll the contract call at every block. For even better optimization, it might be interesting in some cases to use a custom block or transaction sync.
In these cases we recommend switching to Block syncing, which will poll the contract call at every block. For even better optimization, it could be beneficial to use a custom block or transaction sync.

## Custom Call Syncs

:::tip
We recommend using Event Sync when possible as this is often the most optimal solution, only updating when the relevant state is modified.
We recommend using Event Sync when possible as it is often the most optimal solution only updating when the relevant state is modified.
:::

### Custom Block Sync

This might be useful as a quick solution to implement polling behaviour to the way you refresh a smart contract's data. This solution is especially optimal wfor state that depends on the block number (eg. some beacon).
This might be useful as a quick solution to implement polling behaviour to the way you refresh a smart contract's data. This solution is especially optimal for state that depends on the block number (eg. some beacon).

```typescript
//Sync every 10 blocks
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
---
sidebar_position: 3
label: 'Sync Middleware'
---

# Sync Middleware

Web3-Redux comes with a built-in Sync ta model which serves as a form of dynamic middleware that can be added, removed, and customized. There are three types of syncs, [BlockSync](../web3-redux-reference/interfaces/Sync.BlockSync.md), [EventSync](../web3-redux-reference/interfaces/Sync.EventSync.md), and [TransactionSync](../web3-redux-reference/interfaces/Sync.TransactionSync.md) which each can trigger actions upon receiving updates to a new block, new event, or new transaction.
Web3-Redux comes with a built-in Sync model which serves as a form of dynamic middleware that can be added, removed, and customized. There are three types of syncs: [BlockSync](../web3-redux-reference/interfaces/Sync.BlockSync.md), [EventSync](../web3-redux-reference/interfaces/Sync.EventSync.md), and [TransactionSync](../web3-redux-reference/interfaces/Sync.TransactionSync.md) which each can trigger actions upon receiving updates to a new block, new event or new transaction, respectively.

Sync middleware can be useful when looking to dispatch your own custom Redux action as a result of some blockchain update. They are also used as the building blocks for the Contract Call sync.

Expand All @@ -27,7 +28,7 @@ Sync.create({ id: '1', type: 'Block', matchBlockNumberModulo: 1, actions });

## Event Sync

This middleware listens for [ContractEvent/CREATE](../web3-redux-reference/namespaces/ContractEvent.md#create) actions, and if an event matches its `matchAddress`, `matchName`, and `matchReturnValues`, will dispatch its `actions`.
This middleware listens for [ContractEvent/CREATE](../web3-redux-reference/namespaces/ContractEvent.md#create) actions, and if an event matches its `matchAddress`, `matchName` and `matchReturnValues`, will dispatch its `actions`.
The following example filters for `Transfer` events:

```typescript
Expand All @@ -42,7 +43,7 @@ An event sync middleware is **NOT** the same as an event subscription. Sync midd

## Transaction Sync

This middleware listens for [Transaction/CREATE](../web3-redux-reference/namespaces/Transaction.md#create) actions, and if an transaction matches its `matchFrom` and `matchTo` parameteres, will dispatch its `actions`.
This middleware listens for [Transaction/CREATE](../web3-redux-reference/namespaces/Transaction.md#create) actions and if an transaction matches its `matchFrom` and `matchTo` parameteres, will dispatch its `actions`.
The following example filters for tranaction from a particular sender:

```typescript
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
sidebar_position: 0
label: 'Infura'
---

# Infura
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
---
sidebar_position: 1
label: 'Metamask'
---

# Metamask

See [Manual Network Initialization](#manual) for more detail.
Metamask can cause issues as the injected Web3 instance is mutable and changes as users change networks. To mitigate this, Networks can be initialized with 2 web3 instances, one for read-only calls (eg. Infura) and one for wallet signed send transactions (Metamask). This way, subcriptions and call syncs can continue to work even if a user changes networks.
Metamask can cause issues as the injected Web3 instance is mutable and changes as users change networks. To mitigate this, Networks can be initialized with two `web3` instances: one for read-only calls (eg. Infura) and one for wallet signed send transactions (Metamask). This way, subcriptions and call syncs can continue to work even if a user changes networks.

Override the optional `web3Sender` parameter when initializing the Network and set it to the injected Web3 instance. The regular read-only web3 instance should
To do this, override the optional `web3Sender` parameter when initializing the Network and set it to the injected Web3 instance. The regular read-only `web3` instance should

```typescript
const web3Sender = window.web3; //Metamask wallet, used for send transactions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ label: 'Configure Contract'

The [Contract](../web3-redux-reference/interfaces/Contract.Contract-1.md) entity is the most used model in Web3-Redux. In Web3-Redux, a contract can be one of:

- **Externally Owned Account (EOA)**: This is a simple Ethereum address that can have some balance, send transactions but that does not have any code. Can be used to track Ethereum balance of some address for example.
- **Externally Owned Account (EOA)**: This is a simple Ethereum address that can have some balance, send transactions but does not have any code. Can be used to track Ethereum balance of some address for example.
- **Smart Contract**: This is a program on the blockchain that stores and executes EVM bytecode. Can be used to track ERC20 token (eg. USDC) balance of some address for example.

Both are stored in the same `Contract` model as they are indexed by `networkId-address` in the store.
Expand All @@ -20,7 +20,7 @@ We do not use the sole address alone for indexing as a EOA or Smart Contract can

## Add Contract

Contracts can be used in multiple ways such as fetching native token balance (ETH), making smart contract calls, or listening for event logs. One you've added a network (as in the previous section), add a contract by dispatching a `Contract.create` action with the following parameters:
Contracts can be used in multiple ways, such as fetching native token balance (ETH), making smart contract calls or listening for event logs. Once you've added a network (as in the previous section), add a contract by dispatching a `Contract.create` action with the following parameters:

- `networkId` **(required)**: The network this contract lives on. Important to configure how data will be fetched.
- `address` **(required)**: The address of this contract.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ label: 'Configure Network'

## Network

All entities in the Web3-Redux store are indexed by networkId. Web3-Redux let's you sync multiple networks concurrently (eg. sync Mainnet & Ropsten blocks). The [Network](../web3-redux-reference/interfaces/Network.Network-1.md) object is meant to store a global `web3` object that is responsible for connecting to the Ethereum RPC. You must first configure a network by adding it to the store and passing it a web3 instance or an Ethereum RPC.
All entities in the Web3-Redux store are indexed by `networkId`. Web3-Redux let's you sync multiple networks concurrently (eg. sync Mainnet & Ropsten blocks). The [Network](../web3-redux-reference/interfaces/Network.Network-1.md) object is meant to store a global `web3` object that is responsible for connecting to the Ethereum RPC. You must first configure a network by adding it to the store and passing it a web3 instance or an Ethereum RPC.
:::tip
We recomend using a Websocket (`wss://`) connection as this enables more advanced usage such as subscriptions.
:::
Expand All @@ -28,7 +28,7 @@ You can configure your network by simply dispatching the following create action
store.dispatch(Network.create({ networkId: '1', /*web3Rpc: 'ws://localhost:8546'*/})
```
Web3-Redux will automatically use the envvar configured RPC as a default for supported networks (Ethereum, Testnets, Polygon). For custom networks, you can manually set the `web3Rpc` parameter in the create action.
Web3-Redux will automatically use the environment variable configured RPC as a default for supported networks (Ethereum, Testnets, Polygon). For custom networks, you can manually set the `web3Rpc` parameter in the create action.
For more details on supported envvars (additional default networks), check out [Reference/Environment](../web3-redux-reference/namespaces/Environment.md).
Also see the React Documentation on [Adding Custom Environment Variables](https://create-react-app.dev/docs/adding-custom-environment-variables/).
Expand Down Expand Up @@ -58,10 +58,10 @@ const App = () => {
In pure Redux, the configuration can be dispatched from the store.
```typescript
import { Network } from '@leovigna/web3-redux';
import { Network } from '@owlprotocol/web3-redux';
store.dispatch(Network.create({ networkId: '1' }));
```
## Advanced
For more dynamic configuration such as integration with Metamask, and setting up a dual configuration with a `web3Sender` object, check out [Integrations/Metamask](../web3-redux-integrations/metamask.md).
For more dynamic configuration such as integrating with Metamask or setting a dual configuration using a `web3Sender` object. (Check out [Integrations/Metamask](../web3-redux-integrations/metamask.md))
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ label: 'Configure Store'

# Initialize the Redux Store

In this quickstart example, we will be using the default Web3-Redux store. You may have a more complex setup depending on your needs however:
In this quickstart example, we will be using the default Web3-Redux store. You may also leverage a more complex setup depending on your needs:

- Enable persistance middleware using [redux-persist](https://github.com/rt2zz/redux-persist). See [Advanced/Persistence](/docs/web3-redux-advanced/persistence)
- Integrate web3-redux with existing redux store. This is often required in more complex applications that need to store their own state. See [Advanced/Custom Store](../web3-redux-advanced/custom_store.md).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ Now that you've completed this initial quickstart, consider the following topics
- Multi-network: Understand the Web3-Redux Architecture and fetch data concurrently from multiple blockchains.
- Metamask: Integrate Metamask to enable sending transactions that writes data on the blockchain.
- Persistence: Enable local storage persistence using [redux-persist](https://github.com/rt2zz/redux-persist) to immediately populate your app with cached data when users re-open a tab
- Sync Optimization: Learn how to optimize the RPC requests made by your app by only refreshing data when needed by efficiently combining event subscriptions with contract calls.
- Sync Optimization: Learn how to optimize the RPC requests made by your app by only refreshing data when needed by combining event subscriptions with contract calls.
Loading

0 comments on commit 3db9f67

Please sign in to comment.