Skip to content

Commit ca7e4da

Browse files
Merge pull request #94 from smartcontractkit/ggoh/DPA-1265/solana-chain-config
[DPA-1265]: feat(chain-config): support create solana config
2 parents 7c02aca + 22813fc commit ca7e4da

File tree

8 files changed

+209
-97
lines changed

8 files changed

+209
-97
lines changed

.changeset/flat-impalas-peel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@smartcontractkit/operator-ui': minor
3+
---
4+
5+
Support creating solana chain config

src/components/Form/ChainConfigurationForm.test.tsx

Lines changed: 117 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ describe('ChainConfigurationForm', () => {
1818
initialValues={initialValues}
1919
onSubmit={handleSubmit}
2020
accountsEVM={[]}
21-
accountsAptos={[]}
2221
chains={[]}
2322
p2pKeys={[]}
2423
ocrKeys={[]}
@@ -46,7 +45,6 @@ describe('ChainConfigurationForm', () => {
4645
initialValues={initialValues}
4746
onSubmit={handleSubmit}
4847
accountsEVM={[]}
49-
accountsAptos={[]}
5048
chains={[]}
5149
p2pKeys={[]}
5250
ocrKeys={[]}
@@ -85,7 +83,6 @@ describe('ChainConfigurationForm', () => {
8583
initialValues={initialValues}
8684
onSubmit={handleSubmit}
8785
accountsEVM={[]}
88-
accountsAptos={[]}
8986
chains={[]}
9087
p2pKeys={[]}
9188
ocrKeys={[]}
@@ -125,43 +122,9 @@ describe('ChainConfigurationForm', () => {
125122
initialValues.chainType = ChainTypes.EVM
126123
initialValues.adminAddr = '0x1234567'
127124

128-
const { container } = render(
129-
<ChainConfigurationForm
130-
initialValues={initialValues}
131-
onSubmit={(x, _) => handleSubmit(x)}
132-
accountsEVM={[
133-
{
134-
address: '0x1111',
135-
chain: {
136-
id: '1111',
137-
},
138-
createdAt: '2021-10-06T00:00:00Z',
139-
isDisabled: false,
140-
},
141-
]}
142-
accountsAptos={[
143-
{
144-
account: '0x123',
145-
id: '2222',
146-
},
147-
]}
148-
chains={[
149-
{
150-
id: '1111',
151-
enabled: true,
152-
network: 'evm',
153-
},
154-
{
155-
id: '2222',
156-
enabled: true,
157-
network: 'aptos',
158-
},
159-
]}
160-
p2pKeys={[]}
161-
ocrKeys={[]}
162-
ocr2Keys={[]}
163-
showSubmit
164-
/>,
125+
const { container } = renderChainConfigurationForm(
126+
initialValues,
127+
handleSubmit,
165128
)
166129

167130
const chainType = getByRole('button', { name: 'EVM' })
@@ -217,6 +180,69 @@ describe('ChainConfigurationForm', () => {
217180
})
218181
})
219182

183+
test('should able to create Solana chain config', async () => {
184+
const handleSubmit = jest.fn()
185+
const initialValues = emptyFormValues()
186+
initialValues.chainType = ChainTypes.EVM
187+
initialValues.adminAddr = '0x1234567'
188+
189+
const { container } = renderChainConfigurationForm(
190+
initialValues,
191+
handleSubmit,
192+
)
193+
194+
const chainType = getByRole('button', { name: 'EVM' })
195+
userEvent.click(chainType)
196+
userEvent.click(getByRole('option', { name: 'SOLANA' }))
197+
await screen.findByRole('button', { name: 'SOLANA' })
198+
199+
// no easy way to use react testing framework to do what i want,
200+
// had to resort to using #id and querySelector
201+
// formik does not seem to work well with react testing framework
202+
const chainId = container.querySelector('#select-chainID')
203+
expect(chainId).toBeInTheDocument()
204+
// workaround ts lint warning - unable to use chainId!
205+
chainId && userEvent.click(chainId)
206+
userEvent.click(getByRole('option', { name: '3333' }))
207+
await screen.findByRole('button', { name: '3333' })
208+
209+
const address = container.querySelector('#select-accountAddr')
210+
expect(address).toBeInTheDocument()
211+
address && userEvent.click(address)
212+
userEvent.click(getByRole('option', { name: 'solana_xxxx' }))
213+
await screen.findByRole('button', { name: 'solana_xxxx' })
214+
215+
await userEvent.click(getByRole('button', { name: /submit/i }))
216+
217+
await waitFor(() => {
218+
expect(handleSubmit).toHaveBeenCalledWith({
219+
accountAddr: 'solana_xxxx',
220+
accountAddrPubKey: '',
221+
adminAddr: '0x1234567',
222+
chainID: '3333',
223+
chainType: 'SOLANA',
224+
fluxMonitorEnabled: false,
225+
ocr1Enabled: false,
226+
ocr1IsBootstrap: false,
227+
ocr1KeyBundleID: '',
228+
ocr1Multiaddr: '',
229+
ocr1P2PPeerID: '',
230+
ocr2CommitPluginEnabled: false,
231+
ocr2Enabled: false,
232+
ocr2ExecutePluginEnabled: false,
233+
ocr2ForwarderAddress: '',
234+
ocr2IsBootstrap: false,
235+
ocr2KeyBundleID: '',
236+
ocr2MedianPluginEnabled: false,
237+
ocr2MercuryPluginEnabled: false,
238+
ocr2Multiaddr: '',
239+
ocr2P2PPeerID: '',
240+
ocr2RebalancerPluginEnabled: false,
241+
})
242+
expect(handleSubmit).toHaveBeenCalledTimes(1)
243+
})
244+
})
245+
220246
function emptyFormValues(): FormValues {
221247
return {
222248
chainID: '',
@@ -243,3 +269,54 @@ function emptyFormValues(): FormValues {
243269
ocr2ForwarderAddress: '',
244270
}
245271
}
272+
273+
function renderChainConfigurationForm(
274+
initialValues: FormValues,
275+
onSubmit: (x: FormValues) => void,
276+
) {
277+
return render(
278+
<ChainConfigurationForm
279+
initialValues={initialValues}
280+
onSubmit={(x, _) => onSubmit(x)}
281+
accountsEVM={[
282+
{
283+
address: '0x1111',
284+
chain: {
285+
id: '1111',
286+
},
287+
createdAt: '2021-10-06T00:00:00Z',
288+
isDisabled: false,
289+
},
290+
]}
291+
accountsNonEvm={{
292+
aptosKeys: {
293+
results: [{ account: '0x123', id: '2222' }],
294+
},
295+
solanaKeys: {
296+
results: [{ id: 'solana_xxxx' }],
297+
},
298+
}}
299+
chains={[
300+
{
301+
id: '1111',
302+
enabled: true,
303+
network: 'evm',
304+
},
305+
{
306+
id: '2222',
307+
enabled: true,
308+
network: 'aptos',
309+
},
310+
{
311+
id: '3333',
312+
enabled: true,
313+
network: 'solana',
314+
},
315+
]}
316+
p2pKeys={[]}
317+
ocrKeys={[]}
318+
ocr2Keys={[]}
319+
showSubmit
320+
/>,
321+
)
322+
}

src/components/Form/ChainConfigurationForm.tsx

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export interface Props extends WithStyles<typeof styles> {
204204
) => void | Promise<any>
205205
chains: ReadonlyArray<ChainsPayload_ResultsFields>
206206
accountsEVM: ReadonlyArray<EthKeysPayload_ResultsFields>
207-
accountsAptos: ReadonlyArray<AptosKeysPayload_ResultsFields>
207+
accountsNonEvm?: FetchNonEvmKeys
208208
p2pKeys: ReadonlyArray<P2PKeysPayload_ResultsFields>
209209
ocrKeys: ReadonlyArray<OcrKeyBundlesPayload_ResultsFields>
210210
ocr2Keys: ReadonlyArray<Ocr2KeyBundlesPayload_ResultsFields>
@@ -222,7 +222,7 @@ export const ChainConfigurationForm = withStyles(styles)(
222222
onSubmit,
223223
chains = [],
224224
accountsEVM = [],
225-
accountsAptos = [],
225+
accountsNonEvm,
226226
p2pKeys = [],
227227
ocrKeys = [],
228228
ocr2Keys = [],
@@ -237,17 +237,26 @@ export const ChainConfigurationForm = withStyles(styles)(
237237
>
238238
{({ values }) => {
239239
let chainAccountAddresses: string[] = []
240-
if (values.chainType === ChainTypes.EVM) {
241-
chainAccountAddresses = accountsEVM
242-
.filter(
243-
(acc) => acc.chain.id == values.chainID && !acc.isDisabled,
244-
)
245-
.map((acc) => acc.address)
240+
switch (values.chainType) {
241+
case ChainTypes.EVM:
242+
chainAccountAddresses = accountsEVM
243+
.filter(
244+
(acc) => acc.chain.id == values.chainID && !acc.isDisabled,
245+
)
246+
.map((acc) => acc.address)
247+
break
248+
case ChainTypes.APTOS:
249+
chainAccountAddresses =
250+
accountsNonEvm?.aptosKeys.results.map((acc) => acc.account) ??
251+
[]
252+
break
253+
case ChainTypes.SOLANA:
254+
chainAccountAddresses =
255+
accountsNonEvm?.solanaKeys.results.map((acc) => acc.id) ?? []
256+
break
257+
default:
258+
chainAccountAddresses = []
246259
}
247-
if (values.chainType === ChainTypes.APTOS) {
248-
chainAccountAddresses = accountsAptos.map((acc) => acc.account)
249-
}
250-
251260
return (
252261
<Form
253262
data-testid="feeds-manager-form"
@@ -273,6 +282,9 @@ export const ChainConfigurationForm = withStyles(styles)(
273282
<MenuItem key={ChainTypes.APTOS} value={ChainTypes.APTOS}>
274283
APTOS
275284
</MenuItem>
285+
<MenuItem key={ChainTypes.SOLANA} value={ChainTypes.SOLANA}>
286+
SOLANA
287+
</MenuItem>
276288
</Field>
277289
</Grid>
278290

src/hooks/queries/useAptosAccountsQuery.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/hooks/queries/useAptosAccountsQuery.test.tsx renamed to src/hooks/queries/useNonEvmAccountsQuery.test.tsx

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import React from 'react'
22
import { render, screen, waitFor } from '@testing-library/react'
33
import { MockedProvider } from '@apollo/client/testing'
44
import {
5-
useAptosAccountsQuery,
6-
APTOS_KEYS_QUERY,
7-
} from './useAptosAccountsQuery'
5+
useNonEvmAccountsQuery,
6+
NON_EVM_KEYS_QUERY,
7+
} from './useNonEvmAccountsQuery'
88

99
const mockData = {
1010
data: {
@@ -15,20 +15,24 @@ const mockData = {
1515
{ __typename: 'AptosKey', account: 'account2', id: '2' },
1616
],
1717
},
18+
solanaKeys: {
19+
__typename: 'SolanaKeys',
20+
results: [{ __typename: 'SolanaKey', id: '3' }],
21+
},
1822
},
1923
}
2024

2125
const mocks = [
2226
{
2327
request: {
24-
query: APTOS_KEYS_QUERY,
28+
query: NON_EVM_KEYS_QUERY,
2529
},
2630
result: mockData,
2731
},
2832
]
2933

3034
const TestComponent: React.FC = () => {
31-
const { data, loading, error } = useAptosAccountsQuery()
35+
const { data, loading, error } = useNonEvmAccountsQuery()
3236

3337
if (loading) return <p>Loading... </p>
3438
if (error) return <p>Error: {error.message}</p>
@@ -38,14 +42,20 @@ const TestComponent: React.FC = () => {
3842
{data?.aptosKeys.results.map((key, i) => (
3943
<div key={i}>
4044
<p>Account: {key.account}</p>
41-
<p>ID: {key.id}</p>
45+
<p>Aptos ID: {key.id}</p>
46+
</div>
47+
))}
48+
49+
{data?.solanaKeys.results.map((key, i) => (
50+
<div key={i}>
51+
<p>Solana ID: {key.id}</p>
4252
</div>
4353
))}
4454
</div>
4555
)
4656
}
4757

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

5666
await waitFor(() => {
5767
expect(screen.getByText('Account: account1')).toBeInTheDocument()
58-
expect(screen.getByText('ID: 1')).toBeInTheDocument()
68+
expect(screen.getByText('Aptos ID: 1')).toBeInTheDocument()
5969
expect(screen.getByText('Account: account2')).toBeInTheDocument()
60-
expect(screen.getByText('ID: 2')).toBeInTheDocument()
70+
expect(screen.getByText('Aptos ID: 2')).toBeInTheDocument()
71+
72+
expect(screen.getByText('Solana ID: 3')).toBeInTheDocument()
6173
})
6274
})
6375
})

0 commit comments

Comments
 (0)