Skip to content

Commit

Permalink
Merge pull request #94 from smartcontractkit/ggoh/DPA-1265/solana-cha…
Browse files Browse the repository at this point in the history
…in-config

[DPA-1265]: feat(chain-config): support  create solana config
  • Loading branch information
graham-chainlink authored Nov 14, 2024
2 parents 7c02aca + 22813fc commit ca7e4da
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 97 deletions.
5 changes: 5 additions & 0 deletions .changeset/flat-impalas-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@smartcontractkit/operator-ui': minor
---

Support creating solana chain config
157 changes: 117 additions & 40 deletions src/components/Form/ChainConfigurationForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ describe('ChainConfigurationForm', () => {
initialValues={initialValues}
onSubmit={handleSubmit}
accountsEVM={[]}
accountsAptos={[]}
chains={[]}
p2pKeys={[]}
ocrKeys={[]}
Expand Down Expand Up @@ -46,7 +45,6 @@ describe('ChainConfigurationForm', () => {
initialValues={initialValues}
onSubmit={handleSubmit}
accountsEVM={[]}
accountsAptos={[]}
chains={[]}
p2pKeys={[]}
ocrKeys={[]}
Expand Down Expand Up @@ -85,7 +83,6 @@ describe('ChainConfigurationForm', () => {
initialValues={initialValues}
onSubmit={handleSubmit}
accountsEVM={[]}
accountsAptos={[]}
chains={[]}
p2pKeys={[]}
ocrKeys={[]}
Expand Down Expand Up @@ -125,43 +122,9 @@ describe('ChainConfigurationForm', () => {
initialValues.chainType = ChainTypes.EVM
initialValues.adminAddr = '0x1234567'

const { container } = render(
<ChainConfigurationForm
initialValues={initialValues}
onSubmit={(x, _) => handleSubmit(x)}
accountsEVM={[
{
address: '0x1111',
chain: {
id: '1111',
},
createdAt: '2021-10-06T00:00:00Z',
isDisabled: false,
},
]}
accountsAptos={[
{
account: '0x123',
id: '2222',
},
]}
chains={[
{
id: '1111',
enabled: true,
network: 'evm',
},
{
id: '2222',
enabled: true,
network: 'aptos',
},
]}
p2pKeys={[]}
ocrKeys={[]}
ocr2Keys={[]}
showSubmit
/>,
const { container } = renderChainConfigurationForm(
initialValues,
handleSubmit,
)

const chainType = getByRole('button', { name: 'EVM' })
Expand Down Expand Up @@ -217,6 +180,69 @@ describe('ChainConfigurationForm', () => {
})
})

test('should able to create Solana chain config', async () => {
const handleSubmit = jest.fn()
const initialValues = emptyFormValues()
initialValues.chainType = ChainTypes.EVM
initialValues.adminAddr = '0x1234567'

const { container } = renderChainConfigurationForm(
initialValues,
handleSubmit,
)

const chainType = getByRole('button', { name: 'EVM' })
userEvent.click(chainType)
userEvent.click(getByRole('option', { name: 'SOLANA' }))
await screen.findByRole('button', { name: 'SOLANA' })

// no easy way to use react testing framework to do what i want,
// had to resort to using #id and querySelector
// formik does not seem to work well with react testing framework
const chainId = container.querySelector('#select-chainID')
expect(chainId).toBeInTheDocument()
// workaround ts lint warning - unable to use chainId!
chainId && userEvent.click(chainId)
userEvent.click(getByRole('option', { name: '3333' }))
await screen.findByRole('button', { name: '3333' })

const address = container.querySelector('#select-accountAddr')
expect(address).toBeInTheDocument()
address && userEvent.click(address)
userEvent.click(getByRole('option', { name: 'solana_xxxx' }))
await screen.findByRole('button', { name: 'solana_xxxx' })

await userEvent.click(getByRole('button', { name: /submit/i }))

await waitFor(() => {
expect(handleSubmit).toHaveBeenCalledWith({
accountAddr: 'solana_xxxx',
accountAddrPubKey: '',
adminAddr: '0x1234567',
chainID: '3333',
chainType: 'SOLANA',
fluxMonitorEnabled: false,
ocr1Enabled: false,
ocr1IsBootstrap: false,
ocr1KeyBundleID: '',
ocr1Multiaddr: '',
ocr1P2PPeerID: '',
ocr2CommitPluginEnabled: false,
ocr2Enabled: false,
ocr2ExecutePluginEnabled: false,
ocr2ForwarderAddress: '',
ocr2IsBootstrap: false,
ocr2KeyBundleID: '',
ocr2MedianPluginEnabled: false,
ocr2MercuryPluginEnabled: false,
ocr2Multiaddr: '',
ocr2P2PPeerID: '',
ocr2RebalancerPluginEnabled: false,
})
expect(handleSubmit).toHaveBeenCalledTimes(1)
})
})

function emptyFormValues(): FormValues {
return {
chainID: '',
Expand All @@ -243,3 +269,54 @@ function emptyFormValues(): FormValues {
ocr2ForwarderAddress: '',
}
}

function renderChainConfigurationForm(
initialValues: FormValues,
onSubmit: (x: FormValues) => void,
) {
return render(
<ChainConfigurationForm
initialValues={initialValues}
onSubmit={(x, _) => onSubmit(x)}
accountsEVM={[
{
address: '0x1111',
chain: {
id: '1111',
},
createdAt: '2021-10-06T00:00:00Z',
isDisabled: false,
},
]}
accountsNonEvm={{
aptosKeys: {
results: [{ account: '0x123', id: '2222' }],
},
solanaKeys: {
results: [{ id: 'solana_xxxx' }],
},
}}
chains={[
{
id: '1111',
enabled: true,
network: 'evm',
},
{
id: '2222',
enabled: true,
network: 'aptos',
},
{
id: '3333',
enabled: true,
network: 'solana',
},
]}
p2pKeys={[]}
ocrKeys={[]}
ocr2Keys={[]}
showSubmit
/>,
)
}
36 changes: 24 additions & 12 deletions src/components/Form/ChainConfigurationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export interface Props extends WithStyles<typeof styles> {
) => void | Promise<any>
chains: ReadonlyArray<ChainsPayload_ResultsFields>
accountsEVM: ReadonlyArray<EthKeysPayload_ResultsFields>
accountsAptos: ReadonlyArray<AptosKeysPayload_ResultsFields>
accountsNonEvm?: FetchNonEvmKeys
p2pKeys: ReadonlyArray<P2PKeysPayload_ResultsFields>
ocrKeys: ReadonlyArray<OcrKeyBundlesPayload_ResultsFields>
ocr2Keys: ReadonlyArray<Ocr2KeyBundlesPayload_ResultsFields>
Expand All @@ -222,7 +222,7 @@ export const ChainConfigurationForm = withStyles(styles)(
onSubmit,
chains = [],
accountsEVM = [],
accountsAptos = [],
accountsNonEvm,
p2pKeys = [],
ocrKeys = [],
ocr2Keys = [],
Expand All @@ -237,17 +237,26 @@ export const ChainConfigurationForm = withStyles(styles)(
>
{({ values }) => {
let chainAccountAddresses: string[] = []
if (values.chainType === ChainTypes.EVM) {
chainAccountAddresses = accountsEVM
.filter(
(acc) => acc.chain.id == values.chainID && !acc.isDisabled,
)
.map((acc) => acc.address)
switch (values.chainType) {
case ChainTypes.EVM:
chainAccountAddresses = accountsEVM
.filter(
(acc) => acc.chain.id == values.chainID && !acc.isDisabled,
)
.map((acc) => acc.address)
break
case ChainTypes.APTOS:
chainAccountAddresses =
accountsNonEvm?.aptosKeys.results.map((acc) => acc.account) ??
[]
break
case ChainTypes.SOLANA:
chainAccountAddresses =
accountsNonEvm?.solanaKeys.results.map((acc) => acc.id) ?? []
break
default:
chainAccountAddresses = []
}
if (values.chainType === ChainTypes.APTOS) {
chainAccountAddresses = accountsAptos.map((acc) => acc.account)
}

return (
<Form
data-testid="feeds-manager-form"
Expand All @@ -273,6 +282,9 @@ export const ChainConfigurationForm = withStyles(styles)(
<MenuItem key={ChainTypes.APTOS} value={ChainTypes.APTOS}>
APTOS
</MenuItem>
<MenuItem key={ChainTypes.SOLANA} value={ChainTypes.SOLANA}>
SOLANA
</MenuItem>
</Field>
</Grid>

Expand Down
24 changes: 0 additions & 24 deletions src/hooks/queries/useAptosAccountsQuery.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react'
import { render, screen, waitFor } from '@testing-library/react'
import { MockedProvider } from '@apollo/client/testing'
import {
useAptosAccountsQuery,
APTOS_KEYS_QUERY,
} from './useAptosAccountsQuery'
useNonEvmAccountsQuery,
NON_EVM_KEYS_QUERY,
} from './useNonEvmAccountsQuery'

const mockData = {
data: {
Expand All @@ -15,20 +15,24 @@ const mockData = {
{ __typename: 'AptosKey', account: 'account2', id: '2' },
],
},
solanaKeys: {
__typename: 'SolanaKeys',
results: [{ __typename: 'SolanaKey', id: '3' }],
},
},
}

const mocks = [
{
request: {
query: APTOS_KEYS_QUERY,
query: NON_EVM_KEYS_QUERY,
},
result: mockData,
},
]

const TestComponent: React.FC = () => {
const { data, loading, error } = useAptosAccountsQuery()
const { data, loading, error } = useNonEvmAccountsQuery()

if (loading) return <p>Loading... </p>
if (error) return <p>Error: {error.message}</p>
Expand All @@ -38,14 +42,20 @@ const TestComponent: React.FC = () => {
{data?.aptosKeys.results.map((key, i) => (
<div key={i}>
<p>Account: {key.account}</p>
<p>ID: {key.id}</p>
<p>Aptos ID: {key.id}</p>
</div>
))}

{data?.solanaKeys.results.map((key, i) => (
<div key={i}>
<p>Solana ID: {key.id}</p>
</div>
))}
</div>
)
}

describe('useAptosAccountsQuery', () => {
describe('useNonEvmAccountsQuery', () => {
test('renders data with correct graphql query', async () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
Expand All @@ -55,9 +65,11 @@ describe('useAptosAccountsQuery', () => {

await waitFor(() => {
expect(screen.getByText('Account: account1')).toBeInTheDocument()
expect(screen.getByText('ID: 1')).toBeInTheDocument()
expect(screen.getByText('Aptos ID: 1')).toBeInTheDocument()
expect(screen.getByText('Account: account2')).toBeInTheDocument()
expect(screen.getByText('ID: 2')).toBeInTheDocument()
expect(screen.getByText('Aptos ID: 2')).toBeInTheDocument()

expect(screen.getByText('Solana ID: 3')).toBeInTheDocument()
})
})
})
Loading

0 comments on commit ca7e4da

Please sign in to comment.