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

Commit

Permalink
typed events from client and misc
Browse files Browse the repository at this point in the history
  • Loading branch information
harrysolovay committed Feb 8, 2023
1 parent 52b2fd8 commit 42e260c
Show file tree
Hide file tree
Showing 16 changed files with 110 additions and 237 deletions.
2 changes: 2 additions & 0 deletions _tasks/star.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,5 @@ for (const [file, deps] of entries.slice(1)) {
done.add(d)
}
}

console.log("Checked successfully")
11 changes: 8 additions & 3 deletions codegen/frame/FrameCodegen.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Metadata } from "../../frame_metadata/mod.ts"
import { Ty } from "../../scale_info/mod.ts"
import { SequenceTyDef, Ty } from "../../scale_info/mod.ts"
import { codecs } from "./codecs.ts"
import { File } from "./File.ts"
import { pallet } from "./pallet.ts"
Expand Down Expand Up @@ -39,7 +39,10 @@ export class FrameCodegen {
.fromEntries(this.metadata.extrinsic.ty.params.map((x) => [x.name.toLowerCase(), x.ty]))
.call!

const callTySrcPath = this.typeVisitor.visit(callTy)
const eventTy = (this.metadata
.pallets.find((x) => x.name === "System")
?.storage?.entries.find((x) => x.name === "Events")
?.value! as SequenceTyDef).typeParam

let palletNamespaceExports = ""
for (const p of this.metadata.pallets) {
Expand All @@ -53,7 +56,9 @@ export class FrameCodegen {
new File(`
import * as C from "./capi.ts"
import * as types from "./types/mod.ts"
export type Chain = C.Chain<${callTySrcPath}>
export type Chain = C.Chain<${this.typeVisitor.visit(callTy)}, ${
this.typeVisitor.visit(eventTy)
}>
export * from "./client.ts"
export * as types from "./types/mod.ts"
Expand Down
5 changes: 5 additions & 0 deletions codegen/frame/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ function createTypeDecl(ctx: FrameCodegen, visitor: TyVisitor<string>, path: str
}): C.ValueRune<${memberPath}, C.RunicArgs.U<X>>`
+ `{ return C.Rune.rec({ type: ${S.string(type)}, ${factory[1]} }) }`,
)
factories.push(
`export function is${type}(value: ${path}): value is ${memberPath} { return value.type === ${
S.string(type)
} }`,
)
types.push(
makeDocComment(docs)
+ `export interface ${type}`
Expand Down
4 changes: 3 additions & 1 deletion examples/block_author.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { consensus } from "capi/patterns"
import { client } from "polkadot/mod.ts"

const result = await consensus.babeBlockAuthor(client).run()
const result = await consensus
.babeBlockAuthor(client, client.latestBlock.hash)
.run()

console.log(result)
5 changes: 1 addition & 4 deletions examples/block_events.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { client } from "polkadot/mod.ts"

const result = await client
.block()
.events()
.run()
const result = await client.latestBlock.events().run()

console.log(result)
5 changes: 1 addition & 4 deletions examples/block_extrinsics.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { client } from "polkadot/mod.ts"

const result = await client
.block()
.extrinsics()
.run()
const result = await client.latestBlock.extrinsics().run()

console.log(result)
16 changes: 8 additions & 8 deletions examples/ink_e2e/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ink } from "capi/patterns"
import { client } from "zombienet/examples/ink_e2e/zombienet.toml/collator/@latest/mod.ts"
import { parse } from "../../deps/std/flags.ts"

export const contract = ink.InkMetadataRune.from(
export const metadata = ink.InkMetadataRune.from(
client,
Deno.readTextFileSync("examples/ink_e2e/metadata.json"),
)
Expand All @@ -13,10 +13,10 @@ const sender = alice.publicKey
let { address } = parse(Deno.args, { string: ["address"] })
if (!address) {
class FailedToFindContractInstantiatedError extends Error {
override readonly name = "FailedToFindContractAddressError"
override readonly name = "FailedToFindContractInstantiatedError"
}

address = await contract
address = await metadata
.instantiate({
sender,
code: Deno.readFileSync("examples/ink_e2e/code.wasm"),
Expand All @@ -38,19 +38,19 @@ console.log(`Contract address: ${address}`)
const publicKey = AddressRune.from(address, client).publicKey()
console.log("Contract public key:", await publicKey.run())

const instance = contract.instance(client, publicKey)
const contract = metadata.instance(client, publicKey)

console.log("Get:", await instance.call({ sender, method: "get" }).run())
console.log("Get:", await contract.call({ sender, method: "get" }).run())

console.log(
await instance
await contract
.tx({ sender, method: "flip" })
.signed({ sender: alice })
.sent()
.logStatus("Flip status:")
.txEvents()
.pipe(instance.filterContractEvents)
.pipe(contract.filterContractEvents)
.run(),
)

console.log("Get:", await instance.call({ sender, method: "get" }).run())
console.log("Get:", await contract.call({ sender, method: "get" }).run())
36 changes: 16 additions & 20 deletions examples/watch.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import { Rune, ValueRune } from "capi"
import { Rune } from "capi"
import { client, Timestamp } from "polkadot/mod.ts"

const { blockHash } = client

const block = client.block(blockHash)
const block = client.latestBlock
const extrinsics = block.extrinsics()
const events = block.events()
const now = Timestamp.Now.entry([], blockHash)
const now = Timestamp.Now.entry([], block.hash)

const root = Rune.rec({
hash: block.hash,
block,
extrinsics,
events,
now,
})

await Rune
.rec({
blockHash,
block,
extrinsics,
events,
now,
})
.into(ValueRune)
.reduce(0, (i, values) => {
console.log(i, values)
return i + 1
})
.filter((i) => i === 3)
.run()
let i = 0
for await (const values of root.watch()) {
console.log(values)
if (++i === 3) break
}
39 changes: 18 additions & 21 deletions examples/xcm/asset_teleportation.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { alice, ApplyExtrinsicEvent, applyExtrinsicGuard, Rune, ValueRune } from "capi"
import { alice, Rune, ValueRune } from "capi"
import { types, XcmPallet } from "zombienet/examples/xcm/zombienet.toml/alice/@latest/mod.ts"
import { Event as XcmPalletEvent } from "zombienet/examples/xcm/zombienet.toml/alice/@latest/types/pallet_xcm/pallet.ts"
import { RuntimeEvent as AliceRuntimeEvent } from "zombienet/examples/xcm/zombienet.toml/alice/@latest/types/rococo_runtime/mod.ts"
import { client, System } from "zombienet/examples/xcm/zombienet.toml/collator/@latest/mod.ts"
import { Event as ParachainSystemEvent } from "zombienet/examples/xcm/zombienet.toml/collator/@latest/types/cumulus_pallet_parachain_system/pallet.ts"
import { RuntimeEvent as CollatorRuntimeEvent } from "zombienet/examples/xcm/zombienet.toml/collator/@latest/types/statemine_runtime.ts"

// TODO: have the recipient associate the downward message with the sender

Expand Down Expand Up @@ -55,13 +57,25 @@ const initiatedEvent = XcmPallet
.sent()
.logStatus("Teleportation status:")
.txEvents()
.map((events) => events.find(isXcmPalletAttemptedEvent) ?? new CannotFindAttemptError())
.map((events) =>
events.find((e) =>
AliceRuntimeEvent.isXcmPallet(e.event)
&& XcmPalletEvent.isAttempted(e.event.value)
)
?? new CannotFindAttemptError()
)
.unhandle(CannotFindAttemptError)

const processedEvent = System.Events
.entry([], client.blockHash)
.entry([], client.latestBlock.hash)
.into(ValueRune)
.map((events) => events.find(isParachainSystemDownwardMessageProcessedEvent))
.map((events) =>
events
.find((e) =>
CollatorRuntimeEvent.isParachainSystem(e.event)
&& ParachainSystemEvent.isDownwardMessagesProcessed(e.event.value)
)
)
.filter((event) => !!event)

console.log(
Expand All @@ -70,20 +84,3 @@ console.log(
.run(),
)
console.log("Final balance:", await aliceFree.run())

const isXcmPalletAttemptedEvent = applyExtrinsicGuard<AttemptedXcmPalletEvent>(
"XcmPallet",
"Attempted",
)
type AttemptedXcmPalletEvent = ApplyExtrinsicEvent<"XcmPallet", XcmPalletEvent.Attempted>

const isParachainSystemDownwardMessageProcessedEvent = applyExtrinsicGuard<
ParachainSystemDownwardMessageProcessedEvent
>(
"ParachainSystem",
"DownwardMessagesProcessed",
)
type ParachainSystemDownwardMessageProcessedEvent = ApplyExtrinsicEvent<
"ParachainSystem",
ParachainSystemEvent.DownwardMessagesProcessed
>
14 changes: 5 additions & 9 deletions fluent/ClientRune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,20 @@ export interface Chain<C = unknown, E extends Event = Event> {
}

export class ClientRune<out U, out C extends Chain = Chain> extends Rune<rpc.Client, U> {
blockHash = chain.getBlockHash(
latestBlock = this.block(chain.getBlockHash(
this,
chain
.subscribeNewHeads(this.as(ClientRune))
.map((header) => Rune.constant(header))
.into(MetaRune)
.flatMap((headers) => headers.into(ValueRune))
.access("number"),
)
))

block<X>(...[_maybeHash]: RunicArgs<X, [blockHash?: HexHash]>) {
const maybeHash = Rune.resolve(_maybeHash)
const blockHash = maybeHash
.unhandle(undefined)
.rehandle(undefined, () => chain.getFinalizedHead(this.as(Rune)))
block<X>(...[blockHash]: RunicArgs<X, [blockHash: HexHash]>) {
return chain
.getBlock(this.as(Rune), blockHash)
.into(BlockRune, this, blockHash)
.into(BlockRune, this, Rune.resolve(blockHash))
}

metadata<X>(...[blockHash]: RunicArgs<X, [blockHash?: HexHash]>) {
Expand All @@ -46,7 +42,7 @@ export class ClientRune<out U, out C extends Chain = Chain> extends Rune<rpc.Cli

extrinsic<X>(...args: RunicArgs<X, [call: C["call"]]>) {
const [call] = RunicArgs.resolve(args)
return call.into(ExtrinsicRune, this.as(ClientRune))
return call.into(ExtrinsicRune, this.as(ClientRune<U, C>))
}

addressPrefix() {
Expand Down
2 changes: 1 addition & 1 deletion fluent/SignedExtrinsicRune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class SignedExtrinsicRune<out U, out C extends Chain = Chain> extends Run
sent() {
return this
.hex()
.map((hex) => author.submitAndWatchExtrinsic(this.client, hex))
.map((hex) => author.submitAndWatchExtrinsic(this.client as ClientRune<never, C>, hex))
.into(ExtrinsicStatusRune, this)
}
}
2 changes: 1 addition & 1 deletion patterns/consensus/babeBlockAuthor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Rune, RunicArgs, ValueRune } from "../../rune/mod.ts"
import { HexHash } from "../../util/branded.ts"
import { preRuntimeDigest } from "./preRuntimeDigest.ts"

export function babeBlockAuthor<X>(...args: RunicArgs<X, [client: Client, at?: HexHash]>) {
export function babeBlockAuthor<X>(...args: RunicArgs<X, [client: Client, at: HexHash]>) {
const [client, at] = RunicArgs.resolve(args)
const validators = client
.into(ClientRune)
Expand Down
2 changes: 1 addition & 1 deletion patterns/consensus/preRuntimeDigest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { RunicArgs, ValueRune } from "../../rune/mod.ts"
import { HexHash } from "../../util/branded.ts"
import { hex } from "../../util/mod.ts"

export function preRuntimeDigest<X>(...args: RunicArgs<X, [client: Client, at?: HexHash]>) {
export function preRuntimeDigest<X>(...args: RunicArgs<X, [client: Client, at: HexHash]>) {
const [client, at] = RunicArgs.resolve(args)
return client
.into(ClientRune)
Expand Down
47 changes: 17 additions & 30 deletions patterns/ink/InkRune.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as $ from "../../deps/scale.ts"
import { equals } from "../../deps/std/bytes/mod.ts"
import {
Chain,
Expand All @@ -8,10 +7,10 @@ import {
MultiAddressRune,
state,
} from "../../fluent/mod.ts"
import { Event, ExtrinsicFailEvent } from "../../primitives/mod.ts"
import { Event } from "../../primitives/mod.ts"
import { Rune, RunicArgs, ValueRune } from "../../rune/mod.ts"
import { hex } from "../../util/mod.ts"
import { ContractEvent, isContractEmittedEvent } from "./events.ts"
import { isInstantiatedEvent } from "./events.ts"
import { InkMetadataRune } from "./InkMetadataRune.ts"
import { $contractsApiCallArgs, $contractsApiCallResult, Weight } from "./known.ts"

Expand Down Expand Up @@ -95,30 +94,18 @@ export class InkRune<out U, out C extends Chain = Chain> extends Rune<Uint8Array
}

filterContractEvents = <X>(...[events]: RunicArgs<X, [events: Event[]]>) => {
// TODO: return all relevant events, not just instantiated
return Rune
.tuple([Rune.resolve(events), this])
.map(([events, publicKey]) =>
events.filter((e) => {
console.log(e)
if (e.event.type !== "Contracts") return false
const { event } = e as ContractEvent
switch (event.value.type) {
case "Called":
case "ContractCodeUpdated":
case "ContractEmitted":
case "DelegateCalled":
case "Terminated":
case "Instantiated":
return equals(event.value.contract, publicKey)
case "CodeRemoved":
case "CodeStored":
return false
}
return isInstantiatedEvent(e) && equals(e.event.value.contract, publicKey)
})
)
}

decodeErrorEvent = <X>(...[failRuntimeEvent]: RunicArgs<X, [ExtrinsicFailEvent]>) => {
// TODO: improve
decodeErrorEvent = <X>(...[failRuntimeEvent]: RunicArgs<X, [any]>) => {
const metadata = this.client.metadata()
const $error = metadata.codec(
metadata
Expand All @@ -139,17 +126,17 @@ export class InkRune<out U, out C extends Chain = Chain> extends Rune<Uint8Array
.unhandle(FailedToDecodeErrorError)
}

// TODO: finish this
emissions<X>(...[events]: RunicArgs<X, [events: Event[]]>) {
const $event: $.Codec<unknown> = null!
return Rune
.tuple([Rune.resolve(events), $event])
.map(([events, $event]) =>
events
.filter(isContractEmittedEvent)
.map((event) => $event.decode(event.event.value.data))
)
}
// // TODO: finish this
// emissions<X>(...[events]: RunicArgs<X, [events: Event[]]>) {
// const $event: $.Codec<unknown> = null!
// return Rune
// .tuple([Rune.resolve(events), $event])
// .map(([events, $event]) =>
// events
// .filter(isContractEmittedEvent)
// .map((event) => $event.decode(event.event.value.data))
// )
// }
}

export class MethodNotFoundError extends Error {
Expand Down
Loading

0 comments on commit 42e260c

Please sign in to comment.