Skip to content

Commit 49f9743

Browse files
authored
feat: add offline api docs (#51)
1 parent e4aaf26 commit 49f9743

File tree

4 files changed

+84
-22
lines changed

4 files changed

+84
-22
lines changed

docs/pages/client.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ interface PolkadotClient {
1111
getChainSpecData: () => Promise<ChainSpecData>
1212

1313
/**
14-
* Observable that emits `BlockInfo` from the latest known finalized block.
15-
* It's a multicast and stateful observable, that will synchronously replay
16-
* its latest known state.
14+
* Observable that emits `BlockInfo` for every new finalized block. It's a
15+
* multicast and stateful observable, that will synchronously replay its
16+
* latest known state.
1717
*/
1818
finalizedBlock$: Observable<BlockInfo>
1919
/**
@@ -29,9 +29,8 @@ interface PolkadotClient {
2929
* i.e. a new array is emitted at every event but the reference to its
3030
* children are stable if the children didn't change.
3131
*
32-
* Note that subscribing to this observable already supersedes the need of
33-
* subscribing to `finalizedBlock$`, since the last element of the array will
34-
* be the latest known finalized block.
32+
* Note that some blocks might not get reported, e.g. if they become finalized
33+
* immediately without being part of the best block chain.
3534
*/
3635
bestBlocks$: Observable<BlockInfo[]>
3736
/**
@@ -67,37 +66,38 @@ interface PolkadotClient {
6766
getBlockHeader: (hash?: string) => Promise<BlockHeader>
6867

6968
/**
70-
* Broadcast a transaction (Promise-based)
69+
* Broadcasts a transaction (Promise-based). The promise will resolve when the
70+
* transaction is found in a finalized block; and will reject if the
71+
* transaction is invalid and can't be broadcasted, or if it is deemed invalid
72+
* later on.
7173
*
7274
* @param transaction SCALE-encoded tx to broadcast.
7375
* @param at It can be a block hash, `"finalized"`, or `"best"`.
7476
* That block will be used to verify the validity of
75-
* the tx, retrieve the next nonce,
76-
* and create the mortality taking that block into
77-
* account.
77+
* the tx.
7878
*/
7979
submit: (
8080
transaction: HexString,
8181
at?: HexString,
8282
) => Promise<TxFinalizedPayload>
8383
/**
84-
* Broadcast a transaction and returns an Observable. The observable will
85-
* complete as soon as the transaction is in a finalized block.
84+
* Broadcasts a transaction and returns an Observable. The observable will
85+
* complete as soon as the transaction is in a finalized block. See
86+
* https://papi.how/typed/tx#signsubmitandwatch to learn about all possible
87+
* events.
8688
*
8789
* @param transaction SCALE-encoded tx to broadcast.
8890
* @param at It can be a block hash, `"finalized"`, or `"best"`.
8991
* That block will be used to verify the validity of
90-
* the tx, retrieve the next nonce,
91-
* and create the mortality taking that block into
92-
* account.
92+
* the tx.
9393
*/
9494
submitAndWatch: (
9595
transaction: HexString,
9696
at?: HexString,
9797
) => Observable<TxBroadcastEvent>
9898

9999
/**
100-
* Returns an instance of a `TypedApi`
100+
* Returns an instance of a `TypedApi`.
101101
*
102102
* @param descriptors Pass descriptors from `@polkadot-api/descriptors`
103103
* generated by `papi` CLI.

docs/pages/offline.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Offline API
2+
3+
The rationale behind the offline api is to allow consumers to do certain actions with PAPI without the need of a provider. As expected, this client is more limited than the regular [`PolkadotClient`](/client).
4+
5+
Let's see an example first of all:
6+
7+
```typescript
8+
import { getOfflineApi } from "polkadot-api"
9+
import { dotDescriptors } from "@polkadot-api/descriptors" // you'll need them!
10+
11+
const offline = await getOfflineApi(dotDescriptors) // it is async!
12+
13+
// metadata constants can be easily accessed
14+
const prefix = api.constants.System.SS58Prefix // directly the value; e.g. `0`
15+
const { spec_name, spec_version } = api.constants.System.Version
16+
17+
// transactions can be created and signed
18+
const tx = api.tx.Balances.transfer_keep_alive({
19+
dest: MultiAddress.Id(myAddr),
20+
value: amount,
21+
})
22+
23+
tx.encodedData // we have the encoded callData
24+
tx.decodedCall // and the decodedCall
25+
26+
const tx2 = offline.tx.Utility.batch({
27+
calls: [
28+
offline.tx.System.remark({ remark: Binary.fromText("HELLO!") }).decodedCall,
29+
tx.decodedCall,
30+
],
31+
})
32+
33+
// we can sign txs, but we need to add more stuff than usual!
34+
const signedTx = await tx2.sign(signer, {
35+
nonce: 24, // nonce is always compulsory
36+
mortality: { mortal: false }, // and mortality!
37+
})
38+
```
39+
40+
## Constants
41+
42+
Constants can be accessed easily having the metadata. `api.constants.Pallet.Entry` already gives the decoded value.
43+
44+
## Transactions
45+
46+
This is the main usecase of offline api. It allows to create and encode transactions, and even sign them.
47+
The transactions are created in the exact same way as in the regular API ([see docs](/typed/tx)). Nevertheless, only a subset of the fields are exposed:
48+
49+
- `decodedCall`: it enables to get the _PAPI decoded_ transaction. It is helpful to create other txs that require them as a parameter (e.g. `Utility.batch`).
50+
- `encodedData`: a `Binary` with the encoded call data.
51+
- `sign`: it takes the same arguments as the regular API, but there are two compulsory signed extensions:
52+
- `nonce`: nonce cannot be retrieved anymore from the chain, and therefore has to be passed
53+
- `mortality`: transactions can be signed either mortal or immortal. In case the tx were to be mortal, the block information has to be passed as well.
54+
```typescript
55+
type Mortality =
56+
| { mortal: false }
57+
| {
58+
mortal: true
59+
period: number
60+
startAtBlock: { height: number; hash: HexString }
61+
}
62+
```

docs/pages/requirements.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ PAPI is designed to work flawlessly with almost any Polkadot-like chain. Even th
66

77
### NodeJS
88

9-
PAPI is developed using the latest NodeJS LTS (currently `20.x`). The minimum required version is `20.6.0`, while we recommend the latest available release.
9+
PAPI is developed using the latest NodeJS LTS (currently `22.x`). The minimum required version is `20.6.0`, while we recommend the latest available release.
1010

1111
### Bun
1212

@@ -70,10 +70,6 @@ Besides that, Polkadot-API requires runtimes to implement some basic runtime cal
7070
- In order to get the metadata, it needs `Metadata_metadata_versions` and `Metadata_metadata_at_version`. If they are not present, then `Metadata_metadata` needs to be there and answer a `v14` Metadata.
7171
- To create and broadcast transactions, Polkadot-API needs `AccountNonceApi_account_nonce` and `TaggedTransactionQueue_validate_transaction`. To estimate the fees, it also requires `TransactionPaymentApi_query_info`.
7272

73-
In order to create transactions as well, the following storage entry is required for obtaining the genesis block-hash:
74-
75-
- `System.BlockHash`
76-
77-
And the following constant:
73+
In order to create transactions as well, the following constant is required:
7874

7975
- `System.Version`, having `spec_version` and `transaction_version` fields.

vocs.config.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ export default defineConfig({
9595
},
9696
],
9797
},
98+
{
99+
text: "Offline API",
100+
link: "/offline",
101+
},
98102
{
99103
text: "PAPI SDKs",
100104
link: "/sdks/intro",

0 commit comments

Comments
 (0)