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

Commit

Permalink
curry extrinsic effect factory
Browse files Browse the repository at this point in the history
  • Loading branch information
harrysolovay committed Nov 9, 2022
1 parent 9dd1643 commit 1d77a04
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 35 deletions.
3 changes: 1 addition & 2 deletions effects/extrinsic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ export async function assertExtrinsicStatusOrder({
}: AssertExtrinsicStatusOrderProps) {
const extrinsicEvents = U.throwIfError(
await T.extrinsic.collectExtrinsicEvents(
extrinsic({
client: T.westend,
extrinsic(T.westend)({
sender: compat.multiAddressFromKeypair(keypair),
...rest,
})
Expand Down
51 changes: 34 additions & 17 deletions effects/extrinsic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,59 @@ export interface CallData {
}

export interface ExtrinsicProps extends CallData {
client: rpc.Client;
sender: M.MultiAddress;
checkpoint?: U.HexHash;
mortality?: [period: bigint, phase: bigint];
nonce?: string;
tip?: bigint;
}

export function extrinsic<Props extends Z.Rec$<ExtrinsicProps>>(props: Props): Extrinsic<Props> {
return new Extrinsic(props);
export function extrinsic<Client extends Z.$<rpc.Client>>(client: Client) {
return <Props extends Z.Rec$<ExtrinsicProps>>(props: Props): Extrinsic<Client, Props> => {
return new Extrinsic(client, props);
};
}

export class Extrinsic<Props extends Z.Rec$<ExtrinsicProps>> {
constructor(readonly props: Props) {}
export class Extrinsic<
Client extends Z.$<rpc.Client>,
Props extends Z.Rec$<ExtrinsicProps>,
> {
constructor(
readonly client: Client,
readonly props: Props,
) {}

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

export class SignedExtrinsic<
Client extends Z.$<rpc.Client>,
Props extends Z.Rec$<ExtrinsicProps>,
Sign extends Z.$<M.Signer>,
> {
client;
props;
sign;
extrinsic;

constructor(props_: Props, readonly sign: Sign) {
this.props = props_ as Z.Rec$Access<Props>;
const metadata_ = metadata(this.props.client)();
constructor(
client: Client,
props: Props,
sign: Sign,
) {
this.client = client as Client;
this.props = props as Z.Rec$Access<Props>;
this.sign = sign as Sign;

const metadata_ = metadata(this.client)();
const deriveCodec_ = deriveCodec(metadata_);
const addrPrefix = const_(this.props.client)("System", "SS58Prefix")
const addrPrefix = const_(this.client)("System", "SS58Prefix")
.access("value")
.as<number>();
const $extrinsic_ = $extrinsic(deriveCodec_, metadata_, this.sign, addrPrefix);
const versions = const_(this.props.client)("System", "Version")
const versions = const_(this.client)("System", "Version")
.access("value");
const specVersion = versions
.access("spec_version").as<number>();
Expand All @@ -74,8 +91,8 @@ export class SignedExtrinsic<
}
}
}, k0_);
const nonce = system.accountNextIndex(this.props.client)(senderSs58);
const genesisHashBytes = chain.getBlockHash(this.props.client)(0);
const nonce = system.accountNextIndex(this.client)(senderSs58);
const genesisHashBytes = chain.getBlockHash(this.client)(0);
const genesisHash = genesisHashBytes.next(U.hex.decode);
const checkpointHash = this.props.checkpoint
? Z.option(this.props.checkpoint, U.hex.decode)
Expand Down Expand Up @@ -105,16 +122,16 @@ export class SignedExtrinsic<
watch<Listener extends Z.$<U.Listener<known.TransactionStatus, rpc.ClientSubscribeContext>>>(
listener: Listener,
) {
const subscriptionId = author.submitAndWatchExtrinsic(this.props.client)(
const subscriptionId = author.submitAndWatchExtrinsic(this.client)(
[this.extrinsic],
listener,
);
return author.unwatchExtrinsic(this.props.client)(subscriptionId)
return author.unwatchExtrinsic(this.client)(subscriptionId)
.zoned("ExtrinsicWatch");
}

get sent() {
return author.submitExtrinsic(this.props.client)(this.extrinsic)
return author.submitExtrinsic(this.client)(this.extrinsic)
.zoned("ExtrinsicSent");
}
}
3 changes: 1 addition & 2 deletions examples/batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import * as U from "../util/mod.ts";
// }),
// )

const tx = C.extrinsic({
client: T.westend,
const tx = C.extrinsic(T.westend)({
sender: C.compat.multiAddressFromKeypair(T.alice),
palletName: "Utility",
methodName: "batch_all",
Expand Down
16 changes: 7 additions & 9 deletions examples/multisig_transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ if (!hostname || !portRaw) {
throw new Error("Must be running inside a test ctx");
}

const entryRead = C.entryRead(T.polkadot);
const extrinsic = C.extrinsic(T.polkadot);

const signatories = T.users
.slice(0, 3)
.map(({ publicKey }) => publicKey)
Expand All @@ -19,8 +22,7 @@ const THRESHOLD = 2;
const multisigPublicKey = createKeyMulti(signatories, THRESHOLD);

// Transfer initial balance (existential deposit) to multisig address
const existentialDeposit = C.extrinsic({
client: T.polkadot,
const existentialDeposit = extrinsic({
sender: C.compat.multiAddressFromKeypair(T.alice),
palletName: "Balances",
methodName: "transfer",
Expand All @@ -46,17 +48,14 @@ const key = C.keyPageRead(T.polkadot)("Multisig", "Multisigs", 1, [multisigPubli
.access(1);

// Get the timepoint itself
const maybeTimepoint = C.entryRead(T.polkadot)("Multisig", "Multisigs", [
multisigPublicKey,
key,
])
const maybeTimepoint = entryRead("Multisig", "Multisigs", [multisigPublicKey, key])
.access("value")
.access("when");

const approval = createOrApproveMultisigProposal("Approval", T.bob, maybeTimepoint);

// check T.dave new balance
const daveBalance = C.entryRead(T.polkadot)("System", "Account", [T.dave.publicKey]);
const daveBalance = entryRead("System", "Account", [T.dave.publicKey]);

// TODO: use common env
U.throwIfError(await existentialDeposit.run());
Expand All @@ -77,8 +76,7 @@ function createOrApproveMultisigProposal<
pair: KeyringPair,
...[maybeTimepoint]: Rest
) {
return C.extrinsic({
client: T.polkadot,
return extrinsic({
sender: C.compat.multiAddressFromKeypair(pair),
palletName: "Multisig",
methodName: "as_multi",
Expand Down
3 changes: 1 addition & 2 deletions examples/polkadot_js_signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +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 = C.extrinsic({
client: T.westend,
const root = C.extrinsic(T.westend)({
sender: C.compat.multiAddressFromKeypair(T.alice),
palletName: "Balances",
methodName: "transfer",
Expand Down
3 changes: 1 addition & 2 deletions examples/transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +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 = C.extrinsic({
client: T.westend,
const root = C.extrinsic(T.westend)({
sender: C.compat.multiAddressFromKeypair(T.alice),
palletName: "Balances",
methodName: "transfer",
Expand Down
4 changes: 3 additions & 1 deletion test_util/extrinsic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ import * as Z from "../deps/zones.ts";
import { ExtrinsicProps, SignedExtrinsic } from "../effects/extrinsic.ts";
import * as M from "../frame_metadata/mod.ts";
import * as known from "../known/rpc/mod.ts";
import * as rpc from "../rpc/mod.ts";

const k0_ = Symbol();

// TODO: use context / properly scope context / make it accessible outside of subscription lifecycle
// TODO: better zones-level way to share context between effects
export function collectExtrinsicEvents<
Client extends Z.$<rpc.Client>,
Props extends Z.Rec$<ExtrinsicProps>,
Sign extends Z.$<M.Signer>,
>(extrinsic: SignedExtrinsic<Props, Sign>) {
>(extrinsic: SignedExtrinsic<Client, Props, Sign>) {
const events: known.TransactionStatus[] = [];
return extrinsic
.watch(function(status) {
Expand Down

0 comments on commit 1d77a04

Please sign in to comment.