From a6d3a02f77b9bd28d7f1cb475bf08163c76a398c Mon Sep 17 00:00:00 2001 From: Victor Oliva Date: Sat, 17 May 2025 18:35:52 +0200 Subject: [PATCH] grab current value when setting storage --- src/pages/Storage/StorageQuery.tsx | 2 +- src/pages/Storage/StorageSet.tsx | 133 ++++++++++++++++++++++------- 2 files changed, 103 insertions(+), 32 deletions(-) diff --git a/src/pages/Storage/StorageQuery.tsx b/src/pages/Storage/StorageQuery.tsx index 0e618b8..8981df2 100644 --- a/src/pages/Storage/StorageQuery.tsx +++ b/src/pages/Storage/StorageQuery.tsx @@ -103,7 +103,7 @@ const [keyValueChange$, setKeyValue] = createSignal<{ idx: number value: unknown | NOTIN }>() -const keyValues$ = keys$.pipeState( +export const keyValues$ = keys$.pipeState( switchMap((keys) => { const values: unknown[] = keys.map(() => NOTIN) return keyValueChange$.pipe( diff --git a/src/pages/Storage/StorageSet.tsx b/src/pages/Storage/StorageSet.tsx index e5c9ce7..4bf6945 100644 --- a/src/pages/Storage/StorageSet.tsx +++ b/src/pages/Storage/StorageSet.tsx @@ -2,21 +2,76 @@ import { chopsticksInstance$ } from "@/chopsticks/chopsticks" import { LookupTypeEdit } from "@/codec-components/LookupTypeEdit" import { Chopsticks } from "@/components/Icons" import { Button } from "@/components/ui/button" -import { lookup$ } from "@/state/chains/chain.state" +import { chainClient$, lookup$ } from "@/state/chains/chain.state" import { getTypeComplexity } from "@/utils" import { setStorage } from "@acala-network/chopsticks-core" import { toHex } from "@polkadot-api/utils" -import { useStateObservable } from "@react-rxjs/core" +import { state, useStateObservable } from "@react-rxjs/core" +import { createSignal } from "@react-rxjs/utils" import { FC, useState } from "react" -import { firstValueFrom } from "rxjs" +import { + combineLatest, + filter, + firstValueFrom, + map, + merge, + switchMap, + withLatestFrom, +} from "rxjs" import { selectedEntry$ } from "./storage.state" import { encodedKey$, KeyDisplay, StorageKeysInput } from "./StorageQuery" +import { Binary } from "polkadot-api" + +const [setValue$, setValue] = createSignal() +const currentValue$ = state( + merge( + combineLatest([ + encodedKey$.pipe(filter((v) => v != null)), + selectedEntry$.pipe(filter((v) => v != null)), + chainClient$, + ]).pipe( + switchMap(([key, entry, client]) => + client.chainHead.storage$( + null, + "value", + () => key, + null, + (data, ctx) => { + // We must comply with the original mapper, or the cache will contain a wrong value. + const codec = ctx.dynamicBuilder.buildStorage( + entry.pallet, + entry.entry, + ) + return data === null ? codec.fallback : codec.value.dec(data) + }, + ), + ), + withLatestFrom(lookup$, selectedEntry$.pipe(filter((v) => v != null))), + map(([v, lookup, entry]) => { + if (v.raw !== null) return v.raw + const pallet = lookup.metadata.pallets.find( + (p) => p.name == entry.pallet, + )! + const storageItem = pallet.storage!.items.find( + (i) => i.name === entry.entry, + )! + + return storageItem.modifier ? storageItem.fallback : null + }), + map((v) => (v != null ? Binary.fromHex(v).asBytes() : v)), + ), + setValue$, + ).pipe( + withLatestFrom(encodedKey$), + map(([value, encodedKey]) => ({ value, encodedKey })), + ), + null, +) export const StorageSet: FC = () => { const selectedEntry = useStateObservable(selectedEntry$) const lookup = useStateObservable(lookup$) - const [value, setValue] = useState(null) - const encodedKey = useStateObservable(encodedKey$) + const currentValue = useStateObservable(currentValue$) const [isLoading, setIsLoading] = useState(false) if (!lookup || !selectedEntry) return null @@ -28,33 +83,49 @@ export const StorageSet: FC = () => {
- - + await setStorage(chopsticks, [ + [currentValue.encodedKey, toHex(currentValue.value)], + ]) + await chopsticks.newBlock() + } finally { + setIsLoading(false) + } + }} + > + Set Storage + + + + ) : null}
) }