polkadot-api 1.9.13 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.mjs +1 -1
- package/dist/esm/client.mjs +1 -0
- package/dist/esm/client.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/storage.mjs +7 -8
- package/dist/esm/storage.mjs.map +1 -1
- package/dist/esm/tx/create-tx.mjs +54 -5
- package/dist/esm/tx/create-tx.mjs.map +1 -1
- package/dist/esm/tx/submit-fns.mjs +1 -1
- package/dist/esm/tx/submit-fns.mjs.map +1 -1
- package/dist/esm/typed-codecs/typed-codecs.mjs +52 -0
- package/dist/esm/typed-codecs/typed-codecs.mjs.map +1 -0
- package/dist/index.d.ts +80 -2
- package/dist/index.js +108 -11
- package/dist/index.js.map +1 -1
- package/dist/umd/index.min.js +3 -3
- package/dist/umd/ink.min.js +1 -1
- package/dist/umd/pjs-signer.min.js +1 -1
- package/dist/umd/signer.min.js +1 -1
- package/package.json +16 -16
package/bin/cli.mjs
CHANGED
package/dist/esm/client.mjs
CHANGED
|
@@ -177,6 +177,7 @@ function createClient(provider) {
|
|
|
177
177
|
const { broadcastTx$ } = client;
|
|
178
178
|
return {
|
|
179
179
|
getChainSpecData,
|
|
180
|
+
blocks$: chainHead.newBlocks$,
|
|
180
181
|
finalizedBlock$: chainHead.finalized$,
|
|
181
182
|
getFinalizedBlock: () => firstValueFrom(chainHead.finalized$),
|
|
182
183
|
bestBlocks$: chainHead.bestBlocks$,
|
package/dist/esm/client.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","sources":["../../src/client.ts"],"sourcesContent":["import { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport {\n enumValueEntryPointNode,\n runtimeCallEntryPoint,\n singleValueEntryPoint,\n storageEntryPoint,\n voidEntryPointNode,\n} from \"@polkadot-api/metadata-compatibility\"\nimport {\n ChainHead$,\n RuntimeContext,\n getObservableClient,\n} from \"@polkadot-api/observable-client\"\nimport {\n SubstrateClient,\n createClient as createRawClient,\n} from \"@polkadot-api/substrate-client\"\nimport {\n Observable,\n catchError,\n defer,\n firstValueFrom,\n map,\n shareReplay,\n} from \"rxjs\"\nimport {\n CompatibilityToken,\n OpType,\n RuntimeToken,\n compatibilityHelper,\n createCompatibilityToken,\n createRuntimeToken,\n getCompatibilityApi,\n} from \"./compatibility\"\nimport { createConstantEntry } from \"./constants\"\nimport { ChainDefinition } from \"./descriptors\"\nimport { createEventEntry } from \"./event\"\nimport { createRuntimeCallEntry } from \"./runtime-call\"\nimport { createStorageEntry } from \"./storage\"\nimport { createTxEntry, submit, submit$ } from \"./tx\"\nimport type { AnyApi, PolkadotClient } from \"./types\"\nimport { Binary } from \"@polkadot-api/substrate-bindings\"\nimport { createWatchEntries } from \"./watch-entries\"\n\nconst createApi = <Unsafe extends true | false, D>(\n compatibilityToken: Promise<CompatibilityToken | RuntimeToken>,\n chainHead: ChainHead$,\n broadcast$: (tx: string) => Observable<never>,\n): AnyApi<Unsafe, D> => {\n const target = {}\n const createProxy = (propCall: (prop: string) => unknown) =>\n new Proxy(target, {\n get(_, prop) {\n return propCall(prop as string)\n },\n })\n const createProxyPath = <T>(pathCall: (a: string, b: string) => T) => {\n const cache: Record<string, Record<string, T>> = {}\n return createProxy((a) => {\n if (!cache[a]) cache[a] = {}\n return createProxy((b) => {\n if (!cache[a][b]) cache[a][b] = pathCall(a, b)\n return cache[a][b]\n })\n }) as Record<string, Record<string, T>>\n }\n\n const getPallet = (ctx: RuntimeContext, name: string) =>\n ctx.lookup.metadata.pallets.find((p) => p.name === name)\n\n const getWatchEntries = createWatchEntries(\n chainHead.pinnedBlocks$,\n chainHead.storage$,\n chainHead.withRuntime,\n )\n const query = createProxyPath((pallet, name) =>\n createStorageEntry(\n pallet,\n name,\n chainHead,\n getWatchEntries,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getPalletEntryPoint(OpType.Storage, pallet, name),\n // TODO this is way sub-optimal. Needs some rethought - maybe a builder for entry points?.\n (ctx) => {\n const item = getPallet(ctx, pallet)?.storage?.items.find(\n (s) => s.name === name,\n )\n return item == null ? null : storageEntryPoint(item)\n },\n ),\n ),\n )\n\n const getEnumEntry = (\n ctx: RuntimeContext,\n side: \"args\" | \"values\",\n id: number | undefined,\n name: string,\n ) => {\n if (id == null) return null\n const entry = ctx.lookup(id)\n if (entry.type !== \"enum\") throw new Error(\"Expected enum\")\n\n if (entry.value[name] == null) return null\n const node = enumValueEntryPointNode(entry.value[name])\n return {\n args: side === \"args\" ? node : voidEntryPointNode,\n values: side === \"args\" ? voidEntryPointNode : node,\n }\n }\n const tx = createProxyPath((pallet, name) =>\n createTxEntry(\n pallet,\n name,\n chainHead,\n broadcast$,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getPalletEntryPoint(OpType.Tx, pallet, name),\n (ctx) => getEnumEntry(ctx, \"args\", getPallet(ctx, pallet)?.calls, name),\n ),\n true,\n ),\n )\n\n const event = createProxyPath((pallet, name) =>\n createEventEntry(\n pallet,\n name,\n chainHead,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getPalletEntryPoint(OpType.Event, pallet, name),\n (ctx) =>\n getEnumEntry(ctx, \"values\", getPallet(ctx, pallet)?.events, name),\n ),\n ),\n )\n\n const constants = createProxyPath((pallet, name) =>\n createConstantEntry(\n pallet,\n name,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getPalletEntryPoint(OpType.Const, pallet, name),\n (ctx) => {\n const item = getPallet(ctx, pallet)?.constants.find(\n (c) => c.name === name,\n )?.type\n return item == null ? null : singleValueEntryPoint(item)\n },\n ),\n ),\n )\n\n const apis = createProxyPath((api, method) =>\n createRuntimeCallEntry(\n api,\n method,\n chainHead,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getApiEntryPoint(api, method),\n (ctx) =>\n runtimeCallEntryPoint(\n ctx.lookup.metadata.apis\n .find((a) => a.name === api)!\n .methods.find((m) => m.name === method)!,\n ),\n ),\n ),\n )\n\n const _callDataTx = (\n callData: Binary,\n token: CompatibilityToken | RuntimeToken,\n ) => {\n const { lookup, dynamicBuilder } = getCompatibilityApi(token).runtime()\n try {\n const decoded = dynamicBuilder\n .buildDefinition(lookup.call!)\n .dec(callData.asBytes())\n const pallet = decoded.type\n const call = decoded.value.type\n const args = decoded.value.value\n\n return createTxEntry(\n pallet,\n call,\n chainHead,\n broadcast$,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getPalletEntryPoint(OpType.Tx, pallet, call),\n (ctx) =>\n getEnumEntry(ctx, \"args\", getPallet(ctx, pallet)?.calls, call),\n ),\n false,\n )(args)\n } catch {\n throw new Error(\"createTx: invalid call data\")\n }\n }\n\n return {\n query,\n txFromCallData: (\n callData: Binary,\n token?: CompatibilityToken | RuntimeToken,\n ) =>\n token\n ? _callDataTx(callData, token)\n : compatibilityToken.then((t) => _callDataTx(callData, t)),\n tx,\n event,\n apis,\n constants,\n } as any\n}\n\n/**\n * This is the top-level export for `polkadot-api`.\n *\n * @param provider A `JsonRpcProvider` compliant with the [JSON-RPC\n * spec](https://paritytech.github.io/json-rpc-interface-spec/),\n * which must support the `chainHead`, `transaction` and\n * `chainSpec` groups.\n * @example\n *\n * import { createClient } from \"polkadot-api\"\n * import { getSmProvider } from \"polkadot-api/sm-provider\"\n * import { chainSpec } from \"polkadot-api/chains/polkadot\"\n * import { start } from \"polkadot-api/smoldot\"\n *\n * const smoldot = start()\n * const chain = await smoldot.addChain({ chainSpec })\n *\n * // Connect to the polkadot relay chain.\n * const client = createClient(getSmProvider(chain))\n *\n */\nexport function createClient(provider: JsonRpcProvider): PolkadotClient {\n const rawClient: SubstrateClient = createRawClient(provider)\n const client = getObservableClient(rawClient)\n const { getChainSpecData } = rawClient\n\n const { genesis$, ..._chainHead } = client.chainHead$()\n const chainHead: ChainHead$ = {\n ..._chainHead,\n genesis$: defer(getChainSpecData).pipe(\n map(({ genesisHash }) => genesisHash),\n catchError(() => genesis$),\n shareReplay(1),\n ),\n }\n\n const _request: <Reply = any, Params extends Array<any> = any[]>(\n method: string,\n params: Params,\n ) => Promise<Reply> = rawClient.request\n\n let runtimeToken: Promise<RuntimeToken>\n const compatibilityToken = new WeakMap<\n ChainDefinition,\n Promise<CompatibilityToken<any>>\n >()\n const getChainToken = (chainDefinition: ChainDefinition) => {\n const result =\n compatibilityToken.get(chainDefinition) ||\n createCompatibilityToken(chainDefinition, chainHead)\n compatibilityToken.set(chainDefinition, result)\n return result\n }\n const getRuntimeToken = <D>(): Promise<RuntimeToken<D>> =>\n (runtimeToken ??= createRuntimeToken(chainHead))\n const { broadcastTx$ } = client\n return {\n getChainSpecData,\n\n finalizedBlock$: chainHead.finalized$,\n getFinalizedBlock: () => firstValueFrom(chainHead.finalized$),\n\n bestBlocks$: chainHead.bestBlocks$,\n getBestBlocks: () => firstValueFrom(chainHead.bestBlocks$),\n\n watchBlockBody: chainHead.body$,\n getBlockBody: (hash: string) => firstValueFrom(chainHead.body$(hash)),\n\n getBlockHeader: (hash?: string) =>\n firstValueFrom(chainHead.header$(hash ?? null)),\n\n submit: (...args) => submit(chainHead, broadcastTx$, ...args),\n submitAndWatch: (...args) => submit$(chainHead, broadcastTx$, ...args),\n\n getTypedApi: <D extends ChainDefinition>(chainDefinition: D) => {\n const token = getChainToken(chainDefinition)\n return Object.assign(\n createApi<false, D>(token, chainHead, broadcastTx$),\n { compatibilityToken: token },\n )\n },\n\n getUnsafeApi: <D>() => {\n const token = getRuntimeToken()\n return Object.assign(createApi<true, D>(token, chainHead, broadcastTx$), {\n runtimeToken: token,\n })\n },\n\n destroy: () => {\n chainHead.unfollow()\n client.destroy()\n },\n\n _request,\n }\n}\n"],"names":["createRawClient"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.mjs","sources":["../../src/client.ts"],"sourcesContent":["import { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport {\n enumValueEntryPointNode,\n runtimeCallEntryPoint,\n singleValueEntryPoint,\n storageEntryPoint,\n voidEntryPointNode,\n} from \"@polkadot-api/metadata-compatibility\"\nimport {\n ChainHead$,\n RuntimeContext,\n getObservableClient,\n} from \"@polkadot-api/observable-client\"\nimport { Binary } from \"@polkadot-api/substrate-bindings\"\nimport {\n SubstrateClient,\n createClient as createRawClient,\n} from \"@polkadot-api/substrate-client\"\nimport {\n Observable,\n catchError,\n defer,\n firstValueFrom,\n map,\n shareReplay,\n} from \"rxjs\"\nimport {\n CompatibilityToken,\n OpType,\n RuntimeToken,\n compatibilityHelper,\n createCompatibilityToken,\n createRuntimeToken,\n getCompatibilityApi,\n} from \"./compatibility\"\nimport { createConstantEntry } from \"./constants\"\nimport { ChainDefinition } from \"./descriptors\"\nimport { createEventEntry } from \"./event\"\nimport { createRuntimeCallEntry } from \"./runtime-call\"\nimport { createStorageEntry } from \"./storage\"\nimport { createTxEntry, submit, submit$ } from \"./tx\"\nimport type { AnyApi, PolkadotClient } from \"./types\"\nimport { createWatchEntries } from \"./watch-entries\"\n\nconst createApi = <Unsafe extends true | false, D>(\n compatibilityToken: Promise<CompatibilityToken | RuntimeToken>,\n chainHead: ChainHead$,\n broadcast$: (tx: string) => Observable<never>,\n): AnyApi<Unsafe, D> => {\n const target = {}\n const createProxy = (propCall: (prop: string) => unknown) =>\n new Proxy(target, {\n get(_, prop) {\n return propCall(prop as string)\n },\n })\n const createProxyPath = <T>(pathCall: (a: string, b: string) => T) => {\n const cache: Record<string, Record<string, T>> = {}\n return createProxy((a) => {\n if (!cache[a]) cache[a] = {}\n return createProxy((b) => {\n if (!cache[a][b]) cache[a][b] = pathCall(a, b)\n return cache[a][b]\n })\n }) as Record<string, Record<string, T>>\n }\n\n const getPallet = (ctx: RuntimeContext, name: string) =>\n ctx.lookup.metadata.pallets.find((p) => p.name === name)\n\n const getWatchEntries = createWatchEntries(\n chainHead.pinnedBlocks$,\n chainHead.storage$,\n chainHead.withRuntime,\n )\n const query = createProxyPath((pallet, name) =>\n createStorageEntry(\n pallet,\n name,\n chainHead,\n getWatchEntries,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getPalletEntryPoint(OpType.Storage, pallet, name),\n // TODO this is way sub-optimal. Needs some rethought - maybe a builder for entry points?.\n (ctx) => {\n const item = getPallet(ctx, pallet)?.storage?.items.find(\n (s) => s.name === name,\n )\n return item == null ? null : storageEntryPoint(item)\n },\n ),\n ),\n )\n\n const getEnumEntry = (\n ctx: RuntimeContext,\n side: \"args\" | \"values\",\n id: number | undefined,\n name: string,\n ) => {\n if (id == null) return null\n const entry = ctx.lookup(id)\n if (entry.type !== \"enum\") throw new Error(\"Expected enum\")\n\n if (entry.value[name] == null) return null\n const node = enumValueEntryPointNode(entry.value[name])\n return {\n args: side === \"args\" ? node : voidEntryPointNode,\n values: side === \"args\" ? voidEntryPointNode : node,\n }\n }\n const tx = createProxyPath((pallet, name) =>\n createTxEntry(\n pallet,\n name,\n chainHead,\n broadcast$,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getPalletEntryPoint(OpType.Tx, pallet, name),\n (ctx) => getEnumEntry(ctx, \"args\", getPallet(ctx, pallet)?.calls, name),\n ),\n true,\n ),\n )\n\n const event = createProxyPath((pallet, name) =>\n createEventEntry(\n pallet,\n name,\n chainHead,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getPalletEntryPoint(OpType.Event, pallet, name),\n (ctx) =>\n getEnumEntry(ctx, \"values\", getPallet(ctx, pallet)?.events, name),\n ),\n ),\n )\n\n const constants = createProxyPath((pallet, name) =>\n createConstantEntry(\n pallet,\n name,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getPalletEntryPoint(OpType.Const, pallet, name),\n (ctx) => {\n const item = getPallet(ctx, pallet)?.constants.find(\n (c) => c.name === name,\n )?.type\n return item == null ? null : singleValueEntryPoint(item)\n },\n ),\n ),\n )\n\n const apis = createProxyPath((api, method) =>\n createRuntimeCallEntry(\n api,\n method,\n chainHead,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getApiEntryPoint(api, method),\n (ctx) =>\n runtimeCallEntryPoint(\n ctx.lookup.metadata.apis\n .find((a) => a.name === api)!\n .methods.find((m) => m.name === method)!,\n ),\n ),\n ),\n )\n\n const _callDataTx = (\n callData: Binary,\n token: CompatibilityToken | RuntimeToken,\n ) => {\n const { lookup, dynamicBuilder } = getCompatibilityApi(token).runtime()\n try {\n const decoded = dynamicBuilder\n .buildDefinition(lookup.call!)\n .dec(callData.asBytes())\n const pallet = decoded.type\n const call = decoded.value.type\n const args = decoded.value.value\n\n return createTxEntry(\n pallet,\n call,\n chainHead,\n broadcast$,\n compatibilityHelper(\n compatibilityToken,\n (r) => r.getPalletEntryPoint(OpType.Tx, pallet, call),\n (ctx) =>\n getEnumEntry(ctx, \"args\", getPallet(ctx, pallet)?.calls, call),\n ),\n false,\n )(args)\n } catch {\n throw new Error(\"createTx: invalid call data\")\n }\n }\n\n return {\n query,\n txFromCallData: (\n callData: Binary,\n token?: CompatibilityToken | RuntimeToken,\n ) =>\n token\n ? _callDataTx(callData, token)\n : compatibilityToken.then((t) => _callDataTx(callData, t)),\n tx,\n event,\n apis,\n constants,\n } as any\n}\n\n/**\n * This is the top-level export for `polkadot-api`.\n *\n * @param provider A `JsonRpcProvider` compliant with the [JSON-RPC\n * spec](https://paritytech.github.io/json-rpc-interface-spec/),\n * which must support the `chainHead`, `transaction` and\n * `chainSpec` groups.\n * @example\n *\n * import { createClient } from \"polkadot-api\"\n * import { getSmProvider } from \"polkadot-api/sm-provider\"\n * import { chainSpec } from \"polkadot-api/chains/polkadot\"\n * import { start } from \"polkadot-api/smoldot\"\n *\n * const smoldot = start()\n * const chain = await smoldot.addChain({ chainSpec })\n *\n * // Connect to the polkadot relay chain.\n * const client = createClient(getSmProvider(chain))\n *\n */\nexport function createClient(provider: JsonRpcProvider): PolkadotClient {\n const rawClient: SubstrateClient = createRawClient(provider)\n const client = getObservableClient(rawClient)\n const { getChainSpecData } = rawClient\n\n const { genesis$, ..._chainHead } = client.chainHead$()\n const chainHead: ChainHead$ = {\n ..._chainHead,\n genesis$: defer(getChainSpecData).pipe(\n map(({ genesisHash }) => genesisHash),\n catchError(() => genesis$),\n shareReplay(1),\n ),\n }\n\n const _request: <Reply = any, Params extends Array<any> = any[]>(\n method: string,\n params: Params,\n ) => Promise<Reply> = rawClient.request\n\n let runtimeToken: Promise<RuntimeToken>\n const compatibilityToken = new WeakMap<\n ChainDefinition,\n Promise<CompatibilityToken<any>>\n >()\n const getChainToken = (chainDefinition: ChainDefinition) => {\n const result =\n compatibilityToken.get(chainDefinition) ||\n createCompatibilityToken(chainDefinition, chainHead)\n compatibilityToken.set(chainDefinition, result)\n return result\n }\n const getRuntimeToken = <D>(): Promise<RuntimeToken<D>> =>\n (runtimeToken ??= createRuntimeToken(chainHead))\n const { broadcastTx$ } = client\n return {\n getChainSpecData,\n\n blocks$: chainHead.newBlocks$,\n\n finalizedBlock$: chainHead.finalized$,\n getFinalizedBlock: () => firstValueFrom(chainHead.finalized$),\n\n bestBlocks$: chainHead.bestBlocks$,\n getBestBlocks: () => firstValueFrom(chainHead.bestBlocks$),\n\n watchBlockBody: chainHead.body$,\n getBlockBody: (hash: string) => firstValueFrom(chainHead.body$(hash)),\n\n getBlockHeader: (hash?: string) =>\n firstValueFrom(chainHead.header$(hash ?? null)),\n\n submit: (...args) => submit(chainHead, broadcastTx$, ...args),\n submitAndWatch: (...args) => submit$(chainHead, broadcastTx$, ...args),\n\n getTypedApi: <D extends ChainDefinition>(chainDefinition: D) => {\n const token = getChainToken(chainDefinition)\n return Object.assign(\n createApi<false, D>(token, chainHead, broadcastTx$),\n { compatibilityToken: token },\n )\n },\n\n getUnsafeApi: <D>() => {\n const token = getRuntimeToken()\n return Object.assign(createApi<true, D>(token, chainHead, broadcastTx$), {\n runtimeToken: token,\n })\n },\n\n destroy: () => {\n chainHead.unfollow()\n client.destroy()\n },\n\n _request,\n }\n}\n"],"names":["createRawClient"],"mappings":"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"}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -3,5 +3,6 @@ export { AccountId, Binary, Enum, FixedSizeBinary, _Enum, getSs58AddressInfo } f
|
|
|
3
3
|
export { CompatibilityLevel } from '@polkadot-api/metadata-compatibility';
|
|
4
4
|
import './tx/tx.mjs';
|
|
5
5
|
export { getOfflineApi } from './offline.mjs';
|
|
6
|
+
export { getTypedCodecs } from './typed-codecs/typed-codecs.mjs';
|
|
6
7
|
export { InvalidTxError } from './tx/submit-fns.mjs';
|
|
7
8
|
//# sourceMappingURL=index.mjs.map
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
package/dist/esm/storage.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BlockNotPinnedError } from '@polkadot-api/observable-client';
|
|
2
2
|
import './utils/shareLatest.mjs';
|
|
3
3
|
import { map, filter, take, identity, shareReplay, pipe, combineLatestWith, distinctUntilChanged, from, mergeMap } from 'rxjs';
|
|
4
4
|
import { firstValueFromWithSignal } from './utils/firstValueFromWithSignal.mjs';
|
|
@@ -59,14 +59,13 @@ const createStorageEntry = (pallet, name, chainHead, getWatchEntries, {
|
|
|
59
59
|
const { at: _at } = isLastArgOptional ? lastArg : {};
|
|
60
60
|
const at = _at ?? null;
|
|
61
61
|
if (isSystemNumber)
|
|
62
|
-
return chainHead.
|
|
62
|
+
return chainHead.pinnedBlocks$.pipe(
|
|
63
63
|
map((blocks) => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (!block) throw new NotBestBlockError();
|
|
64
|
+
const hash = at === "finalized" || !at ? blocks.finalized : at === "best" ? blocks.best : at;
|
|
65
|
+
const block = blocks.blocks.get(hash);
|
|
66
|
+
if (!block) {
|
|
67
|
+
throw new BlockNotPinnedError(hash, "System.Number");
|
|
68
|
+
}
|
|
70
69
|
return block.number;
|
|
71
70
|
}),
|
|
72
71
|
distinctUntilChanged(),
|
package/dist/esm/storage.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.mjs","sources":["../../src/storage.ts"],"sourcesContent":["import {\n firstValueFromWithSignal,\n isOptionalArg,\n lossLessExhaustMap,\n} from \"@/utils\"\nimport { CompatibilityLevel } from \"@polkadot-api/metadata-compatibility\"\nimport {\n BlockInfo,\n ChainHead$,\n NotBestBlockError,\n RuntimeContext,\n} from \"@polkadot-api/observable-client\"\nimport { FixedSizeBinary } from \"@polkadot-api/substrate-bindings\"\nimport { StorageItemInput, StorageResult } from \"@polkadot-api/substrate-client\"\nimport {\n Observable,\n OperatorFunction,\n combineLatestWith,\n distinctUntilChanged,\n filter,\n from,\n identity,\n map,\n mergeMap,\n pipe,\n shareReplay,\n take,\n} from \"rxjs\"\nimport {\n CompatibilityFunctions,\n CompatibilityHelper,\n minCompatLevel,\n} from \"./compatibility\"\nimport { createWatchEntries } from \"./watch-entries\"\n\ntype CallOptions = Partial<{\n /**\n * `at` could be a blockHash, `best`, or `finalized` (default)\n */\n at: string\n /**\n * `signal` allows you to abort an ongoing Promise. See [MDN\n * docs](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) for\n * more information\n */\n signal: AbortSignal\n}>\n\ntype WithCallOptions<Args extends Array<any>> = [\n ...args: Args,\n options?: CallOptions,\n]\n\ntype WithWatchOptions<Args extends Array<any>> = [\n ...args: Args,\n options?: { at: \"best\" },\n]\n\ntype PossibleParents<A extends Array<any>> = A extends [...infer Left, any]\n ? Left | PossibleParents<Left>\n : ArrayPossibleParents<A>\n\n// Fixed-size arrays values can't be extracted one-by-one, so that's a specific case\ntype ArrayPossibleParents<\n A extends Array<any>,\n Count extends Array<any> = [],\n R = [],\n> = A extends Array<infer T> & { length: infer L }\n ? number extends L\n ? Array<T> // Case variable-size array it's an unknown amount of entries\n : L extends Count[\"length\"]\n ? R\n : ArrayPossibleParents<A, [...Count, T], R | Count>\n : never\n\ntype StorageEntryWithoutKeys<Unsafe, D, Payload> = {\n /**\n * Get `Payload` (Promise-based) for the storage entry.\n *\n * @param options Optionally set which block to target (latest known\n * finalized is the default) and an AbortSignal.\n */\n getValue: (options?: CallOptions) => Promise<Payload>\n /**\n * Watch changes in `Payload` (observable-based) for the storage entry.\n *\n * @param bestOrFinalized Optionally choose which block to query and watch\n * changes, `best` or `finalized` (default)\n */\n watchValue: (bestOrFinalized?: \"best\" | \"finalized\") => Observable<Payload>\n} & (Unsafe extends true ? {} : CompatibilityFunctions<D>)\n\nexport type StorageEntryWithKeys<\n Unsafe,\n D,\n Args extends Array<any>,\n Payload,\n ArgsOut extends Array<any>,\n> = {\n /**\n * Get `Payload` (Promise-based) for the storage entry with a specific set of\n * `Args`.\n *\n * @param args All keys needed for that storage entry.\n * At the end, optionally set which block to target (latest\n * known finalized is the default) and an AbortSignal.\n */\n getValue: (...args: [...WithCallOptions<Args>]) => Promise<Payload>\n /**\n * Watch changes in `Payload` (observable-based) for the storage entry.\n *\n * @param args All keys needed for that storage entry.\n * At the end, optionally choose which block to query and\n * watch changes, `best` or `finalized` (default)\n */\n watchValue: (\n ...args: [...Args, bestOrFinalized?: \"best\" | \"finalized\"]\n ) => Observable<Payload>\n /**\n * Get an Array of `Payload` (Promise-based) for the storage entry with\n * several sets of `Args`.\n *\n * @param keys Array of sets of keys needed for the storage entry.\n * @param options Optionally set which block to target (latest known\n * finalized is the default) and an AbortSignal.\n */\n getValues: (\n keys: Array<[...Args]>,\n options?: CallOptions,\n ) => Promise<Array<Payload>>\n /**\n * Get an Array of `Payload` (Promise-based) for the storage entry with a\n * subset of `Args`.\n *\n * @param args Subset of keys needed for the storage entry.\n * At the end, optionally set which block to target (latest\n * known finalized is the default) and an AbortSignal.\n * @example\n *\n * // this is a query with 3 keys\n * typedApi.query.Pallet.Query.getEntries({ at: \"best\" }) // no keys\n * typedApi.query.Pallet.Query.getEntries(arg1, { at: \"finalized\" }) // 1/3 keys\n * typedApi.query.Pallet.Query.getEntries(arg1, arg2, { at: \"0x12345678\" }) // 2/3 keys\n *\n */\n getEntries: (\n ...args: WithCallOptions<PossibleParents<Args>>\n ) => Promise<Array<{ keyArgs: ArgsOut; value: NonNullable<Payload> }>>\n /**\n * Watch changes (Observable-based) for the storage entries with a subset of\n * `Args`.\n *\n * @param args Subset of keys needed for the storage entry.\n * At the end, optionally set whether to watch against the\n * `best` block.\n * By default watches changes against the finalized block.\n * When watching changes against the \"best\" block, this API\n * gratiously handles the re-orgs and provides the deltas\n * based on the latest emission.\n * The observed value contains the following properties:\n * - `block`: the block in where the `deltas` took place -\n * `deltas`: `null` indicates that nothing has changed from\n * the latest emission.\n * If the value is not `null` then the `deleted` and `upsrted`\n * properties indicate the entries that have changed.\n * - `entries`: it's an immutable data-structure with the\n * latest entries.\n * @example\n *\n * typedApi.query.Staking.Nominators.watchEntries()\n * typedApi.query.Staking.Nominators.watchEntries({ at: \"best\" })\n *\n */\n watchEntries: (\n ...args: WithWatchOptions<PossibleParents<Args>>\n ) => Observable<{\n block: BlockInfo\n deltas: null | {\n deleted: Array<{ args: ArgsOut; value: NonNullable<Payload> }>\n upserted: Array<{ args: ArgsOut; value: NonNullable<Payload> }>\n }\n entries: Array<{ args: ArgsOut; value: NonNullable<Payload> }>\n }>\n} & (Unsafe extends true ? {} : CompatibilityFunctions<D>)\n\nexport type StorageEntry<\n Unsafe,\n D,\n Args extends Array<any>,\n ArgsOut extends Array<any>,\n Payload,\n> = Args extends []\n ? StorageEntryWithoutKeys<Unsafe, D, Payload>\n : StorageEntryWithKeys<Unsafe, D, Args, Payload, ArgsOut>\n\nexport type Storage$ = <Type extends StorageItemInput[\"type\"]>(\n hash: string | null,\n type: Type,\n key: string,\n childTrie: string | null,\n) => Observable<StorageResult<Type>>\n\nconst toMapped = map(<T>(x: { mapped: T }) => x.mapped)\nexport const createStorageEntry = (\n pallet: string,\n name: string,\n chainHead: ChainHead$,\n getWatchEntries: ReturnType<typeof createWatchEntries>,\n {\n isCompatible,\n getCompatibilityLevel,\n getCompatibilityLevels,\n descriptors: descriptorsPromise,\n argsAreCompatible,\n valuesAreCompatible,\n }: CompatibilityHelper,\n): StorageEntry<any, any, any, any, any> => {\n const isSystemNumber = pallet === \"System\" && name === \"Number\"\n const isBlockHash = pallet === \"System\" && name === \"BlockHash\"\n const sysNumberMapper$ = chainHead.runtime$.pipe(\n filter(Boolean),\n take(1),\n map(({ dynamicBuilder }) =>\n typeof dynamicBuilder\n .buildStorage(\"System\", \"Number\")\n .value.dec(new Uint8Array(32)) === \"bigint\"\n ? BigInt\n : identity,\n ),\n shareReplay(),\n )\n const bigIntOrNumber: OperatorFunction<number, number | bigint> = pipe(\n combineLatestWith(sysNumberMapper$),\n map(([input, mapper]) => mapper(input)),\n )\n\n const incompatibleError = () =>\n new Error(`Incompatible runtime entry Storage(${pallet}.${name})`)\n const invalidArgs = (args: Array<any>) =>\n new Error(`Invalid Arguments calling ${pallet}.${name}(${args})`)\n\n const getCodec = (ctx: RuntimeContext) => {\n try {\n return ctx.dynamicBuilder.buildStorage(pallet, name)\n } catch (e: any) {\n throw new Error(`Runtime entry Storage(${pallet}.${name}) not found`)\n }\n }\n\n const watchValue = (...args: Array<any>) => {\n const target = args[args.length - 1]\n const isBest = target === \"best\"\n const actualArgs =\n isBest || target === \"finalized\" ? args.slice(0, -1) : args\n\n return chainHead[isBest ? \"best$\" : \"finalized$\"].pipe(\n lossLessExhaustMap(() =>\n getRawValue$(...actualArgs, isBest ? { at: \"best\" } : {}),\n ),\n distinctUntilChanged((a, b) => a.raw === b.raw),\n toMapped,\n )\n }\n\n const getRawValue$ = (...args: Array<any>) => {\n const lastArg = args[args.length - 1]\n const isLastArgOptional = isOptionalArg(lastArg)\n const { at: _at }: CallOptions = isLastArgOptional ? lastArg : {}\n const at = _at ?? null\n\n if (isSystemNumber)\n return chainHead.bestBlocks$.pipe(\n map((blocks) => {\n if (at === \"finalized\" || !at) return blocks.at(-1)\n if (at === \"best\") return blocks.at(0)\n return blocks.find((block) => block.hash === at)\n }),\n map((block) => {\n if (!block) throw new NotBestBlockError()\n return block.number\n }),\n distinctUntilChanged(),\n bigIntOrNumber,\n map((mapped) => ({ raw: mapped, mapped })),\n )\n\n if (isBlockHash && Number(args[0]) === 0) {\n return chainHead.genesis$.pipe(\n map((raw) => ({ raw, mapped: FixedSizeBinary.fromHex(raw) })),\n ) as Observable<any>\n }\n\n return from(descriptorsPromise).pipe(\n mergeMap((descriptors) =>\n chainHead.storage$(\n at,\n \"value\",\n (ctx) => {\n const codecs = getCodec(ctx)\n const actualArgs =\n args.length === codecs.len ? args : args.slice(0, -1)\n if (args !== actualArgs && !isLastArgOptional)\n throw invalidArgs(args)\n if (!argsAreCompatible(descriptors, ctx, actualArgs))\n throw incompatibleError()\n return codecs.keys.enc(...actualArgs)\n },\n null,\n (data, ctx) => {\n const codecs = getCodec(ctx)\n const value =\n data === null ? codecs.fallback : codecs.value.dec(data)\n if (!valuesAreCompatible(descriptors, ctx, value))\n throw incompatibleError()\n return value\n },\n ),\n ),\n )\n }\n\n const getValue = async (...args: Array<any>) => {\n const lastArg = args[args.length - 1]\n const isLastArgOptional = isOptionalArg(lastArg)\n const { signal }: CallOptions = isLastArgOptional ? lastArg : {}\n\n return firstValueFromWithSignal(\n getRawValue$(...args).pipe(toMapped),\n signal,\n )\n }\n\n const getEntries = async (...args: Array<any>) => {\n const lastArg = args[args.length - 1]\n const isLastArgOptional = isOptionalArg(lastArg)\n const { signal, at: _at }: CallOptions = isLastArgOptional ? lastArg : {}\n const at = _at ?? null\n\n const descriptors = await descriptorsPromise\n const result$ = chainHead\n .storage$(\n at,\n \"descendantsValues\",\n (ctx) => {\n const codecs = getCodec(ctx)\n // TODO partial compatibility check for args that become optional\n if (\n minCompatLevel(getCompatibilityLevels(descriptors, ctx)) ===\n CompatibilityLevel.Incompatible\n )\n throw incompatibleError()\n\n if (args.length > codecs.len) throw invalidArgs(args)\n const actualArgs =\n args.length > 0 && isLastArgOptional ? args.slice(0, -1) : args\n if (args.length === codecs.len && actualArgs === args)\n throw invalidArgs(args)\n return codecs.keys.enc(...actualArgs)\n },\n null,\n (values, ctx) => {\n const codecs = getCodec(ctx)\n const decodedValues = values.map(({ key, value }) => ({\n keyArgs: codecs.keys.dec(key),\n value: codecs.value.dec(value),\n }))\n if (\n decodedValues.some(\n ({ value }) => !valuesAreCompatible(descriptors, ctx, value),\n )\n )\n throw incompatibleError()\n return decodedValues\n },\n )\n .pipe(toMapped)\n return firstValueFromWithSignal(result$, signal)\n }\n\n const getValues = (keyArgs: Array<Array<any>>, options?: CallOptions) =>\n Promise.all(\n keyArgs.map((args) => getValue(...(options ? [...args, options] : args))),\n )\n\n const watchEntries: any = (...args: Array<any>) => {\n const lastArg = args.at(-1)\n const isLastArgOptional = isOptionalArg(lastArg)\n\n return getWatchEntries(\n pallet,\n name,\n isLastArgOptional ? args.slice(0, -1) : args,\n isLastArgOptional && lastArg.at === \"best\",\n )\n }\n\n return {\n isCompatible,\n getCompatibilityLevel,\n getValue,\n getValues,\n getEntries,\n watchValue,\n watchEntries,\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"storage.mjs","sources":["../../src/storage.ts"],"sourcesContent":["import {\n firstValueFromWithSignal,\n isOptionalArg,\n lossLessExhaustMap,\n} from \"@/utils\"\nimport { CompatibilityLevel } from \"@polkadot-api/metadata-compatibility\"\nimport {\n BlockInfo,\n BlockNotPinnedError,\n ChainHead$,\n RuntimeContext,\n} from \"@polkadot-api/observable-client\"\nimport { FixedSizeBinary } from \"@polkadot-api/substrate-bindings\"\nimport { StorageItemInput, StorageResult } from \"@polkadot-api/substrate-client\"\nimport {\n Observable,\n OperatorFunction,\n combineLatestWith,\n distinctUntilChanged,\n filter,\n from,\n identity,\n map,\n mergeMap,\n pipe,\n shareReplay,\n take,\n} from \"rxjs\"\nimport {\n CompatibilityFunctions,\n CompatibilityHelper,\n minCompatLevel,\n} from \"./compatibility\"\nimport { createWatchEntries } from \"./watch-entries\"\n\ntype CallOptions = Partial<{\n /**\n * `at` could be a blockHash, `best`, or `finalized` (default)\n */\n at: string\n /**\n * `signal` allows you to abort an ongoing Promise. See [MDN\n * docs](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) for\n * more information\n */\n signal: AbortSignal\n}>\n\ntype WithCallOptions<Args extends Array<any>> = [\n ...args: Args,\n options?: CallOptions,\n]\n\ntype WithWatchOptions<Args extends Array<any>> = [\n ...args: Args,\n options?: { at: \"best\" },\n]\n\ntype PossibleParents<A extends Array<any>> = A extends [...infer Left, any]\n ? Left | PossibleParents<Left>\n : ArrayPossibleParents<A>\n\n// Fixed-size arrays values can't be extracted one-by-one, so that's a specific case\ntype ArrayPossibleParents<\n A extends Array<any>,\n Count extends Array<any> = [],\n R = [],\n> = A extends Array<infer T> & { length: infer L }\n ? number extends L\n ? Array<T> // Case variable-size array it's an unknown amount of entries\n : L extends Count[\"length\"]\n ? R\n : ArrayPossibleParents<A, [...Count, T], R | Count>\n : never\n\ntype StorageEntryWithoutKeys<Unsafe, D, Payload> = {\n /**\n * Get `Payload` (Promise-based) for the storage entry.\n *\n * @param options Optionally set which block to target (latest known\n * finalized is the default) and an AbortSignal.\n */\n getValue: (options?: CallOptions) => Promise<Payload>\n /**\n * Watch changes in `Payload` (observable-based) for the storage entry.\n *\n * @param bestOrFinalized Optionally choose which block to query and watch\n * changes, `best` or `finalized` (default)\n */\n watchValue: (bestOrFinalized?: \"best\" | \"finalized\") => Observable<Payload>\n} & (Unsafe extends true ? {} : CompatibilityFunctions<D>)\n\nexport type StorageEntryWithKeys<\n Unsafe,\n D,\n Args extends Array<any>,\n Payload,\n ArgsOut extends Array<any>,\n> = {\n /**\n * Get `Payload` (Promise-based) for the storage entry with a specific set of\n * `Args`.\n *\n * @param args All keys needed for that storage entry.\n * At the end, optionally set which block to target (latest\n * known finalized is the default) and an AbortSignal.\n */\n getValue: (...args: [...WithCallOptions<Args>]) => Promise<Payload>\n /**\n * Watch changes in `Payload` (observable-based) for the storage entry.\n *\n * @param args All keys needed for that storage entry.\n * At the end, optionally choose which block to query and\n * watch changes, `best` or `finalized` (default)\n */\n watchValue: (\n ...args: [...Args, bestOrFinalized?: \"best\" | \"finalized\"]\n ) => Observable<Payload>\n /**\n * Get an Array of `Payload` (Promise-based) for the storage entry with\n * several sets of `Args`.\n *\n * @param keys Array of sets of keys needed for the storage entry.\n * @param options Optionally set which block to target (latest known\n * finalized is the default) and an AbortSignal.\n */\n getValues: (\n keys: Array<[...Args]>,\n options?: CallOptions,\n ) => Promise<Array<Payload>>\n /**\n * Get an Array of `Payload` (Promise-based) for the storage entry with a\n * subset of `Args`.\n *\n * @param args Subset of keys needed for the storage entry.\n * At the end, optionally set which block to target (latest\n * known finalized is the default) and an AbortSignal.\n * @example\n *\n * // this is a query with 3 keys\n * typedApi.query.Pallet.Query.getEntries({ at: \"best\" }) // no keys\n * typedApi.query.Pallet.Query.getEntries(arg1, { at: \"finalized\" }) // 1/3 keys\n * typedApi.query.Pallet.Query.getEntries(arg1, arg2, { at: \"0x12345678\" }) // 2/3 keys\n *\n */\n getEntries: (\n ...args: WithCallOptions<PossibleParents<Args>>\n ) => Promise<Array<{ keyArgs: ArgsOut; value: NonNullable<Payload> }>>\n /**\n * Watch changes (Observable-based) for the storage entries with a subset of\n * `Args`.\n *\n * @param args Subset of keys needed for the storage entry.\n * At the end, optionally set whether to watch against the\n * `best` block.\n * By default watches changes against the finalized block.\n * When watching changes against the \"best\" block, this API\n * gratiously handles the re-orgs and provides the deltas\n * based on the latest emission.\n * The observed value contains the following properties:\n * - `block`: the block in where the `deltas` took place -\n * `deltas`: `null` indicates that nothing has changed from\n * the latest emission.\n * If the value is not `null` then the `deleted` and `upsrted`\n * properties indicate the entries that have changed.\n * - `entries`: it's an immutable data-structure with the\n * latest entries.\n * @example\n *\n * typedApi.query.Staking.Nominators.watchEntries()\n * typedApi.query.Staking.Nominators.watchEntries({ at: \"best\" })\n *\n */\n watchEntries: (\n ...args: WithWatchOptions<PossibleParents<Args>>\n ) => Observable<{\n block: BlockInfo\n deltas: null | {\n deleted: Array<{ args: ArgsOut; value: NonNullable<Payload> }>\n upserted: Array<{ args: ArgsOut; value: NonNullable<Payload> }>\n }\n entries: Array<{ args: ArgsOut; value: NonNullable<Payload> }>\n }>\n} & (Unsafe extends true ? {} : CompatibilityFunctions<D>)\n\nexport type StorageEntry<\n Unsafe,\n D,\n Args extends Array<any>,\n ArgsOut extends Array<any>,\n Payload,\n> = Args extends []\n ? StorageEntryWithoutKeys<Unsafe, D, Payload>\n : StorageEntryWithKeys<Unsafe, D, Args, Payload, ArgsOut>\n\nexport type Storage$ = <Type extends StorageItemInput[\"type\"]>(\n hash: string | null,\n type: Type,\n key: string,\n childTrie: string | null,\n) => Observable<StorageResult<Type>>\n\nconst toMapped = map(<T>(x: { mapped: T }) => x.mapped)\nexport const createStorageEntry = (\n pallet: string,\n name: string,\n chainHead: ChainHead$,\n getWatchEntries: ReturnType<typeof createWatchEntries>,\n {\n isCompatible,\n getCompatibilityLevel,\n getCompatibilityLevels,\n descriptors: descriptorsPromise,\n argsAreCompatible,\n valuesAreCompatible,\n }: CompatibilityHelper,\n): StorageEntry<any, any, any, any, any> => {\n const isSystemNumber = pallet === \"System\" && name === \"Number\"\n const isBlockHash = pallet === \"System\" && name === \"BlockHash\"\n const sysNumberMapper$ = chainHead.runtime$.pipe(\n filter(Boolean),\n take(1),\n map(({ dynamicBuilder }) =>\n typeof dynamicBuilder\n .buildStorage(\"System\", \"Number\")\n .value.dec(new Uint8Array(32)) === \"bigint\"\n ? BigInt\n : identity,\n ),\n shareReplay(),\n )\n const bigIntOrNumber: OperatorFunction<number, number | bigint> = pipe(\n combineLatestWith(sysNumberMapper$),\n map(([input, mapper]) => mapper(input)),\n )\n\n const incompatibleError = () =>\n new Error(`Incompatible runtime entry Storage(${pallet}.${name})`)\n const invalidArgs = (args: Array<any>) =>\n new Error(`Invalid Arguments calling ${pallet}.${name}(${args})`)\n\n const getCodec = (ctx: RuntimeContext) => {\n try {\n return ctx.dynamicBuilder.buildStorage(pallet, name)\n } catch (e: any) {\n throw new Error(`Runtime entry Storage(${pallet}.${name}) not found`)\n }\n }\n\n const watchValue = (...args: Array<any>) => {\n const target = args[args.length - 1]\n const isBest = target === \"best\"\n const actualArgs =\n isBest || target === \"finalized\" ? args.slice(0, -1) : args\n\n return chainHead[isBest ? \"best$\" : \"finalized$\"].pipe(\n lossLessExhaustMap(() =>\n getRawValue$(...actualArgs, isBest ? { at: \"best\" } : {}),\n ),\n distinctUntilChanged((a, b) => a.raw === b.raw),\n toMapped,\n )\n }\n\n const getRawValue$ = (...args: Array<any>) => {\n const lastArg = args[args.length - 1]\n const isLastArgOptional = isOptionalArg(lastArg)\n const { at: _at }: CallOptions = isLastArgOptional ? lastArg : {}\n const at = _at ?? null\n\n if (isSystemNumber)\n return chainHead.pinnedBlocks$.pipe(\n map((blocks) => {\n const hash =\n at === \"finalized\" || !at\n ? blocks.finalized\n : at === \"best\"\n ? blocks.best\n : at\n const block = blocks.blocks.get(hash)\n if (!block) {\n throw new BlockNotPinnedError(hash, \"System.Number\")\n }\n return block.number\n }),\n distinctUntilChanged(),\n bigIntOrNumber,\n map((mapped) => ({ raw: mapped, mapped })),\n )\n\n if (isBlockHash && Number(args[0]) === 0) {\n return chainHead.genesis$.pipe(\n map((raw) => ({ raw, mapped: FixedSizeBinary.fromHex(raw) })),\n ) as Observable<any>\n }\n\n return from(descriptorsPromise).pipe(\n mergeMap((descriptors) =>\n chainHead.storage$(\n at,\n \"value\",\n (ctx) => {\n const codecs = getCodec(ctx)\n const actualArgs =\n args.length === codecs.len ? args : args.slice(0, -1)\n if (args !== actualArgs && !isLastArgOptional)\n throw invalidArgs(args)\n if (!argsAreCompatible(descriptors, ctx, actualArgs))\n throw incompatibleError()\n return codecs.keys.enc(...actualArgs)\n },\n null,\n (data, ctx) => {\n const codecs = getCodec(ctx)\n const value =\n data === null ? codecs.fallback : codecs.value.dec(data)\n if (!valuesAreCompatible(descriptors, ctx, value))\n throw incompatibleError()\n return value\n },\n ),\n ),\n )\n }\n\n const getValue = async (...args: Array<any>) => {\n const lastArg = args[args.length - 1]\n const isLastArgOptional = isOptionalArg(lastArg)\n const { signal }: CallOptions = isLastArgOptional ? lastArg : {}\n\n return firstValueFromWithSignal(\n getRawValue$(...args).pipe(toMapped),\n signal,\n )\n }\n\n const getEntries = async (...args: Array<any>) => {\n const lastArg = args[args.length - 1]\n const isLastArgOptional = isOptionalArg(lastArg)\n const { signal, at: _at }: CallOptions = isLastArgOptional ? lastArg : {}\n const at = _at ?? null\n\n const descriptors = await descriptorsPromise\n const result$ = chainHead\n .storage$(\n at,\n \"descendantsValues\",\n (ctx) => {\n const codecs = getCodec(ctx)\n // TODO partial compatibility check for args that become optional\n if (\n minCompatLevel(getCompatibilityLevels(descriptors, ctx)) ===\n CompatibilityLevel.Incompatible\n )\n throw incompatibleError()\n\n if (args.length > codecs.len) throw invalidArgs(args)\n const actualArgs =\n args.length > 0 && isLastArgOptional ? args.slice(0, -1) : args\n if (args.length === codecs.len && actualArgs === args)\n throw invalidArgs(args)\n return codecs.keys.enc(...actualArgs)\n },\n null,\n (values, ctx) => {\n const codecs = getCodec(ctx)\n const decodedValues = values.map(({ key, value }) => ({\n keyArgs: codecs.keys.dec(key),\n value: codecs.value.dec(value),\n }))\n if (\n decodedValues.some(\n ({ value }) => !valuesAreCompatible(descriptors, ctx, value),\n )\n )\n throw incompatibleError()\n return decodedValues\n },\n )\n .pipe(toMapped)\n return firstValueFromWithSignal(result$, signal)\n }\n\n const getValues = (keyArgs: Array<Array<any>>, options?: CallOptions) =>\n Promise.all(\n keyArgs.map((args) => getValue(...(options ? [...args, options] : args))),\n )\n\n const watchEntries: any = (...args: Array<any>) => {\n const lastArg = args.at(-1)\n const isLastArgOptional = isOptionalArg(lastArg)\n\n return getWatchEntries(\n pallet,\n name,\n isLastArgOptional ? args.slice(0, -1) : args,\n isLastArgOptional && lastArg.at === \"best\",\n )\n }\n\n return {\n isCompatible,\n getCompatibilityLevel,\n getValue,\n getValues,\n getEntries,\n watchValue,\n watchEntries,\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;AA0MA,MAAM,QAAW,GAAA,GAAA,CAAI,CAAI,CAAA,KAAqB,EAAE,MAAM,CAAA;AAC/C,MAAM,kBAAqB,GAAA,CAChC,MACA,EAAA,IAAA,EACA,WACA,eACA,EAAA;AAAA,EACE,YAAA;AAAA,EACA,qBAAA;AAAA,EACA,sBAAA;AAAA,EACA,WAAa,EAAA,kBAAA;AAAA,EACb,iBAAA;AAAA,EACA;AACF,CAC0C,KAAA;AAC1C,EAAM,MAAA,cAAA,GAAiB,MAAW,KAAA,QAAA,IAAY,IAAS,KAAA,QAAA;AACvD,EAAM,MAAA,WAAA,GAAc,MAAW,KAAA,QAAA,IAAY,IAAS,KAAA,WAAA;AACpD,EAAM,MAAA,gBAAA,GAAmB,UAAU,QAAS,CAAA,IAAA;AAAA,IAC1C,OAAO,OAAO,CAAA;AAAA,IACd,KAAK,CAAC,CAAA;AAAA,IACN,GAAA;AAAA,MAAI,CAAC,EAAE,cAAA,OACL,OAAO,cAAA,CACJ,aAAa,QAAU,EAAA,QAAQ,CAC/B,CAAA,KAAA,CAAM,IAAI,IAAI,UAAA,CAAW,EAAE,CAAC,CAAA,KAAM,WACjC,MACA,GAAA;AAAA,KACN;AAAA,IACA,WAAY;AAAA,GACd;AACA,EAAA,MAAM,cAA4D,GAAA,IAAA;AAAA,IAChE,kBAAkB,gBAAgB,CAAA;AAAA,IAClC,GAAA,CAAI,CAAC,CAAC,KAAA,EAAO,MAAM,CAAM,KAAA,MAAA,CAAO,KAAK,CAAC;AAAA,GACxC;AAEA,EAAM,MAAA,iBAAA,GAAoB,MACxB,IAAI,KAAA,CAAM,sCAAsC,MAAM,CAAA,CAAA,EAAI,IAAI,CAAG,CAAA,CAAA,CAAA;AACnE,EAAM,MAAA,WAAA,GAAc,CAAC,IAAA,KACnB,IAAI,KAAA,CAAM,CAA6B,0BAAA,EAAA,MAAM,CAAI,CAAA,EAAA,IAAI,CAAI,CAAA,EAAA,IAAI,CAAG,CAAA,CAAA,CAAA;AAElE,EAAM,MAAA,QAAA,GAAW,CAAC,GAAwB,KAAA;AACxC,IAAI,IAAA;AACF,MAAA,OAAO,GAAI,CAAA,cAAA,CAAe,YAAa,CAAA,MAAA,EAAQ,IAAI,CAAA;AAAA,aAC5C,CAAQ,EAAA;AACf,MAAA,MAAM,IAAI,KAAM,CAAA,CAAA,sBAAA,EAAyB,MAAM,CAAA,CAAA,EAAI,IAAI,CAAa,WAAA,CAAA,CAAA;AAAA;AACtE,GACF;AAEA,EAAM,MAAA,UAAA,GAAa,IAAI,IAAqB,KAAA;AAC1C,IAAA,MAAM,MAAS,GAAA,IAAA,CAAK,IAAK,CAAA,MAAA,GAAS,CAAC,CAAA;AACnC,IAAA,MAAM,SAAS,MAAW,KAAA,MAAA;AAC1B,IAAM,MAAA,UAAA,GACJ,UAAU,MAAW,KAAA,WAAA,GAAc,KAAK,KAAM,CAAA,CAAA,EAAG,EAAE,CAAI,GAAA,IAAA;AAEzD,IAAA,OAAO,SAAU,CAAA,MAAA,GAAS,OAAU,GAAA,YAAY,CAAE,CAAA,IAAA;AAAA,MAChD,kBAAA;AAAA,QAAmB,MACjB,YAAa,CAAA,GAAG,UAAY,EAAA,MAAA,GAAS,EAAE,EAAI,EAAA,MAAA,EAAW,GAAA,EAAE;AAAA,OAC1D;AAAA,MACA,qBAAqB,CAAC,CAAA,EAAG,MAAM,CAAE,CAAA,GAAA,KAAQ,EAAE,GAAG,CAAA;AAAA,MAC9C;AAAA,KACF;AAAA,GACF;AAEA,EAAM,MAAA,YAAA,GAAe,IAAI,IAAqB,KAAA;AAC5C,IAAA,MAAM,OAAU,GAAA,IAAA,CAAK,IAAK,CAAA,MAAA,GAAS,CAAC,CAAA;AACpC,IAAM,MAAA,iBAAA,GAAoB,cAAc,OAAO,CAAA;AAC/C,IAAA,MAAM,EAAE,EAAI,EAAA,GAAA,EAAqB,GAAA,iBAAA,GAAoB,UAAU,EAAC;AAChE,IAAA,MAAM,KAAK,GAAO,IAAA,IAAA;AAElB,IAAI,IAAA,cAAA;AACF,MAAA,OAAO,UAAU,aAAc,CAAA,IAAA;AAAA,QAC7B,GAAA,CAAI,CAAC,MAAW,KAAA;AACd,UAAM,MAAA,IAAA,GACJ,EAAO,KAAA,WAAA,IAAe,CAAC,EAAA,GACnB,OAAO,SACP,GAAA,EAAA,KAAO,MACL,GAAA,MAAA,CAAO,IACP,GAAA,EAAA;AACR,UAAA,MAAM,KAAQ,GAAA,MAAA,CAAO,MAAO,CAAA,GAAA,CAAI,IAAI,CAAA;AACpC,UAAA,IAAI,CAAC,KAAO,EAAA;AACV,YAAM,MAAA,IAAI,mBAAoB,CAAA,IAAA,EAAM,eAAe,CAAA;AAAA;AAErD,UAAA,OAAO,KAAM,CAAA,MAAA;AAAA,SACd,CAAA;AAAA,QACD,oBAAqB,EAAA;AAAA,QACrB,cAAA;AAAA,QACA,IAAI,CAAC,MAAA,MAAY,EAAE,GAAK,EAAA,MAAA,EAAQ,QAAS,CAAA;AAAA,OAC3C;AAEF,IAAA,IAAI,eAAe,MAAO,CAAA,IAAA,CAAK,CAAC,CAAC,MAAM,CAAG,EAAA;AACxC,MAAA,OAAO,UAAU,QAAS,CAAA,IAAA;AAAA,QACxB,GAAA,CAAI,CAAC,GAAA,MAAS,EAAE,GAAA,EAAK,QAAQ,eAAgB,CAAA,OAAA,CAAQ,GAAG,CAAA,EAAI,CAAA;AAAA,OAC9D;AAAA;AAGF,IAAO,OAAA,IAAA,CAAK,kBAAkB,CAAE,CAAA,IAAA;AAAA,MAC9B,QAAA;AAAA,QAAS,CAAC,gBACR,SAAU,CAAA,QAAA;AAAA,UACR,EAAA;AAAA,UACA,OAAA;AAAA,UACA,CAAC,GAAQ,KAAA;AACP,YAAM,MAAA,MAAA,GAAS,SAAS,GAAG,CAAA;AAC3B,YAAM,MAAA,UAAA,GACJ,KAAK,MAAW,KAAA,MAAA,CAAO,MAAM,IAAO,GAAA,IAAA,CAAK,KAAM,CAAA,CAAA,EAAG,EAAE,CAAA;AACtD,YAAI,IAAA,IAAA,KAAS,cAAc,CAAC,iBAAA;AAC1B,cAAA,MAAM,YAAY,IAAI,CAAA;AACxB,YAAA,IAAI,CAAC,iBAAA,CAAkB,WAAa,EAAA,GAAA,EAAK,UAAU,CAAA;AACjD,cAAA,MAAM,iBAAkB,EAAA;AAC1B,YAAA,OAAO,MAAO,CAAA,IAAA,CAAK,GAAI,CAAA,GAAG,UAAU,CAAA;AAAA,WACtC;AAAA,UACA,IAAA;AAAA,UACA,CAAC,MAAM,GAAQ,KAAA;AACb,YAAM,MAAA,MAAA,GAAS,SAAS,GAAG,CAAA;AAC3B,YAAM,MAAA,KAAA,GACJ,SAAS,IAAO,GAAA,MAAA,CAAO,WAAW,MAAO,CAAA,KAAA,CAAM,IAAI,IAAI,CAAA;AACzD,YAAA,IAAI,CAAC,mBAAA,CAAoB,WAAa,EAAA,GAAA,EAAK,KAAK,CAAA;AAC9C,cAAA,MAAM,iBAAkB,EAAA;AAC1B,YAAO,OAAA,KAAA;AAAA;AACT;AACF;AACF,KACF;AAAA,GACF;AAEA,EAAM,MAAA,QAAA,GAAW,UAAU,IAAqB,KAAA;AAC9C,IAAA,MAAM,OAAU,GAAA,IAAA,CAAK,IAAK,CAAA,MAAA,GAAS,CAAC,CAAA;AACpC,IAAM,MAAA,iBAAA,GAAoB,cAAc,OAAO,CAAA;AAC/C,IAAA,MAAM,EAAE,MAAA,EAAwB,GAAA,iBAAA,GAAoB,UAAU,EAAC;AAE/D,IAAO,OAAA,wBAAA;AAAA,MACL,YAAa,CAAA,GAAG,IAAI,CAAA,CAAE,KAAK,QAAQ,CAAA;AAAA,MACnC;AAAA,KACF;AAAA,GACF;AAEA,EAAM,MAAA,UAAA,GAAa,UAAU,IAAqB,KAAA;AAChD,IAAA,MAAM,OAAU,GAAA,IAAA,CAAK,IAAK,CAAA,MAAA,GAAS,CAAC,CAAA;AACpC,IAAM,MAAA,iBAAA,GAAoB,cAAc,OAAO,CAAA;AAC/C,IAAA,MAAM,EAAE,MAAQ,EAAA,EAAA,EAAI,KAAqB,GAAA,iBAAA,GAAoB,UAAU,EAAC;AACxE,IAAA,MAAM,KAAK,GAAO,IAAA,IAAA;AAElB,IAAA,MAAM,cAAc,MAAM,kBAAA;AAC1B,IAAA,MAAM,UAAU,SACb,CAAA,QAAA;AAAA,MACC,EAAA;AAAA,MACA,mBAAA;AAAA,MACA,CAAC,GAAQ,KAAA;AACP,QAAM,MAAA,MAAA,GAAS,SAAS,GAAG,CAAA;AAE3B,QAAA,IACE,eAAe,sBAAuB,CAAA,WAAA,EAAa,GAAG,CAAC,MACvD,kBAAmB,CAAA,YAAA;AAEnB,UAAA,MAAM,iBAAkB,EAAA;AAE1B,QAAA,IAAI,KAAK,MAAS,GAAA,MAAA,CAAO,GAAK,EAAA,MAAM,YAAY,IAAI,CAAA;AACpD,QAAM,MAAA,UAAA,GACJ,KAAK,MAAS,GAAA,CAAA,IAAK,oBAAoB,IAAK,CAAA,KAAA,CAAM,CAAG,EAAA,EAAE,CAAI,GAAA,IAAA;AAC7D,QAAA,IAAI,IAAK,CAAA,MAAA,KAAW,MAAO,CAAA,GAAA,IAAO,UAAe,KAAA,IAAA;AAC/C,UAAA,MAAM,YAAY,IAAI,CAAA;AACxB,QAAA,OAAO,MAAO,CAAA,IAAA,CAAK,GAAI,CAAA,GAAG,UAAU,CAAA;AAAA,OACtC;AAAA,MACA,IAAA;AAAA,MACA,CAAC,QAAQ,GAAQ,KAAA;AACf,QAAM,MAAA,MAAA,GAAS,SAAS,GAAG,CAAA;AAC3B,QAAA,MAAM,gBAAgB,MAAO,CAAA,GAAA,CAAI,CAAC,EAAE,GAAA,EAAK,OAAa,MAAA;AAAA,UACpD,OAAS,EAAA,MAAA,CAAO,IAAK,CAAA,GAAA,CAAI,GAAG,CAAA;AAAA,UAC5B,KAAO,EAAA,MAAA,CAAO,KAAM,CAAA,GAAA,CAAI,KAAK;AAAA,SAC7B,CAAA,CAAA;AACF,QAAA,IACE,aAAc,CAAA,IAAA;AAAA,UACZ,CAAC,EAAE,KAAM,EAAA,KAAM,CAAC,mBAAoB,CAAA,WAAA,EAAa,KAAK,KAAK;AAAA,SAC7D;AAEA,UAAA,MAAM,iBAAkB,EAAA;AAC1B,QAAO,OAAA,aAAA;AAAA;AACT,KACF,CACC,KAAK,QAAQ,CAAA;AAChB,IAAO,OAAA,wBAAA,CAAyB,SAAS,MAAM,CAAA;AAAA,GACjD;AAEA,EAAA,MAAM,SAAY,GAAA,CAAC,OAA4B,EAAA,OAAA,KAC7C,OAAQ,CAAA,GAAA;AAAA,IACN,OAAQ,CAAA,GAAA,CAAI,CAAC,IAAA,KAAS,QAAS,CAAA,GAAI,OAAU,GAAA,CAAC,GAAG,IAAA,EAAM,OAAO,CAAA,GAAI,IAAK,CAAC;AAAA,GAC1E;AAEF,EAAM,MAAA,YAAA,GAAoB,IAAI,IAAqB,KAAA;AACjD,IAAM,MAAA,OAAA,GAAU,IAAK,CAAA,EAAA,CAAG,EAAE,CAAA;AAC1B,IAAM,MAAA,iBAAA,GAAoB,cAAc,OAAO,CAAA;AAE/C,IAAO,OAAA,eAAA;AAAA,MACL,MAAA;AAAA,MACA,IAAA;AAAA,MACA,iBAAoB,GAAA,IAAA,CAAK,KAAM,CAAA,CAAA,EAAG,EAAE,CAAI,GAAA,IAAA;AAAA,MACxC,iBAAA,IAAqB,QAAQ,EAAO,KAAA;AAAA,KACtC;AAAA,GACF;AAEA,EAAO,OAAA;AAAA,IACL,YAAA;AAAA,IACA,qBAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { u64, u32, u16, u8 } from '@polkadot-api/substrate-bindings';
|
|
2
|
-
import { combineLatest, of, take, mergeMap, map } from 'rxjs';
|
|
3
2
|
import { toHex, fromHex } from '@polkadot-api/utils';
|
|
3
|
+
import { combineLatest, of, take, mergeMap, filter, map, switchMap, catchError, scan, startWith, distinctUntilChanged } from 'rxjs';
|
|
4
4
|
import { getSignExtensionsCreator } from './signed-extensions/sign-extensions.mjs';
|
|
5
5
|
|
|
6
6
|
const NONCE_RUNTIME_CALL = "AccountNonceApi_account_nonce";
|
|
@@ -10,7 +10,7 @@ const lenToDecoder = {
|
|
|
10
10
|
4: u32.dec,
|
|
11
11
|
8: u64.dec
|
|
12
12
|
};
|
|
13
|
-
const
|
|
13
|
+
const getNonceAtBlock$ = (call$, from, at) => call$(at, NONCE_RUNTIME_CALL, from).pipe(
|
|
14
14
|
map((result) => {
|
|
15
15
|
const bytes = fromHex(result);
|
|
16
16
|
const decoder = lenToDecoder[bytes.length];
|
|
@@ -20,7 +20,7 @@ const getNonce$ = (call$, from, at) => call$(at, NONCE_RUNTIME_CALL, from).pipe(
|
|
|
20
20
|
})
|
|
21
21
|
);
|
|
22
22
|
const createTx = (chainHead, signer, callData, atBlock, customSignedExtensions, hinted = {}) => combineLatest([
|
|
23
|
-
hinted.nonce ? of(hinted.nonce) : getNonce$(chainHead
|
|
23
|
+
hinted.nonce ? of(hinted.nonce) : getNonce$(chainHead, toHex(signer.publicKey)),
|
|
24
24
|
chainHead.getRuntimeContext$(atBlock.hash),
|
|
25
25
|
chainHead.genesis$
|
|
26
26
|
]).pipe(
|
|
@@ -43,7 +43,8 @@ const createTx = (chainHead, signer, callData, atBlock, customSignedExtensions,
|
|
|
43
43
|
hash: atBlock.hash
|
|
44
44
|
}
|
|
45
45
|
} : { mortal: false },
|
|
46
|
-
customSignedExtensions
|
|
46
|
+
customSignedExtensions,
|
|
47
|
+
asset: hinted.asset
|
|
47
48
|
});
|
|
48
49
|
return signer.signTx(
|
|
49
50
|
callData,
|
|
@@ -53,6 +54,54 @@ const createTx = (chainHead, signer, callData, atBlock, customSignedExtensions,
|
|
|
53
54
|
);
|
|
54
55
|
})
|
|
55
56
|
);
|
|
57
|
+
const getNonce$ = (chainHead, from) => {
|
|
58
|
+
const followHead$ = (head) => chainHead.newBlocks$.pipe(
|
|
59
|
+
scan((acc, block) => block.parent === acc ? block.hash : acc, head),
|
|
60
|
+
startWith(head),
|
|
61
|
+
distinctUntilChanged()
|
|
62
|
+
);
|
|
63
|
+
const followNonce$ = (head) => followHead$(head).pipe(
|
|
64
|
+
take(2),
|
|
65
|
+
switchMap((hash) => getNonceAtBlock$(chainHead.call$, from, hash))
|
|
66
|
+
);
|
|
67
|
+
const getHeadsNonce$ = (heads) => combineLatest(
|
|
68
|
+
heads.map(
|
|
69
|
+
(head) => followNonce$(head).pipe(
|
|
70
|
+
map((value) => ({
|
|
71
|
+
success: true,
|
|
72
|
+
value
|
|
73
|
+
})),
|
|
74
|
+
catchError(
|
|
75
|
+
(err) => of({
|
|
76
|
+
success: false,
|
|
77
|
+
value: err
|
|
78
|
+
})
|
|
79
|
+
)
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
).pipe(take(1));
|
|
83
|
+
return chainHead.pinnedBlocks$.pipe(
|
|
84
|
+
filter((v) => !v.recovering && v.blocks.size > 0),
|
|
85
|
+
take(1),
|
|
86
|
+
map(({ blocks, best }) => {
|
|
87
|
+
const bestBlock = blocks.get(best);
|
|
88
|
+
return [...blocks.values()].filter(
|
|
89
|
+
(v) => !v.unpinnable && v.children.size === 0 && v.number >= bestBlock.number
|
|
90
|
+
).map((v) => v.hash);
|
|
91
|
+
}),
|
|
92
|
+
switchMap(getHeadsNonce$),
|
|
93
|
+
map((result) => {
|
|
94
|
+
const winner = result.reduce(
|
|
95
|
+
(acc, v) => v.success ? v.value >= (acc ?? 0) ? v.value : acc : acc,
|
|
96
|
+
null
|
|
97
|
+
);
|
|
98
|
+
if (winner == null) {
|
|
99
|
+
throw result[0].value;
|
|
100
|
+
}
|
|
101
|
+
return winner;
|
|
102
|
+
})
|
|
103
|
+
);
|
|
104
|
+
};
|
|
56
105
|
|
|
57
|
-
export { createTx
|
|
106
|
+
export { createTx };
|
|
58
107
|
//# sourceMappingURL=create-tx.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-tx.mjs","sources":["../../../src/tx/create-tx.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"create-tx.mjs","sources":["../../../src/tx/create-tx.ts"],"sourcesContent":["import { BlockInfo, ChainHead$ } from \"@polkadot-api/observable-client\"\nimport type { PolkadotSigner } from \"@polkadot-api/polkadot-signer\"\nimport { HexString, u16, u32, u64, u8 } from \"@polkadot-api/substrate-bindings\"\nimport { fromHex, toHex } from \"@polkadot-api/utils\"\nimport {\n Observable,\n catchError,\n combineLatest,\n distinctUntilChanged,\n filter,\n map,\n mergeMap,\n of,\n scan,\n startWith,\n switchMap,\n take,\n} from \"rxjs\"\nimport { getSignExtensionsCreator } from \"./signed-extensions\"\nimport { CustomSignedExtensionValues } from \"./types\"\n\ntype HintedSignedExtensions = Partial<{\n tip: bigint\n mortality: { mortal: false } | { mortal: true; period: number }\n asset: Uint8Array\n nonce: number\n}>\n\nconst NONCE_RUNTIME_CALL = \"AccountNonceApi_account_nonce\"\nconst lenToDecoder = {\n 1: u8.dec,\n 2: u16.dec,\n 4: u32.dec,\n 8: u64.dec,\n}\n\nconst getNonceAtBlock$ = (\n call$: ChainHead$[\"call$\"],\n from: HexString,\n at: string,\n) =>\n call$(at, NONCE_RUNTIME_CALL, from).pipe(\n map((result) => {\n const bytes = fromHex(result)\n const decoder = lenToDecoder[bytes.length as 2 | 4 | 8]\n if (!decoder)\n throw new Error(`${NONCE_RUNTIME_CALL} retrieved wrong data`)\n return decoder(bytes)\n }),\n )\n\nexport const createTx: (\n chainHead: ChainHead$,\n signer: PolkadotSigner,\n callData: Uint8Array,\n atBlock: BlockInfo,\n customSignExt: Record<string, CustomSignedExtensionValues>,\n hinted?: HintedSignedExtensions,\n) => Observable<Uint8Array> = (\n chainHead,\n signer,\n callData,\n atBlock,\n customSignedExtensions,\n hinted = {},\n) =>\n combineLatest([\n hinted.nonce\n ? of(hinted.nonce)\n : getNonce$(chainHead, toHex(signer.publicKey)),\n chainHead.getRuntimeContext$(atBlock.hash),\n chainHead.genesis$,\n ]).pipe(\n take(1),\n mergeMap(([nonce, ctx, genesis]) => {\n const signExtCreator = getSignExtensionsCreator(\n fromHex(genesis),\n ctx.lookup,\n ctx.dynamicBuilder,\n )\n\n const mortality: HintedSignedExtensions[\"mortality\"] =\n hinted.mortality ?? { period: 64, mortal: true }\n\n const signExtensions = signExtCreator({\n nonce: nonce as number,\n tip: hinted.tip ?? 0n,\n mortality: mortality.mortal\n ? {\n mortal: true,\n period: mortality.period,\n startAtBlock: {\n height: atBlock.number,\n hash: atBlock.hash,\n },\n }\n : { mortal: false },\n customSignedExtensions,\n asset: hinted.asset,\n })\n\n return signer.signTx(\n callData,\n signExtensions,\n ctx.metadataRaw,\n atBlock.number,\n )\n }),\n )\n\nconst getNonce$ = (chainHead: ChainHead$, from: HexString) => {\n const followHead$ = (head: string) =>\n chainHead.newBlocks$.pipe(\n scan((acc, block) => (block.parent === acc ? block.hash : acc), head),\n startWith(head),\n distinctUntilChanged(),\n )\n const followNonce$ = (head: string) =>\n followHead$(head).pipe(\n take(2),\n switchMap((hash) => getNonceAtBlock$(chainHead.call$, from, hash)),\n )\n const getHeadsNonce$ = (heads: string[]) =>\n combineLatest(\n heads.map((head) =>\n followNonce$(head).pipe(\n map((value) => ({\n success: true as const,\n value,\n })),\n catchError((err) =>\n of({\n success: false as const,\n value: err,\n }),\n ),\n ),\n ),\n ).pipe(take(1))\n\n return chainHead.pinnedBlocks$.pipe(\n filter((v) => !v.recovering && v.blocks.size > 0),\n take(1),\n map(({ blocks, best }) => {\n // Grab only the heads: those blocks above the best that don't have children and are not getting pruned\n const bestBlock = blocks.get(best)!\n return [...blocks.values()]\n .filter(\n (v) =>\n !v.unpinnable &&\n v.children.size === 0 &&\n v.number >= bestBlock.number,\n )\n .map((v) => v.hash)\n }),\n switchMap(getHeadsNonce$),\n map((result) => {\n const winner = result.reduce(\n (acc: bigint | number | null, v) =>\n v.success ? (v.value >= (acc ?? 0) ? v.value : acc) : acc,\n null,\n )\n\n if (winner == null) {\n // We must have at least one error\n throw result[0].value\n }\n return winner\n }),\n )\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -117,7 +117,7 @@ const submit$ = (chainHead, broadcastTx$, tx, at, emitSign = false) => {
|
|
|
117
117
|
take(1),
|
|
118
118
|
map((blocks) => {
|
|
119
119
|
const block = blocks.blocks.get(at);
|
|
120
|
-
return block
|
|
120
|
+
return block ? block.hash : blocks.finalized;
|
|
121
121
|
})
|
|
122
122
|
);
|
|
123
123
|
const validate$ = at$.pipe(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit-fns.mjs","sources":["../../../src/tx/submit-fns.ts"],"sourcesContent":["import {\n Binary,\n Blake2256,\n HexString,\n ResultPayload,\n} from \"@polkadot-api/substrate-bindings\"\nimport {\n EMPTY,\n Observable,\n concat,\n distinctUntilChanged,\n filter,\n lastValueFrom,\n map,\n mergeMap,\n of,\n take,\n} from \"rxjs\"\nimport {\n ChainHead$,\n PinnedBlocks,\n SystemEvent,\n} from \"@polkadot-api/observable-client\"\nimport { AnalyzedBlock } from \"@polkadot-api/observable-client\"\nimport { TxEvent, TxEventsPayload, TxFinalizedPayload } from \"./types\"\nimport { continueWith } from \"@/utils\"\nimport { fromHex, toHex } from \"@polkadot-api/utils\"\n\n// TODO: make it dynamic based on the tx-function of the client\nconst hashFromTx = (tx: HexString) => toHex(Blake2256(fromHex(tx)))\n\nconst computeState = (\n analized$: Observable<AnalyzedBlock>,\n blocks$: Observable<PinnedBlocks>,\n) =>\n new Observable<\n | {\n found: true\n hash: string\n number: number\n index: number\n events: any\n }\n | { found: false; validity: ResultPayload<any, any> | null }\n >((observer) => {\n const analyzedBlocks = new Map<string, AnalyzedBlock>()\n let pinnedBlocks: PinnedBlocks\n let latestState:\n | {\n found: true\n hash: string\n number: number\n index: number\n events: any\n }\n | { found: false; validity: ResultPayload<any, any> | null }\n\n const computeNextState = () => {\n let current: string = pinnedBlocks.best\n let analyzed: AnalyzedBlock | undefined = analyzedBlocks.get(current)\n let analyzedNumber = pinnedBlocks.blocks.get(current)!.number\n\n while (!analyzed) {\n const block = pinnedBlocks.blocks.get(current)\n if (!block) break\n analyzed = analyzedBlocks.get((current = block.parent))\n analyzedNumber--\n }\n\n if (!analyzed) return // this shouldn't happen, though\n\n const isFinalized =\n analyzedNumber <=\n pinnedBlocks.blocks.get(pinnedBlocks.finalized)!.number\n\n const found = analyzed.found.type\n if (found && latestState?.found && latestState.hash === analyzed.hash) {\n if (isFinalized) observer.complete()\n return\n }\n\n observer.next(\n (latestState = analyzed.found.type\n ? {\n found: found as true,\n hash: analyzed.hash,\n number: analyzedNumber,\n index: analyzed.found.index,\n events: analyzed.found.events,\n }\n : {\n found: found as false,\n validity: analyzed.found.validity,\n }),\n )\n\n if (isFinalized) {\n if (found) observer.complete()\n else if (analyzed.found.validity?.success === false)\n observer.error(new InvalidTxError(analyzed.found.validity.value))\n }\n }\n\n const subscription = blocks$\n .pipe(\n distinctUntilChanged(\n (a, b) => a.finalized === b.finalized && a.best === b.best,\n ),\n )\n .subscribe({\n next: (pinned: PinnedBlocks) => {\n pinnedBlocks = pinned\n if (analyzedBlocks.size === 0) return\n computeNextState()\n },\n error(e) {\n observer.error(e)\n },\n })\n\n subscription.add(\n analized$.subscribe({\n next: (block) => {\n analyzedBlocks.set(block.hash, block)\n computeNextState()\n },\n error(e) {\n observer.error(e)\n },\n }),\n )\n\n return subscription\n }).pipe(distinctUntilChanged((a, b) => a === b))\n\nconst getTxSuccessFromSystemEvents = (\n systemEvents: Array<SystemEvent>,\n txIdx: number,\n): Omit<TxEventsPayload, \"block\"> => {\n const events = systemEvents\n .filter((x) => x.phase.type === \"ApplyExtrinsic\" && x.phase.value === txIdx)\n .map((x) => ({ ...x.event, topics: x.topics }))\n\n const lastEvent = events[events.length - 1]\n if (\n lastEvent.type === \"System\" &&\n lastEvent.value.type === \"ExtrinsicFailed\"\n ) {\n return {\n ok: false,\n events,\n dispatchError: lastEvent.value.value.dispatch_error,\n }\n }\n\n return { ok: true, events }\n}\n\n/*\ntype TransactionValidityError = Enum<{\n Invalid: Enum<{\n Call: undefined\n Payment: undefined\n Future: undefined\n Stale: undefined\n BadProof: undefined\n AncientBirthBlock: undefined\n ExhaustsResources: undefined\n Custom: number\n BadMandatory: undefined\n MandatoryValidation: undefined\n BadSigner: undefined\n }>\n Unknown: Enum<{\n CannotLookup: undefined\n NoUnsignedValidator: undefined\n Custom: number\n }>\n}>\n*/\n\nexport class InvalidTxError extends Error {\n error: any // likely to be a `TransactionValidityError`\n constructor(e: any) {\n super(\n JSON.stringify(\n e,\n (_, value) => {\n if (typeof value === \"bigint\") return value.toString()\n return value instanceof Binary ? value.asHex() : value\n },\n 2,\n ),\n )\n this.name = \"InvalidTxError\"\n this.error = e\n }\n}\n\nexport const submit$ = (\n chainHead: ChainHead$,\n broadcastTx$: (tx: string) => Observable<never>,\n tx: HexString,\n at?: HexString,\n emitSign = false,\n): Observable<TxEvent> => {\n const txHash = hashFromTx(tx)\n const getTxEvent = <\n Type extends TxEvent[\"type\"],\n Rest extends Omit<TxEvent & { type: Type }, \"type\" | \"txHash\">,\n >(\n type: Type,\n rest: Rest,\n ): TxEvent & { type: Type } =>\n ({\n type,\n txHash,\n ...rest,\n }) as any\n\n const at$ = chainHead.pinnedBlocks$.pipe(\n take(1),\n map((blocks) => {\n const block = blocks.blocks.get(at!)\n return block && !block.unpinned ? block.hash : blocks.finalized\n }),\n )\n\n const validate$: Observable<never> = at$.pipe(\n mergeMap((at) =>\n chainHead.validateTx$(at, tx).pipe(\n filter((x) => !x.success),\n map((x) => {\n throw new InvalidTxError(x.value)\n }),\n ),\n ),\n )\n\n const track$ = new Observable<AnalyzedBlock>((observer) => {\n const subscription = chainHead.trackTx$(tx).subscribe(observer)\n subscription.add(\n broadcastTx$(tx).subscribe({\n error(e) {\n observer.error(e)\n },\n }),\n )\n return subscription\n })\n\n const bestBlockState$ = computeState(track$, chainHead.pinnedBlocks$).pipe(\n map((x) => {\n if (!x.found)\n return getTxEvent(\"txBestBlocksState\", {\n found: false,\n isValid: x.validity?.success !== false,\n })\n\n return getTxEvent(\"txBestBlocksState\", {\n found: true,\n block: {\n index: x.index,\n number: x.number,\n hash: x.hash,\n },\n ...getTxSuccessFromSystemEvents(x.events, x.index),\n })\n }),\n )\n\n return concat(\n emitSign ? of(getTxEvent(\"signed\", {})) : EMPTY,\n validate$,\n of(getTxEvent(\"broadcasted\", {})),\n bestBlockState$.pipe(\n continueWith(({ found, type, ...rest }) =>\n found ? of(getTxEvent(\"finalized\", rest as any)) : EMPTY,\n ),\n ),\n )\n}\n\nexport const submit = async (\n chainHead: ChainHead$,\n broadcastTx$: (tx: string) => Observable<never>,\n transaction: HexString,\n at?: HexString,\n): Promise<TxFinalizedPayload> =>\n lastValueFrom(submit$(chainHead, broadcastTx$, transaction, at)).then((x) => {\n if (x.type !== \"finalized\") throw null\n const result: TxFinalizedPayload = { ...x }\n delete (result as any).type\n return result\n })\n"],"names":["at"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"submit-fns.mjs","sources":["../../../src/tx/submit-fns.ts"],"sourcesContent":["import {\n Binary,\n Blake2256,\n HexString,\n ResultPayload,\n} from \"@polkadot-api/substrate-bindings\"\nimport {\n EMPTY,\n Observable,\n concat,\n distinctUntilChanged,\n filter,\n lastValueFrom,\n map,\n mergeMap,\n of,\n take,\n} from \"rxjs\"\nimport {\n ChainHead$,\n PinnedBlocks,\n SystemEvent,\n} from \"@polkadot-api/observable-client\"\nimport { AnalyzedBlock } from \"@polkadot-api/observable-client\"\nimport { TxEvent, TxEventsPayload, TxFinalizedPayload } from \"./types\"\nimport { continueWith } from \"@/utils\"\nimport { fromHex, toHex } from \"@polkadot-api/utils\"\n\n// TODO: make it dynamic based on the tx-function of the client\nconst hashFromTx = (tx: HexString) => toHex(Blake2256(fromHex(tx)))\n\nconst computeState = (\n analized$: Observable<AnalyzedBlock>,\n blocks$: Observable<PinnedBlocks>,\n) =>\n new Observable<\n | {\n found: true\n hash: string\n number: number\n index: number\n events: any\n }\n | { found: false; validity: ResultPayload<any, any> | null }\n >((observer) => {\n const analyzedBlocks = new Map<string, AnalyzedBlock>()\n let pinnedBlocks: PinnedBlocks\n let latestState:\n | {\n found: true\n hash: string\n number: number\n index: number\n events: any\n }\n | { found: false; validity: ResultPayload<any, any> | null }\n\n const computeNextState = () => {\n let current: string = pinnedBlocks.best\n let analyzed: AnalyzedBlock | undefined = analyzedBlocks.get(current)\n let analyzedNumber = pinnedBlocks.blocks.get(current)!.number\n\n while (!analyzed) {\n const block = pinnedBlocks.blocks.get(current)\n if (!block) break\n analyzed = analyzedBlocks.get((current = block.parent))\n analyzedNumber--\n }\n\n if (!analyzed) return // this shouldn't happen, though\n\n const isFinalized =\n analyzedNumber <=\n pinnedBlocks.blocks.get(pinnedBlocks.finalized)!.number\n\n const found = analyzed.found.type\n if (found && latestState?.found && latestState.hash === analyzed.hash) {\n if (isFinalized) observer.complete()\n return\n }\n\n observer.next(\n (latestState = analyzed.found.type\n ? {\n found: found as true,\n hash: analyzed.hash,\n number: analyzedNumber,\n index: analyzed.found.index,\n events: analyzed.found.events,\n }\n : {\n found: found as false,\n validity: analyzed.found.validity,\n }),\n )\n\n if (isFinalized) {\n if (found) observer.complete()\n else if (analyzed.found.validity?.success === false)\n observer.error(new InvalidTxError(analyzed.found.validity.value))\n }\n }\n\n const subscription = blocks$\n .pipe(\n distinctUntilChanged(\n (a, b) => a.finalized === b.finalized && a.best === b.best,\n ),\n )\n .subscribe({\n next: (pinned: PinnedBlocks) => {\n pinnedBlocks = pinned\n if (analyzedBlocks.size === 0) return\n computeNextState()\n },\n error(e) {\n observer.error(e)\n },\n })\n\n subscription.add(\n analized$.subscribe({\n next: (block) => {\n analyzedBlocks.set(block.hash, block)\n computeNextState()\n },\n error(e) {\n observer.error(e)\n },\n }),\n )\n\n return subscription\n }).pipe(distinctUntilChanged((a, b) => a === b))\n\nconst getTxSuccessFromSystemEvents = (\n systemEvents: Array<SystemEvent>,\n txIdx: number,\n): Omit<TxEventsPayload, \"block\"> => {\n const events = systemEvents\n .filter((x) => x.phase.type === \"ApplyExtrinsic\" && x.phase.value === txIdx)\n .map((x) => ({ ...x.event, topics: x.topics }))\n\n const lastEvent = events[events.length - 1]\n if (\n lastEvent.type === \"System\" &&\n lastEvent.value.type === \"ExtrinsicFailed\"\n ) {\n return {\n ok: false,\n events,\n dispatchError: lastEvent.value.value.dispatch_error,\n }\n }\n\n return { ok: true, events }\n}\n\n/*\ntype TransactionValidityError = Enum<{\n Invalid: Enum<{\n Call: undefined\n Payment: undefined\n Future: undefined\n Stale: undefined\n BadProof: undefined\n AncientBirthBlock: undefined\n ExhaustsResources: undefined\n Custom: number\n BadMandatory: undefined\n MandatoryValidation: undefined\n BadSigner: undefined\n }>\n Unknown: Enum<{\n CannotLookup: undefined\n NoUnsignedValidator: undefined\n Custom: number\n }>\n}>\n*/\n\nexport class InvalidTxError extends Error {\n error: any // likely to be a `TransactionValidityError`\n constructor(e: any) {\n super(\n JSON.stringify(\n e,\n (_, value) => {\n if (typeof value === \"bigint\") return value.toString()\n return value instanceof Binary ? value.asHex() : value\n },\n 2,\n ),\n )\n this.name = \"InvalidTxError\"\n this.error = e\n }\n}\n\nexport const submit$ = (\n chainHead: ChainHead$,\n broadcastTx$: (tx: string) => Observable<never>,\n tx: HexString,\n at?: HexString,\n emitSign = false,\n): Observable<TxEvent> => {\n const txHash = hashFromTx(tx)\n const getTxEvent = <\n Type extends TxEvent[\"type\"],\n Rest extends Omit<TxEvent & { type: Type }, \"type\" | \"txHash\">,\n >(\n type: Type,\n rest: Rest,\n ): TxEvent & { type: Type } =>\n ({\n type,\n txHash,\n ...rest,\n }) as any\n\n const at$ = chainHead.pinnedBlocks$.pipe(\n take(1),\n map((blocks) => {\n const block = blocks.blocks.get(at!)\n return block ? block.hash : blocks.finalized\n }),\n )\n\n const validate$: Observable<never> = at$.pipe(\n mergeMap((at) =>\n chainHead.validateTx$(at, tx).pipe(\n filter((x) => !x.success),\n map((x) => {\n throw new InvalidTxError(x.value)\n }),\n ),\n ),\n )\n\n const track$ = new Observable<AnalyzedBlock>((observer) => {\n const subscription = chainHead.trackTx$(tx).subscribe(observer)\n subscription.add(\n broadcastTx$(tx).subscribe({\n error(e) {\n observer.error(e)\n },\n }),\n )\n return subscription\n })\n\n const bestBlockState$ = computeState(track$, chainHead.pinnedBlocks$).pipe(\n map((x) => {\n if (!x.found)\n return getTxEvent(\"txBestBlocksState\", {\n found: false,\n isValid: x.validity?.success !== false,\n })\n\n return getTxEvent(\"txBestBlocksState\", {\n found: true,\n block: {\n index: x.index,\n number: x.number,\n hash: x.hash,\n },\n ...getTxSuccessFromSystemEvents(x.events, x.index),\n })\n }),\n )\n\n return concat(\n emitSign ? of(getTxEvent(\"signed\", {})) : EMPTY,\n validate$,\n of(getTxEvent(\"broadcasted\", {})),\n bestBlockState$.pipe(\n continueWith(({ found, type, ...rest }) =>\n found ? of(getTxEvent(\"finalized\", rest as any)) : EMPTY,\n ),\n ),\n )\n}\n\nexport const submit = async (\n chainHead: ChainHead$,\n broadcastTx$: (tx: string) => Observable<never>,\n transaction: HexString,\n at?: HexString,\n): Promise<TxFinalizedPayload> =>\n lastValueFrom(submit$(chainHead, broadcastTx$, transaction, at)).then((x) => {\n if (x.type !== \"finalized\") throw null\n const result: TxFinalizedPayload = { ...x }\n delete (result as any).type\n return result\n })\n"],"names":["at"],"mappings":";;;;;;;;;;;AA6BA,MAAM,UAAA,GAAa,CAAC,EAAkB,KAAA,KAAA,CAAM,UAAU,OAAQ,CAAA,EAAE,CAAC,CAAC,CAAA;AAElE,MAAM,eAAe,CACnB,SAAA,EACA,YAEA,IAAI,UAAA,CASF,CAAC,QAAa,KAAA;AACd,EAAM,MAAA,cAAA,uBAAqB,GAA2B,EAAA;AACtD,EAAI,IAAA,YAAA;AACJ,EAAI,IAAA,WAAA;AAUJ,EAAA,MAAM,mBAAmB,MAAM;AAC7B,IAAA,IAAI,UAAkB,YAAa,CAAA,IAAA;AACnC,IAAI,IAAA,QAAA,GAAsC,cAAe,CAAA,GAAA,CAAI,OAAO,CAAA;AACpE,IAAA,IAAI,cAAiB,GAAA,YAAA,CAAa,MAAO,CAAA,GAAA,CAAI,OAAO,CAAG,CAAA,MAAA;AAEvD,IAAA,OAAO,CAAC,QAAU,EAAA;AAChB,MAAA,MAAM,KAAQ,GAAA,YAAA,CAAa,MAAO,CAAA,GAAA,CAAI,OAAO,CAAA;AAC7C,MAAA,IAAI,CAAC,KAAO,EAAA;AACZ,MAAA,QAAA,GAAW,cAAe,CAAA,GAAA,CAAK,OAAU,GAAA,KAAA,CAAM,MAAO,CAAA;AACtD,MAAA,cAAA,EAAA;AAAA;AAGF,IAAA,IAAI,CAAC,QAAU,EAAA;AAEf,IAAA,MAAM,cACJ,cACA,IAAA,YAAA,CAAa,OAAO,GAAI,CAAA,YAAA,CAAa,SAAS,CAAG,CAAA,MAAA;AAEnD,IAAM,MAAA,KAAA,GAAQ,SAAS,KAAM,CAAA,IAAA;AAC7B,IAAA,IAAI,SAAS,WAAa,EAAA,KAAA,IAAS,WAAY,CAAA,IAAA,KAAS,SAAS,IAAM,EAAA;AACrE,MAAI,IAAA,WAAA,WAAsB,QAAS,EAAA;AACnC,MAAA;AAAA;AAGF,IAAS,QAAA,CAAA,IAAA;AAAA,MACN,WAAA,GAAc,QAAS,CAAA,KAAA,CAAM,IAC1B,GAAA;AAAA,QACE,KAAA;AAAA,QACA,MAAM,QAAS,CAAA,IAAA;AAAA,QACf,MAAQ,EAAA,cAAA;AAAA,QACR,KAAA,EAAO,SAAS,KAAM,CAAA,KAAA;AAAA,QACtB,MAAA,EAAQ,SAAS,KAAM,CAAA;AAAA,OAEzB,GAAA;AAAA,QACE,KAAA;AAAA,QACA,QAAA,EAAU,SAAS,KAAM,CAAA;AAAA;AAC3B,KACN;AAEA,IAAA,IAAI,WAAa,EAAA;AACf,MAAI,IAAA,KAAA,WAAgB,QAAS,EAAA;AAAA,WACpB,IAAA,QAAA,CAAS,KAAM,CAAA,QAAA,EAAU,OAAY,KAAA,KAAA;AAC5C,QAAA,QAAA,CAAS,MAAM,IAAI,cAAA,CAAe,SAAS,KAAM,CAAA,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA;AACpE,GACF;AAEA,EAAA,MAAM,eAAe,OAClB,CAAA,IAAA;AAAA,IACC,oBAAA;AAAA,MACE,CAAC,GAAG,CAAM,KAAA,CAAA,CAAE,cAAc,CAAE,CAAA,SAAA,IAAa,CAAE,CAAA,IAAA,KAAS,CAAE,CAAA;AAAA;AACxD,IAED,SAAU,CAAA;AAAA,IACT,IAAA,EAAM,CAAC,MAAyB,KAAA;AAC9B,MAAe,YAAA,GAAA,MAAA;AACf,MAAI,IAAA,cAAA,CAAe,SAAS,CAAG,EAAA;AAC/B,MAAiB,gBAAA,EAAA;AAAA,KACnB;AAAA,IACA,MAAM,CAAG,EAAA;AACP,MAAA,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA;AAClB,GACD,CAAA;AAEH,EAAa,YAAA,CAAA,GAAA;AAAA,IACX,UAAU,SAAU,CAAA;AAAA,MAClB,IAAA,EAAM,CAAC,KAAU,KAAA;AACf,QAAe,cAAA,CAAA,GAAA,CAAI,KAAM,CAAA,IAAA,EAAM,KAAK,CAAA;AACpC,QAAiB,gBAAA,EAAA;AAAA,OACnB;AAAA,MACA,MAAM,CAAG,EAAA;AACP,QAAA,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA;AAClB,KACD;AAAA,GACH;AAEA,EAAO,OAAA,YAAA;AACT,CAAC,CAAA,CAAE,KAAK,oBAAqB,CAAA,CAAC,GAAG,CAAM,KAAA,CAAA,KAAM,CAAC,CAAC,CAAA;AAEjD,MAAM,4BAAA,GAA+B,CACnC,YAAA,EACA,KACmC,KAAA;AACnC,EAAM,MAAA,MAAA,GAAS,YACZ,CAAA,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,KAAM,CAAA,IAAA,KAAS,gBAAoB,IAAA,CAAA,CAAE,KAAM,CAAA,KAAA,KAAU,KAAK,CAC1E,CAAA,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,EAAE,KAAO,EAAA,MAAA,EAAQ,CAAE,CAAA,MAAA,EAAS,CAAA,CAAA;AAEhD,EAAA,MAAM,SAAY,GAAA,MAAA,CAAO,MAAO,CAAA,MAAA,GAAS,CAAC,CAAA;AAC1C,EAAA,IACE,UAAU,IAAS,KAAA,QAAA,IACnB,SAAU,CAAA,KAAA,CAAM,SAAS,iBACzB,EAAA;AACA,IAAO,OAAA;AAAA,MACL,EAAI,EAAA,KAAA;AAAA,MACJ,MAAA;AAAA,MACA,aAAA,EAAe,SAAU,CAAA,KAAA,CAAM,KAAM,CAAA;AAAA,KACvC;AAAA;AAGF,EAAO,OAAA,EAAE,EAAI,EAAA,IAAA,EAAM,MAAO,EAAA;AAC5B,CAAA;AAyBO,MAAM,uBAAuB,KAAM,CAAA;AAAA;AAAA,EAExC,YAAY,CAAQ,EAAA;AAClB,IAAA,KAAA;AAAA,MACE,IAAK,CAAA,SAAA;AAAA,QACH,CAAA;AAAA,QACA,CAAC,GAAG,KAAU,KAAA;AACZ,UAAA,IAAI,OAAO,KAAA,KAAU,QAAU,EAAA,OAAO,MAAM,QAAS,EAAA;AACrD,UAAA,OAAO,KAAiB,YAAA,MAAA,GAAS,KAAM,CAAA,KAAA,EAAU,GAAA,KAAA;AAAA,SACnD;AAAA,QACA;AAAA;AACF,KACF;AAXF,IAAA,aAAA,CAAA,IAAA,EAAA,OAAA,CAAA;AAYE,IAAA,IAAA,CAAK,IAAO,GAAA,gBAAA;AACZ,IAAA,IAAA,CAAK,KAAQ,GAAA,CAAA;AAAA;AAEjB;AAEO,MAAM,UAAU,CACrB,SAAA,EACA,cACA,EACA,EAAA,EAAA,EACA,WAAW,KACa,KAAA;AACxB,EAAM,MAAA,MAAA,GAAS,WAAW,EAAE,CAAA;AAC5B,EAAM,MAAA,UAAA,GAAa,CAIjB,IAAA,EACA,IAEC,MAAA;AAAA,IACC,IAAA;AAAA,IACA,MAAA;AAAA,IACA,GAAG;AAAA,GACL,CAAA;AAEF,EAAM,MAAA,GAAA,GAAM,UAAU,aAAc,CAAA,IAAA;AAAA,IAClC,KAAK,CAAC,CAAA;AAAA,IACN,GAAA,CAAI,CAAC,MAAW,KAAA;AACd,MAAA,MAAM,KAAQ,GAAA,MAAA,CAAO,MAAO,CAAA,GAAA,CAAI,EAAG,CAAA;AACnC,MAAO,OAAA,KAAA,GAAQ,KAAM,CAAA,IAAA,GAAO,MAAO,CAAA,SAAA;AAAA,KACpC;AAAA,GACH;AAEA,EAAA,MAAM,YAA+B,GAAI,CAAA,IAAA;AAAA,IACvC,QAAA;AAAA,MAAS,CAACA,GACR,KAAA,SAAA,CAAU,WAAYA,CAAAA,GAAAA,EAAI,EAAE,CAAE,CAAA,IAAA;AAAA,QAC5B,MAAO,CAAA,CAAC,CAAM,KAAA,CAAC,EAAE,OAAO,CAAA;AAAA,QACxB,GAAA,CAAI,CAAC,CAAM,KAAA;AACT,UAAM,MAAA,IAAI,cAAe,CAAA,CAAA,CAAE,KAAK,CAAA;AAAA,SACjC;AAAA;AACH;AACF,GACF;AAEA,EAAA,MAAM,MAAS,GAAA,IAAI,UAA0B,CAAA,CAAC,QAAa,KAAA;AACzD,IAAA,MAAM,eAAe,SAAU,CAAA,QAAA,CAAS,EAAE,CAAA,CAAE,UAAU,QAAQ,CAAA;AAC9D,IAAa,YAAA,CAAA,GAAA;AAAA,MACX,YAAA,CAAa,EAAE,CAAA,CAAE,SAAU,CAAA;AAAA,QACzB,MAAM,CAAG,EAAA;AACP,UAAA,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA;AAClB,OACD;AAAA,KACH;AACA,IAAO,OAAA,YAAA;AAAA,GACR,CAAA;AAED,EAAA,MAAM,eAAkB,GAAA,YAAA,CAAa,MAAQ,EAAA,SAAA,CAAU,aAAa,CAAE,CAAA,IAAA;AAAA,IACpE,GAAA,CAAI,CAAC,CAAM,KAAA;AACT,MAAA,IAAI,CAAC,CAAE,CAAA,KAAA;AACL,QAAA,OAAO,WAAW,mBAAqB,EAAA;AAAA,UACrC,KAAO,EAAA,KAAA;AAAA,UACP,OAAA,EAAS,CAAE,CAAA,QAAA,EAAU,OAAY,KAAA;AAAA,SAClC,CAAA;AAEH,MAAA,OAAO,WAAW,mBAAqB,EAAA;AAAA,QACrC,KAAO,EAAA,IAAA;AAAA,QACP,KAAO,EAAA;AAAA,UACL,OAAO,CAAE,CAAA,KAAA;AAAA,UACT,QAAQ,CAAE,CAAA,MAAA;AAAA,UACV,MAAM,CAAE,CAAA;AAAA,SACV;AAAA,QACA,GAAG,4BAAA,CAA6B,CAAE,CAAA,MAAA,EAAQ,EAAE,KAAK;AAAA,OAClD,CAAA;AAAA,KACF;AAAA,GACH;AAEA,EAAO,OAAA,MAAA;AAAA,IACL,WAAW,EAAG,CAAA,UAAA,CAAW,UAAU,EAAE,CAAC,CAAI,GAAA,KAAA;AAAA,IAC1C,SAAA;AAAA,IACA,EAAG,CAAA,UAAA,CAAW,aAAe,EAAA,EAAE,CAAC,CAAA;AAAA,IAChC,eAAgB,CAAA,IAAA;AAAA,MACd,YAAA;AAAA,QAAa,CAAC,EAAE,KAAO,EAAA,IAAA,EAAM,GAAG,IAAA,EAC9B,KAAA,KAAA,GAAQ,EAAG,CAAA,UAAA,CAAW,WAAa,EAAA,IAAW,CAAC,CAAI,GAAA;AAAA;AACrD;AACF,GACF;AACF;AAEO,MAAM,SAAS,OACpB,SAAA,EACA,YACA,EAAA,WAAA,EACA,OAEA,aAAc,CAAA,OAAA,CAAQ,SAAW,EAAA,YAAA,EAAc,aAAa,EAAE,CAAC,CAAE,CAAA,IAAA,CAAK,CAAC,CAAM,KAAA;AAC3E,EAAI,IAAA,CAAA,CAAE,IAAS,KAAA,WAAA,EAAmB,MAAA,IAAA;AAClC,EAAM,MAAA,MAAA,GAA6B,EAAE,GAAG,CAAE,EAAA;AAC1C,EAAA,OAAQ,MAAe,CAAA,IAAA;AACvB,EAAO,OAAA,MAAA;AACT,CAAC;;;;"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getLookupFn, getDynamicBuilder } from '@polkadot-api/metadata-builders';
|
|
2
|
+
import { decAnyMetadata } from '@polkadot-api/substrate-bindings';
|
|
3
|
+
|
|
4
|
+
const withError = (builder, errName) => (pallet, name) => {
|
|
5
|
+
try {
|
|
6
|
+
return builder(pallet, name);
|
|
7
|
+
} catch {
|
|
8
|
+
throw new Error(`Runtime entry ${errName}(${pallet}.${name}) not found`);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const getTypedCodecs = async (descriptors) => {
|
|
12
|
+
const metadata = decAnyMetadata(await descriptors.getMetadata()).metadata.value;
|
|
13
|
+
const target = {};
|
|
14
|
+
const createProxy = (propCall) => new Proxy(target, {
|
|
15
|
+
get(_, prop) {
|
|
16
|
+
return propCall(prop);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const createProxyPath = (pathCall) => {
|
|
20
|
+
const cache = {};
|
|
21
|
+
return createProxy((a) => {
|
|
22
|
+
if (!cache[a]) cache[a] = {};
|
|
23
|
+
return createProxy((b) => {
|
|
24
|
+
if (!cache[a][b]) cache[a][b] = pathCall(a, b);
|
|
25
|
+
return cache[a][b];
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
const lookup = getLookupFn(metadata);
|
|
30
|
+
const {
|
|
31
|
+
buildRuntimeCall,
|
|
32
|
+
buildStorage,
|
|
33
|
+
buildConstant,
|
|
34
|
+
buildCall,
|
|
35
|
+
buildEvent
|
|
36
|
+
} = getDynamicBuilder(lookup);
|
|
37
|
+
return {
|
|
38
|
+
query: createProxyPath((...a) => {
|
|
39
|
+
const { value, args } = withError(buildStorage, "Storage")(...a);
|
|
40
|
+
return { value, args };
|
|
41
|
+
}),
|
|
42
|
+
tx: createProxyPath((...a) => withError(buildCall, "Call")(...a).codec),
|
|
43
|
+
event: createProxyPath(
|
|
44
|
+
(...args) => withError(buildEvent, "Event")(...args).codec
|
|
45
|
+
),
|
|
46
|
+
apis: createProxyPath(withError(buildRuntimeCall, "Runtime API")),
|
|
47
|
+
constants: createProxyPath(withError(buildConstant, "Constant"))
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export { getTypedCodecs };
|
|
52
|
+
//# sourceMappingURL=typed-codecs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-codecs.mjs","sources":["../../../src/typed-codecs/typed-codecs.ts"],"sourcesContent":["import { type ChainDefinition } from \"@/descriptors\"\nimport {\n getDynamicBuilder,\n getLookupFn,\n MetadataLookup,\n} from \"@polkadot-api/metadata-builders\"\nimport { decAnyMetadata, V14, V15 } from \"@polkadot-api/substrate-bindings\"\nimport { TypedCodecs } from \"./types\"\n\nexport const createConstantEntry = (\n palletName: string,\n name: string,\n lookup: MetadataLookup,\n { buildConstant }: ReturnType<typeof getDynamicBuilder>,\n) => {\n const pallet = lookup.metadata.pallets.find((p) => p.name === palletName)\n const constant = pallet?.constants.find((c) => c.name === name)\n if (constant == null)\n throw new Error(`Runtime entry Constant(${palletName}.${name}) not found`)\n return buildConstant(palletName, name)\n}\n\nconst withError =\n <T>(\n builder: (pallet: string, name: string) => T,\n errName: string,\n ): ((pallet: string, name: string) => T) =>\n (pallet, name) => {\n try {\n return builder(pallet, name)\n } catch {\n throw new Error(`Runtime entry ${errName}(${pallet}.${name}) not found`)\n }\n }\n\n/**\n * It provides access the codecs of all possible on-chain interactions.\n *\n * @param descriptors Pass descriptors from `@polkadot-api/descriptors`\n * generated by `papi` CLI.\n */\nexport const getTypedCodecs = async <D extends ChainDefinition>(\n descriptors: D,\n): Promise<TypedCodecs<D>> => {\n const metadata = decAnyMetadata(await descriptors.getMetadata()).metadata\n .value as V14 | V15\n const target = {}\n const createProxy = (propCall: (prop: string) => unknown) =>\n new Proxy(target, {\n get(_, prop) {\n return propCall(prop as string)\n },\n })\n const createProxyPath = <T>(pathCall: (a: string, b: string) => T) => {\n const cache: Record<string, Record<string, T>> = {}\n return createProxy((a) => {\n if (!cache[a]) cache[a] = {}\n return createProxy((b) => {\n if (!cache[a][b]) cache[a][b] = pathCall(a, b)\n return cache[a][b]\n })\n }) as Record<string, Record<string, T>>\n }\n\n const lookup = getLookupFn(metadata)\n const {\n buildRuntimeCall,\n buildStorage,\n buildConstant,\n buildCall,\n buildEvent,\n } = getDynamicBuilder(lookup)\n\n return {\n query: createProxyPath((...a) => {\n const { value, args } = withError(buildStorage, \"Storage\")(...a)\n return { value, args }\n }),\n tx: createProxyPath((...a) => withError(buildCall, \"Call\")(...a).codec),\n event: createProxyPath(\n (...args) => withError(buildEvent, \"Event\")(...args).codec,\n ),\n apis: createProxyPath(withError(buildRuntimeCall, \"Runtime API\")),\n constants: createProxyPath(withError(buildConstant, \"Constant\")),\n } as TypedCodecs<D>\n}\n"],"names":[],"mappings":";;;AAsBA,MAAM,YACJ,CACE,OAAA,EACA,OAEF,KAAA,CAAC,QAAQ,IAAS,KAAA;AAChB,EAAI,IAAA;AACF,IAAO,OAAA,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,GACrB,CAAA,MAAA;AACN,IAAM,MAAA,IAAI,MAAM,CAAiB,cAAA,EAAA,OAAO,IAAI,MAAM,CAAA,CAAA,EAAI,IAAI,CAAa,WAAA,CAAA,CAAA;AAAA;AAE3E,CAAA;AAQW,MAAA,cAAA,GAAiB,OAC5B,WAC4B,KAAA;AAC5B,EAAA,MAAM,WAAW,cAAe,CAAA,MAAM,YAAY,WAAY,EAAC,EAAE,QAC9D,CAAA,KAAA;AACH,EAAA,MAAM,SAAS,EAAC;AAChB,EAAA,MAAM,WAAc,GAAA,CAAC,QACnB,KAAA,IAAI,MAAM,MAAQ,EAAA;AAAA,IAChB,GAAA,CAAI,GAAG,IAAM,EAAA;AACX,MAAA,OAAO,SAAS,IAAc,CAAA;AAAA;AAChC,GACD,CAAA;AACH,EAAM,MAAA,eAAA,GAAkB,CAAI,QAA0C,KAAA;AACpE,IAAA,MAAM,QAA2C,EAAC;AAClD,IAAO,OAAA,WAAA,CAAY,CAAC,CAAM,KAAA;AACxB,MAAA,IAAI,CAAC,KAAM,CAAA,CAAC,GAAS,KAAA,CAAA,CAAC,IAAI,EAAC;AAC3B,MAAO,OAAA,WAAA,CAAY,CAAC,CAAM,KAAA;AACxB,QAAA,IAAI,CAAC,KAAA,CAAM,CAAC,CAAA,CAAE,CAAC,CAAA,EAAS,KAAA,CAAA,CAAC,CAAE,CAAA,CAAC,CAAI,GAAA,QAAA,CAAS,GAAG,CAAC,CAAA;AAC7C,QAAO,OAAA,KAAA,CAAM,CAAC,CAAA,CAAE,CAAC,CAAA;AAAA,OAClB,CAAA;AAAA,KACF,CAAA;AAAA,GACH;AAEA,EAAM,MAAA,MAAA,GAAS,YAAY,QAAQ,CAAA;AACnC,EAAM,MAAA;AAAA,IACJ,gBAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF,GAAI,kBAAkB,MAAM,CAAA;AAE5B,EAAO,OAAA;AAAA,IACL,KAAA,EAAO,eAAgB,CAAA,CAAA,GAAI,CAAM,KAAA;AAC/B,MAAM,MAAA,EAAE,OAAO,IAAK,EAAA,GAAI,UAAU,YAAc,EAAA,SAAS,CAAE,CAAA,GAAG,CAAC,CAAA;AAC/D,MAAO,OAAA,EAAE,OAAO,IAAK,EAAA;AAAA,KACtB,CAAA;AAAA,IACD,EAAA,EAAI,eAAgB,CAAA,CAAA,GAAI,CAAM,KAAA,SAAA,CAAU,SAAW,EAAA,MAAM,CAAE,CAAA,GAAG,CAAC,CAAA,CAAE,KAAK,CAAA;AAAA,IACtE,KAAO,EAAA,eAAA;AAAA,MACL,CAAA,GAAI,SAAS,SAAU,CAAA,UAAA,EAAY,OAAO,CAAE,CAAA,GAAG,IAAI,CAAE,CAAA;AAAA,KACvD;AAAA,IACA,IAAM,EAAA,eAAA,CAAgB,SAAU,CAAA,gBAAA,EAAkB,aAAa,CAAC,CAAA;AAAA,IAChE,SAAW,EAAA,eAAA,CAAgB,SAAU,CAAA,aAAA,EAAe,UAAU,CAAC;AAAA,GACjE;AACF;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
|
|
2
2
|
import { BlockInfo, SystemEvent as SystemEvent$1 } from '@polkadot-api/observable-client';
|
|
3
|
-
import { HexString, OpaqueKeyHash, Binary, SS58String, Enum, BlockHeader } from '@polkadot-api/substrate-bindings';
|
|
3
|
+
import { HexString, OpaqueKeyHash, Binary, SS58String, Enum, BlockHeader, Codec, FixedSizeBinary, ResultPayload } from '@polkadot-api/substrate-bindings';
|
|
4
4
|
export { AccountId, Binary, Codec, Enum, EnumVariant, FixedSizeBinary, GetEnum, HexString, ResultPayload, SS58AddressInfo, SS58String, _Enum, getSs58AddressInfo } from '@polkadot-api/substrate-bindings';
|
|
5
5
|
import { ChainSpecData } from '@polkadot-api/substrate-client';
|
|
6
6
|
import { Observable } from 'rxjs';
|
|
@@ -885,6 +885,10 @@ interface PolkadotClient {
|
|
|
885
885
|
* finalized block.
|
|
886
886
|
*/
|
|
887
887
|
getBestBlocks: () => Promise<BlockInfo[]>;
|
|
888
|
+
/**
|
|
889
|
+
* Observable of new blocks that have been discovered by the client.
|
|
890
|
+
*/
|
|
891
|
+
blocks$: Observable<BlockInfo>;
|
|
888
892
|
/**
|
|
889
893
|
* Observable to watch Block Body.
|
|
890
894
|
*
|
|
@@ -1011,5 +1015,79 @@ declare function createClient(provider: JsonRpcProvider): PolkadotClient;
|
|
|
1011
1015
|
*/
|
|
1012
1016
|
declare const getOfflineApi: <D extends ChainDefinition>(chainDefinition: D) => Promise<OfflineApi<D>>;
|
|
1013
1017
|
|
|
1014
|
-
|
|
1018
|
+
type Tuple<T> = [T, ...T[]];
|
|
1019
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
1020
|
+
type UndoEnum<T> = UnionToIntersection<T extends {
|
|
1021
|
+
type: string;
|
|
1022
|
+
value: unknown;
|
|
1023
|
+
} ? {
|
|
1024
|
+
[K in T["type"]]: (T & {
|
|
1025
|
+
type: K;
|
|
1026
|
+
})["value"];
|
|
1027
|
+
} : T>;
|
|
1028
|
+
type _Inner<T> = T extends void ? {} : undefined extends T ? {
|
|
1029
|
+
inner: ShapedCodec<Exclude<T, undefined>>;
|
|
1030
|
+
} : T extends string | number | bigint | boolean | void | undefined | null | symbol | Uint8Array | Binary | FixedSizeBinary<any> ? {} : T extends Tuple<any> ? {
|
|
1031
|
+
inner: {
|
|
1032
|
+
[K in keyof T]: ShapedCodec<T[K]>;
|
|
1033
|
+
};
|
|
1034
|
+
} : T extends Array<infer R> ? {
|
|
1035
|
+
inner: ShapedCodec<R>;
|
|
1036
|
+
} : T extends ResultPayload<infer OK, infer KO> ? {
|
|
1037
|
+
inner: {
|
|
1038
|
+
ok: ShapedCodec<OK>;
|
|
1039
|
+
ko: ShapedCodec<KO>;
|
|
1040
|
+
};
|
|
1041
|
+
} : {
|
|
1042
|
+
inner: {
|
|
1043
|
+
[K in keyof T]: ShapedCodec<T[K]>;
|
|
1044
|
+
};
|
|
1045
|
+
};
|
|
1046
|
+
type Inner<T> = _Inner<UndoEnum<T>>;
|
|
1047
|
+
type ShapedCodec<T> = Codec<T> & Inner<T>;
|
|
1048
|
+
|
|
1049
|
+
type StorageCodecs<Args extends Array<any>, T> = {
|
|
1050
|
+
args: ShapedCodec<Args>;
|
|
1051
|
+
value: ShapedCodec<T>;
|
|
1052
|
+
};
|
|
1053
|
+
type ExtractStorageCodec<T extends DescriptorEntry<StorageDescriptor<any, any, any, any>>> = {
|
|
1054
|
+
[K in keyof T]: {
|
|
1055
|
+
[KK in keyof T[K]]: T[K][KK] extends StorageDescriptor<infer Key, infer Value, any, any> ? StorageCodecs<Key, Value> : unknown;
|
|
1056
|
+
};
|
|
1057
|
+
};
|
|
1058
|
+
type ExtractTxCodec<T extends DescriptorEntry<TxDescriptor<any>>> = {
|
|
1059
|
+
[K in keyof T]: {
|
|
1060
|
+
[KK in keyof T[K]]: T[K][KK] extends TxDescriptor<infer Args> ? ShapedCodec<Args> : unknown;
|
|
1061
|
+
};
|
|
1062
|
+
};
|
|
1063
|
+
type ExtractRuntimeCodec<T extends DescriptorEntry<RuntimeDescriptor<any, any>>> = {
|
|
1064
|
+
[K in keyof T]: {
|
|
1065
|
+
[KK in keyof T[K]]: T[K][KK] extends RuntimeDescriptor<infer Args, infer Value> ? {
|
|
1066
|
+
args: ShapedCodec<Args>;
|
|
1067
|
+
value: ShapedCodec<Value>;
|
|
1068
|
+
} : unknown;
|
|
1069
|
+
};
|
|
1070
|
+
};
|
|
1071
|
+
type ExtractPlainCodec<T extends DescriptorEntry<PlainDescriptor<any>>> = {
|
|
1072
|
+
[K in keyof T]: {
|
|
1073
|
+
[KK in keyof T[K]]: T[K][KK] extends PlainDescriptor<infer Value> ? ShapedCodec<Value> : unknown;
|
|
1074
|
+
};
|
|
1075
|
+
};
|
|
1076
|
+
type TypedCodecs<T extends ChainDefinition> = {
|
|
1077
|
+
query: ExtractStorageCodec<T["descriptors"]["pallets"]["__storage"]>;
|
|
1078
|
+
tx: ExtractTxCodec<T["descriptors"]["pallets"]["__tx"]>;
|
|
1079
|
+
event: ExtractPlainCodec<T["descriptors"]["pallets"]["__event"]>;
|
|
1080
|
+
apis: ExtractRuntimeCodec<T["descriptors"]["apis"]>;
|
|
1081
|
+
constants: ExtractPlainCodec<T["descriptors"]["pallets"]["__const"]>;
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
/**
|
|
1085
|
+
* It provides access the codecs of all possible on-chain interactions.
|
|
1086
|
+
*
|
|
1087
|
+
* @param descriptors Pass descriptors from `@polkadot-api/descriptors`
|
|
1088
|
+
* generated by `papi` CLI.
|
|
1089
|
+
*/
|
|
1090
|
+
declare const getTypedCodecs: <D extends ChainDefinition>(descriptors: D) => Promise<TypedCodecs<D>>;
|
|
1091
|
+
|
|
1092
|
+
export { CompatibilityToken, InvalidTxError, RuntimeToken, createClient, getOfflineApi, getTypedCodecs };
|
|
1015
1093
|
export type { ApisTypedef, ChainDefinition, ConstFromPalletsDef, DescriptorEntry, ErrorsFromPalletsDef, EventPhase, EventsFromPalletsDef, FixedSizeArray, PalletsTypedef, PlainDescriptor, PolkadotClient, QueryFromPalletsDef, RuntimeDescriptor, StorageDescriptor, Transaction, TransactionValidityError, TxBestBlocksState, TxBroadcastEvent, TxBroadcasted, TxCall, TxCallData, TxDescriptor, TxEntry, TxEvent, TxEventsPayload, TxFinalized, TxFinalizedPayload, TxFromPalletsDef, TxInBestBlocksFound, TxInBestBlocksNotFound, TxObservable, TxOptions, TxPromise, TxSignFn, TxSigned, TypedApi, UnsafeApi, UnsafeTransaction, UnsafeTxCall, UnsafeTxEntry };
|