-
Notifications
You must be signed in to change notification settings - Fork 90
/
chain.ts
120 lines (102 loc) · 3.53 KB
/
chain.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import { Header as CodecHeader } from '@polkadot/types/interfaces'
import { HexString } from '@polkadot/util/types'
import { hexToNumber, isHex } from '@polkadot/util'
import { Handler, ResponseError } from '../shared.js'
import type { Header } from '../../index.js'
const processHeader = ({ parentHash, number, stateRoot, extrinsicsRoot, digest }: CodecHeader) => {
return {
parentHash: parentHash.toHex(),
number: number.toHex(),
stateRoot: stateRoot.toHex(),
extrinsicsRoot: extrinsicsRoot.toHex(),
digest: {
logs: digest.logs.map((log) => log.toHex()),
},
}
}
/**
* @param context
* @param params - [`blockNumber` | `blockNumber[]` | null]
*
* @return Block hash | hash[] | null
*/
export const chain_getBlockHash: Handler<
[number | HexString | number[] | HexString[] | null],
HexString | (HexString | null)[] | null
> = async (context, [blockNumber]) => {
const numbers = Array.isArray(blockNumber) ? blockNumber : [blockNumber]
const hashes = await Promise.all(
numbers.map((n) => (isHex(n, undefined, true) ? hexToNumber(n) : n)).map((n) => context.chain.getBlockAt(n)),
).then((blocks) => blocks.map((b) => b?.hash || null))
return Array.isArray(blockNumber) ? hashes : hashes[0]
}
/**
* @param context
* @param params - [`blockhash`]
*
* @return Header - see `@polkadot/types/interfaces`
*/
export const chain_getHeader: Handler<[HexString], Header> = async (context, [hash]) => {
const block = await context.chain.getBlock(hash)
if (!block) {
throw new ResponseError(1, `Block ${hash} not found`)
}
return processHeader(await block.header)
}
/**
* @param context
* @param params - [`blockhash`]
*
* @return Block header and extrinsics
*/
export const chain_getBlock: Handler<
[HexString],
{ block: { header: Header; extrinsics: HexString[] }; justifications: null }
> = async (context, [hash]) => {
const block = await context.chain.getBlock(hash)
if (!block) {
throw new ResponseError(1, `Block ${hash} not found`)
}
return {
block: {
header: processHeader(await block.header),
extrinsics: await block.extrinsics,
},
justifications: null,
}
}
/**
* @param context
*
* @return head hash
*/
export const chain_getFinalizedHead: Handler<void, HexString> = async (context) => {
return context.chain.head.hash
}
export const chain_subscribeNewHead: Handler<void, string> = async (context, _params, { subscribe }) => {
let update = () => {}
const id = context.chain.headState.subscribeHead(() => update())
const callback = subscribe('chain_newHead', id, () => context.chain.headState.unsubscribeHead(id))
update = async () => {
callback(processHeader(await context.chain.head.header))
}
setTimeout(update, 50)
return id
}
export const chain_subscribeFinalizedHeads: Handler<void, string> = async (context, _params, { subscribe }) => {
let update = () => {}
const id = context.chain.headState.subscribeHead(() => update())
const callback = subscribe('chain_finalizedHead', id, () => context.chain.headState.unsubscribeHead(id))
update = async () => {
callback(processHeader(await context.chain.head.header))
}
setTimeout(update, 50)
return id
}
export const chain_unsubscribeNewHead: Handler<[string], void> = async (_context, [subid], { unsubscribe }) => {
unsubscribe(subid)
}
export const chain_getHead = chain_getBlockHash
export const chain_subscribeNewHeads = chain_subscribeNewHead
export const chain_unsubscribeNewHeads = chain_unsubscribeNewHead
export const chain_unsubscribeFinalizedHeads = chain_unsubscribeNewHead