Skip to content

Commit

Permalink
feat: add deploy method + some refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
brusherru committed Jan 17, 2025
1 parent 8fc33f9 commit 4803f8c
Show file tree
Hide file tree
Showing 12 changed files with 482 additions and 291 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@noble/ed25519": "^2.1.0",
"@scure/bip39": "^1.2.2",
"@spacemesh/ed25519-bip32": "^0.2.1",
"@spacemesh/sm-codec": "^0.9.0-athena.3",
"@spacemesh/sm-codec": "0.9.0-athena.4",
"@tabler/icons-react": "^3.1.0",
"@tanstack/react-virtual": "^3.3.0",
"@uidotdev/usehooks": "^2.4.1",
Expand Down
2 changes: 1 addition & 1 deletion src/api/requests/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export const fetchTransactionsByAddress = async (
return txs.map((tx) => {
const templateAddress = toHexString(getWords(tx.template));
try {
const template = getTemplateMethod(templateAddress, tx.method);
const template = getTemplateMethod(templateAddress, String(tx.method));
const parsedRaw = template.decode(fromBase64(tx.raw));
const parsed =
tx.method === 0
Expand Down
4 changes: 2 additions & 2 deletions src/api/schemas/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { z } from 'zod';
import { Bech32Address } from '../../types/common';

import { Bech32AddressSchema } from './address';
import { Base64Schema } from './common';
import { Base64Schema, HexStringSchema } from './common';
import { BigIntStringSchema } from './strNumber';

// Common stuff
Expand Down Expand Up @@ -39,7 +39,7 @@ export const TransactionSchema = z.object({
type: TransactionTemplateMethodType,
principal: Bech32AddressSchema,
template: Bech32AddressSchema,
method: z.number(),
method: z.union([z.number(), HexStringSchema]),
nonce: NonceSchema,
maxGas: BigIntStringSchema,
gasPrice: BigIntStringSchema,
Expand Down
6 changes: 4 additions & 2 deletions src/components/PreviewDataRow.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { Box, Text, TextProps } from '@chakra-ui/react';
import { Box, BoxProps, Text, TextProps } from '@chakra-ui/react';

type PreviewDataRowProps = {
label: string;
value: string;
boxProps?: BoxProps;
labelProps?: TextProps;
valueProps?: TextProps;
};
function PreviewDataRow({
label,
value,
boxProps = {},
labelProps = {},
valueProps = {},
}: PreviewDataRowProps) {
return (
<Box mb={2}>
<Box mb={2} {...boxProps}>
<Text fontSize="xs" color="gray.400" {...labelProps}>
{label}
</Text>
Expand Down
18 changes: 9 additions & 9 deletions src/components/sendTx/ConfirmationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ type ConfirmationModalProps = ConfirmationData & {
const renderTemplateSpecificFields = (form: FormValues) => {
switch (form.templateAddress) {
case athenaSuffix(Athena.Wallet.TEMPLATE_PUBKEY_HEX): {
if (form.payload.methodSelector === MethodSelectors.Spawn) {
if (form.payload.methodSelector === MethodSelectors.Spawn.toString()) {
const args = AthenaWalletSpawnSchema.parse(form.payload);
return <PreviewDataRow label="Public key" value={args.PublicKey} />;
}
if (form.payload.methodSelector === MethodSelectors.Spend) {
if (form.payload.methodSelector === MethodSelectors.Spend.toString()) {
const args = SpendSchema.parse(form.payload);
return (
<>
Expand All @@ -108,11 +108,11 @@ const renderTemplateSpecificFields = (form: FormValues) => {
);
}
case StdPublicKeys.SingleSig: {
if (form.payload.methodSelector === MethodSelectors.Spawn) {
if (form.payload.methodSelector === MethodSelectors.Spawn.toString()) {
const args = SingleSigSpawnSchema.parse(form.payload);
return <PreviewDataRow label="Public key" value={args.PublicKey} />;
}
if (form.payload.methodSelector === MethodSelectors.Spend) {
if (form.payload.methodSelector === MethodSelectors.Spend.toString()) {
const args = SpendSchema.parse(form.payload);
return (
<>
Expand All @@ -133,7 +133,7 @@ const renderTemplateSpecificFields = (form: FormValues) => {
}
case StdPublicKeys.MultiSig:
case StdPublicKeys.Vesting: {
if (form.payload.methodSelector === MethodSelectors.Spawn) {
if (form.payload.methodSelector === MethodSelectors.Spawn.toString()) {
const args = MultiSigSpawnSchema.parse(form.payload);
return (
<>
Expand All @@ -147,7 +147,7 @@ const renderTemplateSpecificFields = (form: FormValues) => {
</>
);
}
if (form.payload.methodSelector === MethodSelectors.Spend) {
if (form.payload.methodSelector === MethodSelectors.Spend.toString()) {
const args = SpendSchema.parse(form.payload);
return (
<>
Expand All @@ -161,7 +161,7 @@ const renderTemplateSpecificFields = (form: FormValues) => {
}
if (
form.templateAddress === StdPublicKeys.Vesting &&
form.payload.methodSelector === MethodSelectors.Drain
form.payload.methodSelector === MethodSelectors.Drain.toString()
) {
const args = DrainSchema.parse(form.payload);
return (
Expand All @@ -183,7 +183,7 @@ const renderTemplateSpecificFields = (form: FormValues) => {
);
}
case StdPublicKeys.Vault: {
if (form.payload.methodSelector === MethodSelectors.Spawn) {
if (form.payload.methodSelector === MethodSelectors.Spawn.toString()) {
const args = VaultSpawnSchema.parse(form.payload);
return (
<>
Expand All @@ -207,7 +207,7 @@ const renderTemplateSpecificFields = (form: FormValues) => {
</>
);
}
if (form.payload.methodSelector === MethodSelectors.Spend) {
if (form.payload.methodSelector === MethodSelectors.Spend.toString()) {
const args = SpendSchema.parse(form.payload);
return (
<>
Expand Down
99 changes: 99 additions & 0 deletions src/components/sendTx/Deploy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { useEffect, useRef, useState } from 'react';
import {
UseFormRegister,
UseFormSetValue,
UseFormUnregister,
} from 'react-hook-form';

import { Button, FormControl, FormLabel, Input } from '@chakra-ui/react';

import { toHexString } from '../../utils/hexString';
import PreviewDataRow from '../PreviewDataRow';

import { FormValues } from './schemas';

type DeployProps = {
register: UseFormRegister<FormValues>;
unregister: UseFormUnregister<FormValues>;
setValue: UseFormSetValue<FormValues>;
};

function Deploy({ register, unregister, setValue }: DeployProps): JSX.Element {
const [program, setProgram] = useState('');
const fileRef = useRef<HTMLInputElement | null>(null);

useEffect(() => {
register('payload.program');
return () => {
unregister('payload.program');
};
}, [unregister, register]);

useEffect(() => {
if (program) {
setValue('payload.program', program);
}
}, [program, setValue, unregister]);

return (
<FormControl isRequired>
<FormLabel fontSize="sm" mb={1}>
Choose the compiled program to deploy a template:
</FormLabel>
<Button
w="100%"
variant="whiteModal"
onClick={() => {
if (fileRef.current) {
fileRef.current.click();
}
}}
>
Select .ELF file
</Button>
<Input
ref={fileRef}
type="file"
accept=".elf"
multiple={false}
display="none"
onChange={(evt) => {
if (evt.target.files?.[0]) {
const file = evt.target.files[0];
const reader = new FileReader();
reader.onloadend = () => {
if (!reader.result) return;
const content =
typeof reader.result === 'string'
? reader.result
: toHexString(reader.result);
setProgram(content);
// To allow load the same program again:
// eslint-disable-next-line no-param-reassign
evt.target.value = '';
};
reader.readAsArrayBuffer(file);
}
}}
/>
<PreviewDataRow
label="Program bytecode"
value={program}
boxProps={{
my: 2,
display: program ? 'block' : 'none',
}}
valueProps={{
as: 'pre',
fontSize: 'xx-small',
wordBreak: 'break-all',
whiteSpace: 'pre-wrap',
maxH: '100px',
overflowY: 'auto',
}}
/>
</FormControl>
);
}

export default Deploy;
Loading

0 comments on commit 4803f8c

Please sign in to comment.