This repository has been archived by the owner on Sep 14, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5bd2f57
commit 8f1ed25
Showing
66 changed files
with
664 additions
and
972 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,10 @@ await Promise.all([ | |
name: "parity-scale-codec", | ||
version: "^0.6.1", | ||
}, | ||
"https://deno.land/x/[email protected]/mod.ts": { | ||
name: "zones", | ||
version: "0.1.0-beta.6", | ||
}, | ||
"deps/smoldot_phantom.ts": { | ||
name: "@substrate/smoldot-light", | ||
version: "0.6.20", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "https://deno.land/x/[email protected]/mod.ts"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import * as Z from "../deps/zones.ts"; | ||
import * as known from "../known/mod.ts"; | ||
import * as U from "../util/mod.ts"; | ||
import { $extrinsic } from "./core/$extrinsic.ts"; | ||
import { deriveCodec } from "./core/deriveCodec.ts"; | ||
import { Metadata } from "./Metadata.ts"; | ||
import { RpcCall } from "./RpcCall.ts"; | ||
|
||
export class BlockRead<Rest extends [blockHash?: Z.$<U.HashHexString | undefined>]> extends Z.Name { | ||
root; | ||
|
||
constructor( | ||
config: known.rpc.Config<string, "state_getMetadata" | "chain_getBlock">, | ||
...[blockHash]: [...Rest] | ||
) { | ||
super(); | ||
const metadata_ = new Metadata(config, blockHash); | ||
const $extrinsic_ = $extrinsic(deriveCodec(metadata_), metadata_, undefined!); | ||
const call = new RpcCall(config, "chain_getBlock", [blockHash]); | ||
const decoded = Z.call(Z.ls($extrinsic_, call), function mapExtrinsicCall([$extrinsic_, call]) { | ||
const { block: { extrinsics, header }, justifications } = call.result; | ||
return { | ||
justifications, | ||
block: { | ||
header, | ||
extrinsics: extrinsics.map((extrinsic) => { | ||
return $extrinsic_.decode(U.hex.decode(extrinsic)); | ||
}), | ||
}, | ||
}; | ||
}); | ||
this.root = Z.wrap(decoded, "block"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import * as Z from "../deps/zones.ts"; | ||
import { Extrinsic } from "../frame_metadata/mod.ts"; | ||
import * as known from "../known/mod.ts"; | ||
import * as U from "../util/mod.ts"; | ||
import { BlockRead } from "./BlockRead.ts"; | ||
import { RpcCall } from "./RpcCall.ts"; | ||
import { RpcSubscription } from "./RpcSubscription.ts"; | ||
import { run } from "./run.ts"; | ||
|
||
export class BlockWatch extends Z.Name { | ||
root; | ||
|
||
constructor( | ||
config: known.rpc.Config< | ||
string, | ||
"state_getMetadata" | "chain_getBlockHash" | "chain_getBlock" | "chain_unsubscribeNewHead", | ||
"chain_subscribeNewHeads" | ||
>, | ||
createWatchHandler: U.CreateWatchHandler<known.types.Block<Extrinsic>>, | ||
) { | ||
super(); | ||
this.root = new RpcSubscription( | ||
config, | ||
"chain_subscribeNewHeads", | ||
[], | ||
function subscribeNewHeadsHandler(stop) { | ||
const watchHandler = createWatchHandler(stop); | ||
return async (result) => { | ||
const blockNum = result.params.result.number; | ||
const blockHash = Z.sel(new RpcCall(config, "chain_getBlockHash", [blockNum]), "result"); | ||
// TODO: use derived util from Zones | ||
const block = U.throwIfError(await run(new BlockRead(config, blockHash))); | ||
watchHandler(block.block); | ||
}; | ||
}, | ||
(ok) => new RpcCall(config, "chain_unsubscribeNewHead", [ok.result]), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import * as Z from "../deps/zones.ts"; | ||
import * as known from "../known/mod.ts"; | ||
import * as U from "../util/mod.ts"; | ||
import { $storageKey } from "./core/$storageKey.ts"; | ||
import { codec } from "./core/codec.ts"; | ||
import { decoded } from "./core/decoded.ts"; | ||
import { deriveCodec } from "./core/deriveCodec.ts"; | ||
import { storageKey } from "./core/storageKey.ts"; | ||
import { entryMetadata, Metadata, palletMetadata } from "./Metadata.ts"; | ||
import { RpcCall } from "./RpcCall.ts"; | ||
|
||
export class EntryRead< | ||
PalletName extends Z.$<string>, | ||
EntryName extends Z.$<string>, | ||
Keys extends unknown[], | ||
Rest extends [blockHash?: Z.$<U.HashHexString | undefined>], | ||
> extends Z.Name { | ||
root; | ||
|
||
constructor( | ||
config: known.rpc.Config<string, "state_getMetadata" | "state_getStorage">, | ||
palletName: PalletName, | ||
entryName: EntryName, | ||
keys: [...Keys], | ||
...[blockHash]: [...Rest] | ||
) { | ||
super(); | ||
const metadata_ = new Metadata(config, blockHash); | ||
const deriveCodec_ = deriveCodec(metadata_); | ||
const palletMetadata_ = palletMetadata(metadata_, palletName); | ||
const entryMetadata_ = entryMetadata(palletMetadata_, entryName); | ||
const $storageKey_ = $storageKey(deriveCodec_, palletMetadata_, entryMetadata_); | ||
const storageKey_ = storageKey($storageKey_, ...keys); | ||
const storageCall = new RpcCall(config, "state_getStorage", [storageKey_, blockHash]); | ||
const entryValueTypeI = Z.sel(entryMetadata_, "value"); | ||
const $entry = codec(deriveCodec_, entryValueTypeI); | ||
const resultHex = Z.sel(storageCall, "result"); | ||
this.root = decoded($entry, resultHex, "value"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import * as Z from "../deps/zones.ts"; | ||
import * as known from "../known/mod.ts"; | ||
import * as rpc from "../rpc/mod.ts"; | ||
import * as U from "../util/mod.ts"; | ||
import { $storageKey } from "./core/$storageKey.ts"; | ||
import { codec } from "./core/codec.ts"; | ||
import { deriveCodec } from "./core/deriveCodec.ts"; | ||
import { storageKey } from "./core/storageKey.ts"; | ||
import { entryMetadata, Metadata, palletMetadata } from "./Metadata.ts"; | ||
import { RpcCall } from "./RpcCall.ts"; | ||
import { RpcSubscription } from "./RpcSubscription.ts"; | ||
|
||
export type WatchEntryEvent = [key?: U.HexString, value?: unknown]; | ||
|
||
type Config = known.rpc.Config< | ||
string, | ||
"state_getMetadata" | "state_unsubscribeStorage", | ||
"state_subscribeStorage" | ||
>; | ||
|
||
export class EntryWatch< | ||
PalletName extends Z.$<string>, | ||
EntryName extends Z.$<string>, | ||
Keys extends unknown[], | ||
> extends Z.Name { | ||
root; | ||
|
||
constructor( | ||
readonly config: Config, | ||
readonly palletName: PalletName, | ||
readonly entryName: EntryName, | ||
readonly keys: Keys, | ||
readonly createWatchHandler: U.CreateWatchHandler<WatchEntryEvent[]>, | ||
) { | ||
super(); | ||
const metadata_ = new Metadata(config); | ||
const deriveCodec_ = deriveCodec(metadata_); | ||
const palletMetadata_ = palletMetadata(metadata_, palletName); | ||
const entryMetadata_ = entryMetadata(palletMetadata_, entryName); | ||
const $storageKey_ = $storageKey(deriveCodec_, palletMetadata_, entryMetadata_); | ||
const entryValueTypeI = Z.sel(entryMetadata_, "value"); | ||
const $entry = codec(deriveCodec_, entryValueTypeI); | ||
const storageKeys = Z.call( | ||
storageKey($storageKey_, ...keys.length ? [keys] : []), | ||
function wrapWithList(v) { | ||
return [v]; | ||
}, | ||
); | ||
const watchInit = Z.call($entry, function entryWatchInit($entry) { | ||
return U.mapCreateWatchHandler( | ||
createWatchHandler, | ||
(message: rpc.NotifMessage<Config, "state_subscribeStorage">) => { | ||
return message.params.result.changes.map(([key, val]) => { | ||
return <WatchEntryEvent> [key, val ? $entry.decode(U.hex.decode(val)) : undefined]; | ||
}); | ||
}, | ||
); | ||
}); | ||
this.root = new RpcSubscription( | ||
config, | ||
"state_subscribeStorage", | ||
[storageKeys], | ||
watchInit, | ||
(ok) => { | ||
return new RpcCall(config, "state_unsubscribeStorage", [ok.result]); | ||
}, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import { unimplemented } from "../deps/std/testing/asserts.ts"; | ||
import * as Z from "../deps/zones.ts"; | ||
import * as M from "../frame_metadata/mod.ts"; | ||
import * as known from "../known/mod.ts"; | ||
import * as rpc from "../rpc/mod.ts"; | ||
import * as ss58 from "../ss58/mod.ts"; | ||
import * as U from "../util/mod.ts"; | ||
import { $extrinsic } from "./core/$extrinsic.ts"; | ||
import { deriveCodec } from "./core/deriveCodec.ts"; | ||
import { hexDecode } from "./core/hex.ts"; | ||
import { Metadata } from "./Metadata.ts"; | ||
import { RpcCall } from "./RpcCall.ts"; | ||
import { RpcSubscription } from "./RpcSubscription.ts"; | ||
|
||
export { type Config as SendAndWatchExtrinsicConfig }; | ||
type Config = known.rpc.Config< | ||
string, | ||
| "state_getMetadata" | ||
| "state_getRuntimeVersion" | ||
| "chain_getBlockHash" | ||
| "system_accountNextIndex" | ||
| "system_chain" | ||
| "author_unwatchExtrinsic", | ||
"author_submitAndWatchExtrinsic" | ||
>; | ||
|
||
export interface SendAndWatchExtrinsicProps { | ||
sender: M.MultiAddress; | ||
palletName: string; | ||
methodName: string; | ||
args: Record<string, unknown>; | ||
checkpoint?: U.HashHexString; | ||
mortality?: [period: bigint, phase: bigint]; | ||
nonce?: string; | ||
tip?: bigint; | ||
sign: M.SignExtrinsic; | ||
createWatchHandler: U.CreateWatchHandler< | ||
rpc.NotifMessage<Config, "author_submitAndWatchExtrinsic"> | ||
>; | ||
} | ||
|
||
export class ExtrinsicSentWatch<Props extends Z.Rec$<SendAndWatchExtrinsicProps>> extends Z.Name { | ||
root; | ||
|
||
constructor( | ||
readonly config: Config, | ||
readonly props_: Props, | ||
) { | ||
super(); | ||
const props = props_ as Z.Rec$Access<Props>; | ||
const metadata_ = new Metadata(config); | ||
const deriveCodec_ = deriveCodec(metadata_); | ||
const $extrinsic_ = $extrinsic(deriveCodec_, metadata_, props.sign, config.addressPrefix); | ||
const runtimeVersion = new RpcCall(config, "state_getRuntimeVersion", []); | ||
const senderSs58 = Z.call(props.sender, function senderSs58(sender) { | ||
return ((): string => { | ||
switch (sender.type) { | ||
case "Id": { | ||
return ss58.encode(config.addressPrefix, sender.value); | ||
} | ||
// TODO: other types | ||
default: { | ||
unimplemented(); | ||
} | ||
} | ||
})() as U.AccountIdString; | ||
}); | ||
const accountNextIndex = new RpcCall(config, "system_accountNextIndex", [senderSs58]); | ||
const genesisHash = hexDecode(Z.sel(new RpcCall(config, "chain_getBlockHash", [0]), "result")); | ||
const checkpointHash = props.checkpoint | ||
? Z.call(props.checkpoint, function checkpointOrUndef(v) { | ||
return v ? U.hex.decode(v) : v; | ||
}) | ||
: genesisHash; | ||
const extrinsicHex = Z.call( | ||
Z.ls( | ||
$extrinsic_, | ||
props.sender, | ||
props.methodName, | ||
props.palletName, | ||
runtimeVersion, | ||
accountNextIndex, | ||
genesisHash, | ||
props.args, | ||
checkpointHash, | ||
props.tip, | ||
props.mortality, | ||
), | ||
async function formExtrinsicHex([ | ||
$extrinsic, | ||
sender, | ||
methodName, | ||
palletName, | ||
{ result: { specVersion, transactionVersion } }, | ||
{ result: nonce }, | ||
genesisHash, | ||
args, | ||
checkpoint, | ||
tip, | ||
mortality, | ||
]) { | ||
const extrinsicBytes = await $extrinsic.encodeAsync({ | ||
protocolVersion: 4, // TODO: grab this from elsewhere | ||
palletName, | ||
methodName, | ||
args, | ||
signature: { | ||
address: sender, | ||
extra: [ | ||
mortality | ||
? { | ||
type: "Mortal", | ||
value: mortality, | ||
} | ||
: { type: "Immortal" }, | ||
nonce, | ||
tip || 0, | ||
], | ||
additional: [specVersion, transactionVersion, checkpoint, genesisHash], | ||
}, | ||
}); | ||
return U.hex.encode(extrinsicBytes) as U.HexString; | ||
}, | ||
); | ||
this.root = new RpcSubscription( | ||
config, | ||
"author_submitAndWatchExtrinsic", | ||
[extrinsicHex], | ||
props.createWatchHandler, | ||
// TODO: use effect system for cbs such as this | ||
(ok) => new RpcCall(config, "author_unwatchExtrinsic", [ok.result]), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import * as Z from "../deps/zones.ts"; | ||
import * as known from "../known/mod.ts"; | ||
import * as U from "../util/mod.ts"; | ||
import { $key } from "./core/$key.ts"; | ||
import { $storageKey } from "./core/$storageKey.ts"; | ||
import { deriveCodec } from "./core/deriveCodec.ts"; | ||
import { storageKey } from "./core/storageKey.ts"; | ||
import { entryMetadata, Metadata, palletMetadata } from "./Metadata.ts"; | ||
import { RpcCall } from "./RpcCall.ts"; | ||
|
||
export class KeyPageRead< | ||
PalletName extends Z.$<string>, | ||
EntryName extends Z.$<string>, | ||
Count extends Z.$<number>, | ||
Rest extends [start?: unknown[] | undefined, blockHash?: Z.$<U.HashHexString | undefined>], | ||
> extends Z.Name { | ||
root; | ||
|
||
constructor( | ||
config: known.rpc.Config<string, "state_getMetadata" | "state_getKeysPaged">, | ||
palletName: PalletName, | ||
entryName: EntryName, | ||
count: Count, | ||
...[start, blockHash]: [...Rest] | ||
) { | ||
super(); | ||
const metadata_ = new Metadata(config, blockHash as Rest[1]); | ||
const deriveCodec_ = deriveCodec(metadata_); | ||
const palletMetadata_ = palletMetadata(metadata_, palletName); | ||
const entryMetadata_ = Z.call( | ||
entryMetadata(palletMetadata_, entryName), | ||
function assertIsMap(entryMetadata) { | ||
if (entryMetadata.type !== "Map") { | ||
return new ReadingKeysOfNonMapError(); | ||
} | ||
return entryMetadata; | ||
}, | ||
); | ||
const $storageKey_ = $storageKey(deriveCodec_, palletMetadata_, entryMetadata_); | ||
const startKey = start ? storageKey($storageKey_, start) : undefined; | ||
const storageKey_ = storageKey($storageKey_); | ||
const call = new RpcCall(config, "state_getKeysPaged", [ | ||
storageKey_, | ||
count, | ||
startKey, | ||
blockHash as Rest[1], | ||
]); | ||
const $key_ = $key(deriveCodec_, palletMetadata_, entryMetadata_); | ||
const keysEncoded = Z.sel(call, "result"); | ||
const keysDecoded = Z.call( | ||
Z.ls($key_, keysEncoded), | ||
function keysDecodedImpl([$key, keysEncoded]) { | ||
return keysEncoded.map((keyEncoded) => { | ||
return $key.decode(U.hex.decode(keyEncoded)); | ||
}); | ||
}, | ||
); | ||
this.root = Z.wrap(keysDecoded, "keys"); | ||
} | ||
} | ||
|
||
export class ReadingKeysOfNonMapError extends U.ErrorCtor("ReadingKeysOfNonMap") {} |
Oops, something went wrong.