mirror of
https://github.com/pezkuwichain/pezkuwi-api.git
synced 2026-11-03 15:01:06 +00:00
chore(papi): commit the sources behind the four polkadot-api packages (#15)
* chore(papi): commit the sources behind the four polkadot-api packages papi-utils, bizinikiwi-bindings, metadata-builders and merkleize-metadata held only dist/ builds, and no repository held their source. Every source map in dist/ embeds the TypeScript it was compiled from; that is now committed as src/ (59 files), and it matches upstream polkadot-api (MIT) exactly once @polkadot-api/* imports are renamed: papi-utils @polkadot-api/utils 0.2.0 bizinikiwi-bindings @polkadot-api/substrate-bindings 0.16.6 metadata-builders @polkadot-api/metadata-builders 0.13.0-0.13.2 merkleize-metadata @polkadot-api/merkleize-metadata 1.1.21-1.1.23 scripts/check-papi-sources.mjs, run in the lint job, fails unless the source embedded in dist/ is exactly the committed src/. tsconfig.json excludes these src/ trees; ESLint already skipped the packages. Each README now states the upstream package and version. * chore(papi): keep the upstream sources in upstream-src/ The pezkuwi-dev build treats any package with a src/ directory as its own: it requires our license header on every file and builds it. These are upstream files that must stay byte-identical to the source embedded in dist/, so they live in upstream-src/ instead, which neither the build nor the root tsconfig picks up.
This commit is contained in:
1 parent
622f49e4a8
commit
e3c72817fb
66 files changed
+4674
-5
No files matched your search
@@ -0,0 +1,191 @@
|
||||
import type { Codec, StringRecord } from "@pezkuwi/bizinikiwi-bindings"
|
||||
import * as scale from "@pezkuwi/bizinikiwi-bindings"
|
||||
import { mapObject } from "@pezkuwi/papi-utils"
|
||||
import type { EnumVar, MetadataLookup } from "./lookups"
|
||||
import { getLookupCodecBuilder } from "./lookup-codec-builder"
|
||||
|
||||
const nullCodec = scale.enhanceCodec(
|
||||
scale._void,
|
||||
() => undefined,
|
||||
() => null,
|
||||
)
|
||||
|
||||
export const getDynamicBuilder = (getLookupEntryDef: MetadataLookup) => {
|
||||
const { metadata } = getLookupEntryDef
|
||||
let buildDefinition = getLookupCodecBuilder(getLookupEntryDef)
|
||||
|
||||
const prefix = metadata.pallets
|
||||
.find((x) => x.name === "System")
|
||||
?.constants.find((x) => x.name === "SS58Prefix")
|
||||
|
||||
let ss58Prefix: number | undefined
|
||||
if (prefix) {
|
||||
try {
|
||||
const prefixVal = buildDefinition(prefix.type).dec(prefix.value)
|
||||
if (typeof prefixVal === "number") {
|
||||
ss58Prefix = prefixVal
|
||||
buildDefinition = getLookupCodecBuilder(
|
||||
getLookupEntryDef,
|
||||
scale.AccountId(prefixVal),
|
||||
)
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
const storagePallets = new Map<string, ReturnType<typeof scale.Storage>>()
|
||||
|
||||
const buildStorage = (pallet: string, entry: string) => {
|
||||
let storagePallet = storagePallets.get(pallet)
|
||||
if (!storagePallet)
|
||||
storagePallets.set(pallet, (storagePallet = scale.Storage(pallet)))
|
||||
|
||||
const storageEntry = metadata.pallets
|
||||
.find((x) => x.name === pallet)!
|
||||
.storage!.items.find((s) => s.name === entry)!
|
||||
|
||||
// if val is `void` it decodes to `undefined`, making it impossible
|
||||
// to differentiate from a non-existant key
|
||||
// therefore, if the key exists => null, if it doesn't => undefined
|
||||
const withNullVoid = (codec: Codec<any>) =>
|
||||
codec === scale._void ? nullCodec : codec
|
||||
|
||||
const storageWithFallback = (
|
||||
len: number,
|
||||
value: Codec<any>,
|
||||
...args: Parameters<ReturnType<typeof scale.Storage>>
|
||||
) => {
|
||||
const keys = storagePallet!(...args)
|
||||
const [, ...encodersWithHash] = args
|
||||
return {
|
||||
args: scale.Tuple(...encodersWithHash.map(([codec]) => codec)),
|
||||
keys,
|
||||
value,
|
||||
len,
|
||||
fallback:
|
||||
storageEntry.modifier === 1
|
||||
? value.dec(storageEntry.fallback)
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
if (storageEntry.type.tag === "plain")
|
||||
return storageWithFallback(
|
||||
0,
|
||||
withNullVoid(buildDefinition(storageEntry.type.value)),
|
||||
entry,
|
||||
)
|
||||
|
||||
const { key, value, hashers } = storageEntry.type.value
|
||||
const val = withNullVoid(buildDefinition(value))
|
||||
const hashes = hashers.map((x) => scale[x.tag])
|
||||
|
||||
const hashArgs: scale.EncoderWithHash<unknown>[] = (() => {
|
||||
if (hashes.length === 1) {
|
||||
return [[buildDefinition(key), hashes[0]]]
|
||||
}
|
||||
|
||||
const keyDef = getLookupEntryDef(key)
|
||||
|
||||
switch (keyDef.type) {
|
||||
case "array":
|
||||
return hashes.map((hash) => [buildDefinition(keyDef.value.id), hash])
|
||||
case "tuple":
|
||||
return keyDef.value.map((x, idx) => [
|
||||
buildDefinition(x.id),
|
||||
hashes[idx],
|
||||
])
|
||||
default:
|
||||
throw new Error("Invalid key type")
|
||||
}
|
||||
})()
|
||||
|
||||
return storageWithFallback(hashes.length, val, entry, ...hashArgs)
|
||||
}
|
||||
|
||||
const buildEnumEntry = (
|
||||
entry: EnumVar["value"][keyof EnumVar["value"]],
|
||||
): Codec<any> => {
|
||||
switch (entry.type) {
|
||||
case "void":
|
||||
return scale._void
|
||||
case "lookupEntry":
|
||||
return buildDefinition(entry.value.id)
|
||||
case "tuple":
|
||||
return scale.Tuple(
|
||||
...Object.values(entry.value).map((l) => buildDefinition(l.id)),
|
||||
)
|
||||
case "struct":
|
||||
return scale.Struct(
|
||||
mapObject(entry.value, (x) => buildDefinition(x.id)) as StringRecord<
|
||||
Codec<any>
|
||||
>,
|
||||
)
|
||||
case "array":
|
||||
return scale.Vector(buildDefinition(entry.value.id), entry.len)
|
||||
}
|
||||
}
|
||||
|
||||
const buildConstant = (pallet: string, constantName: string) => {
|
||||
const storageEntry = metadata.pallets
|
||||
.find((x) => x.name === pallet)!
|
||||
.constants!.find((s) => s.name === constantName)!
|
||||
|
||||
return buildDefinition(storageEntry.type as number)
|
||||
}
|
||||
|
||||
const buildVariant =
|
||||
(type: "errors" | "events" | "calls") =>
|
||||
(
|
||||
pallet: string,
|
||||
name: string,
|
||||
): {
|
||||
codec: Codec<any>
|
||||
location: [number, number]
|
||||
} => {
|
||||
const palletEntry = metadata.pallets.find((x) => x.name === pallet)!
|
||||
const lookup = getLookupEntryDef(palletEntry[type]!.type)
|
||||
if (lookup.type !== "enum") throw null
|
||||
const entry = lookup.value[name]
|
||||
|
||||
return {
|
||||
location: [palletEntry.index, entry.idx],
|
||||
codec: buildEnumEntry(lookup.value[name]),
|
||||
}
|
||||
}
|
||||
|
||||
const buildViewFn = (pallet: string, entry: string) => {
|
||||
const fn = metadata.pallets
|
||||
.find((x) => x.name === pallet)
|
||||
?.viewFns.find((x) => x.name === entry)
|
||||
if (!fn) throw null
|
||||
|
||||
return {
|
||||
args: scale.Tuple(...fn.inputs.map((x) => buildDefinition(x.type))),
|
||||
value: buildDefinition(fn.output),
|
||||
}
|
||||
}
|
||||
|
||||
const buildRuntimeCall = (api: string, method: string) => {
|
||||
const entry = metadata.apis
|
||||
.find((x) => x.name === api)
|
||||
?.methods.find((x) => x.name === method)
|
||||
if (!entry) throw null
|
||||
|
||||
return {
|
||||
args: scale.Tuple(...entry.inputs.map((x) => buildDefinition(x.type))),
|
||||
value: buildDefinition(entry.output),
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
buildDefinition,
|
||||
buildStorage,
|
||||
buildEvent: buildVariant("events"),
|
||||
buildError: buildVariant("errors"),
|
||||
buildViewFn,
|
||||
buildRuntimeCall,
|
||||
buildCall: buildVariant("calls"),
|
||||
buildConstant,
|
||||
ss58Prefix,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user