diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..282e78b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: CI + +on: + pull_request: + merge_group: + workflow_dispatch: + +jobs: + build: + timeout-minutes: 10 + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [20.x] + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v3 + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: pnpm + - name: Install deps + run: pnpm install + - name: Build + run: pnpm build + - name: Lint + run: pnpm lint + - name: Test + run: pnpm test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..eef6d0e --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,72 @@ +name: Publish + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + timeout-minutes: 10 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v3 + - name: Setup Node.js 20.x + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: pnpm + registry-url: https://registry.npmjs.org + - name: Install deps + run: pnpm install + - name: Build + run: pnpm build + - name: Lint + run: pnpm lint + - name: Test + run: pnpm test + publish: + needs: [build] + runs-on: ubuntu-latest + strategy: + matrix: + value: [sdk-governance, sdk-ink] + steps: + - uses: actions/checkout@v4 + - name: Check if version has been updated + id: check + uses: EndBug/version-check@v2 + with: + diff-search: true + file-name: ./packages/${{ matrix.value }}/package.json + - uses: actions/cache@v3 + if: steps.check.outputs.changed == 'true' + with: + path: .turbo + key: ${{ runner.os }}-20.x-turbo-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-20.x-turbo- + - uses: pnpm/action-setup@v3 + if: steps.check.outputs.changed == 'true' + - name: Setup Node.js 20.x + if: steps.check.outputs.changed == 'true' + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: pnpm + registry-url: https://registry.npmjs.org + - name: Install deps + if: steps.check.outputs.changed == 'true' + run: pnpm install + - name: Build + if: steps.check.outputs.changed == 'true' + run: pnpm build + - name: Publish + if: steps.check.outputs.changed == 'true' + working-directory: packages/${{ matrix.value }} + run: | + pnpm publish --no-git-checks --access=public --tag latest + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_AUTOMATION_TOKEN }} diff --git a/package.json b/package.json index aa6ca73..2189cdb 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "rollup": "^4.25.0", "rollup-plugin-dts": "^6.1.1", "rollup-plugin-esbuild": "^6.1.1", - "typescript": "^5.6.3", + "typescript": "^5.7.3", "vitest": "^2.1.4" - } + }, + "packageManager": "pnpm@8.15.4+sha1.c85a4305534f76d461407b59277b954bac97b5c4" } diff --git a/packages/common-utils/package.json b/packages/common-utils/package.json index 06e2624..6e2e8cc 100644 --- a/packages/common-utils/package.json +++ b/packages/common-utils/package.json @@ -41,11 +41,11 @@ }, "license": "MIT", "peerDependencies": { - "polkadot-api": ">=1.7.4", + "polkadot-api": "^1.8.1", "rxjs": ">=7.8.1" }, "devDependencies": { - "polkadot-api": "^1.7.4", + "polkadot-api": "^1.8.1", "rxjs": "^7.8.1" } } diff --git a/packages/sdk-governance/CHANGELOG.md b/packages/sdk-governance/CHANGELOG.md new file mode 100644 index 0000000..f6efa27 --- /dev/null +++ b/packages/sdk-governance/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## Unreleased + +Initial release diff --git a/packages/sdk-governance/README.md b/packages/sdk-governance/README.md new file mode 100644 index 0000000..87d2c2e --- /dev/null +++ b/packages/sdk-governance/README.md @@ -0,0 +1 @@ +# @polkadot-api/ink-sdk diff --git a/packages/sdk-governance/package.json b/packages/sdk-governance/package.json new file mode 100644 index 0000000..df62b12 --- /dev/null +++ b/packages/sdk-governance/package.json @@ -0,0 +1,57 @@ +{ + "name": "@polkadot-api/sdk-governance", + "version": "0.0.1", + "sideEffects": false, + "author": "Victor Oliva (https://github.com/voliva)", + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-api/papi-sdks.git" + }, + "exports": { + ".": { + "node": { + "production": { + "import": "./dist/esm/index.mjs", + "require": "./dist/min/index.js", + "default": "./dist/index.js" + }, + "import": "./dist/esm/index.mjs", + "require": "./dist/index.js", + "default": "./dist/index.js" + }, + "module": "./dist/esm/index.mjs", + "import": "./dist/esm/index.mjs", + "require": "./dist/index.js", + "default": "./dist/index.js" + }, + "./package.json": "./package.json" + }, + "main": "./dist/index.js", + "module": "./dist/esm/index.mjs", + "browser": "./dist/esm/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "tsc --noEmit && rollup -c ../../rollup.config.js", + "lint": "prettier --check README.md \"src/**/*.{js,jsx,ts,tsx,json,md}\"", + "format": "prettier --write README.md \"src/**/*.{js,jsx,ts,tsx,json,md}\"", + "prepack": "pnpm run build" + }, + "license": "MIT", + "dependencies": { + "@polkadot-api/common-sdk-utils": "workspace:*", + "@react-rxjs/utils": "^0.9.7" + }, + "peerDependencies": { + "@noble/hashes": ">=1.6.1", + "polkadot-api": ">=1.8.1", + "rxjs": ">=7.8.0" + }, + "devDependencies": { + "@noble/hashes": "^1.6.1", + "polkadot-api": "^1.8.1", + "rxjs": "^7.8.1" + } +} diff --git a/packages/sdk-governance/src/bounties/bounties-sdk.ts b/packages/sdk-governance/src/bounties/bounties-sdk.ts new file mode 100644 index 0000000..c297a9d --- /dev/null +++ b/packages/sdk-governance/src/bounties/bounties-sdk.ts @@ -0,0 +1,255 @@ +import { combineKeys, partitionByKey, toKeySet } from "@react-rxjs/utils" +import { Binary, TxEvent } from "polkadot-api" +import { + combineLatest, + distinctUntilChanged, + map, + mergeMap, + takeWhile, +} from "rxjs" +import { getBountyDescriptions$ } from "./bounty-descriptions" +import { BountiesSdkTypedApi, BountyWithoutDescription } from "./descriptors" +import { + findApprovingReferenda, + findProposingCuratorReferenda, +} from "./find-referenda" +import { scheduledFinder } from "./find-scheduled" +import { BountiesSdk, Bounty, GenericBounty, ProposedBounty } from "./sdk-types" + +export function createBountiesSdk(typedApi: BountiesSdkTypedApi): BountiesSdk { + const { findScheduledApproved, findScheduledCuratorProposed } = + scheduledFinder(typedApi) + + const enhanceBounty = ( + bounty: BountyWithoutDescription, + description: string | null, + id: number, + ): Bounty => { + const generic: GenericBounty = { + ...bounty, + type: bounty.status.type, + id, + description, + } + + switch (generic.status.type) { + case "Proposed": + return { + ...generic, + type: "Proposed", + approve() { + return typedApi.tx.Bounties.approve_bounty({ bounty_id: id }) + }, + close() { + return typedApi.tx.Bounties.close_bounty({ bounty_id: id }) + }, + filterApprovingReferenda(referenda) { + return findApprovingReferenda(referenda, id) + }, + getScheduledApprovals() { + return findScheduledApproved(id) + }, + } + case "Approved": + return { ...generic, type: "Approved" } + case "Funded": + return { + ...generic, + type: "Funded", + proposeCurator(curator, fee) { + return typedApi.tx.Bounties.propose_curator({ + bounty_id: id, + curator: { + type: "Id", + value: curator, + }, + fee, + }) + }, + close() { + return typedApi.tx.Bounties.close_bounty({ bounty_id: id }) + }, + filterProposingReferenda(referenda) { + return findProposingCuratorReferenda(referenda, id) + }, + getScheduledProposals() { + return findScheduledCuratorProposed(id) + }, + } + case "CuratorProposed": + return { + ...generic, + ...generic.status.value, + type: "CuratorProposed", + acceptCuratorRole() { + return typedApi.tx.Bounties.accept_curator({ bounty_id: id }) + }, + unassignCurator() { + return typedApi.tx.Bounties.unassign_curator({ bounty_id: id }) + }, + close() { + return typedApi.tx.Bounties.close_bounty({ bounty_id: id }) + }, + } + case "Active": + return { + ...generic, + type: "Active", + curator: generic.status.value.curator, + updateDue: generic.status.value.update_due, + extendExpiry(remark) { + return typedApi.tx.Bounties.extend_bounty_expiry({ + bounty_id: id, + remark: Binary.fromText(remark ?? ""), + }) + }, + award(beneficiary) { + return typedApi.tx.Bounties.award_bounty({ + bounty_id: id, + beneficiary: { + type: "Id", + value: beneficiary, + }, + }) + }, + unassignCurator() { + return typedApi.tx.Bounties.unassign_curator({ bounty_id: id }) + }, + close() { + return typedApi.tx.Bounties.close_bounty({ bounty_id: id }) + }, + } + case "PendingPayout": + return { + ...generic, + type: "PendingPayout", + curator: generic.status.value.curator, + unlockAt: generic.status.value.unlock_at, + beneficiary: generic.status.value.beneficiary, + claim() { + return typedApi.tx.Bounties.claim_bounty({ bounty_id: id }) + }, + unassignCurator() { + return typedApi.tx.Bounties.unassign_curator({ bounty_id: id }) + }, + } + } + throw new Error("Unreachable") + } + + function watchBounties() { + const [getBountyById$, bountyKeyChanges$] = partitionByKey( + typedApi.query.Bounties.Bounties.watchEntries().pipe( + mergeMap((v) => + v.deltas + ? [ + ...v.deltas.deleted.map((d) => ({ + id: d.args[0], + value: undefined, + })), + ...v.deltas.upserted.map((d) => ({ + id: d.args[0], + value: d.value, + })), + ].sort((a, b) => a.id - b.id) + : [], + ), + ), + (res) => res.id, + (group$, id) => + group$.pipe( + takeWhile(({ value }) => Boolean(value), false), + map((bounty) => ({ + id, + bounty: bounty.value!, + })), + ), + ) + const descriptions$ = getBountyDescriptions$( + typedApi.query.Bounties.BountyDescriptions.getEntries, + typedApi.query.Bounties.BountyDescriptions.getValues, + bountyKeyChanges$, + ) + + const bountyIds$ = bountyKeyChanges$.pipe( + toKeySet(), + map((set) => [...set]), + ) + + const getEnhancedBountyById$ = (id: number) => + combineLatest([ + getBountyById$(id), + descriptions$.pipe( + map((r): string | null => r[id] ?? null), + distinctUntilChanged(), + ), + ]).pipe( + map(([{ id, bounty }, description]) => + enhanceBounty(bounty, description, id), + ), + ) + + return { + bounties$: combineKeys(bountyIds$, getEnhancedBountyById$), + getBountyById$: getEnhancedBountyById$, + bountyIds$, + } + } + + function getBounty(id: number, at?: string) { + return Promise.all([ + typedApi.query.Bounties.Bounties.getValue(id, { at }), + typedApi.query.Bounties.BountyDescriptions.getValue(id, { at }), + ]).then(([bounty, description]) => + bounty + ? enhanceBounty(bounty, description ? description.asText() : null, id) + : null, + ) + } + + async function getProposedBounty( + txEvent: TxEvent, + ): Promise { + if (!("events" in txEvent)) { + return null + } + const proposedBountyEvt = typedApi.event.Bounties.BountyProposed.filter( + txEvent.events, + )[0] + if (!proposedBountyEvt) { + return null + } + const id = proposedBountyEvt.index + const at = txEvent.type === "finalized" ? undefined : txEvent.block.hash + + const bounty = await getBounty(id, at) + if (!bounty) return null + + return bounty.type === "Proposed" ? bounty : null + } + + function getBounties() { + return Promise.all([ + typedApi.query.Bounties.Bounties.getEntries(), + typedApi.query.Bounties.BountyDescriptions.getEntries(), + ]).then(([entries, descriptions]) => { + const descriptionMap = Object.fromEntries( + descriptions.map(({ keyArgs, value }) => [keyArgs[0], value.asText()]), + ) + + return entries + .map(({ keyArgs: [id], value }) => ({ bounty: value, id })) + .sort((a, b) => a.id - b.id) + .map(({ bounty, id }) => + enhanceBounty(bounty, descriptionMap[id] ?? null, id), + ) + }) + } + + return { + watchBounties, + getBounties, + getBounty, + getProposedBounty, + } +} diff --git a/packages/sdk-governance/src/bounties/bounty-descriptions.ts b/packages/sdk-governance/src/bounties/bounty-descriptions.ts new file mode 100644 index 0000000..97fbd6c --- /dev/null +++ b/packages/sdk-governance/src/bounties/bounty-descriptions.ts @@ -0,0 +1,53 @@ +import { KeyChanges } from "@react-rxjs/utils" +import { Binary } from "polkadot-api" +import { + defer, + merge, + mergeMap, + Observable, + scan, + shareReplay, + skip, + startWith, +} from "rxjs" + +export const getBountyDescriptions$ = ( + getEntries: () => Promise< + { + keyArgs: [Key: number] + value: Binary + }[] + >, + getValues: (keys: [number][]) => Promise<(Binary | undefined)[]>, + keyChanges$: Observable>, +) => + merge( + defer(getEntries), + keyChanges$.pipe( + skip(1), + mergeMap((changes) => { + if (changes.type === "remove") return [] + const keys = Array.from(changes.keys) + return getValues(keys.map((key) => [key])).then((result) => + result + .map((value, i) => ({ + keyArgs: [keys[i]] as [Key: number], + value: value!, + })) + .filter(({ value }) => value != null), + ) + }), + ), + ).pipe( + scan( + (acc, v) => ({ + ...acc, + ...Object.fromEntries( + v.map(({ keyArgs, value }) => [keyArgs[0], value.asText()]), + ), + }), + {} as Record, + ), + startWith({} as Record), + shareReplay({ bufferSize: 1, refCount: true }), + ) diff --git a/packages/sdk-governance/src/bounties/child-bounties-sdk.ts b/packages/sdk-governance/src/bounties/child-bounties-sdk.ts new file mode 100644 index 0000000..f0154d6 --- /dev/null +++ b/packages/sdk-governance/src/bounties/child-bounties-sdk.ts @@ -0,0 +1,186 @@ +import { combineKeys, partitionByKey, toKeySet } from "@react-rxjs/utils" +import { + combineLatest, + distinctUntilChanged, + map, + mergeMap, + takeWhile, +} from "rxjs" +import { getBountyDescriptions$ } from "./bounty-descriptions" +import { + ChildBountiesSdkTypedApi, + ChildBountyWithoutDescription, +} from "./child-descriptors" +import { + ChildBountiesSdk, + ChildBounty, + GenericChildBounty, +} from "./child-sdk-types" + +export function createChildBountiesSdk( + typedApi: ChildBountiesSdkTypedApi, +): ChildBountiesSdk { + const enhanceBounty = ( + bounty: ChildBountyWithoutDescription, + description: string | null, + id: number, + ): ChildBounty => { + const generic: GenericChildBounty = { + ...bounty, + type: bounty.status.type, + id, + description, + } + + const idObj = { + parent_bounty_id: bounty.parent_bounty, + child_bounty_id: id, + } + switch (generic.status.type) { + case "Added": + return { + ...generic, + type: "Added", + proposeCurator(curator, fee) { + return typedApi.tx.ChildBounties.propose_curator({ + ...idObj, + curator: { + type: "Id", + value: curator, + }, + fee, + }) + }, + close() { + return typedApi.tx.ChildBounties.close_child_bounty(idObj) + }, + } + case "CuratorProposed": + return { + ...generic, + ...generic.status.value, + type: "CuratorProposed", + acceptCuratorRole() { + return typedApi.tx.ChildBounties.accept_curator(idObj) + }, + unassignCurator() { + return typedApi.tx.ChildBounties.unassign_curator(idObj) + }, + close() { + return typedApi.tx.ChildBounties.close_child_bounty(idObj) + }, + } + case "Active": + return { + ...generic, + type: "Active", + curator: generic.status.value.curator, + award(beneficiary) { + return typedApi.tx.ChildBounties.award_child_bounty({ + ...idObj, + beneficiary: { + type: "Id", + value: beneficiary, + }, + }) + }, + unassignCurator() { + return typedApi.tx.ChildBounties.unassign_curator(idObj) + }, + close() { + return typedApi.tx.ChildBounties.close_child_bounty(idObj) + }, + } + case "PendingPayout": + return { + ...generic, + type: "PendingPayout", + curator: generic.status.value.curator, + unlockAt: generic.status.value.unlock_at, + beneficiary: generic.status.value.beneficiary, + claim() { + return typedApi.tx.ChildBounties.claim_child_bounty(idObj) + }, + unassignCurator() { + return typedApi.tx.ChildBounties.unassign_curator(idObj) + }, + } + } + throw new Error("Unreachable") + } + + function watchChildBounties(parentId: number) { + const [getBountyById$, bountyKeyChanges$] = partitionByKey( + typedApi.query.ChildBounties.ChildBounties.watchEntries(parentId).pipe( + mergeMap((v) => + v.deltas + ? [ + ...v.deltas.deleted.map((d) => ({ + id: d.args[1], + value: undefined, + })), + ...v.deltas.upserted.map((d) => ({ + id: d.args[1], + value: d.value, + })), + ].sort((a, b) => a.id - b.id) + : [], + ), + ), + (res) => res.id, + (group$, id) => + group$.pipe( + takeWhile(({ value }) => Boolean(value), false), + map((bounty) => ({ + id, + bounty: bounty.value!, + })), + ), + ) + const descriptions$ = getBountyDescriptions$( + typedApi.query.ChildBounties.ChildBountyDescriptions.getEntries, + typedApi.query.ChildBounties.ChildBountyDescriptions.getValues, + bountyKeyChanges$, + ) + + const bountyIds$ = bountyKeyChanges$.pipe( + toKeySet(), + map((set) => [...set]), + ) + + const getEnhancedBountyById$ = (id: number) => + combineLatest([ + getBountyById$(id), + descriptions$.pipe( + map((r): string | null => r[id] ?? null), + distinctUntilChanged(), + ), + ]).pipe( + map(([{ id, bounty }, description]) => + enhanceBounty(bounty, description, id), + ), + ) + + return { + bounties$: combineKeys(bountyIds$, getEnhancedBountyById$), + getBountyById$: getEnhancedBountyById$, + bountyIds$, + } + } + + function getChildBounty(parentId: number, id: number) { + return Promise.all([ + typedApi.query.ChildBounties.ChildBounties.getValue(parentId, id), + typedApi.query.ChildBounties.ChildBountyDescriptions.getValue(id).then( + (r) => (r ? r.asText() : null), + ), + ]).then(([bounty, description]) => + bounty ? enhanceBounty(bounty, description, id) : null, + ) + } + + return { + watchChildBounties, + getChildBounty, + } +} diff --git a/packages/sdk-governance/src/bounties/child-descriptors.ts b/packages/sdk-governance/src/bounties/child-descriptors.ts new file mode 100644 index 0000000..ede6904 --- /dev/null +++ b/packages/sdk-governance/src/bounties/child-descriptors.ts @@ -0,0 +1,133 @@ +import { SdkDefinition } from "@polkadot-api/common-sdk-utils" +import { + ApisTypedef, + Binary, + Enum, + FixedSizeArray, + PalletsTypedef, + SS58String, + StorageDescriptor, + TxDescriptor, + TypedApi, +} from "polkadot-api" +import { MultiAddress } from "./descriptors" + +export type BountiesChildBountyStatus = Enum<{ + Added: undefined + CuratorProposed: { + curator: SS58String + } + Active: { + curator: SS58String + } + PendingPayout: { + curator: SS58String + beneficiary: SS58String + unlock_at: number + } +}> +export interface ChildBountyWithoutDescription { + parent_bounty: number + value: bigint + fee: bigint + curator_deposit: bigint + status: BountiesChildBountyStatus +} + +type ChildBountiesSdkPallets = PalletsTypedef< + { + ChildBounties: { + /** + * Number of child bounties per parent bounty. + * Map of parent bounty index to number of child bounties. + */ + ParentChildBounties: StorageDescriptor< + [Key: number], + number, + false, + never + > + /** + * Child bounties that have been added. + */ + ChildBounties: StorageDescriptor< + FixedSizeArray<2, number>, + ChildBountyWithoutDescription, + true, + never + > + /** + * The description of each child-bounty. + */ + ChildBountyDescriptions: StorageDescriptor< + [Key: number], + Binary, + true, + never + > + } + }, + { + ChildBounties: { + add_child_bounty: TxDescriptor<{ + parent_bounty_id: number + value: bigint + description: Binary + }> + propose_curator: TxDescriptor<{ + parent_bounty_id: number + child_bounty_id: number + curator: MultiAddress + fee: bigint + }> + accept_curator: TxDescriptor<{ + parent_bounty_id: number + child_bounty_id: number + }> + unassign_curator: TxDescriptor<{ + parent_bounty_id: number + child_bounty_id: number + }> + award_child_bounty: TxDescriptor<{ + parent_bounty_id: number + child_bounty_id: number + beneficiary: MultiAddress + }> + claim_child_bounty: TxDescriptor<{ + parent_bounty_id: number + child_bounty_id: number + }> + close_child_bounty: TxDescriptor<{ + parent_bounty_id: number + child_bounty_id: number + }> + } + }, + { + // ChildBounties: { + // /** + // *A child-bounty is added. + // */ + // Added: PlainDescriptor> + // /** + // *A child-bounty is awarded to a beneficiary. + // */ + // Awarded: PlainDescriptor> + // /** + // *A child-bounty is claimed by beneficiary. + // */ + // Claimed: PlainDescriptor> + // /** + // *A child-bounty is cancelled. + // */ + // Canceled: PlainDescriptor> + // } + }, + {}, + {} +> +type ChildBountiesSdkDefinition = SdkDefinition< + ChildBountiesSdkPallets, + ApisTypedef<{}> +> +export type ChildBountiesSdkTypedApi = TypedApi diff --git a/packages/sdk-governance/src/bounties/child-sdk-types.ts b/packages/sdk-governance/src/bounties/child-sdk-types.ts new file mode 100644 index 0000000..e9d3a6e --- /dev/null +++ b/packages/sdk-governance/src/bounties/child-sdk-types.ts @@ -0,0 +1,67 @@ +import { SS58String, Transaction } from "polkadot-api" +import { Observable } from "rxjs" +import { + BountiesChildBountyStatus, + ChildBountyWithoutDescription, +} from "./child-descriptors" + +export interface GenericChildBounty extends ChildBountyWithoutDescription { + type: BountiesChildBountyStatus["type"] + id: number + description: string | null +} + +interface ClosableBounty { + close(): Transaction +} +export interface AddedChildBounty extends GenericChildBounty, ClosableBounty { + type: "Added" + proposeCurator( + curator: SS58String, + fee: bigint, + ): Transaction +} + +interface CuratorUnassignable { + unassignCurator(): Transaction +} +export interface CuratorProposedChildBounty + extends GenericChildBounty, + CuratorUnassignable, + ClosableBounty { + type: "CuratorProposed" + curator: SS58String + acceptCuratorRole(): Transaction +} +export interface ActiveChildBounty + extends GenericChildBounty, + CuratorUnassignable, + ClosableBounty { + type: "Active" + curator: SS58String + award(beneficiary: SS58String): Transaction +} +export interface PendingPayoutChildBounty + extends GenericChildBounty, + CuratorUnassignable { + type: "PendingPayout" + curator: SS58String + beneficiary: SS58String + unlockAt: number + claim(): Transaction +} + +export type ChildBounty = + | AddedChildBounty + | CuratorProposedChildBounty + | ActiveChildBounty + | PendingPayoutChildBounty + +export interface ChildBountiesSdk { + watchChildBounties(parentId: number): { + bounties$: Observable> + bountyIds$: Observable + getBountyById$: (key: number) => Observable + } + getChildBounty(parentId: number, id: number): Promise +} diff --git a/packages/sdk-governance/src/bounties/descriptors.ts b/packages/sdk-governance/src/bounties/descriptors.ts new file mode 100644 index 0000000..846164f --- /dev/null +++ b/packages/sdk-governance/src/bounties/descriptors.ts @@ -0,0 +1,150 @@ +import { SdkDefinition } from "@polkadot-api/common-sdk-utils" +import { + ApisTypedef, + Binary, + Enum, + FixedSizeArray, + FixedSizeBinary, + PalletsTypedef, + PlainDescriptor, + SS58String, + StorageDescriptor, + TxDescriptor, + TypedApi, +} from "polkadot-api" +import { + PolkadotRuntimeOriginCaller, + PreimagesBounded, +} from "../referenda/descriptors" + +export type BountiesBountyStatus = Enum<{ + Proposed: undefined + Approved: undefined + Funded: undefined + CuratorProposed: { + curator: SS58String + } + Active: { + curator: SS58String + update_due: number + } + PendingPayout: { + curator: SS58String + beneficiary: SS58String + unlock_at: number + } +}> +export interface BountyWithoutDescription { + proposer: SS58String + value: bigint + fee: bigint + curator_deposit: bigint + bond: bigint + status: BountiesBountyStatus +} + +type BountiesSdkPallets = PalletsTypedef< + { + Preimage: { + PreimageFor: StorageDescriptor< + [Key: [Binary, number]], + Binary, + true, + never + > + } + Bounties: { + /** + * Number of bounty proposals that have been made. + */ + BountyCount: StorageDescriptor<[], number, false, never> + /** + * Bounties that have been made. + */ + Bounties: StorageDescriptor< + [Key: number], + BountyWithoutDescription, + true, + never + > + /** + * The description of each bounty. + */ + BountyDescriptions: StorageDescriptor<[Key: number], Binary, true, never> + } + Scheduler: { + /** + * Items to be executed, indexed by the block number that they should be executed on. + */ + Agenda: StorageDescriptor< + [Key: number], + Array< + | { + maybe_id?: FixedSizeBinary<32> | undefined + priority: number + call: PreimagesBounded + maybe_periodic?: FixedSizeArray<2, number> | undefined + origin: PolkadotRuntimeOriginCaller + } + | undefined + >, + false, + never + > + } + }, + { + Bounties: { + approve_bounty: TxDescriptor<{ + bounty_id: number + }> + propose_curator: TxDescriptor<{ + bounty_id: number + curator: MultiAddress + fee: bigint + }> + unassign_curator: TxDescriptor<{ + bounty_id: number + }> + accept_curator: TxDescriptor<{ + bounty_id: number + }> + award_bounty: TxDescriptor<{ + bounty_id: number + beneficiary: MultiAddress + }> + claim_bounty: TxDescriptor<{ + bounty_id: number + }> + close_bounty: TxDescriptor<{ + bounty_id: number + }> + extend_bounty_expiry: TxDescriptor<{ + bounty_id: number + remark: Binary + }> + } + }, + { + Bounties: { + /** + *New bounty proposal. + */ + BountyProposed: PlainDescriptor<{ + index: number + }> + } + }, + {}, + {} +> +type BountiesSdkDefinition = SdkDefinition> +export type BountiesSdkTypedApi = TypedApi + +export type MultiAddress = Enum<{ + Id: SS58String + Index: undefined + Raw: Binary + Address32: FixedSizeBinary<32> + Address20: FixedSizeBinary<20> +}> diff --git a/packages/sdk-governance/src/bounties/find-referenda.ts b/packages/sdk-governance/src/bounties/find-referenda.ts new file mode 100644 index 0000000..231cb15 --- /dev/null +++ b/packages/sdk-governance/src/bounties/find-referenda.ts @@ -0,0 +1,107 @@ +import { OngoingReferendum } from "@/referenda/sdk-types" +import { weakMemo } from "@/util/memo" +import { MultiAddress } from "./descriptors" + +const spenderOrigins = [ + "Treasurer", + "SmallSpender", + "MediumSpender", + "BigSpender", + "SmallTipper", + "BigTipper", +] + +const getDecodedSpenderReferenda = weakMemo( + async (ongoingReferenda: OngoingReferendum[]) => { + const spenderReferenda = ongoingReferenda.filter( + (ref) => + (ref.origin.type === "Origins" && + spenderOrigins.includes(ref.origin.value.type)) || + (ref.origin.type === "system" && ref.origin.value.type === "Root"), + ) + const response = await Promise.all( + spenderReferenda.map((referendum) => + referendum.proposal + .decodedCall() + .then((call) => ({ + referendum, + call, + })) + .catch((ex) => { + console.error(ex) + return null + }), + ), + ) + return response.filter((v) => !!v) + }, +) + +export async function findApprovingReferenda( + ongoingReferenda: OngoingReferendum[], + bountyId: number, +) { + const spenderReferenda = await getDecodedSpenderReferenda(ongoingReferenda) + + return spenderReferenda + .filter(({ call }) => + findCalls( + { + pallet: "Bounties", + name: "approve_bounty", + }, + call, + ).some((v) => v?.bounty_id === bountyId), + ) + .map(({ referendum }) => referendum) +} + +export async function findProposingCuratorReferenda( + ongoingReferenda: OngoingReferendum[], + bountyId: number, +) { + const spenderReferenda = await getDecodedSpenderReferenda(ongoingReferenda) + + return spenderReferenda + .map(({ call, referendum }) => { + const proposeCuratorCalls = findCalls( + { + pallet: "Bounties", + name: "propose_curator", + }, + call, + ) + .filter( + (v) => + v?.bounty_id === bountyId && + typeof v.curator === "object" && + typeof v.fee === "bigint", + ) + .map((v) => ({ + curator: v.curator as MultiAddress, + fee: v.fee as bigint, + })) + if (!proposeCuratorCalls.length) return null + return { referendum, proposeCuratorCalls } + }) + .filter((v) => v !== null) +} + +export const findCalls = ( + call: { pallet: string; name: string }, + obj: any, +): any[] => { + if (typeof obj !== "object") return [] + if (Array.isArray(obj)) { + const approves = [] + for (const item of obj) approves.push(...findCalls(call, item)) + return approves + } + if (obj?.type === call.pallet && obj?.value?.type === call.name) { + return [obj.value.value] + } + const approves = [] + for (const key of Object.keys(obj)) + approves.push(...findCalls(call, obj[key])) + return approves +} diff --git a/packages/sdk-governance/src/bounties/find-scheduled.ts b/packages/sdk-governance/src/bounties/find-scheduled.ts new file mode 100644 index 0000000..1050d6e --- /dev/null +++ b/packages/sdk-governance/src/bounties/find-scheduled.ts @@ -0,0 +1,81 @@ +import { getPreimageResolver } from "@/preimages" +import { memo } from "@/util/memo" +import { BountiesSdkTypedApi, MultiAddress } from "./descriptors" +import { findCalls } from "./find-referenda" + +export const scheduledFinder = (typedApi: BountiesSdkTypedApi) => { + const resolvePreimage = getPreimageResolver( + typedApi.query.Preimage.PreimageFor.getValues, + ) + + const getScheduledCalls = memo(async () => { + const agenda = await typedApi.query.Scheduler.Agenda.getEntries() + const token = await typedApi.compatibilityToken + + const scheduled = agenda.flatMap( + ({ keyArgs: [height], value: values }) => + values + ?.filter((v) => !!v) + .map((value) => ({ + height, + call: value.call, + })) ?? [], + ) + + const resolvedCalls = await Promise.all( + scheduled.map(({ height, call }) => + resolvePreimage(call) + .then( + (callData) => typedApi.txFromCallData(callData, token).decodedCall, + ) + .then((decodedCall) => ({ height, call: decodedCall })) + .catch((ex) => { + console.error(ex) + return null + }), + ), + ) + return resolvedCalls.filter((v) => !!v) + }) + async function findScheduledApproved(bountyId: number) { + const calls = await getScheduledCalls() + + return calls + .filter(({ call }) => + findCalls({ pallet: "Bounties", name: "approve_bounty" }, call).some( + (v) => v?.bounty_id === bountyId, + ), + ) + .map(({ height }) => height) + } + + async function findScheduledCuratorProposed(bountyId: number) { + const calls = await getScheduledCalls() + + return calls + .map(({ call, height }) => { + const proposeCuratorCalls = findCalls( + { + pallet: "Bounties", + name: "propose_curator", + }, + call, + ) + .filter( + (v) => + v?.bounty_id === bountyId && + typeof v.curator === "object" && + typeof v.fee === "bigint", + ) + .map((v) => ({ + curator: v.curator as MultiAddress, + fee: v.fee as bigint, + })) + if (!proposeCuratorCalls.length) return null + return { height, proposeCuratorCalls } + }) + .filter((v) => v !== null) + } + + return { findScheduledApproved, findScheduledCuratorProposed } +} diff --git a/packages/sdk-governance/src/bounties/sdk-types.ts b/packages/sdk-governance/src/bounties/sdk-types.ts new file mode 100644 index 0000000..eaa81c1 --- /dev/null +++ b/packages/sdk-governance/src/bounties/sdk-types.ts @@ -0,0 +1,105 @@ +import { SS58String, Transaction, TxEvent } from "polkadot-api" +import { Observable } from "rxjs" +import { OngoingReferendum } from "../referenda/sdk-types" +import { + BountiesBountyStatus, + BountyWithoutDescription, + MultiAddress, +} from "./descriptors" + +export interface GenericBounty extends BountyWithoutDescription { + type: BountiesBountyStatus["type"] + id: number + description: string | null +} + +interface ClosableBounty { + close(): Transaction +} +export interface ProposedBounty extends GenericBounty, ClosableBounty { + type: "Proposed" + approve(): Transaction + filterApprovingReferenda( + referenda: OngoingReferendum[], + ): Promise + getScheduledApprovals(): Promise + // TODO incoming approveWithCurator() +} +export interface ApprovedBounty extends GenericBounty { + type: "Approved" +} +export interface FundedBounty extends GenericBounty, ClosableBounty { + type: "Funded" + proposeCurator( + curator: SS58String, + fee: bigint, + ): Transaction + filterProposingReferenda(referenda: OngoingReferendum[]): Promise< + Array<{ + referendum: OngoingReferendum + proposeCuratorCalls: { + curator: MultiAddress + fee: bigint + }[] + }> + > + getScheduledProposals(): Promise< + Array<{ + height: number + proposeCuratorCalls: { + curator: MultiAddress + fee: bigint + }[] + }> + > +} + +interface CuratorUnassignable { + unassignCurator(): Transaction +} +export interface CuratorProposedBounty + extends GenericBounty, + CuratorUnassignable, + ClosableBounty { + type: "CuratorProposed" + curator: SS58String + acceptCuratorRole(): Transaction +} +export interface ActiveBounty + extends GenericBounty, + CuratorUnassignable, + ClosableBounty { + type: "Active" + curator: SS58String + updateDue: number + extendExpiry(remark?: string): Transaction + award(beneficiary: SS58String): Transaction +} +export interface PendingPayoutBounty + extends GenericBounty, + CuratorUnassignable { + type: "PendingPayout" + curator: SS58String + beneficiary: SS58String + unlockAt: number + claim(): Transaction +} + +export type Bounty = + | ProposedBounty + | ApprovedBounty + | FundedBounty + | CuratorProposedBounty + | ActiveBounty + | PendingPayoutBounty + +export interface BountiesSdk { + watchBounties(): { + bounties$: Observable> + bountyIds$: Observable + getBountyById$: (key: number) => Observable + } + getBounty(id: number): Promise + getBounties(): Promise + getProposedBounty(txEvent: TxEvent): Promise +} diff --git a/packages/sdk-governance/src/index.ts b/packages/sdk-governance/src/index.ts new file mode 100644 index 0000000..7be5ed0 --- /dev/null +++ b/packages/sdk-governance/src/index.ts @@ -0,0 +1,15 @@ +export { createReferendaSdk } from "./referenda/referenda-sdk" +export { + type Origin, + polkadotSpenderOrigin, + kusamaSpenderOrigin, +} from "./referenda/chainConfig" +export type * from "./referenda/descriptors" +export type * from "./referenda/sdk-types" + +export { createBountiesSdk } from "./bounties/bounties-sdk" +export type * from "./bounties/descriptors" +export type * from "./bounties/sdk-types" +export { createChildBountiesSdk } from "./bounties/child-bounties-sdk" +export type * from "./bounties/child-descriptors" +export type * from "./bounties/child-sdk-types" diff --git a/packages/sdk-governance/src/preimages.ts b/packages/sdk-governance/src/preimages.ts new file mode 100644 index 0000000..9dc0cca --- /dev/null +++ b/packages/sdk-governance/src/preimages.ts @@ -0,0 +1,71 @@ +import { Binary } from "polkadot-api" +import { PreimagesBounded } from "./referenda/descriptors" + +const preimageCache = new Map>() + +export const getPreimageResolver = ( + getPreimageValues: ( + keys: [[Binary, number]][], + ) => Promise<(Binary | undefined)[]>, +) => { + const batched = batch((preimages: [Binary, number][]) => + getPreimageValues(preimages.map((v) => [v])), + ) + + return async (proposal: PreimagesBounded) => { + if (proposal.type === "Legacy") + throw new Error("Legacy proposals can't be resolved") + if (proposal.type === "Inline") return proposal.value + + const cached = preimageCache.get(proposal.value.hash.asHex()) + if (cached) return cached + const promise = (async () => { + const result = await batched([proposal.value.hash, proposal.value.len]) + if (!result) + throw new Error(`Preimage ${proposal.value.hash.asHex()} not found`) + return result + })() + preimageCache.set(proposal.value.hash.asHex(), promise) + return promise + } +} + +const batch = (fn: (values: T[]) => Promise) => { + let batched: Array<{ + value: T + resolve: (res: R) => void + reject: (err: any) => void + }> | null = null + + async function execute() { + if (!batched) return + try { + const result = await fn(batched.map((v) => v.value)) + batched.forEach(({ resolve }, i) => resolve(result[i])) + } catch (ex) { + console.error(ex) + batched.forEach(({ reject }) => reject(ex)) + } + batched = null + } + + return (value: T): Promise => + new Promise((resolve, reject) => { + if (!batched) { + batched = [ + { + value, + resolve, + reject, + }, + ] + setTimeout(execute) + } else { + batched.push({ + value, + resolve, + reject, + }) + } + }) +} diff --git a/packages/sdk-governance/src/referenda/chainConfig.ts b/packages/sdk-governance/src/referenda/chainConfig.ts new file mode 100644 index 0000000..a3a017e --- /dev/null +++ b/packages/sdk-governance/src/referenda/chainConfig.ts @@ -0,0 +1,39 @@ +const SpenderOrigin = { + Treasurer: "Treasurer", + SmallTipper: "SmallTipper", + BigTipper: "BigTipper", + SmallSpender: "SmallSpender", + MediumSpender: "MediumSpender", + BigSpender: "BigSpender", +} as const +export type Origin = (typeof SpenderOrigin)[keyof typeof SpenderOrigin] + +export const originToTrack: Record = { + Treasurer: "treasurer", + SmallTipper: "small_tipper", + BigTipper: "big_tipper", + SmallSpender: "small_spender", + MediumSpender: "medium_spender", + BigSpender: "big_spender", +} + +const DOT_UNIT = 10_000_000_000n +export const polkadotSpenderOrigin = (value: bigint): Origin | null => { + if (value <= 250n * DOT_UNIT) return SpenderOrigin.SmallTipper + if (value <= 1_000n * DOT_UNIT) return SpenderOrigin.BigTipper + if (value <= 10_000n * DOT_UNIT) return SpenderOrigin.SmallSpender + if (value <= 100_000n * DOT_UNIT) return SpenderOrigin.MediumSpender + if (value <= 1_000_000n * DOT_UNIT) return SpenderOrigin.BigSpender + if (value <= 10_000_000n * DOT_UNIT) return SpenderOrigin.Treasurer + return null +} + +const KSM_UNIT = 1_000_000_000_000n +export const kusamaSpenderOrigin = (value: bigint): Origin | null => { + if (value <= 1n * KSM_UNIT) return SpenderOrigin.SmallTipper + if (value <= 5n * KSM_UNIT) return SpenderOrigin.BigTipper + if (value <= 333n * KSM_UNIT) return SpenderOrigin.SmallSpender + if (value <= 3_333n * KSM_UNIT) return SpenderOrigin.MediumSpender + if (value <= 33_333n * KSM_UNIT) return SpenderOrigin.BigSpender + return SpenderOrigin.Treasurer +} diff --git a/packages/sdk-governance/src/referenda/descriptors.ts b/packages/sdk-governance/src/referenda/descriptors.ts new file mode 100644 index 0000000..9ae0494 --- /dev/null +++ b/packages/sdk-governance/src/referenda/descriptors.ts @@ -0,0 +1,203 @@ +import { + ApisTypedef, + Binary, + Enum, + FixedSizeArray, + PalletsTypedef, + PlainDescriptor, + SS58String, + StorageDescriptor, + TxCallData, + TxDescriptor, + TypedApi, +} from "polkadot-api" + +type WhoAmount = { + who: SS58String + amount: bigint +} +type BasicReferndumInfo = [number, WhoAmount | undefined, WhoAmount | undefined] + +export type PolkadotRuntimeOriginCaller = Enum<{ + system: Enum<{ + Root: undefined + Signed: SS58String + None: undefined + }> + Origins: Enum<{ + StakingAdmin: undefined + Treasurer: undefined + FellowshipAdmin: undefined + GeneralAdmin: undefined + AuctionAdmin: undefined + LeaseAdmin: undefined + ReferendumCanceller: undefined + ReferendumKiller: undefined + SmallTipper: undefined + BigTipper: undefined + SmallSpender: undefined + MediumSpender: undefined + BigSpender: undefined + WhitelistedCaller: undefined + WishForChange: undefined + }> + ParachainsOrigin: Enum<{ + Parachain: number + }> + XcmPallet: any + Void: undefined +}> + +export type PreimagesBounded = Enum<{ + Legacy: { + hash: Binary + } + Inline: Binary + Lookup: { + hash: Binary + len: number + } +}> +export type TraitsScheduleDispatchTime = Enum<{ + At: number + After: number +}> + +export type ReferendumInfo = Enum<{ + Ongoing: { + track: number + origin: PolkadotRuntimeOriginCaller + proposal: PreimagesBounded + enactment: Enum<{ + At: number + After: number + }> + submitted: number + submission_deposit: WhoAmount + decision_deposit?: WhoAmount | undefined + deciding?: + | { + since: number + confirming?: number | undefined + } + | undefined + tally: { + ayes: bigint + nays: bigint + support: bigint + } + in_queue: boolean + alarm?: [number, FixedSizeArray<2, number>] | undefined + } + Approved: BasicReferndumInfo + Rejected: BasicReferndumInfo + Cancelled: BasicReferndumInfo + TimedOut: BasicReferndumInfo + Killed: number +}> + +export type ReferendaTypesCurve = Enum<{ + LinearDecreasing: { + length: number + floor: number + ceil: number + } + SteppedDecreasing: { + begin: number + end: number + step: number + period: number + } + Reciprocal: { + factor: bigint + x_offset: bigint + y_offset: bigint + } +}> + +export type ReferendaTrackData = { + name: string + max_deciding: number + decision_deposit: bigint + prepare_period: number + decision_period: number + confirm_period: number + min_enactment_period: number + min_approval: ReferendaTypesCurve + min_support: ReferendaTypesCurve +} + +type ReferendaSdkPallets = PalletsTypedef< + { + Preimage: { + PreimageFor: StorageDescriptor< + [Key: [Binary, number]], + Binary, + true, + never + > + } + Referenda: { + /** + * Information concerning any given referendum. + */ + ReferendumInfoFor: StorageDescriptor< + [Key: number], + ReferendumInfo, + true, + never + > + } + Balances: { + TotalIssuance: StorageDescriptor<[], bigint, false, never> + } + }, + { + Referenda: { + submit: TxDescriptor<{ + proposal_origin: PolkadotRuntimeOriginCaller + proposal: PreimagesBounded + enactment_moment: TraitsScheduleDispatchTime + }> + } + Utility: { + batch_all: TxDescriptor<{ + calls: Array + }> + } + Preimage: { + note_preimage: TxDescriptor<{ + bytes: Binary + }> + } + }, + { + Referenda: { + Submitted: PlainDescriptor<{ + index: number + track: number + proposal: PreimagesBounded + }> + } + }, + {}, + { + Referenda: { + Tracks: PlainDescriptor> + } + } +> +type ReferendaSdkDefinition = SdkDefinition< + ReferendaSdkPallets, + ApisTypedef<{}> +> +export type ReferendaSdkTypedApi = TypedApi + +type SdkDefinition = { + descriptors: Promise & { + pallets: P + apis: R + } + asset: any + metadataTypes: any +} diff --git a/packages/sdk-governance/src/referenda/referenda-sdk.ts b/packages/sdk-governance/src/referenda/referenda-sdk.ts new file mode 100644 index 0000000..45e46e3 --- /dev/null +++ b/packages/sdk-governance/src/referenda/referenda-sdk.ts @@ -0,0 +1,226 @@ +import { blake2b } from "@noble/hashes/blake2b" +import { Binary, TxEvent } from "polkadot-api" +import { getPreimageResolver } from "../preimages" +import { originToTrack, polkadotSpenderOrigin } from "./chainConfig" +import { + PolkadotRuntimeOriginCaller, + ReferendaSdkTypedApi, + ReferendumInfo, +} from "./descriptors" +import { + OngoingReferendum, + ReferendaSdk, + ReferendaSdkConfig, +} from "./sdk-types" +import { trackFetcher } from "./track" + +const MAX_INLINE_SIZE = 128 +type RawOngoingReferendum = (ReferendumInfo & { type: "Ongoing" })["value"] + +const defaultConfig: ReferendaSdkConfig = { + spenderOrigin: polkadotSpenderOrigin, +} +export function createReferendaSdk( + typedApi: ReferendaSdkTypedApi, + config?: Partial, +): ReferendaSdk { + const { spenderOrigin } = { ...defaultConfig, ...config } + const resolvePreimage = getPreimageResolver( + typedApi.query.Preimage.PreimageFor.getValues, + ) + const getTrack = trackFetcher(typedApi) + + function enhanceOngoingReferendum( + id: number, + referendum: RawOngoingReferendum, + ): OngoingReferendum { + const resolveProposal = () => resolvePreimage(referendum.proposal) + + async function getConfirmationStart() { + const totalVotes = referendum.tally.ayes + referendum.tally.nays + if (totalVotes == 0n || !referendum.deciding) { + return null + } + if (referendum.deciding.confirming) { + return referendum.deciding.confirming + } + + const approvals = Number(referendum.tally.ayes) / Number(totalVotes) + + const [track, totalIssuance] = await Promise.all([ + getTrack(referendum.track), + typedApi.query.Balances.TotalIssuance.getValue(), + ]) + if (!track) return null + const approvalBlock = Math.max(0, track.minApproval.getBlock(approvals)) + const supportBlock = Math.max( + 0, + track.minSupport.getBlock( + Number(referendum.tally.support) / Number(totalIssuance), + ), + ) + const block = Math.max(approvalBlock, supportBlock) + if (block === Number.POSITIVE_INFINITY) return null + + return referendum.deciding.since + block + } + + return { + ...referendum, + id, + proposal: { + rawValue: referendum.proposal, + resolve: resolveProposal, + decodedCall: async () => { + const proposal = await resolveProposal() + const token = await typedApi.compatibilityToken + + return typedApi.txFromCallData(proposal, token).decodedCall + }, + }, + async getDetails(subscanApiKey: string) { + const result = await fetch( + "https://polkadot.api.subscan.io/api/scan/referenda/referendum", + { + method: "POST", + body: JSON.stringify({ + referendum_index: id, + }), + headers: { + "x-api-key": subscanApiKey, + }, + }, + ).then((r) => r.json()) + // status = "Confirm" => Confirming + + return { + title: result.data.title, + } + }, + getConfirmationStart, + async getConfirmationEnd() { + if (!referendum.deciding) return null + + const track = await getTrack(referendum.track) + if (!track) return null + + const confirmationStart = + referendum.deciding.confirming ?? (await getConfirmationStart()) + if (!confirmationStart) return null + + return confirmationStart + track.confirm_period + }, + } + } + + async function getOngoingReferenda() { + const entries = + await typedApi.query.Referenda.ReferendumInfoFor.getEntries() + + return entries + .map(({ keyArgs: [id], value: info }): OngoingReferendum | null => { + if (info.type !== "Ongoing") return null + + return enhanceOngoingReferendum(id, info.value) + }) + .filter((v) => !!v) + } + + const getSpenderTrack: ReferendaSdk["getSpenderTrack"] = (value) => { + const spenderOriginType = spenderOrigin(value) + const origin: PolkadotRuntimeOriginCaller = spenderOriginType + ? { + type: "Origins", + value: { + type: spenderOriginType, + value: undefined, + }, + } + : { + type: "system", + value: { type: "Root", value: undefined }, + } + + return { + origin, + track: getTrack( + spenderOriginType ? originToTrack[spenderOriginType] : "root", + ).then((r) => { + if (!r) { + throw new Error(`Track ${spenderOriginType ?? "root"} not found`) + } + return r + }), + } + } + + const createReferenda: ReferendaSdk["createReferenda"] = ( + origin, + enactment, + proposal, + ) => { + if (proposal.asBytes().length <= MAX_INLINE_SIZE) { + return typedApi.tx.Referenda.submit({ + enactment_moment: enactment, + proposal: { + type: "Inline", + value: proposal, + }, + proposal_origin: origin, + }) + } + + const hash = blake2b(proposal.asBytes()) + + return typedApi.tx.Utility.batch_all({ + calls: [ + // Expose the deposit required for the preimage + // maybe as part of fee + deposit + typedApi.tx.Preimage.note_preimage({ + bytes: proposal, + }).decodedCall, + typedApi.tx.Referenda.submit({ + enactment_moment: enactment, + proposal: { + type: "Lookup", + value: { + hash: Binary.fromBytes(hash), + len: proposal.asBytes().length, + }, + }, + proposal_origin: origin, + }).decodedCall, + ], + }) + } + + const createSpenderReferenda: ReferendaSdk["createSpenderReferenda"] = ( + callData, + value, + ) => { + const spenderTrack = getSpenderTrack(value) + + return createReferenda( + spenderTrack.origin, + { + type: "After", + value: 0, + }, + callData, + ) + } + + const getSubmittedReferendum = (txEvent: TxEvent) => + "events" in txEvent + ? (typedApi.event.Referenda.Submitted.filter(txEvent.events)[0] ?? null) + : null + + return { + getOngoingReferenda, + getSpenderTrack, + getTrack, + createReferenda, + createSpenderReferenda, + getSubmittedReferendum, + } +} diff --git a/packages/sdk-governance/src/referenda/sdk-types.ts b/packages/sdk-governance/src/referenda/sdk-types.ts new file mode 100644 index 0000000..e98dbd7 --- /dev/null +++ b/packages/sdk-governance/src/referenda/sdk-types.ts @@ -0,0 +1,83 @@ +import { Binary, Transaction, TxEvent } from "polkadot-api" +import { Origin } from "./chainConfig" +import { + PolkadotRuntimeOriginCaller, + PreimagesBounded, + ReferendaTrackData, + ReferendaTypesCurve, + ReferendumInfo, + TraitsScheduleDispatchTime, +} from "./descriptors" + +type RawOngoingReferendum = (ReferendumInfo & { type: "Ongoing" })["value"] + +export interface ReferendumDetails { + title?: string +} + +export type OngoingReferendum = Omit & { + id: number + proposal: { + rawValue: PreimagesBounded + resolve: () => Promise + decodedCall: () => Promise<{ + type: string + value: { + type: string + value: any + } + }> + } + getDetails: (apiKey: string) => Promise + getConfirmationStart: () => Promise + getConfirmationEnd: () => Promise +} + +export interface ReferendaSdkConfig { + spenderOrigin: (value: bigint) => Origin | null +} + +/** + * threshold are in percentage [0-1] + */ +export interface TrackFunctionDetails { + curve: ReferendaTypesCurve + getThreshold(block: number): number + getBlock(threshold: number): number + getData(step?: number): Array<{ + block: number + threshold: number + }> +} +export type ReferendaTrack = Omit< + ReferendaTrackData, + "min_approval" | "min_support" +> & { + minApproval: TrackFunctionDetails + minSupport: TrackFunctionDetails +} + +export interface ReferendaSdk { + getOngoingReferenda(): Promise + getSpenderTrack(value: bigint): { + origin: PolkadotRuntimeOriginCaller + track: Promise + } + + getTrack(id: number | string): Promise + + createReferenda( + origin: PolkadotRuntimeOriginCaller, + enactment: TraitsScheduleDispatchTime, + proposal: Binary, + ): Transaction + createSpenderReferenda( + callData: Binary, + value: bigint, + ): Transaction + getSubmittedReferendum(txEvent: TxEvent): { + index: number + track: number + proposal: PreimagesBounded + } | null +} diff --git a/packages/sdk-governance/src/referenda/track.ts b/packages/sdk-governance/src/referenda/track.ts new file mode 100644 index 0000000..83eda2e --- /dev/null +++ b/packages/sdk-governance/src/referenda/track.ts @@ -0,0 +1,208 @@ +import { keyBy } from "@/util/keyBy" +import { + ReferendaSdkTypedApi, + ReferendaTrackData as ReferendaTrackDescriptor, + ReferendaTypesCurve, +} from "./descriptors" +import { ReferendaTrack, TrackFunctionDetails } from "./sdk-types" + +export function enhanceTrack(track: ReferendaTrackDescriptor): ReferendaTrack { + return { + ...track, + minApproval: curveToFunctionDetails( + track.decision_period, + track.min_approval, + ), + minSupport: curveToFunctionDetails( + track.decision_period, + track.min_support, + ), + } +} + +export function trackFetcher(typedApi: ReferendaSdkTypedApi) { + const referendaTracksPromise = typedApi.constants.Referenda.Tracks().then( + (tracks) => { + const byId = Object.fromEntries(tracks) + const byName = keyBy(Object.values(byId), (v) => v.name) + return { byId, byName } + }, + ) + return async (id: number | string) => { + const referendaTracks = await referendaTracksPromise + const track = + typeof id === "number" + ? referendaTracks.byId[id] + : referendaTracks.byName[id] + if (!track) return null + + return enhanceTrack(track) + } +} + +const BILLION = 1_000_000_000_000 +const blockToPerBill = (block: number, period: number) => + (block * BILLION) / period +const perBillToBlock = (perBillion: number, period: number) => + Math.ceil((perBillion * period) / BILLION) + +function curveToFunctionDetails( + period: number, + curve: ReferendaTypesCurve, +): TrackFunctionDetails { + const curveFn = + curve.type === "LinearDecreasing" + ? linearDecreasing(curve.value) + : curve.type === "SteppedDecreasing" + ? steppedDecreasing(curve.value) + : reciprocal(curve.value) + + return { + curve, + getThreshold(at) { + return curveFn.getValue(blockToPerBill(at, period)) / BILLION + }, + getBlock(pct) { + return perBillToBlock(curveFn.getTime(pct * BILLION), period) + }, + getData(step = 1) { + return curveFn + .getData(blockToPerBill(Math.max(step, 1), period)) + .map(({ time, value }) => ({ + block: perBillToBlock(time, period), + threshold: value / BILLION, + })) + }, + } +} + +function linearDecreasing({ + length, + floor, + ceil, +}: { + length: number + floor: number + ceil: number +}) { + // v(x) = ceil + (x * (floor - ceil)) / length + const getValue = (at: number) => + Math.max( + floor, + Math.min(ceil, Math.round(ceil + (at * (floor - ceil)) / length)), + ) + + const getTime = (value: number) => { + if (value > ceil) return Number.NEGATIVE_INFINITY + if (value < floor) return Number.POSITIVE_INFINITY + return ((value - ceil) * length) / (floor - ceil) + } + const getData = () => [ + { + time: 0, + value: ceil, + }, + { + time: length, + value: floor, + }, + ...(BILLION > length + ? [ + { + time: BILLION, + value: floor, + }, + ] + : []), + ] + return { getValue, getTime, getData } +} +function steppedDecreasing({ + begin, + end, + step, + period, +}: { + begin: number + end: number + step: number + period: number +}) { + const getValue = (at: number) => + Math.max(end, Math.min(begin, begin - (at % period) * step)) + const getTime = (value: number) => { + if (value > begin) return Number.NEGATIVE_INFINITY + if (value < end) return Number.POSITIVE_INFINITY + return Math.ceil((begin - value) / step) + } + const getData = () => { + const result: Array<{ + time: number + value: number + }> = [] + + for (let k = 0, value = begin; value > end; value -= step) { + result.push({ + time: k * period, + value, + }) + } + if ((begin - end) % step != 0) { + result.push({ + time: Math.ceil((begin - end) / step), + value: end, + }) + } + if (result.at(-1)?.time! < BILLION) { + result.push({ + time: BILLION, + value: end, + }) + } + + return result + } + return { getValue, getTime, getData } +} +function reciprocal({ + factor, + x_offset, + y_offset, +}: { + factor: bigint + x_offset: bigint + y_offset: bigint +}) { + // v(x) = factor/(x+x_offset)-y_offset + const getValue = (at: number) => + Number(factor / (BigInt(Math.round(at)) + x_offset) - y_offset) + const getTime = (value: number) => { + const bigValue = BigInt(Math.round(value)) + // Below horizontal asymptote => +Infinity + if (bigValue <= -y_offset) return Number.POSITIVE_INFINITY + // Above y-axis cut => -Infinity + if (x_offset != 0n && bigValue > factor / x_offset - y_offset) + return Number.NEGATIVE_INFINITY + + return Number(factor / (bigValue + y_offset) - x_offset) + } + const getData = (step: number) => { + const result: Array<{ + time: number + value: number + }> = [] + + for (let time = 0; time <= BILLION; time += step) { + result.push({ time, value: getValue(time) }) + } + if (result.at(-1)?.time! < BILLION) { + result.push({ + time: BILLION, + value: getValue(BILLION), + }) + } + + return result + } + return { getValue, getTime, getData } +} diff --git a/packages/sdk-governance/src/util/keyBy.ts b/packages/sdk-governance/src/util/keyBy.ts new file mode 100644 index 0000000..85c3eef --- /dev/null +++ b/packages/sdk-governance/src/util/keyBy.ts @@ -0,0 +1,5 @@ +export const keyBy = ( + arr: Iterable, + mapFn: (v: T) => K, +): Record => + Object.fromEntries(Array.from(arr).map((v) => [mapFn(v), v])) as any diff --git a/packages/sdk-governance/src/util/memo.ts b/packages/sdk-governance/src/util/memo.ts new file mode 100644 index 0000000..2332163 --- /dev/null +++ b/packages/sdk-governance/src/util/memo.ts @@ -0,0 +1,22 @@ +export const weakMemo = (fn: (...arg: Arg) => R) => { + const cache = new WeakMap() + return (...arg: Arg) => { + if (cache.has(arg[0])) return cache.get(arg[0])! + const result = fn(...arg) + cache.set(arg[0], result) + return result + } +} + +export const memo = , R>(fn: (...arg: Arg) => R) => { + let cachedKey: Arg | null = null + let cachedValue: R = null as any + return (...arg: Arg) => { + if (cachedKey && cachedKey.every((k, i) => k === arg[i])) { + return cachedValue + } + cachedKey = arg + cachedValue = fn(...arg) + return cachedValue + } +} diff --git a/packages/sdk-governance/tsconfig.json b/packages/sdk-governance/tsconfig.json new file mode 100644 index 0000000..73f9f03 --- /dev/null +++ b/packages/sdk-governance/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.base", + "include": ["src", "tests"], + "compilerOptions": { + "baseUrl": "src", + "resolveJsonModule": true, + "skipLibCheck": true, + "paths": { + "@/*": ["*"] + } + } +} diff --git a/packages/sdk-ink/README.md b/packages/sdk-ink/README.md index 87d2c2e..b22026a 100644 --- a/packages/sdk-ink/README.md +++ b/packages/sdk-ink/README.md @@ -1 +1 @@ -# @polkadot-api/ink-sdk +# @polkadot-api/sdk-ink diff --git a/packages/sdk-ink/package.json b/packages/sdk-ink/package.json index 1aa7d67..731cd97 100644 --- a/packages/sdk-ink/package.json +++ b/packages/sdk-ink/package.json @@ -44,13 +44,13 @@ "@polkadot-api/common-sdk-utils": "workspace:*" }, "peerDependencies": { - "@polkadot-api/ink-contracts": ">=0.2.1", - "polkadot-api": ">=1.7.4", + "@polkadot-api/ink-contracts": ">=0.2.4", + "polkadot-api": ">=1.8.1", "rxjs": ">=7.8.0" }, "devDependencies": { - "@polkadot-api/ink-contracts": "^0.2.1", - "polkadot-api": "^1.7.4", + "@polkadot-api/ink-contracts": "^0.2.4", + "polkadot-api": "^1.8.1", "rxjs": "^7.8.1" } } diff --git a/packages/sdk-ink/src/descriptor-types.ts b/packages/sdk-ink/src/descriptor-types.ts index 79e6e83..af88bbd 100644 --- a/packages/sdk-ink/src/descriptor-types.ts +++ b/packages/sdk-ink/src/descriptor-types.ts @@ -114,7 +114,8 @@ export type InkSdkPallets = PalletsTypedef< { code_hash: FixedSizeBinary<32> }, - true + true, + never > } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8793429..39de144 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,25 +10,25 @@ importers: devDependencies: '@rollup/plugin-alias': specifier: ^5.1.1 - version: 5.1.1(rollup@4.25.0) + version: 5.1.1(rollup@4.26.0) '@rollup/plugin-node-resolve': specifier: ^15.3.0 - version: 15.3.0(rollup@4.25.0) + version: 15.3.0(rollup@4.26.0) prettier: specifier: ^3.3.3 version: 3.3.3 rollup: specifier: ^4.25.0 - version: 4.25.0 + version: 4.26.0 rollup-plugin-dts: specifier: ^6.1.1 - version: 6.1.1(rollup@4.25.0)(typescript@5.6.3) + version: 6.1.1(rollup@4.26.0)(typescript@5.7.3) rollup-plugin-esbuild: specifier: ^6.1.1 - version: 6.1.1(esbuild@0.24.0)(rollup@4.25.0) + version: 6.1.1(esbuild@0.24.2)(rollup@4.26.0) typescript: - specifier: ^5.6.3 - version: 5.6.3 + specifier: ^5.7.3 + version: 5.7.3 vitest: specifier: ^2.1.4 version: 2.1.4 @@ -37,7 +37,7 @@ importers: dependencies: '@polkadot-api/descriptors': specifier: file:.papi/descriptors - version: file:examples/ink-playground/.papi/descriptors(polkadot-api@1.7.4) + version: file:examples/ink-playground/.papi/descriptors(polkadot-api@1.8.1) '@polkadot-api/sdk-ink': specifier: workspace:* version: link:../../packages/sdk-ink @@ -49,23 +49,42 @@ importers: version: 0.0.8 polkadot-api: specifier: ^1.7.4 - version: 1.7.4(rxjs@7.8.1) + version: 1.8.1(rxjs@7.8.1) rxjs: specifier: 7.8.1 version: 7.8.1 typescript: specifier: ^5.0.0 - version: 5.6.3 + version: 5.7.3 devDependencies: '@types/bun': specifier: latest - version: 1.1.13 + version: 1.1.16 packages/common-utils: devDependencies: polkadot-api: - specifier: ^1.7.4 - version: 1.7.4(rxjs@7.8.1) + specifier: ^1.8.1 + version: 1.8.1(rxjs@7.8.1) + rxjs: + specifier: ^7.8.1 + version: 7.8.1 + + packages/sdk-governance: + dependencies: + '@polkadot-api/common-sdk-utils': + specifier: workspace:* + version: link:../common-utils + '@react-rxjs/utils': + specifier: ^0.9.7 + version: 0.9.7(@react-rxjs/core@0.10.7)(react@19.0.0)(rxjs@7.8.1) + devDependencies: + '@noble/hashes': + specifier: ^1.6.1 + version: 1.6.1 + polkadot-api: + specifier: ^1.8.1 + version: 1.8.1(rxjs@7.8.1) rxjs: specifier: ^7.8.1 version: 7.8.1 @@ -77,11 +96,11 @@ importers: version: link:../common-utils devDependencies: '@polkadot-api/ink-contracts': - specifier: ^0.2.1 - version: 0.2.1 + specifier: ^0.2.4 + version: 0.2.4 polkadot-api: - specifier: ^1.7.4 - version: 1.7.4(rxjs@7.8.1) + specifier: ^1.8.1 + version: 1.8.1(rxjs@7.8.1) rxjs: specifier: ^7.8.1 version: 7.8.1 @@ -118,8 +137,8 @@ packages: dev: true optional: true - /@esbuild/aix-ppc64@0.24.0: - resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + /@esbuild/aix-ppc64@0.24.2: + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -135,8 +154,8 @@ packages: dev: true optional: true - /@esbuild/android-arm64@0.24.0: - resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + /@esbuild/android-arm64@0.24.2: + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -152,8 +171,8 @@ packages: dev: true optional: true - /@esbuild/android-arm@0.24.0: - resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + /@esbuild/android-arm@0.24.2: + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -169,8 +188,8 @@ packages: dev: true optional: true - /@esbuild/android-x64@0.24.0: - resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + /@esbuild/android-x64@0.24.2: + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -186,8 +205,8 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64@0.24.0: - resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + /@esbuild/darwin-arm64@0.24.2: + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -203,8 +222,8 @@ packages: dev: true optional: true - /@esbuild/darwin-x64@0.24.0: - resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + /@esbuild/darwin-x64@0.24.2: + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -220,8 +239,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64@0.24.0: - resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + /@esbuild/freebsd-arm64@0.24.2: + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -237,8 +256,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64@0.24.0: - resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + /@esbuild/freebsd-x64@0.24.2: + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -254,8 +273,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm64@0.24.0: - resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + /@esbuild/linux-arm64@0.24.2: + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -271,8 +290,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm@0.24.0: - resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + /@esbuild/linux-arm@0.24.2: + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -288,8 +307,8 @@ packages: dev: true optional: true - /@esbuild/linux-ia32@0.24.0: - resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + /@esbuild/linux-ia32@0.24.2: + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -305,8 +324,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64@0.24.0: - resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + /@esbuild/linux-loong64@0.24.2: + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -322,8 +341,8 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el@0.24.0: - resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + /@esbuild/linux-mips64el@0.24.2: + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -339,8 +358,8 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64@0.24.0: - resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + /@esbuild/linux-ppc64@0.24.2: + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -356,8 +375,8 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64@0.24.0: - resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + /@esbuild/linux-riscv64@0.24.2: + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -373,8 +392,8 @@ packages: dev: true optional: true - /@esbuild/linux-s390x@0.24.0: - resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + /@esbuild/linux-s390x@0.24.2: + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -390,14 +409,22 @@ packages: dev: true optional: true - /@esbuild/linux-x64@0.24.0: - resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + /@esbuild/linux-x64@0.24.2: + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} engines: {node: '>=18'} cpu: [x64] os: [linux] requiresBuild: true optional: true + /@esbuild/netbsd-arm64@0.24.2: + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + requiresBuild: true + optional: true + /@esbuild/netbsd-x64@0.21.5: resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} @@ -407,16 +434,16 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64@0.24.0: - resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + /@esbuild/netbsd-x64@0.24.2: + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] requiresBuild: true optional: true - /@esbuild/openbsd-arm64@0.24.0: - resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + /@esbuild/openbsd-arm64@0.24.2: + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -432,8 +459,8 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64@0.24.0: - resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + /@esbuild/openbsd-x64@0.24.2: + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -449,8 +476,8 @@ packages: dev: true optional: true - /@esbuild/sunos-x64@0.24.0: - resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + /@esbuild/sunos-x64@0.24.2: + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -466,8 +493,8 @@ packages: dev: true optional: true - /@esbuild/win32-arm64@0.24.0: - resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + /@esbuild/win32-arm64@0.24.2: + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -483,8 +510,8 @@ packages: dev: true optional: true - /@esbuild/win32-ia32@0.24.0: - resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + /@esbuild/win32-ia32@0.24.2: + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -500,8 +527,8 @@ packages: dev: true optional: true - /@esbuild/win32-x64@0.24.0: - resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + /@esbuild/win32-x64@0.24.2: + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -554,6 +581,11 @@ packages: /@noble/hashes@1.5.0: resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} engines: {node: ^14.21.3 || >=16} + dev: false + + /@noble/hashes@1.6.1: + resolution: {integrity: sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==} + engines: {node: ^14.21.3 || >=16} /@pkgjs/parseargs@0.11.0: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -561,35 +593,35 @@ packages: requiresBuild: true optional: true - /@polkadot-api/cli@0.9.18: - resolution: {integrity: sha512-biax8MLK8GO6/YTy0NfkCYB1HT5OEAeHr+9ITyv4klNvF/4uqj3gb0XODjCpFX0aCUp6q8aIFMDhUc7rN47AYg==} + /@polkadot-api/cli@0.10.0: + resolution: {integrity: sha512-ItuM4l3ZPJYy1dx4X50X3rZK7TpWT0unBGRe+mMRcY4TyRkWK2nIMwcA+ggqBiEaM22SpFh9DCixZtRt43OKkg==} hasBin: true dependencies: '@commander-js/extra-typings': 12.1.0(commander@12.1.0) - '@polkadot-api/codegen': 0.12.8 - '@polkadot-api/ink-contracts': 0.2.1 + '@polkadot-api/codegen': 0.12.12 + '@polkadot-api/ink-contracts': 0.2.4 '@polkadot-api/json-rpc-provider': 0.0.4 - '@polkadot-api/known-chains': 0.5.6 - '@polkadot-api/metadata-compatibility': 0.1.11 - '@polkadot-api/observable-client': 0.6.2(@polkadot-api/substrate-client@0.3.0)(rxjs@7.8.1) + '@polkadot-api/known-chains': 0.6.0 + '@polkadot-api/metadata-compatibility': 0.1.14 + '@polkadot-api/observable-client': 0.7.0(@polkadot-api/substrate-client@0.3.0)(rxjs@7.8.1) '@polkadot-api/polkadot-sdk-compat': 2.3.1 - '@polkadot-api/sm-provider': 0.1.6(@polkadot-api/smoldot@0.3.5) - '@polkadot-api/smoldot': 0.3.5 - '@polkadot-api/substrate-bindings': 0.9.3 + '@polkadot-api/sm-provider': 0.1.7(@polkadot-api/smoldot@0.3.8) + '@polkadot-api/smoldot': 0.3.8 + '@polkadot-api/substrate-bindings': 0.11.0 '@polkadot-api/substrate-client': 0.3.0 '@polkadot-api/utils': 0.1.2 '@polkadot-api/wasm-executor': 0.1.2 - '@polkadot-api/ws-provider': 0.3.5 - '@types/node': 22.9.0 + '@polkadot-api/ws-provider': 0.3.6 + '@types/node': 22.10.3 commander: 12.1.0 - execa: 9.5.1 + execa: 9.5.2 fs.promises.exists: 1.1.4 ora: 8.1.1 read-pkg: 9.0.1 rxjs: 7.8.1 - tsc-prog: 2.3.0(typescript@5.6.3) - tsup: 8.3.5(typescript@5.6.3) - typescript: 5.6.3 + tsc-prog: 2.3.0(typescript@5.7.3) + tsup: 8.3.5(typescript@5.7.3) + typescript: 5.7.3 write-package: 7.1.0 transitivePeerDependencies: - '@microsoft/api-extractor' @@ -602,68 +634,68 @@ packages: - utf-8-validate - yaml - /@polkadot-api/codegen@0.12.8: - resolution: {integrity: sha512-uFDi6EYUVyqccTbu8vUsLHMrMTSPh/0D5CwoHuz5rhNH559cdR1kBf/EInhI6AVlnzzUBMAatOc4y5c2bkR+QA==} + /@polkadot-api/codegen@0.12.12: + resolution: {integrity: sha512-0jurC0ziMs0CEmHCZ8o2b4kE2pJz0rb/7LzeX/r0ngx60IJV14KSAFoAfipEMgmui3uTsP9goT/q4RmgnZ/2CQ==} dependencies: - '@polkadot-api/ink-contracts': 0.2.1 - '@polkadot-api/metadata-builders': 0.9.1 - '@polkadot-api/metadata-compatibility': 0.1.11 - '@polkadot-api/substrate-bindings': 0.9.3 + '@polkadot-api/ink-contracts': 0.2.4 + '@polkadot-api/metadata-builders': 0.10.0 + '@polkadot-api/metadata-compatibility': 0.1.14 + '@polkadot-api/substrate-bindings': 0.11.0 '@polkadot-api/utils': 0.1.2 - /@polkadot-api/ink-contracts@0.2.1: - resolution: {integrity: sha512-K7iJv6lE2Z3npXdk12CGHKfQZ0CGN90mXqTNZd3wDli5BX7hGTzBDdZ34hpe537G7rG88SBYeLz7JJ3n+16CDg==} + /@polkadot-api/ink-contracts@0.2.4: + resolution: {integrity: sha512-peBYPJ0UNMpfTk6iNnDv9293miuOyc8L29UbdtcnEBUKgEnhX4U0ke4oFmbuknYMATHU9nyMY3ftXPcYDpTmwQ==} dependencies: - '@polkadot-api/metadata-builders': 0.9.1 - '@polkadot-api/substrate-bindings': 0.9.3 + '@polkadot-api/metadata-builders': 0.10.0 + '@polkadot-api/substrate-bindings': 0.11.0 '@polkadot-api/utils': 0.1.2 scale-ts: 1.6.1 - /@polkadot-api/json-rpc-provider-proxy@0.2.3: - resolution: {integrity: sha512-dukH94xmV2MUYNZZFhGhnaE1WIjVOPlNpcuzYQRdKYLj3zZJnkA6PHPNHiHd4N8XaCTjaDF3GcBTi6MZ0wtbhg==} + /@polkadot-api/json-rpc-provider-proxy@0.2.4: + resolution: {integrity: sha512-nuGoY9QpBAiRU7xmXN3nugFvPcnSu3IxTLm1OWcNTGlZ1LW5bvdQHz3JLk56+Jlyb3GJ971hqdg2DJsMXkKCOg==} /@polkadot-api/json-rpc-provider@0.0.4: resolution: {integrity: sha512-9cDijLIxzHOBuq6yHqpqjJ9jBmXrctjc1OFqU+tQrS96adQze3mTIH6DTgfb/0LMrqxzxffz1HQGrIlEH00WrA==} - /@polkadot-api/known-chains@0.5.6: - resolution: {integrity: sha512-DYxpIfhIvWpjjZ3Y7X6Aomfs1/IbDyU+8R2ijDd6e4OBJzGrSjoU1wq4MZktbCivDXVCSF+NfIQpaHB8roBmOQ==} + /@polkadot-api/known-chains@0.6.0: + resolution: {integrity: sha512-qVNJhqqtjPYgpyEb70KyZPIKunhgR4D3AcZwx5D7QCOumSigEi3vB95pfHHsqER+44jYrlFqzGWauaMMZqQl2Q==} /@polkadot-api/logs-provider@0.0.6: resolution: {integrity: sha512-4WgHlvy+xee1ADaaVf6+MlK/+jGMtsMgAzvbQOJZnP4PfQuagoTqaeayk8HYKxXGphogLlPbD06tANxcb+nvAg==} dependencies: '@polkadot-api/json-rpc-provider': 0.0.4 - /@polkadot-api/metadata-builders@0.9.1: - resolution: {integrity: sha512-yZPm9KKn7QydbjMQMzhKHekDuQSdSZXYdCyqGt74HSNz9DdJSdpFNwHv0p+vmp+9QDlVsKK7nbUTjYxLZT4vCA==} + /@polkadot-api/metadata-builders@0.10.0: + resolution: {integrity: sha512-IQ9WHnyo0nuWudC39wW1wpRl2QZLL8O8WizwB2JjMv+UODJPsSouZpnGLfQo6mX2umGI1IDsTklb2frQOgVuWg==} dependencies: - '@polkadot-api/substrate-bindings': 0.9.3 + '@polkadot-api/substrate-bindings': 0.11.0 '@polkadot-api/utils': 0.1.2 - /@polkadot-api/metadata-compatibility@0.1.11: - resolution: {integrity: sha512-XHl3McfuPSKDAIviGbiuK0epwzcspmvsWSoBywv0l6+adCPw1IpNKKkoj7Wwx4836duD/y/47hQEmkgIbtNQ3A==} + /@polkadot-api/metadata-compatibility@0.1.14: + resolution: {integrity: sha512-O7b2+d1uMYFWpe6yW6kY84PGwzdEPBeLopAX9vJl3WTBavF4GYjztM/BD9GjnZ6n2ehmSRjowqZu7EVxYvQYvQ==} dependencies: - '@polkadot-api/metadata-builders': 0.9.1 - '@polkadot-api/substrate-bindings': 0.9.3 + '@polkadot-api/metadata-builders': 0.10.0 + '@polkadot-api/substrate-bindings': 0.11.0 - /@polkadot-api/observable-client@0.6.2(@polkadot-api/substrate-client@0.3.0)(rxjs@7.8.1): - resolution: {integrity: sha512-0GsJDg95FA8idC+epQTrwkLmWdDl6JdSGuAVmy70TE1dVXC8l6lmVWpSX2ltF8ENqA7oXy7DlDEP7FrbvjvHfg==} + /@polkadot-api/observable-client@0.7.0(@polkadot-api/substrate-client@0.3.0)(rxjs@7.8.1): + resolution: {integrity: sha512-ssDilIFNR+tEMbb9GE/fRXjhKvuFV32DANn5BuQWKOyDbE/d/G206SxLIgBPEQ4HbEzASxFSXJ5L1goDNkJdUA==} peerDependencies: '@polkadot-api/substrate-client': 0.3.0 rxjs: '>=7.8.0' dependencies: - '@polkadot-api/metadata-builders': 0.9.1 - '@polkadot-api/substrate-bindings': 0.9.3 + '@polkadot-api/metadata-builders': 0.10.0 + '@polkadot-api/substrate-bindings': 0.11.0 '@polkadot-api/substrate-client': 0.3.0 '@polkadot-api/utils': 0.1.2 rxjs: 7.8.1 - /@polkadot-api/pjs-signer@0.6.0: - resolution: {integrity: sha512-Dfji5Xbq820iKv5HTCWE1iDlXI/DtNYXTZOFLiL8banrSrcF5wvTq3QFknUv+q1TfwNYEZazT4eG3Dx/XAsosw==} + /@polkadot-api/pjs-signer@0.6.3: + resolution: {integrity: sha512-xXLwtDACcFRi5gyze1sfS/GBTjvs1E12R4zvB6TiIzUskFoc26+5xEqjpgo6VRnuIMVv5kWkCEQt+b5F7t76sw==} dependencies: - '@polkadot-api/metadata-builders': 0.9.1 + '@polkadot-api/metadata-builders': 0.10.0 '@polkadot-api/polkadot-signer': 0.1.6 - '@polkadot-api/signers-common': 0.1.1 - '@polkadot-api/substrate-bindings': 0.9.3 + '@polkadot-api/signers-common': 0.1.4 + '@polkadot-api/substrate-bindings': 0.11.0 '@polkadot-api/utils': 0.1.2 /@polkadot-api/polkadot-sdk-compat@2.3.1: @@ -674,47 +706,47 @@ packages: /@polkadot-api/polkadot-signer@0.1.6: resolution: {integrity: sha512-X7ghAa4r7doETtjAPTb50IpfGtrBmy3BJM5WCfNKa1saK04VFY9w+vDn+hwEcM4p0PcDHt66Ts74hzvHq54d9A==} - /@polkadot-api/signer@0.1.10: - resolution: {integrity: sha512-SW4aqfM0hxsZqjX/pHdCZmVdS9bAXKwRSKzcb8vT9AA5YAq3si/Rue5eGGw8gRVcHOr5TdTicMjjaFDfebDyfQ==} + /@polkadot-api/signer@0.1.13: + resolution: {integrity: sha512-QFBeupXDoK/XVno9RdnUoh5HiPC8YC+HtbL0Jz61WrfnBRo77Trv5b0w7pUngpqjQzRY1w68TbETNTqRPtZOFA==} dependencies: - '@noble/hashes': 1.5.0 + '@noble/hashes': 1.6.1 '@polkadot-api/polkadot-signer': 0.1.6 - '@polkadot-api/signers-common': 0.1.1 - '@polkadot-api/substrate-bindings': 0.9.3 + '@polkadot-api/signers-common': 0.1.4 + '@polkadot-api/substrate-bindings': 0.11.0 '@polkadot-api/utils': 0.1.2 - /@polkadot-api/signers-common@0.1.1: - resolution: {integrity: sha512-327dpMXr1lccrmG94MJqprkGGF5yZFYDBwl+YXl1ATeTDcaW1vzffCAPqx0vWytb2x3AWilJWyc3Q6xFUWzy4A==} + /@polkadot-api/signers-common@0.1.4: + resolution: {integrity: sha512-KMJuu6IMB0K17ppCZM6TSwshTQ8Zgx59+BPVouqnU8pxr+h7EqWf7wv72WyytEAbThWIqFr1VHIdaCj54eeVlg==} dependencies: - '@polkadot-api/metadata-builders': 0.9.1 + '@polkadot-api/metadata-builders': 0.10.0 '@polkadot-api/polkadot-signer': 0.1.6 - '@polkadot-api/substrate-bindings': 0.9.3 + '@polkadot-api/substrate-bindings': 0.11.0 '@polkadot-api/utils': 0.1.2 - /@polkadot-api/sm-provider@0.1.6(@polkadot-api/smoldot@0.3.5): - resolution: {integrity: sha512-+1lRIH6srYFpeFCN35GtFiw+H4Cs+6NmoJMDRdv9EOYg7I2LKmt97N8JNQ/3UVmnH5Rud0U+iaqnat5cJsv1wg==} + /@polkadot-api/sm-provider@0.1.7(@polkadot-api/smoldot@0.3.8): + resolution: {integrity: sha512-BhNKVeIFZdawpPVadXszLl8IP4EDjcLHe/GchfRRFkvoNFuwS2nNv/npYIqCviXV+dd2R8VnEELxwScsf380Og==} peerDependencies: '@polkadot-api/smoldot': '>=0.3' dependencies: '@polkadot-api/json-rpc-provider': 0.0.4 - '@polkadot-api/json-rpc-provider-proxy': 0.2.3 - '@polkadot-api/smoldot': 0.3.5 + '@polkadot-api/json-rpc-provider-proxy': 0.2.4 + '@polkadot-api/smoldot': 0.3.8 - /@polkadot-api/smoldot@0.3.5: - resolution: {integrity: sha512-QiCkI3Z2bSc8yMXChi6dsN7bGB5q8i/a/LGuNEDmMECoLdyEmz7pRBMmi4fnvfbthb+5/c5w5kl/7VOBEJ83tA==} + /@polkadot-api/smoldot@0.3.8: + resolution: {integrity: sha512-dbJSMRFtELDW+rZIWRwKE/K8oy7+gYaGl+DvaOjARoBW2n80rJ7RAMOCCu+b5h2zgl3elftFBwMNAuAWgHT/Zg==} dependencies: - '@types/node': 22.9.0 - smoldot: 2.0.31 + '@types/node': 22.10.3 + smoldot: 2.0.34 transitivePeerDependencies: - bufferutil - utf-8-validate - /@polkadot-api/substrate-bindings@0.9.3: - resolution: {integrity: sha512-ygaZo8+xssTdb6lj9mA8RTlanDfyd0iMex3aBFC1IzOSm08XUWdRpuSLRuerFCimLzKuz/oBOTKdqBFGb7ybUQ==} + /@polkadot-api/substrate-bindings@0.11.0: + resolution: {integrity: sha512-UGCa0xYtfcS/5LJAcro1vhIwxF31fsF5f42mzro9G85T854cbXPzqABDICYmJqdF72tBRMrnJlx6okGtLx9TKA==} dependencies: - '@noble/hashes': 1.5.0 + '@noble/hashes': 1.6.1 '@polkadot-api/utils': 0.1.2 - '@scure/base': 1.1.9 + '@scure/base': 1.2.1 scale-ts: 1.6.1 /@polkadot-api/substrate-client@0.3.0: @@ -729,11 +761,11 @@ packages: /@polkadot-api/wasm-executor@0.1.2: resolution: {integrity: sha512-a5wGenltB3EFPdf72u8ewi6HsUg2qubUAf3ekJprZf24lTK3+w8a/GUF/y6r08LJF35MALZ32SAtLqtVTIOGnQ==} - /@polkadot-api/ws-provider@0.3.5: - resolution: {integrity: sha512-YZJpWhgCuBH9F5VMG85Em212iEHVz/SiyM0ruqxRvXl/L+LVeh0kJ3RHUHi4xgnb24OfBvfCUG4X2PtvfuCbwA==} + /@polkadot-api/ws-provider@0.3.6: + resolution: {integrity: sha512-D2+rvcDc9smt24qUKqFoCuKKNhyBVDQEtnsqHiUN/Ym8UGP+Acegac3b9VOig70EpCcRBoYeXY2gEog2ybx1Kg==} dependencies: '@polkadot-api/json-rpc-provider': 0.0.4 - '@polkadot-api/json-rpc-provider-proxy': 0.2.3 + '@polkadot-api/json-rpc-provider-proxy': 0.2.4 ws: 8.18.0 transitivePeerDependencies: - bufferutil @@ -743,9 +775,9 @@ packages: resolution: {integrity: sha512-nTJOinTKuINHwKsUXR+Q1Hld0DU+EYVxcfQqiJz9PH8L+48K3gPfpAHDApIuOW6Uq6yVb5/pgcDPNCaJS5nYsg==} dependencies: '@noble/curves': 1.6.0 - '@noble/hashes': 1.5.0 + '@noble/hashes': 1.6.1 '@polkadot-labs/schnorrkel-wasm': 0.0.5 - '@scure/base': 1.1.9 + '@scure/base': 1.2.1 scale-ts: 1.6.1 dev: false @@ -760,7 +792,31 @@ packages: resolution: {integrity: sha512-oUKF4Qu+V1bPxEjq3kmzI3FZrMIr1kK/4cxntoHSBDTZn/Ymab9LXVhRNrbVend5JrwDANePcYqbK5Fdn9NGhQ==} dev: false - /@rollup/plugin-alias@5.1.1(rollup@4.25.0): + /@react-rxjs/core@0.10.7(react@19.0.0)(rxjs@7.8.1): + resolution: {integrity: sha512-dornp8pUs9OcdqFKKRh9+I2FVe21gWufNun6RYU1ddts7kUy9i4Thvl0iqcPFbGY61cJQMAJF7dxixWMSD/A/A==} + peerDependencies: + react: '>=16.8.0' + rxjs: '>=7' + dependencies: + '@rx-state/core': 0.1.4(rxjs@7.8.1) + react: 19.0.0 + rxjs: 7.8.1 + use-sync-external-store: 1.4.0(react@19.0.0) + dev: false + + /@react-rxjs/utils@0.9.7(@react-rxjs/core@0.10.7)(react@19.0.0)(rxjs@7.8.1): + resolution: {integrity: sha512-m9CUTdRsglObvUAlYfB24QvN+QH4XqCGEKnCdSILIeOx7mMqSi9TTFp2zrj5XqtMiLnj4ReAdDxrXegLPB73bQ==} + peerDependencies: + '@react-rxjs/core': '>=0.1.0' + react: '>=16.8.0' + rxjs: '>=6' + dependencies: + '@react-rxjs/core': 0.10.7(react@19.0.0)(rxjs@7.8.1) + react: 19.0.0 + rxjs: 7.8.1 + dev: false + + /@rollup/plugin-alias@5.1.1(rollup@4.26.0): resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -769,10 +825,10 @@ packages: rollup: optional: true dependencies: - rollup: 4.25.0 + rollup: 4.26.0 dev: true - /@rollup/plugin-node-resolve@15.3.0(rollup@4.25.0): + /@rollup/plugin-node-resolve@15.3.0(rollup@4.26.0): resolution: {integrity: sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==} engines: {node: '>=14.0.0'} peerDependencies: @@ -781,15 +837,15 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.25.0) + '@rollup/pluginutils': 5.1.3(rollup@4.26.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.8 - rollup: 4.25.0 + rollup: 4.26.0 dev: true - /@rollup/pluginutils@5.1.3(rollup@4.25.0): + /@rollup/pluginutils@5.1.3(rollup@4.26.0): resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} engines: {node: '>=14.0.0'} peerDependencies: @@ -801,16 +857,8 @@ packages: '@types/estree': 1.0.6 estree-walker: 2.0.2 picomatch: 4.0.2 - rollup: 4.25.0 - dev: true - - /@rollup/rollup-android-arm-eabi@4.25.0: - resolution: {integrity: sha512-CC/ZqFZwlAIbU1wUPisHyV/XRc5RydFrNLtgl3dGYskdwPZdt4HERtKm50a/+DtTlKeCq9IXFEWR+P6blwjqBA==} - cpu: [arm] - os: [android] - requiresBuild: true + rollup: 4.26.0 dev: true - optional: true /@rollup/rollup-android-arm-eabi@4.26.0: resolution: {integrity: sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==} @@ -819,14 +867,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-android-arm64@4.25.0: - resolution: {integrity: sha512-/Y76tmLGUJqVBXXCfVS8Q8FJqYGhgH4wl4qTA24E9v/IJM0XvJCGQVSW1QZ4J+VURO9h8YCa28sTFacZXwK7Rg==} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-android-arm64@4.26.0: resolution: {integrity: sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==} cpu: [arm64] @@ -834,14 +874,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-darwin-arm64@4.25.0: - resolution: {integrity: sha512-YVT6L3UrKTlC0FpCZd0MGA7NVdp7YNaEqkENbWQ7AOVOqd/7VzyHpgIpc1mIaxRAo1ZsJRH45fq8j4N63I/vvg==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-darwin-arm64@4.26.0: resolution: {integrity: sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==} cpu: [arm64] @@ -849,14 +881,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-darwin-x64@4.25.0: - resolution: {integrity: sha512-ZRL+gexs3+ZmmWmGKEU43Bdn67kWnMeWXLFhcVv5Un8FQcx38yulHBA7XR2+KQdYIOtD0yZDWBCudmfj6lQJoA==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-darwin-x64@4.26.0: resolution: {integrity: sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==} cpu: [x64] @@ -864,14 +888,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-freebsd-arm64@4.25.0: - resolution: {integrity: sha512-xpEIXhiP27EAylEpreCozozsxWQ2TJbOLSivGfXhU4G1TBVEYtUPi2pOZBnvGXHyOdLAUUhPnJzH3ah5cqF01g==} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-freebsd-arm64@4.26.0: resolution: {integrity: sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==} cpu: [arm64] @@ -879,14 +895,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-freebsd-x64@4.25.0: - resolution: {integrity: sha512-sC5FsmZGlJv5dOcURrsnIK7ngc3Kirnx3as2XU9uER+zjfyqIjdcMVgzy4cOawhsssqzoAX19qmxgJ8a14Qrqw==} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-freebsd-x64@4.26.0: resolution: {integrity: sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==} cpu: [x64] @@ -894,14 +902,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.25.0: - resolution: {integrity: sha512-uD/dbLSs1BEPzg564TpRAQ/YvTnCds2XxyOndAO8nJhaQcqQGFgv/DAVko/ZHap3boCvxnzYMa3mTkV/B/3SWA==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.26.0: resolution: {integrity: sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==} cpu: [arm] @@ -909,14 +909,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-linux-arm-musleabihf@4.25.0: - resolution: {integrity: sha512-ZVt/XkrDlQWegDWrwyC3l0OfAF7yeJUF4fq5RMS07YM72BlSfn2fQQ6lPyBNjt+YbczMguPiJoCfaQC2dnflpQ==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-linux-arm-musleabihf@4.26.0: resolution: {integrity: sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==} cpu: [arm] @@ -924,14 +916,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-linux-arm64-gnu@4.25.0: - resolution: {integrity: sha512-qboZ+T0gHAW2kkSDPHxu7quaFaaBlynODXpBVnPxUgvWYaE84xgCKAPEYE+fSMd3Zv5PyFZR+L0tCdYCMAtG0A==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-linux-arm64-gnu@4.26.0: resolution: {integrity: sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==} cpu: [arm64] @@ -939,14 +923,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-linux-arm64-musl@4.25.0: - resolution: {integrity: sha512-ndWTSEmAaKr88dBuogGH2NZaxe7u2rDoArsejNslugHZ+r44NfWiwjzizVS1nUOHo+n1Z6qV3X60rqE/HlISgw==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-linux-arm64-musl@4.26.0: resolution: {integrity: sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==} cpu: [arm64] @@ -954,14 +930,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-linux-powerpc64le-gnu@4.25.0: - resolution: {integrity: sha512-BVSQvVa2v5hKwJSy6X7W1fjDex6yZnNKy3Kx1JGimccHft6HV0THTwNtC2zawtNXKUu+S5CjXslilYdKBAadzA==} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-linux-powerpc64le-gnu@4.26.0: resolution: {integrity: sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==} cpu: [ppc64] @@ -969,14 +937,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-linux-riscv64-gnu@4.25.0: - resolution: {integrity: sha512-G4hTREQrIdeV0PE2JruzI+vXdRnaK1pg64hemHq2v5fhv8C7WjVaeXc9P5i4Q5UC06d/L+zA0mszYIKl+wY8oA==} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-linux-riscv64-gnu@4.26.0: resolution: {integrity: sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==} cpu: [riscv64] @@ -984,14 +944,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-linux-s390x-gnu@4.25.0: - resolution: {integrity: sha512-9T/w0kQ+upxdkFL9zPVB6zy9vWW1deA3g8IauJxojN4bnz5FwSsUAD034KpXIVX5j5p/rn6XqumBMxfRkcHapQ==} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-linux-s390x-gnu@4.26.0: resolution: {integrity: sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==} cpu: [s390x] @@ -999,14 +951,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-linux-x64-gnu@4.25.0: - resolution: {integrity: sha512-ThcnU0EcMDn+J4B9LD++OgBYxZusuA7iemIIiz5yzEcFg04VZFzdFjuwPdlURmYPZw+fgVrFzj4CA64jSTG4Ig==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-linux-x64-gnu@4.26.0: resolution: {integrity: sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==} cpu: [x64] @@ -1014,14 +958,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-linux-x64-musl@4.25.0: - resolution: {integrity: sha512-zx71aY2oQxGxAT1JShfhNG79PnjYhMC6voAjzpu/xmMjDnKNf6Nl/xv7YaB/9SIa9jDYf8RBPWEnjcdlhlv1rQ==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-linux-x64-musl@4.26.0: resolution: {integrity: sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==} cpu: [x64] @@ -1029,14 +965,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-win32-arm64-msvc@4.25.0: - resolution: {integrity: sha512-JT8tcjNocMs4CylWY/CxVLnv8e1lE7ff1fi6kbGocWwxDq9pj30IJ28Peb+Y8yiPNSF28oad42ApJB8oUkwGww==} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-win32-arm64-msvc@4.26.0: resolution: {integrity: sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==} cpu: [arm64] @@ -1044,14 +972,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-win32-ia32-msvc@4.25.0: - resolution: {integrity: sha512-dRLjLsO3dNOfSN6tjyVlG+Msm4IiZnGkuZ7G5NmpzwF9oOc582FZG05+UdfTbz5Jd4buK/wMb6UeHFhG18+OEg==} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-win32-ia32-msvc@4.26.0: resolution: {integrity: sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==} cpu: [ia32] @@ -1059,14 +979,6 @@ packages: requiresBuild: true optional: true - /@rollup/rollup-win32-x64-msvc@4.25.0: - resolution: {integrity: sha512-/RqrIFtLB926frMhZD0a5oDa4eFIbyNEwLLloMTEjmqfwZWXywwVVOVmwTsuyhC9HKkVEZcOOi+KV4U9wmOdlg==} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@rollup/rollup-win32-x64-msvc@4.26.0: resolution: {integrity: sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==} cpu: [x64] @@ -1074,8 +986,15 @@ packages: requiresBuild: true optional: true - /@scure/base@1.1.9: - resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + /@rx-state/core@0.1.4(rxjs@7.8.1): + resolution: {integrity: sha512-Z+3hjU2xh1HisLxt+W5hlYX/eGSDaXXP+ns82gq/PLZpkXLu0uwcNUh9RLY3Clq4zT+hSsA3vcpIGt6+UAb8rQ==} + peerDependencies: + rxjs: '>=7' + dependencies: + rxjs: 7.8.1 + + /@scure/base@1.2.1: + resolution: {integrity: sha512-DGmGtC8Tt63J5GfHgfl5CuAXh96VF/LD8K9Hr/Gv0J2lAoRGlPOMpqMpMbCTOoOJMZCk2Xt+DskdDyn6dEFdzQ==} /@sec-ant/readable-stream@0.4.1: resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} @@ -1084,10 +1003,10 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - /@types/bun@1.1.13: - resolution: {integrity: sha512-KmQxSBgVWCl6RSuerlLGZlIWfdxkKqat0nxN61+qu4y1KDn0Ll3j7v1Pl8GnaL3a/U6GGWVTJh75ap62kR1E8Q==} + /@types/bun@1.1.16: + resolution: {integrity: sha512-E+ue6NMcn4FXC5bDRE1W/BXUVs01h5Mt02qH8/8HGCox9akuh8KNOFdwvaQS9TDgT2RmUyJYFRRqA60WtTnm2g==} dependencies: - bun-types: 1.1.34 + bun-types: 1.1.43 dev: true /@types/estree@1.0.6: @@ -1099,10 +1018,10 @@ packages: undici-types: 5.26.5 dev: true - /@types/node@22.9.0: - resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} + /@types/node@22.10.3: + resolution: {integrity: sha512-DifAyw4BkrufCILvD3ucnuN8eydUfc/C1GlyrnI+LK6543w5/L3VeVgf05o3B4fqSXP1dKYLOZsKfutpxPzZrw==} dependencies: - undici-types: 6.19.8 + undici-types: 6.20.0 /@types/normalize-package-data@2.4.4: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -1114,7 +1033,7 @@ packages: /@types/ws@8.5.13: resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} dependencies: - '@types/node': 22.9.0 + '@types/node': 22.10.3 dev: true /@vitest/expect@2.1.4: @@ -1212,20 +1131,20 @@ packages: dependencies: balanced-match: 1.0.2 - /bun-types@1.1.34: - resolution: {integrity: sha512-br5QygTEL/TwB4uQOb96Ky22j4Gq2WxWH/8Oqv20fk5HagwKXo/akB+LiYgSfzexCt6kkcUaVm+bKiPl71xPvw==} + /bun-types@1.1.43: + resolution: {integrity: sha512-W0wCtVH+bwFp7p3Zgs03CqxEDmXxEvmmUM/FBKgWIv9T8gyeotvIjIbHzuDScc2DphhRNtr7hJLCR5PspYL5qw==} dependencies: '@types/node': 20.12.14 '@types/ws': 8.5.13 dev: true - /bundle-require@5.0.0(esbuild@0.24.0): + /bundle-require@5.0.0(esbuild@0.24.2): resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} peerDependencies: esbuild: '>=0.18' dependencies: - esbuild: 0.24.0 + esbuild: 0.24.2 load-tsconfig: 0.2.5 /cac@6.7.14: @@ -1289,8 +1208,8 @@ packages: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} - /cross-spawn@7.0.5: - resolution: {integrity: sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==} + /cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} dependencies: path-key: 3.1.1 @@ -1373,36 +1292,37 @@ packages: '@esbuild/win32-x64': 0.21.5 dev: true - /esbuild@0.24.0: - resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + /esbuild@0.24.2: + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} engines: {node: '>=18'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/aix-ppc64': 0.24.0 - '@esbuild/android-arm': 0.24.0 - '@esbuild/android-arm64': 0.24.0 - '@esbuild/android-x64': 0.24.0 - '@esbuild/darwin-arm64': 0.24.0 - '@esbuild/darwin-x64': 0.24.0 - '@esbuild/freebsd-arm64': 0.24.0 - '@esbuild/freebsd-x64': 0.24.0 - '@esbuild/linux-arm': 0.24.0 - '@esbuild/linux-arm64': 0.24.0 - '@esbuild/linux-ia32': 0.24.0 - '@esbuild/linux-loong64': 0.24.0 - '@esbuild/linux-mips64el': 0.24.0 - '@esbuild/linux-ppc64': 0.24.0 - '@esbuild/linux-riscv64': 0.24.0 - '@esbuild/linux-s390x': 0.24.0 - '@esbuild/linux-x64': 0.24.0 - '@esbuild/netbsd-x64': 0.24.0 - '@esbuild/openbsd-arm64': 0.24.0 - '@esbuild/openbsd-x64': 0.24.0 - '@esbuild/sunos-x64': 0.24.0 - '@esbuild/win32-arm64': 0.24.0 - '@esbuild/win32-ia32': 0.24.0 - '@esbuild/win32-x64': 0.24.0 + '@esbuild/aix-ppc64': 0.24.2 + '@esbuild/android-arm': 0.24.2 + '@esbuild/android-arm64': 0.24.2 + '@esbuild/android-x64': 0.24.2 + '@esbuild/darwin-arm64': 0.24.2 + '@esbuild/darwin-x64': 0.24.2 + '@esbuild/freebsd-arm64': 0.24.2 + '@esbuild/freebsd-x64': 0.24.2 + '@esbuild/linux-arm': 0.24.2 + '@esbuild/linux-arm64': 0.24.2 + '@esbuild/linux-ia32': 0.24.2 + '@esbuild/linux-loong64': 0.24.2 + '@esbuild/linux-mips64el': 0.24.2 + '@esbuild/linux-ppc64': 0.24.2 + '@esbuild/linux-riscv64': 0.24.2 + '@esbuild/linux-s390x': 0.24.2 + '@esbuild/linux-x64': 0.24.2 + '@esbuild/netbsd-arm64': 0.24.2 + '@esbuild/netbsd-x64': 0.24.2 + '@esbuild/openbsd-arm64': 0.24.2 + '@esbuild/openbsd-x64': 0.24.2 + '@esbuild/sunos-x64': 0.24.2 + '@esbuild/win32-arm64': 0.24.2 + '@esbuild/win32-ia32': 0.24.2 + '@esbuild/win32-x64': 0.24.2 /estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -1414,19 +1334,19 @@ packages: '@types/estree': 1.0.6 dev: true - /execa@9.5.1: - resolution: {integrity: sha512-QY5PPtSonnGwhhHDNI7+3RvY285c7iuJFFB+lU+oEzMY/gEGJ808owqJsrr8Otd1E/x07po1LkUBmdAc5duPAg==} + /execa@9.5.2: + resolution: {integrity: sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==} engines: {node: ^18.19.0 || >=20.5.0} dependencies: '@sindresorhus/merge-streams': 4.0.0 - cross-spawn: 7.0.5 + cross-spawn: 7.0.6 figures: 6.1.0 get-stream: 9.0.1 human-signals: 8.0.0 is-plain-obj: 4.1.0 is-stream: 4.0.1 npm-run-path: 6.0.0 - pretty-ms: 9.1.0 + pretty-ms: 9.2.0 signal-exit: 4.1.0 strip-final-newline: 4.0.0 yoctocolors: 2.1.1 @@ -1456,7 +1376,7 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} dependencies: - cross-spawn: 7.0.5 + cross-spawn: 7.0.6 signal-exit: 4.1.0 /fs.promises.exists@1.1.4: @@ -1736,30 +1656,31 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - /polkadot-api@1.7.4(rxjs@7.8.1): - resolution: {integrity: sha512-4O9ThkdrW0HGTSfhSyj8HXyC70OKZ6rgfLFkpS9hqV8PfzUShnYy2GqU7YJJ14MGqRTAF6EdKftKzV2g+j09Ow==} + /polkadot-api@1.8.1(rxjs@7.8.1): + resolution: {integrity: sha512-E2Jh9tiO6eB/fjnwr68mnZAZ/UuoZPBZQKjplHSMjVgNNQEkNZSqDcFvH18Rag5x4z7oJzuEk9+Hj62u/+D1PQ==} hasBin: true peerDependencies: rxjs: '>=7.8.0' dependencies: - '@polkadot-api/cli': 0.9.18 - '@polkadot-api/ink-contracts': 0.2.1 + '@polkadot-api/cli': 0.10.0 + '@polkadot-api/ink-contracts': 0.2.4 '@polkadot-api/json-rpc-provider': 0.0.4 - '@polkadot-api/known-chains': 0.5.6 + '@polkadot-api/known-chains': 0.6.0 '@polkadot-api/logs-provider': 0.0.6 - '@polkadot-api/metadata-builders': 0.9.1 - '@polkadot-api/metadata-compatibility': 0.1.11 - '@polkadot-api/observable-client': 0.6.2(@polkadot-api/substrate-client@0.3.0)(rxjs@7.8.1) - '@polkadot-api/pjs-signer': 0.6.0 + '@polkadot-api/metadata-builders': 0.10.0 + '@polkadot-api/metadata-compatibility': 0.1.14 + '@polkadot-api/observable-client': 0.7.0(@polkadot-api/substrate-client@0.3.0)(rxjs@7.8.1) + '@polkadot-api/pjs-signer': 0.6.3 '@polkadot-api/polkadot-sdk-compat': 2.3.1 '@polkadot-api/polkadot-signer': 0.1.6 - '@polkadot-api/signer': 0.1.10 - '@polkadot-api/sm-provider': 0.1.6(@polkadot-api/smoldot@0.3.5) - '@polkadot-api/smoldot': 0.3.5 - '@polkadot-api/substrate-bindings': 0.9.3 + '@polkadot-api/signer': 0.1.13 + '@polkadot-api/sm-provider': 0.1.7(@polkadot-api/smoldot@0.3.8) + '@polkadot-api/smoldot': 0.3.8 + '@polkadot-api/substrate-bindings': 0.11.0 '@polkadot-api/substrate-client': 0.3.0 '@polkadot-api/utils': 0.1.2 - '@polkadot-api/ws-provider': 0.3.5 + '@polkadot-api/ws-provider': 0.3.6 + '@rx-state/core': 0.1.4(rxjs@7.8.1) rxjs: 7.8.1 transitivePeerDependencies: - '@microsoft/api-extractor' @@ -1807,8 +1728,8 @@ packages: hasBin: true dev: true - /pretty-ms@9.1.0: - resolution: {integrity: sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==} + /pretty-ms@9.2.0: + resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} engines: {node: '>=18'} dependencies: parse-ms: 4.0.0 @@ -1817,6 +1738,11 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + /react@19.0.0: + resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} + engines: {node: '>=0.10.0'} + dev: false + /read-pkg@9.0.1: resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} engines: {node: '>=18'} @@ -1855,7 +1781,7 @@ packages: onetime: 7.0.0 signal-exit: 4.1.0 - /rollup-plugin-dts@6.1.1(rollup@4.25.0)(typescript@5.6.3): + /rollup-plugin-dts@6.1.1(rollup@4.26.0)(typescript@5.7.3): resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} engines: {node: '>=16'} peerDependencies: @@ -1863,57 +1789,29 @@ packages: typescript: ^4.5 || ^5.0 dependencies: magic-string: 0.30.12 - rollup: 4.25.0 - typescript: 5.6.3 + rollup: 4.26.0 + typescript: 5.7.3 optionalDependencies: '@babel/code-frame': 7.26.2 dev: true - /rollup-plugin-esbuild@6.1.1(esbuild@0.24.0)(rollup@4.25.0): + /rollup-plugin-esbuild@6.1.1(esbuild@0.24.2)(rollup@4.26.0): resolution: {integrity: sha512-CehMY9FAqJD5OUaE/Mi1r5z0kNeYxItmRO2zG4Qnv2qWKF09J2lTy5GUzjJR354ZPrLkCj4fiBN41lo8PzBUhw==} engines: {node: '>=14.18.0'} peerDependencies: esbuild: '>=0.18.0' rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.25.0) + '@rollup/pluginutils': 5.1.3(rollup@4.26.0) debug: 4.3.7 es-module-lexer: 1.5.4 - esbuild: 0.24.0 + esbuild: 0.24.2 get-tsconfig: 4.8.1 - rollup: 4.25.0 + rollup: 4.26.0 transitivePeerDependencies: - supports-color dev: true - /rollup@4.25.0: - resolution: {integrity: sha512-uVbClXmR6wvx5R1M3Od4utyLUxrmOcEm3pAtMphn73Apq19PDtHpgZoEvqH2YnnaNUuvKmg2DgRd2Sqv+odyqg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - dependencies: - '@types/estree': 1.0.6 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.25.0 - '@rollup/rollup-android-arm64': 4.25.0 - '@rollup/rollup-darwin-arm64': 4.25.0 - '@rollup/rollup-darwin-x64': 4.25.0 - '@rollup/rollup-freebsd-arm64': 4.25.0 - '@rollup/rollup-freebsd-x64': 4.25.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.25.0 - '@rollup/rollup-linux-arm-musleabihf': 4.25.0 - '@rollup/rollup-linux-arm64-gnu': 4.25.0 - '@rollup/rollup-linux-arm64-musl': 4.25.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.25.0 - '@rollup/rollup-linux-riscv64-gnu': 4.25.0 - '@rollup/rollup-linux-s390x-gnu': 4.25.0 - '@rollup/rollup-linux-x64-gnu': 4.25.0 - '@rollup/rollup-linux-x64-musl': 4.25.0 - '@rollup/rollup-win32-arm64-msvc': 4.25.0 - '@rollup/rollup-win32-ia32-msvc': 4.25.0 - '@rollup/rollup-win32-x64-msvc': 4.25.0 - fsevents: 2.3.3 - dev: true - /rollup@4.26.0: resolution: {integrity: sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -1972,8 +1870,8 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - /smoldot@2.0.31: - resolution: {integrity: sha512-nkPbjTb1G0hGji0/GwJELIehkXGIDh/X8PK/p3RjnklvUj4NrbdNuKx3K+PFATgbL7dfhSSYoFFdJ7Ql0T7zWQ==} + /smoldot@2.0.34: + resolution: {integrity: sha512-mw9tCbGEhEp0koMqLL0jBEixVY1MIN/xI3pE6ZY1TuOPU+LnYy8FloODVyzkvzQPaBYrETXJdRlmA/+k6g3gow==} dependencies: ws: 8.18.0 transitivePeerDependencies: @@ -2137,18 +2035,18 @@ packages: /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - /tsc-prog@2.3.0(typescript@5.6.3): + /tsc-prog@2.3.0(typescript@5.7.3): resolution: {integrity: sha512-ycET2d75EgcX7y8EmG4KiZkLAwUzbY4xRhA6NU0uVbHkY4ZjrAAuzTMxXI85kOwATqPnBI5C/7y7rlpY0xdqHA==} engines: {node: '>=12'} peerDependencies: typescript: '>=4' dependencies: - typescript: 5.6.3 + typescript: 5.7.3 /tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - /tsup@8.3.5(typescript@5.6.3): + /tsup@8.3.5(typescript@5.7.3): resolution: {integrity: sha512-Tunf6r6m6tnZsG9GYWndg0z8dEV7fD733VBFzFJ5Vcm1FtlXB8xBD/rtrBi2a3YKEV7hHtxiZtW5EAVADoe1pA==} engines: {node: '>=18'} hasBin: true @@ -2167,12 +2065,12 @@ packages: typescript: optional: true dependencies: - bundle-require: 5.0.0(esbuild@0.24.0) + bundle-require: 5.0.0(esbuild@0.24.2) cac: 6.7.14 chokidar: 4.0.1 consola: 3.2.3 debug: 4.3.7 - esbuild: 0.24.0 + esbuild: 0.24.2 joycon: 3.1.1 picocolors: 1.1.1 postcss-load-config: 6.0.1 @@ -2183,7 +2081,7 @@ packages: tinyexec: 0.3.1 tinyglobby: 0.2.10 tree-kill: 1.2.2 - typescript: 5.6.3 + typescript: 5.7.3 transitivePeerDependencies: - jiti - supports-color @@ -2194,8 +2092,8 @@ packages: resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==} engines: {node: '>=16'} - /typescript@5.6.3: - resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + /typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} engines: {node: '>=14.17'} hasBin: true @@ -2203,8 +2101,8 @@ packages: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} dev: true - /undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + /undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} /unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} @@ -2214,6 +2112,14 @@ packages: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} + /use-sync-external-store@1.4.0(react@19.0.0): + resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + react: 19.0.0 + dev: false + /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -2274,7 +2180,7 @@ packages: dependencies: esbuild: 0.21.5 postcss: 8.4.48 - rollup: 4.25.0 + rollup: 4.26.0 optionalDependencies: fsevents: 2.3.3 dev: true @@ -2420,12 +2326,12 @@ packages: resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} engines: {node: '>=18'} - file:examples/ink-playground/.papi/descriptors(polkadot-api@1.7.4): + file:examples/ink-playground/.papi/descriptors(polkadot-api@1.8.1): resolution: {directory: examples/ink-playground/.papi/descriptors, type: directory} id: file:examples/ink-playground/.papi/descriptors name: '@polkadot-api/descriptors' peerDependencies: polkadot-api: '*' dependencies: - polkadot-api: 1.7.4(rxjs@7.8.1) + polkadot-api: 1.8.1(rxjs@7.8.1) dev: false