Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

chore: high level api speccing #107

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions branded.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
type Branded<T, Brand extends PropertyKey> = T & { [_ in Brand]: undefined };

export const HexStringBrand: unique symbol = Symbol();
export type HexString = Branded<string, typeof HexStringBrand>;

export const HashHexStringBrand: unique symbol = Symbol();
export type HashHexString = Branded<HexString, typeof HashHexStringBrand>;

export const AccountIdStringBrand: unique symbol = Symbol();
export type AccountIdString = Branded<string, typeof AccountIdStringBrand>;

export const SubscriptionIdStringBrand: unique symbol = Symbol();
export type SubscriptionIdString = Branded<string, typeof SubscriptionIdStringBrand>;

export const MultiAddressStringBrand: unique symbol = Symbol();
export type MultiAddressString = Branded<string, typeof MultiAddressStringBrand>;

export const HexU64StringBrand: unique symbol = Symbol();
export type HexU64String = Branded<string, typeof HexU64StringBrand>;

export const WsUrlStringBrand: unique symbol = Symbol();
export type WsUrlString = Branded<string, typeof HexStringBrand>;

export const ChainSpecStringBrand: unique symbol = Symbol();
export type ChainSpecString = Branded<string, typeof ChainSpecStringBrand>;
3 changes: 2 additions & 1 deletion effect/std/atoms/entryKey.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getHashers } from "../../../bindings/mod.ts";
import * as B from "../../../branded.ts";
import * as M from "../../../frame_metadata/mod.ts";
import * as U from "../../../util/mod.ts";
import { effector } from "../../impl/mod.ts";
Expand All @@ -19,6 +20,6 @@ export const entryKey = effector.async(
deriveCodec,
storageEntry: entryMetadata,
}).encode(key),
) as U.HexString;
) as B.HexString;
},
);
4 changes: 2 additions & 2 deletions effect/std/mapKeys.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as U from "../../util/mod.ts";
import * as B from "../../branded.ts";
import { effector } from "../impl/mod.ts";
import { deriveCodec } from "./atoms/deriveCodec.ts";
import { entryKey } from "./atoms/entryKey.ts";
Expand All @@ -15,7 +15,7 @@ import { rpcCall } from "./rpcCall.ts";
export const mapKeys = effector.async(
"mapKeys",
() =>
(map: Map, count?: number, startKey?: U.HashHexString) => {
(map: Map, count?: number, startKey?: B.HashHexString) => {
const metadata_ = metadata(map.pallet.rpc);
const metadataLookup_ = metadataLookup(metadata_);
const deriveCodec_ = deriveCodec(metadata_);
Expand Down
4 changes: 2 additions & 2 deletions effect/std/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as B from "../../branded.ts";
import { RpcClient } from "../../rpc/Base.ts";
import * as U from "../../util/mod.ts";
import { effector, EffectorItem } from "../impl/mod.ts";
import { metadataDecoded } from "./atoms/metadataDecoded.ts";
import { select } from "./atoms/select.ts";
import { rpcCall } from "./rpcCall.ts";

export const metadata = effector(
"metadata",
(rpc: EffectorItem<RpcClient>, blockHash?: EffectorItem<U.HashHexString>) => {
(rpc: EffectorItem<RpcClient>, blockHash?: EffectorItem<B.HashHexString>) => {
const rpcCall_ = rpcCall(rpc, "state_getMetadata", blockHash);
const result = select(rpcCall_, "result");
return metadataDecoded(result);
Expand Down
69 changes: 35 additions & 34 deletions rpc/messages.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as B from "../branded.ts";
import { EnsureLookup } from "../util/mod.ts";
import * as U from "../util/mod.ts";
import * as T from "./types/mod.ts";
Expand Down Expand Up @@ -45,26 +46,26 @@ export type IngressMessage = OkMessage | ErrMessage | NotifMessage;
* @see https://github.com/paritytech/smoldot/blob/82836f4f2af4dd1716c57c14a4f591c7b1043950/src/json_rpc/methods.rs#L338-L479
*/
type MethodLookup = EnsureLookup<string, (...args: any[]) => any, {
system_accountNextIndex(account: U.AccountIdString): number;
system_accountNextIndex(account: B.AccountIdString): number;
account_nextIndex: TODO_NARROW_METHOD_TYPE;
system_dryRun: TODO_NARROW_METHOD_TYPE;
system_dryRunAt: MethodLookup["system_dryRun"];
author_submitExtrinsic(transaction: U.HexString): U.HashHexString;
author_submitExtrinsic(transaction: B.HexString): B.HashHexString;
author_insertKey: TODO_NARROW_METHOD_TYPE;
author_rotateKeys(): U.HexString;
author_rotateKeys(): B.HexString;
author_hasSessionKeys: TODO_NARROW_METHOD_TYPE;
author_hasKey(pubKey: string, keyType: string): string;
author_pendingExtrinsics(): U.HexString[];
author_pendingExtrinsics(): B.HexString[];
author_removeExtrinsics: TODO_NARROW_METHOD_TYPE;
author_submitAndWatchExtrinsic(tx: string): Subscription<unknown>;
author_unwatchExtrinsic(subscriptionId: U.SubscriptionIdString): unknown;
author_unwatchExtrinsic(subscriptionId: B.SubscriptionIdString): unknown;
babe_epochAuthorship(_: unknown): unknown;
chain_getBlock(hash?: U.HashHexString): T.Block;
chain_getBlockHash(height?: number): U.HashHexString;
chain_getBlock(hash?: B.HashHexString): T.Block;
chain_getBlockHash(height?: number): B.HashHexString;
chain_getHead: MethodLookup["chain_getBlockHash"];
chain_getFinalizedHead(): U.HashHexString;
chain_getFinalizedHead(): B.HashHexString;
chain_getFinalisedHead: MethodLookup["chain_getFinalizedHead"];
chain_getHeader(hash?: U.HashHexString): T.Header;
chain_getHeader(hash?: B.HashHexString): T.Header;
chain_subscribeAllHeads(): Subscription<T.Header>;
chain_subscribeFinalizedHeads(): Subscription<T.Header /* TODO: narrow to finalized? */>;
chain_subscribeFinalisedHeads: MethodLookup["chain_subscribeFinalizedHeads"];
Expand All @@ -85,33 +86,33 @@ type MethodLookup = EnsureLookup<string, (...args: any[]) => any, {
grandpa_roundState: TODO_NARROW_METHOD_TYPE;
offchain_localStorageGet: TODO_NARROW_METHOD_TYPE;
offchain_localStorageSet: TODO_NARROW_METHOD_TYPE;
payment_queryInfo(extrinsic: U.HexString, hash?: U.HashHexString): T.RuntimeDispatchInfo;
payment_queryInfo(extrinsic: B.HexString, hash?: B.HashHexString): T.RuntimeDispatchInfo;
rpc_methods(): T.RpcMethods;
state_call: TODO_NARROW_METHOD_TYPE;
state_callAt: MethodLookup["state_call"];
state_getKeys: TODO_NARROW_METHOD_TYPE;
state_getKeysPaged(
prefix: string | undefined,
count: number,
startKey?: U.HexString,
hash?: U.HashHexString,
): U.HexString[];
startKey?: B.HexString,
hash?: B.HashHexString,
): B.HexString[];
state_getKeysPagedAt: MethodLookup["state_getKeysPaged"];
state_getMetadata(hash?: U.HashHexString): string;
state_getMetadata(hash?: B.HashHexString): string;
state_getPairs: TODO_NARROW_METHOD_TYPE;
state_getReadProof: TODO_NARROW_METHOD_TYPE;
state_getRuntimeVersion(at?: U.HashHexString): T.RuntimeVersion;
state_getRuntimeVersion(at?: B.HashHexString): T.RuntimeVersion;
chain_getRuntimeVersion: MethodLookup["state_getRuntimeVersion"];
state_getStorage(key: U.HexString, hash?: U.HashHexString): U.HexString;
state_getStorage(key: B.HexString, hash?: B.HashHexString): B.HexString;
state_getStorageHash: TODO_NARROW_METHOD_TYPE;
state_getStorageHashAt: MethodLookup["state_getStorageHash"];
state_getStorageSize: TODO_NARROW_METHOD_TYPE;
state_getStorageSizeAt: MethodLookup["state_getStorageSize"];
state_queryStorage: TODO_NARROW_METHOD_TYPE;
state_queryStorageAt(keys: U.HexString[], at?: U.HashHexString): T.StorageChangeSet;
state_queryStorageAt(keys: B.HexString[], at?: B.HashHexString): T.StorageChangeSet;
state_subscribeRuntimeVersion: TODO_NARROW_METHOD_TYPE;
chain_subscribeRuntimeVersion: MethodLookup["state_subscribeRuntimeVersion"];
state_subscribeStorage(list: U.HexString[]): Subscription<"TODO">;
state_subscribeStorage(list: B.HexString[]): Subscription<"TODO">;
state_unsubscribeRuntimeVersion(subscription: string): boolean;
chain_unsubscribeRuntimeVersion: MethodLookup["state_unsubscribeRuntimeVersion"];
state_unsubscribeStorage(subscription: string): boolean;
Expand All @@ -129,39 +130,39 @@ type MethodLookup = EnsureLookup<string, (...args: any[]) => any, {
system_removeReservedPeer: TODO_NARROW_METHOD_TYPE;
system_version(): string;
chainHead_unstable_body(
followSubscription: U.HashHexString,
followSubscription: B.HashHexString,
networkConfig?: T.NetworkConfig,
): string;
chainHead_unstable_call(
hash: U.HashHexString | undefined,
hash: B.HashHexString | undefined,
fn: string,
callParameters: U.HexString,
callParameters: B.HexString,
networkConfig?: T.NetworkConfig,
): string;
chainHead_unstable_genesisHash(): U.HashHexString;
chainHead_unstable_genesisHash(): B.HashHexString;
chainHead_unstable_header(
followSubscription: string,
hash: U.HashHexString,
): U.HexString | undefined;
hash: B.HashHexString,
): B.HexString | undefined;
chainHead_unstable_stopBody(subscription: string): void;
chainHead_unstable_stopCall(subscription: string): void;
chainHead_unstable_stopStorage(subscription: string): void;
chainHead_unstable_storage(
follow_subscription: U.SubscriptionIdString,
hash: U.HashHexString,
key: U.HexString,
childKey?: U.HexString,
follow_subscription: B.SubscriptionIdString,
hash: B.HashHexString,
key: B.HexString,
childKey?: B.HexString,
networkConfig?: T.NetworkConfig,
): string;
chainHead_unstable_unfollow(followSubscription: U.SubscriptionIdString): void;
chainHead_unstable_unpin(followSubscription: U.SubscriptionIdString, hash: U.HashHexString): void;
chainHead_unstable_unfollow(followSubscription: B.SubscriptionIdString): void;
chainHead_unstable_unpin(followSubscription: B.SubscriptionIdString, hash: B.HashHexString): void;
chainSpec_unstable_chainName(): string;
chainSpec_unstable_genesisHash(): string;
chainSpec_unstable_properties(): unknown;
sudo_unstable_p2pDiscover(multiaddr: U.MultiAddressString): void;
sudo_unstable_p2pDiscover(multiaddr: B.MultiAddressString): void;
sudo_unstable_version(): string;
transaction_unstable_submitAndWatch(transaction: U.HexString): U.SubscriptionIdString;
transaction_unstable_unwatch(subscription: U.SubscriptionIdString): void;
transaction_unstable_submitAndWatch(transaction: B.HexString): B.SubscriptionIdString;
transaction_unstable_unwatch(subscription: B.SubscriptionIdString): void;
}>;

type ErrDetailLookup = EnsureLookup<string, [code: number, data?: any], {
Expand Down Expand Up @@ -222,7 +223,7 @@ export interface NotifMessageBase<Method extends MethodName, Result> extends Jso
method: Method;
id?: never;
params: {
subscription: U.SubscriptionIdString;
subscription: B.SubscriptionIdString;
result: Result;
};
result?: never;
Expand Down
14 changes: 7 additions & 7 deletions rpc/types/chain_head/unstable/follow.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as U from "../../../../util/mod.ts";
import * as B from "../../../../branded.ts";

export type ChainHeadUnstableFollowEvent =
| ChainHeadUnstableFollowInitializedEvent
Expand All @@ -21,29 +21,29 @@ interface ChainHeadUnstableFollowEventBase<Kind extends ChainHeadUnstableFollowE
export interface ChainHeadUnstableFollowInitializedEvent
extends ChainHeadUnstableFollowEventBase<"initialized">
{
finalizedBlockHash: U.HashHexString;
finalizedBlockHash: B.HashHexString;
finalizedBlockRuntime: string;
}

export interface ChainHeadUnstableFollowNewBlockEvent
extends ChainHeadUnstableFollowEventBase<"newBlock">
{
blockHash: U.HashHexString;
parentBlockHash: U.HashHexString;
blockHash: B.HashHexString;
parentBlockHash: B.HashHexString;
newRuntime: null; // TODO
}

export interface ChainHeadUnstableFollowBestBlockChangedEvent
extends ChainHeadUnstableFollowEventBase<"bestBlockChanged">
{
bestBlockHash: U.HashHexString;
bestBlockHash: B.HashHexString;
}

export interface ChainHeadUnstableFollowFinalizedEvent
extends ChainHeadUnstableFollowEventBase<"finalized">
{
finalizedBlocksHashes: U.HashHexString[];
prunedBlocksHashes: U.HashHexString[];
finalizedBlocksHashes: B.HashHexString[];
prunedBlocksHashes: B.HashHexString[];
}

export type ChainHeadUnstableFollowStopEvent = ChainHeadUnstableFollowEventBase<"stop">;
Expand Down
22 changes: 11 additions & 11 deletions rpc/types/common.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import * as U from "../../util/mod.ts";
import * as B from "../../branded.ts";

export interface Block {
block: {
header: Header;
extrinsics: U.HexString[];
extrinsics: B.HexString[];
};
justifications?: [number[], number[]][];
}

export interface HeaderDigest {
logs: U.HexString[];
logs: B.HexString[];
}

export interface Header {
digest: HeaderDigest;
extrinsicsRoot: U.HashHexString;
number: U.HexU64String;
parentHash: U.HashHexString;
stateRoot: U.HashHexString;
extrinsicsRoot: B.HashHexString;
number: B.HexU64String;
parentHash: B.HashHexString;
stateRoot: B.HashHexString;
}

export interface RuntimeVersion {
Expand All @@ -28,12 +28,12 @@ export interface RuntimeVersion {
implVersion: number;
transactionVersion?: number;
stateVersion?: number;
apis: [U.HexString, number][];
apis: [B.HexString, number][];
}

export interface StorageChangeSet {
block: U.HashHexString;
changes: [U.HexString, U.HexString | undefined][];
block: B.HashHexString;
changes: [B.HexString, B.HexString | undefined][];
}

export interface SystemHealth {
Expand All @@ -50,7 +50,7 @@ export type SystemPeerRole =
export interface SystemPeer {
peerId: string;
roles: SystemPeerRole;
bestHash: U.HashHexString;
bestHash: B.HashHexString;
bestNumber: number;
}

Expand Down
19 changes: 19 additions & 0 deletions spec/Block.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { HashHexString } from "../branded.ts";
import { Chain } from "./Chain.ts";
import { NodeBase, NodeKind } from "./Node.ts";
import { Read } from "./Read.ts";

export class Block extends NodeBase {
readonly kind = NodeKind.Block;

constructor(
readonly chain: Chain,
readonly hash?: HashHexString,
) {
super();
}

read(): Read<this> {
return new Read(this);
}
}
31 changes: 31 additions & 0 deletions spec/Chain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as B from "../branded.ts";
import { Block } from "./Block.ts";
import { Metadata } from "./Metadata.ts";
import { NodeBase, NodeKind } from "./Node.ts";
import { Pallet } from "./Pallet.ts";

export type Beacon = B.WsUrlString | B.ChainSpecString;

export class Chain extends NodeBase {
readonly kind = NodeKind.Chain;

constructor(readonly beacon: Beacon) {
super();
}

metadata(block?: Block): Metadata {
return new Metadata(this, block);
}

block(hash?: B.HashHexString): Block {
return new Block(this, hash);
}

pallet(name: string): Pallet {
return new Pallet(this, name);
}
}

export function chain(beacon: Beacon): Chain {
return new Chain(beacon);
}
22 changes: 22 additions & 0 deletions spec/Extrinsic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { MultiAddress } from "../primitives/MultiAddress.ts";
import { ExtrinsicFactory } from "./ExtrinsicFactory.ts";
import { NodeBase, NodeKind } from "./Node.ts";
import { SignedExtrinsic } from "./SignedExtrinsic.ts";

export class Extrinsic<CallData extends Record<string, unknown> = Record<string, any>>
extends NodeBase
{
readonly kind = NodeKind.Extrinsic;

constructor(
readonly factory: ExtrinsicFactory<CallData>,
readonly caller: MultiAddress,
readonly callData: CallData,
) {
super();
}

sign(sign: (message: Uint8Array) => Uint8Array): SignedExtrinsic {
return new SignedExtrinsic(this as Extrinsic, sign);
}
Comment on lines +23 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to also take extra and additional

}
Loading