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

chore: cleanup to metadata and extrinsic effect apis #312

Merged
merged 4 commits into from
Oct 22, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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
6 changes: 3 additions & 3 deletions effect/EntryRead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ 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 { Metadata } from "./Metadata.ts";
import { RpcCall } from "./RpcCall.ts";

export class EntryRead<
Expand All @@ -27,8 +27,8 @@ export class EntryRead<
super();
const metadata_ = new Metadata(config, blockHash);
const deriveCodec_ = deriveCodec(metadata_);
const palletMetadata_ = palletMetadata(metadata_, palletName);
const entryMetadata_ = entryMetadata(palletMetadata_, entryName);
const palletMetadata_ = metadata_.pallet(palletName);
const entryMetadata_ = palletMetadata_.entry(entryName);
const $storageKey_ = $storageKey(deriveCodec_, palletMetadata_, entryMetadata_);
const storageKey_ = storageKey($storageKey_, ...keys);
const storageCall = new RpcCall(config, "state_getStorage", [storageKey_, blockHash]);
Expand Down
6 changes: 3 additions & 3 deletions effect/EntryWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ 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 { Metadata } from "./Metadata.ts";
import { RpcCall } from "./RpcCall.ts";
import { RpcSubscription } from "./RpcSubscription.ts";

Expand All @@ -29,8 +29,8 @@ export class EntryWatch<
super();
const metadata_ = new Metadata(config);
const deriveCodec_ = deriveCodec(metadata_);
const palletMetadata_ = palletMetadata(metadata_, palletName);
const entryMetadata_ = entryMetadata(palletMetadata_, entryName);
const palletMetadata_ = metadata_.pallet(palletName);
const entryMetadata_ = palletMetadata_.entry(entryName);
const $storageKey_ = $storageKey(deriveCodec_, palletMetadata_, entryMetadata_);
const entryValueTypeI = Z.sel(entryMetadata_, "value");
const $entry = codec(deriveCodec_, entryValueTypeI);
Expand Down
58 changes: 48 additions & 10 deletions effect/ExtrinsicSentWatch.ts → effect/Extrinsic.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
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 author from "../known/rpc/author.ts";
import { Config } from "../mod.ts";
import * as rpc from "../rpc/mod.ts";
import { NotifMessage } from "../rpc/mod.ts";
import * as ss58 from "../ss58/mod.ts";
import * as U from "../util/mod.ts";
import { $extrinsic } from "./core/$extrinsic.ts";
Expand All @@ -12,7 +13,7 @@ import { Metadata } from "./Metadata.ts";
import { RpcCall } from "./RpcCall.ts";
import { RpcSubscription } from "./RpcSubscription.ts";

export interface SendAndWatchExtrinsicProps {
export interface ExtrinsicProps {
sender: M.MultiAddress;
palletName: string;
methodName: string;
Expand All @@ -21,22 +22,35 @@ export interface SendAndWatchExtrinsicProps {
mortality?: [period: bigint, phase: bigint];
nonce?: string;
tip?: bigint;
sign: M.SignExtrinsic;
createWatchHandler: U.CreateWatchHandler<rpc.NotifMessage>;
}

export class ExtrinsicSentWatch<Props extends Z.Rec$<SendAndWatchExtrinsicProps>> extends Z.Name {
export class Extrinsic<Props extends Z.Rec$<ExtrinsicProps>> {
constructor(
readonly config: Config,
readonly props: Props,
) {}

signed<Sign extends Z.$<M.SignExtrinsic>>(sign: Sign): SignedExtrinsic<Props, Sign> {
return new SignedExtrinsic(this.config, this.props, sign);
}
}

export class SignedExtrinsic<
Props extends Z.Rec$<ExtrinsicProps>,
Sign extends Z.$<M.SignExtrinsic>,
> extends Z.Name {
root;

constructor(
readonly config: Config,
readonly props_: Props,
readonly sign: Sign,
) {
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 $extrinsic_ = $extrinsic(deriveCodec_, metadata_, this.sign, config.addressPrefix);
const runtimeVersion = new RpcCall(config, "state_getRuntimeVersion", []);
const senderSs58 = Z.call(props.sender, function senderSs58(sender) {
return ((): string => {
Expand All @@ -52,13 +66,15 @@ export class ExtrinsicSentWatch<Props extends Z.Rec$<SendAndWatchExtrinsicProps>
})();
});
const accountNextIndex = new RpcCall(config, "system_accountNextIndex", [senderSs58]);
const genesisHash = hexDecode(Z.sel(new RpcCall(config, "chain_getBlockHash", [0]), "result"));
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(
this.root = Z.call(
Z.ls(
$extrinsic_,
props.sender,
Expand Down Expand Up @@ -108,11 +124,33 @@ export class ExtrinsicSentWatch<Props extends Z.Rec$<SendAndWatchExtrinsicProps>
return U.hex.encode(extrinsicBytes);
},
);
}

watch<
WatchHandler extends U.CreateWatchHandler<NotifMessage<author.TransactionStatus>>,
>(watchHandler: WatchHandler): SignedExtrinsicWatch<this, WatchHandler> {
return new SignedExtrinsicWatch(this.config, this, watchHandler);
}
}

// TODO: is this really required? Why not use the RPC call effect directly?
export class SignedExtrinsicWatch<
SignedExtrinsic extends Z.$<U.Hex>,
WatchHandler extends U.CreateWatchHandler<NotifMessage<author.TransactionStatus>>,
> extends Z.Name {
root;

constructor(
readonly config: Config,
readonly signedExtrinsic: SignedExtrinsic,
readonly watchHandler: WatchHandler,
) {
super();
this.root = new RpcSubscription(
config,
"author_submitAndWatchExtrinsic",
[extrinsicHex],
props.createWatchHandler,
[signedExtrinsic],
watchHandler,
// TODO: use effect system for cbs such as this
(ok) => new RpcCall(config, "author_unwatchExtrinsic", [ok.result]),
);
Expand Down
6 changes: 3 additions & 3 deletions effect/KeyPageRead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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 { Metadata } from "./Metadata.ts";
import { RpcCall } from "./RpcCall.ts";

export class KeyPageRead<
Expand All @@ -26,9 +26,9 @@ export class KeyPageRead<
super();
const metadata_ = new Metadata(config, blockHash as Rest[1]);
const deriveCodec_ = deriveCodec(metadata_);
const palletMetadata_ = palletMetadata(metadata_, palletName);
const palletMetadata_ = metadata_.pallet(palletName);
const entryMetadata_ = Z.call(
entryMetadata(palletMetadata_, entryName),
palletMetadata_.entry(entryName),
function assertIsMap(entryMetadata) {
if (entryMetadata.type !== "Map") {
return new ReadingKeysOfNonMapError();
Expand Down
49 changes: 43 additions & 6 deletions effect/Metadata.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as $ from "../deps/scale.ts";
import * as Z from "../deps/zones.ts";
import * as M from "../frame_metadata/mod.ts";
import { Config } from "../mod.ts";
Expand All @@ -15,19 +16,55 @@ export class Metadata<Rest extends [blockHash?: Z.$<U.HexHash | undefined>]> ext
try {
return M.fromPrefixedHex(call.result);
} catch (e) {
return new MetadataDecodeError(e);
return e as $.CodecError;
}
},
);
}

pallet = <PalletName extends Z.$<string>>(palletName: PalletName) => {
return new PalletMetadata(this, palletName);
};
}

export const palletMetadata = Z.call.fac(M.getPallet);
export const entryMetadata = Z.call.fac(M.getEntry);
export class PalletMetadata<Metadata extends Z.$<M.Metadata>, PalletName extends Z.$<string>>
extends Z.Name
{
root;

export class MetadataDecodeError extends U.ErrorCtor("MetadataDecode") {
// TODO: replace with internal scale error & ensure appropriate trace info
constructor(readonly scaleError: unknown) {
constructor(
readonly metadata: Metadata,
readonly palletName: PalletName,
) {
super();
this.root = Z.call(
Z.ls(metadata, palletName),
function palletMetadataImpl([metadata, palletName]) {
return M.getPallet(metadata, palletName);
},
);
}

entry = <EntryName extends Z.$<string>>(entryName: EntryName) => {
return new EntryMetadata(this, entryName);
};
}

export class EntryMetadata<PalletMetadata extends Z.$<M.Pallet>, EntryName extends Z.$<string>>
extends Z.Name
{
root;

constructor(
readonly palletMetadata: PalletMetadata,
readonly entryName: EntryName,
) {
super();
this.root = Z.call(
Z.ls(palletMetadata, entryName),
function entryMetadataImpl([palletMetadata, entryName]) {
return M.getEntry(palletMetadata, entryName);
},
);
}
}
23 changes: 9 additions & 14 deletions effect/extrinsic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,29 +87,25 @@ Deno.test({

async function collectExtrinsicEvents(
config: C.Config,
{ palletName, methodName, args }: Pick<
C.SendAndWatchExtrinsicProps,
"palletName" | "methodName" | "args"
>,
{ palletName, methodName, args }: Omit<C.ExtrinsicProps, "sender">,
sender: KeyringPair,
): Promise<string[]> {
const extrinsicEvents: string[] = [];
// TODO: get rid of this `any`
const root = new C.ExtrinsicSentWatch(config as any, {
const root = new C.Extrinsic(config as any, {
sender: {
type: "Id",
value: sender.publicKey,
},
palletName,
methodName,
args,
sign(message) {
return {
type: "Sr25519",
value: sender.sign(message),
};
},
createWatchHandler(stop) {
})
.signed((message) => ({
type: "Sr25519",
value: sender.sign(message),
}))
.watch((stop) => {
return (event) => {
if (typeof event.params.result === "string") {
extrinsicEvents.push(event.params.result);
Expand All @@ -124,8 +120,7 @@ async function collectExtrinsicEvents(
}
}
};
},
});
});
U.throwIfError(await run(root));
return extrinsicEvents;
}
2 changes: 1 addition & 1 deletion effect/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export * from "./BlockRead.ts";
export * from "./BlockWatch.ts";
export * from "./EntryRead.ts";
export * from "./EntryWatch.ts";
export * from "./ExtrinsicSentWatch.ts";
export * from "./Extrinsic.ts";
export * from "./KeyPageRead.ts";
export * from "./Metadata.ts";
export * from "./RpcCall.ts";
Expand Down
12 changes: 6 additions & 6 deletions examples/polkadot_js_signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as C from "../mod.ts";
import * as T from "../test_util/mod.ts";
import * as U from "../util/mod.ts";

const root = new C.ExtrinsicSentWatch(T.westend, {
const root = new C.Extrinsic(T.westend, {
sender: {
type: "Id",
value: T.alice.publicKey,
Expand All @@ -17,7 +17,8 @@ const root = new C.ExtrinsicSentWatch(T.westend, {
value: T.bob.publicKey,
},
},
sign: {
})
.signed({
signPayload(payload) {
const tr = new TypeRegistry();
tr.setSignedExtensions(payload.signedExtensions);
Expand All @@ -27,8 +28,8 @@ const root = new C.ExtrinsicSentWatch(T.westend, {
.sign(T.alice),
);
},
},
createWatchHandler(stop) {
})
.watch((stop) => {
return (event) => {
if (typeof event.params.result === "string") {
console.log("Extrinsic", event.params.result);
Expand All @@ -44,7 +45,6 @@ const root = new C.ExtrinsicSentWatch(T.westend, {
}
}
};
},
});
});

U.throwIfError(await C.run(root));
18 changes: 8 additions & 10 deletions examples/transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as C from "../mod.ts";
import * as T from "../test_util/mod.ts";
import * as U from "../util/mod.ts";

const root = new C.ExtrinsicSentWatch(T.westend, {
const root = new C.Extrinsic(T.westend, {
sender: {
type: "Id",
value: T.alice.publicKey,
Expand All @@ -16,13 +16,12 @@ const root = new C.ExtrinsicSentWatch(T.westend, {
value: T.bob.publicKey,
},
},
sign(message) {
return {
type: "Sr25519",
value: T.alice.sign(message),
};
},
createWatchHandler(stop) {
})
.signed((message) => ({
type: "Sr25519",
value: T.alice.sign(message),
}))
.watch((stop) => {
return (event) => {
if (typeof event.params.result === "string") {
console.log("Extrinsic", event.params.result);
Expand All @@ -38,7 +37,6 @@ const root = new C.ExtrinsicSentWatch(T.westend, {
}
}
};
},
});
});

U.throwIfError(await C.run(root));
Loading