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

fix: broken patterns + examples #786

Merged
merged 21 commits into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from 10 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
File renamed without changes.
55 changes: 21 additions & 34 deletions examples/multisig_pure_proxy_stash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,63 +14,50 @@ const multisig = Rune
})
.into(MultisigRune, chain)

const fundMultisig = Balances
await Balances
.transfer({
value: 20_000_000_000_000n,
dest: multisig.address,
})
.signed(signature({ sender: alexa }))
.sent()
.dbgStatus("Fund Multisig:")
.finalized()
.finalizedHash()
.run()

const aliceRatify = multisig
.ratify({
call: Proxy.createPure({
proxyType: "Any",
delay: 0,
index: 0,
}),
sender: alexa.address,
})
const call = Proxy.createPure({
proxyType: "Any",
delay: 0,
index: 0,
})

await multisig
.ratify({ call, sender: alexa.address })
.signed(signature({ sender: alexa }))
.sent()
.dbgStatus("Alice Ratify:")
.finalized()
.finalizedHash()
.run()

const bobRatify = multisig
.ratify({
call: Proxy.createPure({
proxyType: "Any",
delay: 0,
index: 0,
}),
sender: billy.address,
})
const stashAddress = await multisig
.ratify({ call, sender: billy.address })
.signed(signature({ sender: billy }))
.sent()
.dbgStatus("Bob Ratify:")

const stashAddress = bobRatify
.finalizedEvents()
.pipe(filterPureCreatedEvents)
.map((events) => events[0]!)
.access("pure")
.access(0, "pure")
.run()

const fundStash = Balances
await Balances
.transfer({
value: 20_000_000_000_000n,
dest: MultiAddress.Id(stashAddress),
})
.signed(signature({ sender: alexa }))
.sent()
.dbgStatus("Fund Stash:")
.finalized()

await Rune
.chain(() => fundMultisig)
.chain(() => aliceRatify)
.chain(() => stashAddress)
.chain(() => fundStash)
.chain(() => System.Account.value(stashAddress).dbg("Stash Balance:"))
.finalizedHash()
.run()

console.log("Stash balance:", await System.Account.value(stashAddress).run())
17 changes: 4 additions & 13 deletions examples/multisig_transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ const multisig = Rune
})
.into(MultisigRune, chain)

// Read dave's initial balance (to-be changed by the call)
console.log("Dave initial balance:", await System.Account.value(david.publicKey).run())

// Transfer some funds into the multisig account
await Balances
.transfer({
value: 2_000_000_000_000n,
Expand All @@ -24,28 +22,24 @@ await Balances
.signed(signature({ sender: alexa }))
.sent()
.dbgStatus("Existential deposit:")
.finalized()
.finalizedHash()
.run()

// The to-be proposed and approved call
const call = Balances.transferKeepAlive({
dest: david.address,
value: 1_230_000_000_000n,
})

// Submit a proposal to dispatch the call
await multisig
.ratify({ call, sender: alexa.address })
.signed(signature({ sender: alexa }))
.sent()
.dbgStatus("Proposal:")
.finalized()
.finalizedHash()
.run()

// Check if the call has been proposed
console.log("Is proposed?:", await multisig.isProposed(call.hash).run())

// Send a non-executing approval
await multisig
.approve({
callHash: call.hash,
Expand All @@ -54,27 +48,24 @@ await multisig
.signed(signature({ sender: billy }))
.sent()
.dbgStatus("Vote:")
.finalized()
.finalizedHash()
.run()

// Check for existing approval(s)
console.log(
"Existing approvals:",
await multisig
.proposal(call.hash)
.unsafeAs<any>()
.into(ValueRune)
.access("approvals")
.run(),
)

// Send the executing (final) approval
await multisig
.ratify({ call, sender: carol.address })
.signed(signature({ sender: carol }))
.sent()
.dbgStatus("Approval:")
.finalized()
.finalizedHash()
.run()

// Check to see whether Dave's balance has in fact changed
Expand Down
42 changes: 21 additions & 21 deletions examples/virtual_multisig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ const [alexa, billy, carol, david] = await users(4)
let { state } = parse(Deno.args, { string: ["state"] })
if (!state) {
state = await VirtualMultisigRune
.deployment(chain, {
founders: [alexa.publicKey, billy.publicKey, carol.publicKey],
threshold: 2,
deployer: alexa,
})
.deployment( // TODO: simplify
chain,
{
founders: [alexa.publicKey, billy.publicKey, carol.publicKey],
threshold: 2,
deployer: alexa.address,
},
signature({ sender: alexa }),
)
.hex
.run()
}
Expand All @@ -23,24 +27,26 @@ console.log(`Virtual multisig state hex: ${state}`)

const vMultisig = VirtualMultisigRune.hydrate(chain, state)

const fundStash = Balances
await Balances
.transfer({
dest: MultiAddress.Id(vMultisig.stash),
value: 20_000_000_000_000n,
})
.signed(signature({ sender: alexa }))
.sent()
.dbgStatus("Fund Stash:")
.finalized()
.finalizedHash()
.run()

console.log("Dave balance before:", await System.Account.value(david.publicKey).run())

const proposal = Balances.transfer({
dest: david.address,
value: 1_234_000_000_000n,
})

const bobTx = Utility
await Utility
.batchAll({
// @ts-ignore: fix upon #656
calls: Rune.array([
vMultisig.fundMemberProxy(billy.publicKey, 20_000_000_000_000n),
vMultisig.ratify(billy.publicKey, proposal),
Expand All @@ -49,11 +55,11 @@ const bobTx = Utility
.signed(signature({ sender: billy }))
.sent()
.dbgStatus("Bob fund & ratify:")
.finalized()
.finalizedHash()
.run()

const charlieTx = Utility
await Utility
.batchAll({
// @ts-ignore: fix upon #656
calls: Rune.array([
vMultisig.fundMemberProxy(carol.publicKey, 20_000_000_000_000n),
vMultisig.ratify(carol.publicKey, proposal),
Expand All @@ -62,13 +68,7 @@ const charlieTx = Utility
.signed(signature({ sender: carol }))
.sent()
.dbgStatus("Charlie fund & ratify:")
.finalized()

await Rune
.chain(() => vMultisig)
.chain(() => fundStash)
.chain(() => System.Account.value(david.publicKey).dbg("Dave Balance Before:"))
.chain(() => bobTx)
.chain(() => charlieTx)
.chain(() => System.Account.value(david.publicKey).dbg("Dave Balance After:"))
.finalizedHash()
.run()

console.log("Dave balance after:", await System.Account.value(david.publicKey).run())
15 changes: 15 additions & 0 deletions fluent/EventsRune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ import { PatternRune } from "./PatternRune.ts"

export class EventsRune<out C extends Chain, out U> extends PatternRune<Event<C>[], C, U> {}

export interface TmpEventsChain extends Chain {
harrysolovay marked this conversation as resolved.
Show resolved Hide resolved
metadata: FrameMetadata & {
pallets: {
System: {
storage: {
Events: {
key: Codec<void>
value: Codec<_Event<any>[]>
}
}
}
}
}
}

interface _EventsChain<RE> extends Chain {
metadata: FrameMetadata & {
pallets: {
Expand Down
12 changes: 4 additions & 8 deletions fluent/StorageRune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,10 @@ export class StorageRune<
]>
) {
const storageKey = this.$partialKey.encoded(partialKey).map(hex.encode)
const startKey = Rune.captureUnhandled(
[this.$key, start],
(codec, start) =>
codec.into(CodecRune)
.encoded(start.unhandle(undefined))
.map(hex.encode)
.rehandle(undefined),
)
const startKey = this.$key
.encoded(Rune.resolve(start).unhandle(undefined))
.map(hex.encode)
.rehandle(undefined)
return this.chain.connection.call("state_getKeysPaged", storageKey, count, startKey, blockHash)
}

Expand Down
54 changes: 25 additions & 29 deletions patterns/multisig/MultisigRune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { MultiAddress } from "polkadot/types/sp_runtime/multiaddress.js"
import * as bytes from "../../deps/std/bytes.ts"
import {
Chain,
ChainRune,
ExtrinsicRune,
PatternRune,
Rune,
RunicArgs,
TmpEventsChain,
ValueRune,
} from "../../mod.ts"
import { PolkadotSignatureChain } from "../signature/polkadot.ts" // TODO: delete
import { multisigAccountId } from "./multisigAccountId.ts"

export interface MultisigRatifyProps<C extends Chain> {
Expand All @@ -26,8 +27,12 @@ export interface Multisig {
threshold?: number
}

export type MultisigChain<C extends Chain> = PolkadotSignatureChain & TmpEventsChain

// TODO: swap out `Chain` constraints upon subset gen issue resolution... same for other patterns
export class MultisigRune<out C extends Chain, out U> extends PatternRune<Multisig, C, U> {
export class MultisigRune<out C extends Chain, out U>
extends PatternRune<Multisig, MultisigChain<C>, U>
{
private storage = this.chain.pallet("Multisig").storage("Multisigs")
private value = this.into(ValueRune)
threshold = this.value.map(({ threshold, signatories }) => threshold ?? signatories.length - 1)
Expand All @@ -42,11 +47,8 @@ export class MultisigRune<out C extends Chain, out U> extends PatternRune<Multis
)
}

ratify<X>({ sender, call: call_ }: RunicArgs<X, MultisigRatifyProps<C>>) {
const call = Rune
.resolve(call_)
.unsafeAs<Chain.Call<C>>()
.into(ExtrinsicRune, this.chain)
ratify<X>({ sender, call: call_ }: RunicArgs<X, MultisigRatifyProps<MultisigChain<C>>>) {
const call = Rune.resolve(call_).into(ExtrinsicRune, this.chain)
return Rune
.rec({
type: "Multisig",
Expand All @@ -60,7 +62,6 @@ export class MultisigRune<out C extends Chain, out U> extends PatternRune<Multis
maybeTimepoint: this.maybeTimepoint(call.hash),
}),
})
.unsafeAs<Chain.Call<C>>()
.into(ExtrinsicRune, this.chain)
}

Expand All @@ -82,7 +83,6 @@ export class MultisigRune<out C extends Chain, out U> extends PatternRune<Multis
maybeTimepoint: this.maybeTimepoint(callHash),
}),
})
.unsafeAs<Chain.Call<C>>()
.into(ExtrinsicRune, this.chain)
}

Expand All @@ -98,35 +98,31 @@ export class MultisigRune<out C extends Chain, out U> extends PatternRune<Multis
timepoint: this.maybeTimepoint(callHash).map((x) => x ?? new NoProposalError()),
}),
})
.unsafeAs<Chain.Call<C>>()
.into(ExtrinsicRune, this.chain)
}

private maybeTimepoint<X>(...[callHash]: RunicArgs<X, [callHash: Uint8Array]>) {
return Rune.captureUnhandled(
[this, this.chain, callHash],
(multisig, chain, callHash) =>
multisig.into(MultisigRune, chain.into(ChainRune))
.proposal(callHash)
.unsafeAs<{ when: unknown }>()
.into(ValueRune)
.access("when"),
)
private maybeTimepoint<X>(
...[callHash, blockHash]: RunicArgs<X, [callHash: Uint8Array, blockHash?: string]>
) {
return this
.proposal(callHash, blockHash)
.unhandle(undefined)
.access("when")
.rehandle(undefined)
}

proposals<X>(...[count]: RunicArgs<X, [count: number]>) {
// @ts-ignore .
return this.storage.keyPage(count, Rune.tuple([this.accountId]))
proposals<X>(...[count, blockHash]: RunicArgs<X, [count: number, blockHash?: string]>) {
return this.storage.keyPage(count, Rune.tuple([this.accountId]), undefined, blockHash)
}

proposal<X>(...[callHash]: RunicArgs<X, [callHash: Uint8Array]>) {
// @ts-ignore .
return this.storage.value(Rune.tuple([this.accountId, callHash]))
proposal<X>(...[callHash, blockHash]: RunicArgs<X, [callHash: Uint8Array, blockHash?: string]>) {
return this.storage.value(Rune.tuple([this.accountId, callHash]), blockHash)
}

isProposed<X>(...[callHash]: RunicArgs<X, [callHash: Uint8Array]>) {
// @ts-ignore .
return this.storage.valueRaw(Rune.tuple([this.accountId, callHash]))
isProposed<X>(
...[callHash, blockHash]: RunicArgs<X, [callHash: Uint8Array, blockHash?: string]>
) {
return this.storage.valueRaw(Rune.tuple([this.accountId, callHash]), blockHash)
.map((entry) => entry !== null)
}
}
Expand Down
Loading