mirror of
https://github.com/pezkuwichain/pezkuwi-sdk-ui.git
synced 2026-06-14 08:41:03 +00:00
d949863789
Comprehensive web interface for interacting with Pezkuwi blockchain. Features: - Blockchain explorer - Wallet management - Staking interface - Governance participation - Developer tools Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
126 lines
3.3 KiB
TypeScript
126 lines
3.3 KiB
TypeScript
// Copyright 2017-2026 @pezkuwi/react-params authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import type { Vec } from '@pezkuwi/types';
|
|
import type { KeyValue as Pair } from '@pezkuwi/types/interfaces';
|
|
import type { Props, RawParam } from '../types.js';
|
|
|
|
import React, { useCallback, useState } from 'react';
|
|
|
|
import { assert, isHex, u8aToHex, u8aToString } from '@pezkuwi/util';
|
|
|
|
import { useTranslation } from '../translate.js';
|
|
import Base from './Base.js';
|
|
import Bytes from './Bytes.js';
|
|
import File from './File.js';
|
|
import { createParam } from './KeyValue.js';
|
|
|
|
interface Parsed {
|
|
isValid: boolean;
|
|
value: [Uint8Array, Uint8Array][];
|
|
}
|
|
|
|
const BYTES_TYPE = {
|
|
info: 0,
|
|
type: 'Bytes'
|
|
};
|
|
|
|
function parseFile (raw: Uint8Array): Parsed {
|
|
const json = JSON.parse(u8aToString(raw)) as Record<string, string>;
|
|
const keys = Object.keys(json);
|
|
let isValid = keys.length !== 0;
|
|
const value = keys.map((key): [Uint8Array, Uint8Array] => {
|
|
const value = json[key];
|
|
|
|
assert(isHex(key) && isHex(value), `Non-hex key/value pair found in ${key.toString()} => ${value.toString()}`);
|
|
|
|
const encKey = createParam(key);
|
|
const encValue = createParam(value, true);
|
|
|
|
isValid = isValid && encKey.isValid && encValue.isValid;
|
|
|
|
return [encKey.u8a, encValue.u8a];
|
|
});
|
|
|
|
return {
|
|
isValid,
|
|
value
|
|
};
|
|
}
|
|
|
|
function KeyValueArray ({ className = '', defaultValue, isDisabled, isError, label, onChange, onEnter, onEscape, registry, withLabel }: Props): React.ReactElement<Props> {
|
|
const { t } = useTranslation();
|
|
const [placeholder, setPlaceholder] = useState<string>(t('click to select or drag and drop JSON key/value (hex-encoded) file'));
|
|
|
|
const _onChange = useCallback(
|
|
(raw: Uint8Array): void => {
|
|
let encoded: Parsed = { isValid: false, value: [] };
|
|
|
|
try {
|
|
encoded = parseFile(raw);
|
|
|
|
setPlaceholder(t('{{count}} key/value pairs encoded for submission', {
|
|
replace: {
|
|
count: encoded.value.length
|
|
}
|
|
}));
|
|
} catch (error) {
|
|
console.error('Error converting json k/v', error);
|
|
|
|
setPlaceholder(t('click to select or drag and drop JSON key/value (hex-encoded) file'));
|
|
}
|
|
|
|
onChange && onChange(encoded);
|
|
},
|
|
[onChange, t]
|
|
);
|
|
|
|
if (isDisabled) {
|
|
const pairs = defaultValue.value as Vec<Pair>;
|
|
|
|
return (
|
|
<>
|
|
<Base
|
|
className={className}
|
|
label={label}
|
|
>
|
|
<div />
|
|
</Base>
|
|
<div className='ui--Params'>
|
|
{pairs.map(([key, value]): React.ReactNode => {
|
|
const keyHex = u8aToHex(key.toU8a(true));
|
|
|
|
return (
|
|
<Bytes
|
|
defaultValue={{ value } as unknown as RawParam}
|
|
isDisabled
|
|
key={keyHex}
|
|
label={keyHex}
|
|
name={keyHex}
|
|
onEnter={onEnter}
|
|
onEscape={onEscape}
|
|
registry={registry}
|
|
type={BYTES_TYPE}
|
|
/>
|
|
);
|
|
})}
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<File
|
|
className={className}
|
|
isDisabled={isDisabled}
|
|
isError={isError}
|
|
label={label}
|
|
onChange={_onChange}
|
|
placeholder={placeholder}
|
|
withLabel={withLabel}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export default React.memo(KeyValueArray);
|