From 297d3b553a501f0ac802341a70e9745bf3a5138c Mon Sep 17 00:00:00 2001 From: Carlo Sala Date: Fri, 4 Oct 2024 15:01:10 +0200 Subject: [PATCH] feat: add `UnsafeApi` --- docs/pages/client.md | 11 +++++++++- docs/pages/typed.md | 5 ++++- docs/pages/unsafe.md | 49 ++++++++++++++++++++++++++++++++++++++++++++ vocs.config.tsx | 8 ++++++-- 4 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 docs/pages/unsafe.md diff --git a/docs/pages/client.md b/docs/pages/client.md index 30df483f..8ed39ab9 100644 --- a/docs/pages/client.md +++ b/docs/pages/client.md @@ -104,6 +104,15 @@ interface PolkadotClient { */ getTypedApi: (descriptors: D) => TypedApi + /** + * 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: () => UnsafeApi + /** * This will `unfollow` the provider, disconnect and error every subscription. * After calling it nothing can be done with the client. @@ -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`. diff --git a/docs/pages/typed.md b/docs/pages/typed.md index 00fb50ce..f12ef9c3 100644 --- a/docs/pages/typed.md +++ b/docs/pages/typed.md @@ -6,6 +6,7 @@ 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 @@ -13,7 +14,9 @@ type TypedApi = { } ``` -Every field except for `compatibilityToken` is a `Record>`. 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>`. 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 diff --git a/docs/pages/unsafe.md b/docs/pages/unsafe.md new file mode 100644 index 00000000..b3541046 --- /dev/null +++ b/docs/pages/unsafe.md @@ -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 +} +``` + +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() // 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) +``` diff --git a/vocs.config.tsx b/vocs.config.tsx index 2496616e..b3291bd5 100644 --- a/vocs.config.tsx +++ b/vocs.config.tsx @@ -79,6 +79,10 @@ export default defineConfig({ }, ], }, + { + text: "Unsafe API", + link: "/unsafe", + }, ], }, { @@ -102,8 +106,8 @@ export default defineConfig({ }, { text: "Substrate Kitties", - link: "https://github.com/shawntabrizi/substratekitties" - } + link: "https://github.com/shawntabrizi/substratekitties", + }, ], }, ],