From d36d048199918884e8168f454f577fb48845afef Mon Sep 17 00:00:00 2001 From: Nicko Guyer Date: Mon, 16 Jan 2023 13:58:31 -0500 Subject: [PATCH 1/3] Add contract interface dropdown to token pool creation Signed-off-by: Nicko Guyer --- server/src/controllers/tokens.ts | 8 ++- server/src/interfaces.ts | 4 ++ ui/src/components/Forms/Tokens/PoolForm.tsx | 69 ++++++++++++++++++++- ui/src/translations/en.json | 3 +- 4 files changed, 81 insertions(+), 3 deletions(-) diff --git a/server/src/controllers/tokens.ts b/server/src/controllers/tokens.ts index 3f2e9e2..12a6524 100644 --- a/server/src/controllers/tokens.ts +++ b/server/src/controllers/tokens.ts @@ -74,6 +74,9 @@ export class TokensController { name: body.name, symbol: body.symbol, type: body.type, + interface: { + id: body.contractInterface, + }, config: { address: body.address, blockNumber: body.blockNumber, @@ -285,7 +288,10 @@ export class TokensTemplateController { return formatTemplate(` const pool = await firefly.createTokenPool({ name: <%= ${q('name')} %>,<% if (symbol) { %> - <% print('symbol: ' + ${q('symbol')} + ',') } %> + <% print('symbol: ' + ${q('symbol')} + ',') } %><% if (contractInterface) { %> + interface: { + id: <%= ${q('contractInterface')} %> + },<% } %> type: <%= ${q('type')} %>, config: {<% if (address) { %> <% print('address: ' + ${q('address')} + ',') } %> diff --git a/server/src/interfaces.ts b/server/src/interfaces.ts index b9fd3ad..04582e0 100644 --- a/server/src/interfaces.ts +++ b/server/src/interfaces.ts @@ -146,6 +146,10 @@ export class TokenPoolInput { @IsOptional() config?: TokenConfig; + @IsString() + @IsOptional() + contractInterface?: string; + @IsString() @IsOptional() address?: string; diff --git a/ui/src/components/Forms/Tokens/PoolForm.tsx b/ui/src/components/Forms/Tokens/PoolForm.tsx index f052239..0807264 100644 --- a/ui/src/components/Forms/Tokens/PoolForm.tsx +++ b/ui/src/components/Forms/Tokens/PoolForm.tsx @@ -1,5 +1,6 @@ import { FormControl, + FormHelperText, Grid, InputLabel, MenuItem, @@ -8,10 +9,14 @@ import { } from '@mui/material'; import React, { useContext, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { SDK_PATHS } from '../../../constants/SDK_PATHS'; import { TUTORIAL_FORMS } from '../../../constants/TutorialSections'; import { ApplicationContext } from '../../../contexts/ApplicationContext'; import { FormContext } from '../../../contexts/FormContext'; +import { SnackbarContext } from '../../../contexts/SnackbarContext'; +import { IContractInterface } from '../../../interfaces/api'; import { DEFAULT_SPACING } from '../../../theme'; +import { fetchCatcher } from '../../../utils/fetches'; export const PoolForm: React.FC = () => { const { t } = useTranslation(); @@ -23,6 +28,19 @@ export const PoolForm: React.FC = () => { const [address, setAddress] = useState(); const [blockNumber, setBlockNumber] = useState('0'); const [type, setType] = useState<'fungible' | 'nonfungible'>('fungible'); + const { reportFetchError } = useContext(SnackbarContext); + const [contractInterfaces, setContractInterfaces] = useState< + IContractInterface[] + >([]); + const [selectedContractInterface, setSelectedContractInterface] = + useState('automatic'); + const [isMounted, setIsMounted] = useState(false); + useEffect(() => { + setIsMounted(true); + return () => { + setIsMounted(false); + }; + }, []); useEffect(() => { if (formID !== TUTORIAL_FORMS.POOL) { @@ -36,10 +54,35 @@ export const PoolForm: React.FC = () => { name, symbol: symbol === '' ? null : symbol, type, + contractInterface: + selectedContractInterface === 'automatic' + ? null + : selectedContractInterface, address, blockNumber, }); - }, [name, symbol, type, address, formID, blockNumber]); + }, [ + name, + symbol, + type, + address, + formID, + blockNumber, + selectedContractInterface, + ]); + + useEffect(() => { + isMounted && + fetchCatcher(`${SDK_PATHS.contractsInterface}`) + .then((apiRes: IContractInterface[]) => { + if (isMounted) { + setContractInterfaces(apiRes); + } + }) + .catch((err) => { + reportFetchError(err); + }); + }, [formID, isMounted]); const handleNameChange = (event: React.ChangeEvent) => { if (event.target.value.indexOf(' ') < 0) { @@ -103,6 +146,30 @@ export const PoolForm: React.FC = () => { + + + + {t('contractInterface')} + + + {t('tokenPoolContractInterfaceHelperText')} + + + + Date: Mon, 16 Jan 2023 14:41:32 -0500 Subject: [PATCH 2/3] Update tests for token contract interface Signed-off-by: Nicko Guyer --- server/test/tokens.template.test.ts | 4 ++++ server/test/tokens.test.ts | 1 + 2 files changed, 5 insertions(+) diff --git a/server/test/tokens.template.test.ts b/server/test/tokens.template.test.ts index 45775ce..00b75ee 100644 --- a/server/test/tokens.template.test.ts +++ b/server/test/tokens.template.test.ts @@ -15,6 +15,7 @@ describe('Templates: Tokens', () => { name: 'pool1', symbol: 'P1', type: 'fungible', + contractInterface: 'abcd', address: undefined, blockNumber: '0', }), @@ -23,6 +24,9 @@ describe('Templates: Tokens', () => { const pool = await firefly.createTokenPool({ name: 'pool1', symbol: 'P1', + interface: { + id: 'abcd' + }, type: 'fungible', config: { blockNumber: '0', diff --git a/server/test/tokens.test.ts b/server/test/tokens.test.ts index 09f86c1..e38eefd 100644 --- a/server/test/tokens.test.ts +++ b/server/test/tokens.test.ts @@ -58,6 +58,7 @@ describe('Tokens', () => { symbol: 'P1', type: 'fungible', config: {}, + interface: {}, }); }); From b4de79bc0f07b890f6c1794d41800dc23b76ac07 Mon Sep 17 00:00:00 2001 From: Nicko Guyer Date: Mon, 16 Jan 2023 14:48:34 -0500 Subject: [PATCH 3/3] Fix React warnings Signed-off-by: Nicko Guyer --- ui/src/components/Forms/Tokens/PoolForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/components/Forms/Tokens/PoolForm.tsx b/ui/src/components/Forms/Tokens/PoolForm.tsx index 0807264..7183557 100644 --- a/ui/src/components/Forms/Tokens/PoolForm.tsx +++ b/ui/src/components/Forms/Tokens/PoolForm.tsx @@ -158,7 +158,7 @@ export const PoolForm: React.FC = () => { {t('Automatic')} {contractInterfaces.map((contractInterface, i) => { return ( - + {contractInterface.name} - {contractInterface.version} );