Skip to content

Commit

Permalink
feat: add UnsafeApi
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosala committed Oct 7, 2024
1 parent 6779170 commit 297d3b5
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 4 deletions.
11 changes: 10 additions & 1 deletion docs/pages/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ interface PolkadotClient {
*/
getTypedApi: <D extends ChainDefinition>(descriptors: D) => TypedApi<D>

/**
* Returns an instance of a `UnsafeApi`.
*
* Note that this method is only meant for advanced users that really know
* what are they doing. This API does not provide any runtime compatibility
* checks protection and the consumer should implement them on their own.
*/
getUnsafeApi: <D>() => UnsafeApi<D>

/**
* This will `unfollow` the provider, disconnect and error every subscription.
* After calling it nothing can be done with the client.
Expand Down Expand Up @@ -131,4 +140,4 @@ interface PolkadotClient {
}
```

As one can note, `PolkadotClient` heavily relies on rxjs' `Observable`, used as well under the hood of Promise-based methods. Every method is fairly straight-forward and already documented exhaustively, except for `getTypedApi`. Let's dive into it.
As one can note, `PolkadotClient` heavily relies on rxjs' `Observable`, used as well under the hood of Promise-based methods. Every method is fairly straight-forward and already documented exhaustively, except for `getTypedApi` and `getUnsafeApi`. We will see first of all the `TypedApi`, and afterwards the `UnsafeApi`.
5 changes: 4 additions & 1 deletion docs/pages/typed.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ The `TypedApi` allows to interact with the runtime metadata easily and with a gr
type TypedApi = {
query: StorageApi
tx: TxApi
txFromCallData: TxFromBinary
event: EvApi
apis: RuntimeCallsApi
constants: ConstApi
compatibilityToken: Promise<CompatibilityToken>
}
```
Every field except for `compatibilityToken` is a `Record<string, Record<string, ???>>`. The first index defines the pallet, and the second one defines which query/tx/event/api/constant within that pallet. Each one of them will be described in the following pages, but let's focus on the compatibility check, which is common for all of them.
Every field except for `compatibilityToken` and `txFromCallData` is a `Record<string, Record<string, ???>>`. The first index defines the pallet, and the second one defines which query/tx/event/api/constant within that pallet. Each one of them will be described in the following pages.
`txFromCallData` will be explained as well in the [`tx`](/typed/tx) section. Let's focus on the compatibility check, which is common for all of them.
## getCompatibilityLevel
Expand Down
49 changes: 49 additions & 0 deletions docs/pages/unsafe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# UnsafeApi

The `UnsafeApi` enables interaction with the chain easily to the same extend [TypedApi](/typed) does, but it does not requires any descriptors. It is an advanced method and should only be used if you really know what you are doing. In order to create it, you can still pass a descriptors' type to get the same type inference as in the `typedApi`, but the shape of the entries at runtime level is not guaranteed.

:::warning
The `UnsafeApi` does not provide any compatibility checks protection as `TypedApi` does.
:::

The UnsafeApi has the following structure:

```ts
type UnsafeApi = {
query: StorageApi
tx: TxApi
txFromCallData: TxFromBinary
event: EvApi
apis: RuntimeCallsApi
constants: ConstApi
runtimeToken: Promise<RuntimeToken>
}
```
In order to create the unsafe api, it is actually very straightforward:
```ts
const unsafeApi = client.getUnsafeApi() // without typings

// optionally generate descriptors to get type inference
import { dot } from "@polkadot-api/descriptors"
const unsafeApi = client.getUnsafeApi<typeof dot>() // with typings
```

One can notice the API is actually very similar to the `TypedApi`, check [its docs](/typed) for the API reference since it behaves the exact same way. The only difference is that interactions do not include [compatibility methods](/typed#getcompatibilitylevel), and any reference to `compatibilityToken` in the typedApi is here a `runtimeToken`. For example:

```ts
const typedApi = client.getTypedApi(descriptors)
const unsafeApi = client.getUnsafeApi()

// in typed is `compatibilityToken`
const typedToken = await typedApi.compatibilityToken
// in unsafe is `runtimeToken`
const unsafeToken = await typedApi.runtimeToken

// typed version
typedApi.consts.System.SS58Prefix(typedToken)

// unsafe
unsafeApi.consts.System.SS58Prefix(unsafeToken)
```
8 changes: 6 additions & 2 deletions vocs.config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ export default defineConfig({
},
],
},
{
text: "Unsafe API",
link: "/unsafe",
},
],
},
{
Expand All @@ -102,8 +106,8 @@ export default defineConfig({
},
{
text: "Substrate Kitties",
link: "https://github.com/shawntabrizi/substratekitties"
}
link: "https://github.com/shawntabrizi/substratekitties",
},
],
},
],
Expand Down

0 comments on commit 297d3b5

Please sign in to comment.