Skip to content

Commit

Permalink
docs: JSON-RPC
Browse files Browse the repository at this point in the history
  • Loading branch information
jxom committed Nov 4, 2024
1 parent 95a208b commit cdc8558
Show file tree
Hide file tree
Showing 17 changed files with 365 additions and 57 deletions.
42 changes: 41 additions & 1 deletion site/pages/guides/abi.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ console.log(encoded)
// @log: '0x000000000000000000000000cb98643b8786950f0461f3b0edf99d88f274574d00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003'
```

:::note
**Tip:** You can also provide Human Readable parameters with [`AbiParameters.from`](/api/AbiParameters/from#human-readable-parameters):

```ts twoslash
import { AbiParameters } from 'ox';

const encoded = AbiParameters.encode(
AbiParameters.from(['address', 'uint32[]']),
['0xcb98643b8786950F0461f3B0edf99D88F274574D', [1, 2, 3]]
)
```

:::

The `encoded` variable now contains the ABI-encoded representation of the values we passed with the `address` and `uint32[]` parameters. We won't go into detail on how the encoding works, but you can read more about it [here](https://docs.soliditylang.org/en/latest/abi-spec.html#argument-encoding).

### Decoding
Expand Down Expand Up @@ -59,6 +73,20 @@ console.log(decoded) // [!code focus]
// @log: ['0xcb98643b8786950f0461f3b0edf99d88f274574d', [1, 2, 3]]
```

:::note
**Tip:** You can also provide Human Readable parameters with [`AbiParameters.from`](/api/AbiParameters/from#human-readable-parameters):

```ts twoslash
import { AbiParameters } from 'ox';

const encoded = AbiParameters.decode(
AbiParameters.from(['address', 'uint32[]']),
'0x...'
)
```

:::

Now that we are aware of how to encode and decode primitive types & values, let's take a look at how ABI coding is applied in real-world scenarios.

## Contract Function Calls
Expand Down Expand Up @@ -494,4 +522,16 @@ const hash = await transport.request({ // [!code focus]
**Note:** Deploy Transactions do not contain a `to` address.
:::

::::
::::

## Related Modules

| Module | Description |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| [Abi](/api/Abi) | Utilities & types for working with [Application Binary Interfaces (ABIs)](https://docs.soliditylang.org/en/latest/abi-spec.html) |
| [AbiConstructor](/api/AbiConstructor) | Utilities & types for working with [Constructors](https://docs.soliditylang.org/en/latest/abi-spec.html#json) on ABIs. |
| [AbiError](/api/AbiError) | Utilities & types for working with [Errors](https://docs.soliditylang.org/en/latest/abi-spec.html#json) on ABIs. |
| [AbiEvent](/api/AbiEvent) | Utilities & types for working with [Events](https://docs.soliditylang.org/en/latest/abi-spec.html#json) on ABIs. |
| [AbiFunction](/api/AbiFunction) | Utilities & types for working with [Functions](https://docs.soliditylang.org/en/latest/abi-spec.html#json) on ABIs. |
| [AbiItem](/api/AbiItem) | Utilities & types for working with [ABI Items](https://docs.soliditylang.org/en/latest/abi-spec.html#json) |
| [AbiParameters](/api/AbiParameters) | Utilities & types for encoding, decoding, and working with [ABI Parameters](https://docs.soliditylang.org/en/latest/abi-spec.html#types) |
8 changes: 8 additions & 0 deletions site/pages/guides/bytes-hex.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,11 @@ Hex.assert('abc')
Bytes.assert(Bytes.from([0xde, 0xad, 0xbe, 0xef]))
// @log: no error :)
```

## Related Modules

| Module | Description |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Bytes](/api/Bytes) | A set of Ethereum-related utility functions for working with [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) instances. |
| [Hex](/api/Hex) | A set of Ethereum-related utility functions for working with hexadecimal string values (e.g. `"0xdeadbeef"`). |

13 changes: 12 additions & 1 deletion site/pages/guides/ecdsa.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,4 +294,15 @@ const serialized_bytes = PublicKey.toBytes(publicKey)
// ^?


```
```

## Related Modules

| Module | Description |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [P256](/api/P256) | Utility functions for [NIST P256](https://csrc.nist.gov/csrc/media/events/workshop-on-elliptic-curve-cryptography-standards/documents/papers/session6-adalier-mehmet.pdf) ECDSA cryptography. |
| [PublicKey](/api/PublicKey) | Utility functions for working with ECDSA public keys. |
| [Secp256k1](/api/Secp256k1) | Utility functions for [secp256k1](https://www.secg.org/sec2-v2.pdf) ECDSA cryptography. |
| [Signature](/api/Signature) | Utility functions for working with ECDSA signatures. |
| [WebAuthnP256](/api/WebAuthnP256) | Utility functions for [NIST P256](https://csrc.nist.gov/csrc/media/events/workshop-on-elliptic-curve-cryptography-standards/documents/papers/session6-adalier-mehmet.pdf) ECDSA cryptography using the [Web Authentication API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) |
| [WebCryptoP256](/api/WebCryptoP256) | Utility functions for [NIST P256](https://csrc.nist.gov/csrc/media/events/workshop-on-elliptic-curve-cryptography-standards/documents/papers/session6-adalier-mehmet.pdf) ECDSA cryptography using the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) |
9 changes: 8 additions & 1 deletion site/pages/guides/eip-1193.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,11 @@ const provider = Provider.from({

// 3. Emit Provider Events.
emitter.emit('accountsChanged', ['0x...']) // [!code ++]
```
```

## Related Modules

| Module | Description |
| ------------------------- | ------------------------------------------------------------------------------------------------ |
| [Provider](/api/Provider) | Utilities & types for working with [EIP-1193 Providers](https://eips.ethereum.org/EIPS/eip-1193) |

6 changes: 6 additions & 0 deletions site/pages/guides/encryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,9 @@ const decrypted = await AesGcm.decrypt(encrypted, key) // [!code focus]
```

::::

## Related Modules

| Module | Description |
| --------------------- | ----------------------------------------- |
| [AesGcm](/api/AesGcm) | Utility functions for AES-GCM encryption. |
197 changes: 197 additions & 0 deletions site/pages/guides/json-rpc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# JSON-RPC

## Overview

For an Application to communicate with the Ethereum network, it needs to establish a connection to an Ethereum Node, and be able to send and receive messages in a standardized format.

All Ethereum Nodes implement the [JSON-RPC specification](https://www.jsonrpc.org/specification), which is a stateless & lightweight remote procedure call (RPC) protocol.

Ox provides type-safe primitives for working with the [JSON-RPC specification](https://www.jsonrpc.org/specification).

## Examples

### Sending a Request

The example below demonstrates sending a strongly-typed JSON-RPC request to an Ethereum Node using an auto-incrementing JSON-RPC `id` store via [`RpcRequest.createStore`](/api/RpcRequest/createStore).

```ts twoslash
import { RpcRequest } from 'ox'

// 1. Create a request store.
const store = RpcRequest.createStore()

// 2. Prepare a request.
const request = store.prepare({
method: 'eth_getBlockByNumber',
params: ['latest', false],
})

// 3. Send the request to an Ethereum Node.
const response = await fetch('https://1.rpc.thirdweb.com', {
body: JSON.stringify(request),
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
}).then((res) => res.json())
```

:::note

You can also use the [`RpcRequest.from`](/api/RpcRequest/from) function to create a request and manage the `id` manually.

```ts twoslash
// @noErrors
import { RpcRequest } from 'ox'

const request = RpcRequest.from({ // [!code focus]
id: 0, // [!code focus]
method: 'eth_getBlockByNumber', // [!code focus]
params: ['latest', false], // [!code focus]
}) // [!code focus]

const response = await fetch('https://1.rpc.thirdweb.com', {
body: JSON.stringify(request),
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
}).then((res) => res.json())
```

:::

### Parsing a Response

The example below demonstrates parsing a JSON-RPC response using the [`RpcResponse.parse`](/api/RpcResponse/parse) function. This will extract the JSON-RPC `result` and and strongly type the response based on the `request` used.

```ts twoslash
import { RpcRequest, RpcResponse } from 'ox'

// 1. Create a request store.
const store = RpcRequest.createStore()

// 2. Prepare a request.
const request = store.prepare({
method: 'eth_getBlockByNumber',
params: ['latest', false],
})

// 3. Send the request to an Ethereum Node.
const response = await fetch('https://1.rpc.thirdweb.com', {
body: JSON.stringify(request),
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => res.json())
// 4. Parse the response. // [!code focus]
.then((res) => RpcResponse.parse(res, { request })) // [!code focus]

response // [!code focus]
// ^?











```

:::tip

**Tip:** Setting `raw` to `true` will return the raw JSON-RPC response object.

```ts twoslash
// @noErrors
import { RpcRequest, RpcResponse } from 'ox'

// 1. Create a request store.
const store = RpcRequest.createStore()

// 2. Prepare a request.
const request = store.prepare({
method: 'eth_getBlockByNumber',
params: ['latest', false],
})

// 3. Send the request to an Ethereum Node.
const response = await fetch('https://1.rpc.thirdweb.com', {
body: JSON.stringify(request),
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => res.json())
// ---cut---
.then((res) => RpcResponse.parse(res, { request, raw: true })) // [!code focus]

response // [!code focus]
// ^?















```

:::

### Handling Requests

If you need to handle incoming JSON-RPC requests and return a respective response (for example, if you are building an JSON-RPC API handler or an [EIP-1193 Provider `request` handler](/api/Provider/from#instantiating-a-custom-provider) in a Wallet), you can utilize the [`RpcResponse.from`](/api/RpcResponse/from) function.

```ts twoslash
// @noErrors
import { RpcRequest, RpcResponse, RpcSchema } from 'ox'

const accounts = ['0x...', '0x...'] as const

async function handleRequest(request: RpcRequest.RpcRequest<RpcSchema.Eth>) {
if (request.method === 'eth_accounts')
return RpcResponse.from({ result: accounts }, { request })
if (request.method === 'eth_chainId')
return RpcResponse.from({ result: '0x1' }, { request })
if (request.method === 'eth_getBlock')
// ^|




return await fetch('https://1.rpc.thirdweb.com', {
body: JSON.stringify(request),
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => res.json())
.then((res) => RpcResponse.from(res))
}
```

## Related Modules

| Module | Description |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [RpcRequest](/api/RpcRequest) | Utility types & functions for working with [JSON-RPC 2.0 Requests](https://www.jsonrpc.org/specification#request_object) and Ethereum JSON-RPC methods as defined on the [Ethereum API specification](https://github.com/ethereum/execution-apis) |
| [RpcResponse](/api/RpcResponse) | Utility types & functions for working with [JSON-RPC 2.0 Responses](https://www.jsonrpc.org/specification#response_object) |
| [RpcSchema](/api/RpcSchema) | Utility types for working with Ethereum JSON-RPC namespaces & schemas. |
| [RpcTransport](/api/RpcTransport) | Utility functions for working with JSON-RPC Transports. |
6 changes: 6 additions & 0 deletions site/pages/guides/rlp.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,9 @@ const rlp = Rlp.fromHex([
const values = Rlp.toHex(rlp) // [!code focus]
// @log: [Hex.fromString('hello'), Hex.fromNumber(1337), [Hex.fromString('foo'), Hex.fromString('bar')]]
```

## Related Modules

| Module | Description |
| --------------- | ---------------------------------------------- |
| [Rlp](/api/Rlp) | Utility functions for RLP encoding & decoding. |
8 changes: 8 additions & 0 deletions site/pages/guides/signed-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,11 @@ const signature = await provider.request({ // [!code focus]
params: [address, payload], // [!code focus]
}) // [!code focus]
```

## Related Modules

| Module | Description |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| [PersonalMessage](/api/PersonalMessage) | Utilities & types for working with [EIP-191 Personal Messages](https://eips.ethereum.org/EIPS/eip-191#version-0x45-e) |
| [TypedData](/api/TypedData) | Utility functions for working with [EIP-712 Typed Data](https://eips.ethereum.org/EIPS/eip-712) |
| [ValidatorData](/api/ValidatorData) | Utilities & types for working with [EIP-191 Validator Data](https://eips.ethereum.org/EIPS/eip-191#0x00) |
6 changes: 6 additions & 0 deletions site/pages/guides/siwe.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,9 @@ function handler() {
}
```


## Related Modules

| Module | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------- |
| [Siwe](/api/Siwe) | Utility functions for working with [Sign-In with Ethereum (EIP-4361)](https://eips.ethereum.org/EIPS/eip-4361). |
11 changes: 11 additions & 0 deletions site/pages/guides/transaction-envelopes.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,14 @@ const hash = await provider.request({
params: [envelope_rpc],
})
```

## Related Modules

| Module | Description |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [TransactionEnvelope](/api/TransactionEnvelope) | Errors & Types for working with Transaction Envelopes. |
| [TransactionEnvelopeEip1559](/api/TransactionEnvelopeEip1559) | Utility functions for working with [EIP-1559 Typed Transaction Envelopes](https://eips.ethereum.org/EIPS/eip-1559). |
| [TransactionEnvelopeEip2930](/api/TransactionEnvelopeEip2930) | Utility functions for working with [EIP-2930 Typed Transaction Envelopes](https://eips.ethereum.org/EIPS/eip-2930). |
| [TransactionEnvelopeEip4844](/api/TransactionEnvelopeEip4844) | Utility functions for working with [EIP-4844 Typed Transaction Envelopes](https://eips.ethereum.org/EIPS/eip-4844). |
| [TransactionEnvelopeEip7702](/api/TransactionEnvelopeEip7702) | Utility functions for working with [EIP-7702 Typed Transaction Envelopes](https://eips.ethereum.org/EIPS/eip-7702). |
| [TransactionEnvelopeLegacy](/api/TransactionEnvelopeLegacy) | Utility functions for working with **Legacy Transaction Envelopes**. |
5 changes: 4 additions & 1 deletion site/pages/guides/webauthn.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,8 @@ const verified = await WebAuthnP256.verify({ // [!code focus]
}) // [!code focus]
```

## Related Modules


| Module | Description |
| --------------------------------- | --------------------------------------------------------- |
| [WebAuthnP256](/api/WebAuthnP256) | Utility functions for working with WebAuthn-P256 Signers. |
8 changes: 1 addition & 7 deletions site/vocs.config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default defineConfig({
link: '/guides/eip-7702',
},
{ text: 'ENS 🚧', link: '/guides/ens' },
{ text: 'JSON-RPC & Execution API 🚧', link: '/guides/json-rpc' },
{ text: 'JSON-RPC', link: '/guides/json-rpc' },
{
text: 'Mnemonics 🚧',
link: '/guides/mnemonics',
Expand All @@ -89,12 +89,6 @@ export default defineConfig({
link: '/guides/transaction-envelopes',
},
{ text: 'WebAuthn Signers', link: '/guides/webauthn' },
{ text: 'Using with Effect 🚧', link: '/guides/effect' },
{ text: 'Using with NeverThrow 🚧', link: '/guides/neverthrow' },
{
text: 'Using with Validators 🚧',
link: '/guides/validators',
},
],
},
{
Expand Down
Loading

0 comments on commit cdc8558

Please sign in to comment.