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

Commit

Permalink
chore: misc effect cleanup (#366)
Browse files Browse the repository at this point in the history
  • Loading branch information
harrysolovay authored Nov 8, 2022
1 parent 2c3183e commit 2444a64
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 143 deletions.
4 changes: 2 additions & 2 deletions effects/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import * as Z from "../deps/zones.ts";
import * as rpc from "../rpc/mod.ts";
import * as U from "../util/mod.ts";
import { codec } from "./core/codec.ts";
import { decoded } from "./core/decoded.ts";
import { deriveCodec } from "./core/deriveCodec.ts";
import * as e$ from "./core/scale.ts";
import { constMetadata, metadata, palletMetadata } from "./metadata.ts";

export function const_<Client extends Z.$<rpc.Client>>(client: Client) {
Expand All @@ -23,7 +23,7 @@ export function const_<Client extends Z.$<rpc.Client>>(client: Client) {
const entryValueTypeI = constMetadata_.access("ty").access("id");
const constValue = constMetadata_.access("value");
const $const = codec(deriveCodec_, entryValueTypeI);
return decoded($const, constValue, "value").zoned("Const");
return e$.decoded($const, constValue, "value").zoned("Const");
};
}
Object.defineProperty(const_, "name", {
Expand Down
14 changes: 0 additions & 14 deletions effects/core/$key.ts

This file was deleted.

19 changes: 0 additions & 19 deletions effects/core/decoded.ts

This file was deleted.

5 changes: 0 additions & 5 deletions effects/core/hex.ts

This file was deleted.

11 changes: 11 additions & 0 deletions effects/core/option.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as Z from "../../deps/zones.ts";

// TODO: move this into zones
export function option<Target, UseResult>(
target: Target,
use: (resolved: NonNullable<Z.T<Target>>) => UseResult,
): Z.Effect<undefined | Exclude<UseResult, Error>, Z.E<Target> | Extract<UseResult, Error>> {
return Z.call(target, (resolved) => {
return resolved ? use(resolved) : undefined;
});
}
35 changes: 35 additions & 0 deletions effects/core/scale.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as $ from "../../deps/scale.ts";
import * as Z from "../../deps/zones.ts";

export function decoded<
Codec extends Z.$<$.Codec<unknown>>,
Encoded extends Z.$<Uint8Array>,
Key extends Z.$<PropertyKey>,
>(
codec: Codec,
encoded: Encoded,
key: Key,
) {
return Z.call(
Z.ls(codec, encoded, key),
function decodedImpl([codec, encoded, key]): Record<Z.T<Key>, any> {
return { [key]: codec.decode(encoded) } as any;
},
);
}

// TODO: eventually, utilize `V` to toggle runtime validation
export function encoded<Codec extends Z.$<$.Codec<any>>, Decoded>(
codec: Codec,
decoded: Decoded,
isAsync?: boolean,
) {
return Z.call(Z.ls(codec, decoded, isAsync), function encodedImpl([codec, decoded]) {
try {
$.assert(codec, decoded);
} catch (e) {
return e as $.ScaleAssertError;
}
return codec[isAsync ? "encodeAsync" : "encode"](decoded);
});
}
10 changes: 0 additions & 10 deletions effects/core/storageKey.ts

This file was deleted.

11 changes: 5 additions & 6 deletions effects/entryRead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ 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 { decoded } from "./core/decoded.ts";
import { deriveCodec } from "./core/deriveCodec.ts";
import { hexDecode } from "./core/hex.ts";
import { storageKey } from "./core/storageKey.ts";
import * as e$ from "./core/scale.ts";
import { entryMetadata, metadata, palletMetadata } from "./metadata.ts";
import { state } from "./rpc/known.ts";

Expand All @@ -27,10 +25,11 @@ export function entryRead<Client extends Z.$<rpc.Client>>(client: Client) {
const palletMetadata_ = palletMetadata(metadata_, palletName);
const entryMetadata_ = entryMetadata(palletMetadata_, entryName);
const $storageKey_ = $storageKey(deriveCodec_, palletMetadata_, entryMetadata_);
const storageKey_ = storageKey($storageKey_, ...keys);
const storageValueHex = state.getStorage(client)(storageKey_, blockHash);
const storageKey = Z.call(e$.encoded($storageKey_, Z.ls(...keys)), U.hex.encode);
const storageBytesHex = state.getStorage(client)(storageKey, blockHash);
const storageBytes = Z.call(storageBytesHex, U.hex.decode);
const entryValueTypeI = entryMetadata_.access("value");
const $entry = codec(deriveCodec_, entryValueTypeI);
return decoded($entry, hexDecode(storageValueHex), "value").zoned("EntryRead");
return e$.decoded($entry, storageBytes, "value").zoned("EntryRead");
};
}
17 changes: 11 additions & 6 deletions effects/entryWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ 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 * as e$ from "./core/scale.ts";
import { entryMetadata, metadata, palletMetadata } from "./metadata.ts";
import { state } from "./rpc/known.ts";

export type WatchEntryEvent = [key?: U.Hex, value?: unknown];
export type WatchEntryEvent = [key?: unknown, value?: unknown];

export function entryWatch<Client extends Z.$<rpc.Client>>(client: Client) {
return <
Expand All @@ -30,18 +30,23 @@ export function entryWatch<Client extends Z.$<rpc.Client>>(client: Client) {
const entryValueTypeI = entryMetadata_.access("value");
const $entry = codec(deriveCodec_, entryValueTypeI);
const storageKeys = Z.call(
storageKey($storageKey_, ...keys.length ? [keys] : []),
function wrapWithList(v) {
return [v];
e$.encoded($storageKey_, keys.length ? [keys] : []),
function hexEncodeAndWrapWithList(v) {
return [U.hex.encode(v)];
},
);
const listenerMapped = Z.call(Z.ls($entry, listener), ([$entry, listener]) => {
return function listenerMapped(
this: rpc.ClientSubscribeContext,
changeset: known.StorageChangeSet,
) {
// TODO: in some cases there might be keys to decode
// key ? $storageKey.decode(U.hex.decode(key)) : undefined
const getKey = (key: known.Hex) => {
return key;
};
const changes: WatchEntryEvent[] = changeset.changes.map(([key, val]) => {
return [key, val ? $entry.decode(U.hex.decode(val)) : undefined];
return [getKey(key), val ? $entry.decode(U.hex.decode(val)) : undefined];
});
listener.apply(this, [changes]);
};
Expand Down
110 changes: 40 additions & 70 deletions effects/extrinsic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import * as U from "../util/mod.ts";
import { const as const_ } from "./const.ts";
import { $extrinsic } from "./core/$extrinsic.ts";
import { deriveCodec } from "./core/deriveCodec.ts";
import { hexDecode } from "./core/hex.ts";
import { option } from "./core/option.ts";
import * as e$ from "./core/scale.ts";
import { metadata } from "./metadata.ts";
import { author, chain, system } from "./rpc/known.ts";

Expand Down Expand Up @@ -43,19 +44,22 @@ export class SignedExtrinsic<
Props extends Z.Rec$<ExtrinsicProps>,
Sign extends Z.$<M.SignExtrinsic>,
> {
props;
extrinsic;

constructor(readonly props_: Props, readonly sign: Sign) {
const props = props_ as Z.Rec$Access<Props>;
const metadata_ = metadata(props.client)();
constructor(props_: Props, readonly sign: Sign) {
this.props = props_ as Z.Rec$Access<Props>;
const metadata_ = metadata(this.props.client)();
const deriveCodec_ = deriveCodec(metadata_);
const addrPrefix = const_(props.client)("System", "SS58Prefix").access("value").as<number>();
const addrPrefix = const_(this.props.client)("System", "SS58Prefix")
.access("value").as<number>();
const $extrinsic_ = $extrinsic(deriveCodec_, metadata_, this.sign, addrPrefix);
const versions = const_(props.client)("System", "Version").access("value");
const versions = const_(this.props.client)("System", "Version").access("value");
const specVersion = versions.access("spec_version").as<number>();
const transactionVersion = versions.access("transaction_version").as<number>();
// TODO: create match effect in zones and use here
const senderSs58 = Z.call(
Z.ls(addrPrefix, props.sender),
Z.ls(addrPrefix, this.props.sender),
function senderSs58([addrPrefix, sender]) {
switch (sender.type) {
case "Id": {
Expand All @@ -68,79 +72,45 @@ export class SignedExtrinsic<
}
},
);
const nonce = system.accountNextIndex(props.client)(senderSs58);
const genesisHash = hexDecode(chain.getBlockHash(props.client)(0));
const checkpointHash = props.checkpoint
? Z.call(props.checkpoint, function checkpointOrUndef(v) {
return v ? U.hex.decode(v) : v;
})
const nonce = system.accountNextIndex(this.props.client)(senderSs58);
const genesisHashBytes = chain.getBlockHash(this.props.client)(0);
const genesisHash = Z.call(genesisHashBytes, U.hex.decode);
const checkpointHash = this.props.checkpoint
? option(this.props.checkpoint, U.hex.decode)
: genesisHash;
this.extrinsic = Z.call(
Z.ls(
$extrinsic_,
props.sender,
props.methodName,
props.palletName,
specVersion,
transactionVersion,
nonce,
genesisHash,
props.args,
checkpointHash,
props.tip,
props.mortality,
),
async function formExtrinsicHex([
$extrinsic,
sender,
methodName,
palletName,
specVersion,
transactionVersion,
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);
},
);
const $extrinsicProps = Z.rec({
protocolVersion: 4,
palletName: this.props.palletName,
methodName: this.props.methodName,
args: this.props.args,
signature: Z.rec({
address: this.props.sender,
extra: Z.ls(
this.props.mortality
? Z.rec({ type: "Mortal", value: this.props.mortality })
: { type: "Immortal" },
nonce,
this.props.tip || 0,
),
additional: Z.ls(specVersion, transactionVersion, checkpointHash, genesisHash),
}),
});
this.extrinsic = Z.call(e$.encoded($extrinsic_, $extrinsicProps, true), U.hex.encode);
}

watch<Listener extends Z.$<U.Listener<known.TransactionStatus, rpc.ClientSubscribeContext>>>(
listener: Listener,
) {
const subscriptionId = author.submitAndWatchExtrinsic(
this.props_.client as Props["client"],
)([this.extrinsic], listener);
return author.unwatchExtrinsic(this.props_.client as Props["client"])(subscriptionId)
const subscriptionId = author.submitAndWatchExtrinsic(this.props.client)(
[this.extrinsic],
listener,
);
return author.unwatchExtrinsic(this.props.client)(subscriptionId)
.zoned("ExtrinsicWatch");
}

get sent() {
return author.submitExtrinsic(this.props_.client as Props["client"])(this.extrinsic)
return author.submitExtrinsic(this.props.client)(this.extrinsic)
.zoned("ExtrinsicSent");
}
}
19 changes: 8 additions & 11 deletions effects/keyPageRead.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import * as Z from "../deps/zones.ts";
import * as rpc from "../rpc/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 * as e$ from "./core/scale.ts";
import { mapMetadata, metadata, palletMetadata } from "./metadata.ts";
import { state } from "./rpc/known.ts";

Expand All @@ -25,22 +24,20 @@ export function keyPageRead<Client extends Z.$<rpc.Client>>(client: Client) {
const palletMetadata_ = palletMetadata(metadata_, palletName);
const entryMetadata_ = mapMetadata(palletMetadata_, entryName);
const $storageKey_ = $storageKey(deriveCodec_, palletMetadata_, entryMetadata_);
const startKey = start ? storageKey($storageKey_, start) : undefined;
const storageKey_ = storageKey($storageKey_);
const storageKey = Z.call(e$.encoded($storageKey_, []), U.hex.encode);
const startKey = start ? Z.call(e$.encoded($storageKey_, []), U.hex.encode) : undefined;
const keysEncoded = state.getKeysPaged(client)(
storageKey_,
storageKey,
count,
startKey,
blockHash as Rest[1],
);
const $key_ = $key(deriveCodec_, palletMetadata_, entryMetadata_);
return Z.call(
Z.ls($key_, keysEncoded),
function keysDecodedImpl([$key, keysEncoded]) {
return Z
.call(Z.ls($storageKey_, keysEncoded), function keysDecodedImpl([$key, keysEncoded]) {
return keysEncoded.map((keyEncoded: U.Hex) => {
return $key.decode(U.hex.decode(keyEncoded));
});
},
).zoned("KeyPageRead");
})
.zoned("KeyPageRead");
};
}
1 change: 1 addition & 0 deletions effects/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as rpc from "../rpc/mod.ts";
import * as U from "../util/mod.ts";
import { state } from "./rpc/known.ts";

// TODO: callable object so that one doesn't need the extra parens when not specifying block hash?
export function metadata<Client extends Z.$<rpc.Client>>(client: Client) {
return <Rest extends [blockHash?: Z.$<U.HexHash | undefined>]>(...[blockHash]: [...Rest]) => {
return Z.call(
Expand Down

0 comments on commit 2444a64

Please sign in to comment.