types#OrFalsy TypeScript Examples
The following examples show how to use
types#OrFalsy.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: blockTime.ts From contracts-ui with GNU General Public License v3.0 | 6 votes |
export function blockTimeMs(a: OrFalsy<ApiPromise>): BN {
return (a?.consts.babe?.expectedBlockTime || // Babe
// POW, eg. Kulupu
a?.consts.difficulty?.targetBlockTime ||
// Check against threshold to determine value validity
(a?.consts.timestamp?.minimumPeriod.gte(THRESHOLD)
? // Default minimum period config
a.consts.timestamp.minimumPeriod.mul(BN_TWO)
: a?.query.parachainSystem
? // default guess for a parachain
DEFAULT_TIME.mul(BN_TWO)
: // default guess for others
DEFAULT_TIME)) as BN;
}
Example #2
Source File: useMetadataField.tsx From contracts-ui with GNU General Public License v3.0 | 6 votes |
useMetadataField = (): UseMetadataField => {
const navigate = useNavigate();
const { codeHash: codeHashUrlParam } = useParams<{ codeHash: string }>();
const [file, setFile] = useState<OrFalsy<FileState>>(null);
const codeBundleQuery = useCodeBundle(codeHashUrlParam || '');
const codeBundle = codeBundleQuery.data;
const metadata = useMetadata(codeBundle?.document?.abi, {
isWasmRequired: !codeBundle,
onChange: setFile,
});
const isLoading = useMemo(
() => !!codeHashUrlParam && codeBundleQuery.isLoading,
[codeHashUrlParam, codeBundleQuery.isLoading]
);
const isStored = useMemo((): boolean => !!codeBundle?.document, [codeBundle?.document]);
useEffect((): void => {
if (codeHashUrlParam && !codeBundleQuery.isValid) {
navigate(`/instantiate/${codeHashUrlParam}`);
}
}, [codeHashUrlParam, codeBundleQuery.isValid, navigate]);
return {
file,
isLoading,
isStored,
...metadata,
};
}
Example #3
Source File: useAccountId.ts From contracts-ui with GNU General Public License v3.0 | 6 votes |
export function useAccountId(initialValue = '', isOwned = false): ValidFormField<string> {
const { keyring } = useApi();
const validate = useCallback(
(value: OrFalsy<string>): Validation => {
if (!value?.trim() || (isOwned && !keyring?.getAccount(value))) {
return { isValid: false, message: 'Specified account does not exist' };
}
return { isValid: true, message: null };
},
[keyring, isOwned]
);
return useFormField<string>(initialValue || keyring?.getAccounts()[0].address || '', validate);
}
Example #4
Source File: useStorageDepositLimit.ts From contracts-ui with GNU General Public License v3.0 | 6 votes |
export function useStorageDepositLimit(accountId: OrFalsy<string>): UseStorageDepositLimit {
const { api } = useApi();
const [maximum, setMaximum] = useState<BN | null>(null);
const storageDepositLimit = useBalance(0, { maxValue: maximum || undefined });
useEffect((): void => {
accountId &&
api.derive.balances
.account(accountId)
.then(({ freeBalance }) => setMaximum(freeBalance))
.catch(console.error);
}, [accountId, api]);
return {
...storageDepositLimit,
maximum,
};
}
Example #5
Source File: index.ts From contracts-ui with GNU General Public License v3.0 | 5 votes |
export function maximumBlockWeight(api: OrFalsy<ApiPromise>): Weight {
return api?.consts.system.blockWeights
? api.consts.system.blockWeights.maxBlock
: (api?.consts.system.maximumBlockWeight as Weight) || MAX_CALL_WEIGHT;
}
Example #6
Source File: Enum.tsx From contracts-ui with GNU General Public License v3.0 | 5 votes |
export function Enum(props: Props) {
const { components, typeDef, onChange: _onChange, registry, value = {} } = props;
const variants = typeDef.sub as TypeDef[];
const { keyring } = useApi();
const [variantIndex, _setVariantIndex] = useState<number>(
Math.max(
0,
variants.findIndex(({ name }) => name === Object.keys(value)[0])
)
);
const Component = components[variantIndex];
const onChange = useCallback(
(value: unknown): void => {
_onChange({ [variants[variantIndex].name as string]: value });
},
[_onChange, variants, variantIndex]
);
const setVariantIndex = useCallback(
(value: OrFalsy<number>) => {
if (isNumber(value)) {
_setVariantIndex(value);
_onChange({
[variants[value].name as string]: getInitValue(registry, keyring, variants[value]),
});
}
},
[registry, keyring, _onChange, variants]
);
return (
<>
<Dropdown
options={variants.map(({ name }, index) => ({ label: name, value: index }))}
value={variantIndex}
onChange={setVariantIndex}
/>
{variants[variantIndex].type !== 'Null' && (
<FormField
className="ml-8 mt-2"
label={<ArgSignature arg={{ type: variants[variantIndex] }} />}
{...getValidation(props)}
>
<Component value={Object.values(value)[0]} onChange={onChange} />
</FormField>
)}
</>
);
}
Example #7
Source File: InputBalance.tsx From contracts-ui with GNU General Public License v3.0 | 5 votes |
function getStringValue(api: ApiPromise, value: OrFalsy<BN>) {
if (!value) {
return '';
}
return fromBalance(fromSats(api, value || BN_ZERO));
}
Example #8
Source File: Option.tsx From contracts-ui with GNU General Public License v3.0 | 5 votes |
export function Option({
component: Component,
onChange: _onChange,
registry,
typeDef,
value = null,
}: Props) {
const { keyring } = useApi();
const [isSupplied, toggleIsSupplied] = useToggle();
const onChange = useCallback(
(value: OrFalsy<unknown>): void => {
if (!isSupplied) {
_onChange(null);
return;
}
_onChange(value);
},
[_onChange, isSupplied]
);
useEffect((): void => {
if (isSupplied && value === null) {
onChange(getInitValue(registry, keyring, typeDef.sub as TypeDef));
} else {
if (!isSupplied && value !== null) {
onChange(null);
}
}
}, [keyring, registry, onChange, value, isSupplied, typeDef.sub]);
return (
<div className="flex items-start">
{isSupplied ? (
<Component className="flex-1" onChange={onChange} value={value} />
) : (
<Input className="flex-1" isDisabled onChange={NOOP} value="" placeholder="Do not supply" />
)}
<div className="flex justify-center items-center w-18 my-2.5">
<Switch value={isSupplied} onChange={toggleIsSupplied} />
</div>
</div>
);
}
Example #9
Source File: useCodeBundle.ts From contracts-ui with GNU General Public License v3.0 | 5 votes |
function isValidHash(input: OrFalsy<string>): boolean {
const codeHashRegex = /^0x[0-9a-fA-F]{64}$/;
return !!input && codeHashRegex.test(input);
}
Example #10
Source File: useWeight.ts From contracts-ui with GNU General Public License v3.0 | 5 votes |
function getEstimatedMegaGas(api: ApiPromise, estimatedWeight: OrFalsy<BN>, withBuffer = true): BN {
return (estimatedWeight || maximumBlockWeight(api)).div(BN_MILLION).addn(withBuffer ? 1 : 0);
}
Example #11
Source File: useWeight.ts From contracts-ui with GNU General Public License v3.0 | 5 votes |
function getDefaultMegaGas(api: OrFalsy<ApiPromise>, estimatedWeight?: OrFalsy<BN>): BN {
if (api && estimatedWeight) {
return getEstimatedMegaGas(api, estimatedWeight);
}
return maximumBlockWeight(api).div(BN_MILLION).div(BN_TEN);
}
Example #12
Source File: useWeight.ts From contracts-ui with GNU General Public License v3.0 | 5 votes |
useWeight = (estimatedWeight: OrFalsy<BN>): UseWeight => {
// const estimatedWeightRef = useRef(estimatedWeight);
const { api } = useApi();
const [blockTime] = useBlockTime();
const [megaGas, _setMegaGas] = useState<BN>(getDefaultMegaGas(api, estimatedWeight));
const [isActive, setIsActive] = useState(!!estimatedWeight);
const defaultWeight = useMemo((): BN => maximumBlockWeight(api), [api]);
const setMegaGas = useCallback(
(value?: BN | undefined) => {
_setMegaGas(value || getDefaultMegaGas(api, null));
},
[api]
);
useEffect((): void => {
if (!isActive) {
_setMegaGas(getDefaultMegaGas(api, estimatedWeight));
}
}, [api, estimatedWeight, isActive]);
return useMemo((): UseWeight => {
let executionTime = 0;
let percentage = 0;
let weight = BN_ZERO;
let isValid = false;
if (megaGas) {
weight = megaGas.mul(BN_MILLION);
executionTime = weight.muln(blockTime).div(maximumBlockWeight(api)).toNumber();
percentage = (executionTime / blockTime) * 100;
// execution is 2s of 6s blocks, i.e. 1/3
executionTime = executionTime / 3000;
isValid = !megaGas.isZero() && percentage < 65;
}
return {
defaultWeight,
estimatedWeight,
executionTime,
isActive,
isValid: !isActive || isValid,
megaGas: megaGas || BN_ZERO,
percentage,
setIsActive,
setMegaGas,
weight,
};
}, [api, blockTime, defaultWeight, estimatedWeight, isActive, megaGas, setIsActive, setMegaGas]);
}
Example #13
Source File: InputFile.tsx From contracts-ui with GNU General Public License v3.0 | 4 votes |
export function InputFile({
className = '',
errorMessage,
value: propsFile,
isError,
onChange,
placeholder,
onRemove,
}: Props) {
const ref = createRef<DropzoneRef>();
const [file, setFile] = useState<OrFalsy<FileState>>(propsFile);
const onDrop = useCallback(
(files: File[]): void => {
files.forEach((file): void => {
const reader = new FileReader();
reader.onabort = NOOP;
reader.onerror = NOOP;
reader.onload = ({ target }: ProgressEvent<FileReader>): void => {
if (target && target.result) {
const name = file.name;
const data = convertResult(target.result as ArrayBuffer);
const size = data.length;
onChange && onChange({ data, name, size });
ref &&
!propsFile &&
setFile({
data,
name,
size: data.length,
});
}
};
reader.readAsArrayBuffer(file);
});
},
[ref, onChange, propsFile]
);
const removeHandler = useCallback((): void => {
onRemove && onRemove();
!propsFile && setFile(undefined);
}, [onRemove, propsFile]);
useEffect((): void => {
if (file !== propsFile) {
setFile(propsFile);
}
}, [file, propsFile]);
return file ? (
<div className={`${className} flex`}>
<div className="p-6 border dark:bg-elevation-1 dark:border-gray-700 border-gray-300 inline-flex items-center rounded shadow">
<DocumentTextIcon
className="w-7 h-7 mr-2 text-gray-500 justify-self-start"
aria-hidden="true"
/>
<span className="dark:text-gray-300 text-gray-500 text-xs min-w-600 justify-self-start mr-20">
{file.name} ({(file.size / 1000).toFixed(2)}kb)
</span>
{errorMessage && isError && (
<span className="dark:text-gray-300 text-gray-500 text-xs min-w-600 justify-self-start mr-20">
{errorMessage}
</span>
)}
<XIcon
className="w-5 h-5 mr-2 text-gray-500 justify-self-end cursor-pointer"
aria-hidden="true"
onClick={removeHandler}
/>
</div>
</div>
) : (
<Dropzone multiple={false} onDrop={onDrop} ref={ref}>
{({ getInputProps, getRootProps }) => {
return (
<div className={className} {...getRootProps()}>
<label
className="dark:text-gray-700 text-gray-400 font-normal py-2 px-4 border dark:border-gray-700 border-gray-200 rounded flex flex-col h-36 items-center cursor-pointer justify-center"
htmlFor="file"
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-8 mb-2 dark:text-gray-500"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"
/>
</svg>
<span className="text-sm dark:text-gray-500 text-gray-400">{placeholder}</span>
</label>
<input {...getInputProps()} data-cy="file-input" />
</div>
);
}}
</Dropzone>
);
}
Example #14
Source File: Step2.tsx From contracts-ui with GNU General Public License v3.0 | 4 votes |
export function Step2() {
const {
data: { accountId, metadata },
dryRunResult,
stepBackward,
currentStep,
onFinalize,
onFormChange,
} = useInstantiate();
const { value, onChange: onChangeValue, ...valueValidation } = useBalance(10000);
const dbValue = useDebounce(value);
const [estimatedWeight, setEstimatedWeight] = useState<OrFalsy<BN>>(null);
const weight = useWeight(estimatedWeight);
const dbWeight = useDebounce(weight.weight);
const storageDepositLimit = useStorageDepositLimit(accountId);
const dbStorageDepositLimit = useDebounce(storageDepositLimit.value);
const salt = useFormField<string>(randomAsHex(), value => {
if (!!value && isHex(value) && value.length === 66) {
return { isValid: true };
}
return { isValid: false, isError: true, message: 'Invalid hex string' };
});
const dbSalt = useDebounce(salt.value);
const [constructorIndex, setConstructorIndex] = useState<number>(0);
const [deployConstructor, setDeployConstructor] = useState<AbiMessage>();
const [argValues, setArgValues] = useArgValues(deployConstructor?.args || null);
const dbArgValues = useDebounce(argValues);
useEffect(() => {
setConstructorIndex(0);
metadata && setDeployConstructor(metadata.constructors[0]);
}, [metadata, setConstructorIndex]);
const [isUsingSalt, toggleIsUsingSalt] = useToggle(true);
const [isUsingStorageDepositLimit, toggleIsUsingStorageDepositLimit] = useToggle();
const onSubmit = () => {
onFinalize &&
onFinalize({
constructorIndex,
salt: isUsingSalt ? salt.value : undefined,
value,
argValues,
storageDepositLimit: isUsingStorageDepositLimit ? storageDepositLimit.value : undefined,
weight: weight.isActive ? weight.weight : estimatedWeight || weight.defaultWeight,
});
};
useEffect((): void => {
if (
dryRunResult?.result.isOk &&
dryRunResult.gasRequired &&
!estimatedWeight?.eq(dryRunResult.gasRequired)
) {
setEstimatedWeight(dryRunResult.gasRequired);
}
}, [
dryRunResult?.result.isOk,
dryRunResult?.result.isErr,
dryRunResult?.gasRequired,
estimatedWeight,
]);
useEffect((): void => {
onFormChange &&
onFormChange({
constructorIndex,
salt: isUsingSalt ? dbSalt : null,
value: dbValue && deployConstructor?.isPayable ? dbValue : null,
argValues: dbArgValues,
storageDepositLimit: isUsingStorageDepositLimit ? dbStorageDepositLimit : null,
weight: weight.isActive ? dbWeight : weight.defaultWeight,
});
}, [
onFormChange,
constructorIndex,
deployConstructor,
dbSalt,
dbValue,
dbArgValues,
dbStorageDepositLimit,
dbWeight,
isUsingSalt,
isUsingStorageDepositLimit,
weight.defaultWeight,
weight.isActive,
]);
useEffect(
(): void => {
if (!metadata) {
setEstimatedWeight(null);
weight.setIsActive(false);
}
},
// eslint-disable-next-line
[metadata]
);
if (currentStep !== 2) return null;
return metadata ? (
<>
<Form>
<FormField
help="The constructor to use for this contract deployment."
id="constructor"
label="Deployment Constructor"
>
<Dropdown
id="constructor"
options={createConstructorOptions(metadata.constructors)}
className="mb-4"
value={constructorIndex}
onChange={v => {
if (isNumber(v)) {
setConstructorIndex(v);
setDeployConstructor(metadata.constructors[v]);
}
}}
>
No constructors found
</Dropdown>
{deployConstructor && argValues && (
<ArgumentForm
key={`args-${deployConstructor.method}`}
args={deployConstructor.args}
registry={metadata.registry}
setArgValues={setArgValues}
argValues={argValues}
className="argument-form"
/>
)}
</FormField>
{deployConstructor?.isPayable && (
<FormField
help="The balance to transfer from the `origin` to the newly created contract."
id="value"
label="Value"
{...valueValidation}
>
<InputBalance id="value" value={value} onChange={onChangeValue} />
</FormField>
)}
<FormField
help="A hex or string value that acts as a salt for this deployment."
id="salt"
label="Deployment Salt"
{...getValidation(salt)}
>
<InputSalt isActive={isUsingSalt} toggleIsActive={toggleIsUsingSalt} {...salt} />
</FormField>
<FormField
help="The maximum amount of gas (in millions of units) to use for this instantiation. If the transaction requires more, it will fail."
id="maxGas"
label="Max Gas Allowed"
isError={!weight.isValid}
message={!weight.isValid ? 'Invalid gas limit' : null}
>
<InputGas isCall withEstimate {...weight} />
</FormField>
<FormField
help="The maximum balance allowed to be deducted for the new contract's storage deposit."
id="storageDepositLimit"
label="Storage Deposit Limit"
isError={!storageDepositLimit.isValid}
message={
!storageDepositLimit.isValid
? storageDepositLimit.message || 'Invalid storage deposit limit'
: null
}
>
<InputStorageDepositLimit
isActive={isUsingStorageDepositLimit}
toggleIsActive={toggleIsUsingStorageDepositLimit}
{...storageDepositLimit}
/>
</FormField>
</Form>
<Buttons>
<Button
isDisabled={
(deployConstructor?.isPayable && !valueValidation.isValid) ||
(isUsingSalt && !salt.isValid) ||
!weight.isValid ||
!storageDepositLimit.isValid ||
!deployConstructor?.method ||
!argValues ||
(dryRunResult && dryRunResult.result.isErr)
}
onClick={onSubmit}
variant="primary"
data-cy="next-btn"
>
Next
</Button>
<Button onClick={stepBackward} variant="default">
Go Back
</Button>
</Buttons>
</>
) : null;
}