@@ -3,8 +3,18 @@ import type { HederaMirrornodeService } from '@/core/services/mirrornode/hedera-
33import type { NetworkService } from '@/core/services/network/network-service.interface' ;
44
55import {
6+ ECDSA_DER_PUBLIC_KEY ,
7+ ECDSA_HEX_PUBLIC_KEY ,
8+ ED25519_DER_PUBLIC_KEY ,
9+ ED25519_HEX_PUBLIC_KEY ,
10+ MOCK_TOPIC_ADMIN_KEY_REF_ID ,
11+ MOCK_TOPIC_SUBMIT_KEY_REF_ID ,
12+ } from '@/__tests__/mocks/fixtures' ;
13+ import {
14+ createMockKmsRecord ,
615 makeAliasMock ,
716 makeArgs ,
17+ makeKmsMock ,
818 makeLogger ,
919 makeMirrorMock ,
1020 makeNetworkMock ,
@@ -144,6 +154,167 @@ describe('topic plugin - import command (ADR-007)', () => {
144154 expect ( output . name ) . toBe ( undefined ) ;
145155 } ) ;
146156
157+ test ( 'imports topic with admin_key and submit_key matched in KMS' , async ( ) => {
158+ const logger = makeLogger ( ) ;
159+ const saveTopicMock = jest . fn ( ) . mockReturnValue ( undefined ) ;
160+
161+ MockedHelper . mockImplementation ( ( ) => ( {
162+ loadTopic : jest . fn ( ) . mockReturnValue ( null ) ,
163+ saveTopic : saveTopicMock ,
164+ } ) ) ;
165+
166+ const topicInfo = createMockTopicInfo ( {
167+ topic_id : '0.0.123456' ,
168+ memo : 'Topic with keys' ,
169+ created_timestamp : '1704067200.000000000' ,
170+ admin_key : { _type : 'ED25519' , key : ED25519_DER_PUBLIC_KEY } ,
171+ submit_key : { _type : 'ECDSA_SECP256K1' , key : ECDSA_DER_PUBLIC_KEY } ,
172+ } ) ;
173+
174+ const mirrorMock = makeMirrorMock ( ) as Partial < HederaMirrornodeService > & {
175+ getTopicInfo : jest . Mock ;
176+ } ;
177+ mirrorMock . getTopicInfo = jest . fn ( ) . mockResolvedValue ( topicInfo ) ;
178+
179+ const kms = makeKmsMock ( ) ;
180+ kms . findByPublicKey . mockImplementation ( ( publicKey : string ) => {
181+ if ( publicKey === ED25519_HEX_PUBLIC_KEY )
182+ return createMockKmsRecord ( MOCK_TOPIC_ADMIN_KEY_REF_ID , publicKey ) ;
183+ if ( publicKey === ECDSA_HEX_PUBLIC_KEY )
184+ return createMockKmsRecord ( MOCK_TOPIC_SUBMIT_KEY_REF_ID , publicKey ) ;
185+ return undefined ;
186+ } ) ;
187+
188+ const api : Partial < CoreApi > = {
189+ mirror : mirrorMock as HederaMirrornodeService ,
190+ network : makeNetworkMock ( SupportedNetwork . TESTNET ) as NetworkService ,
191+ alias : makeAliasMock ( ) ,
192+ logger,
193+ state : makeStateMock ( ) ,
194+ kms,
195+ } ;
196+
197+ const args = makeArgs ( api , logger , { topic : '0.0.123456' } ) ;
198+
199+ const result = await topicImport ( args ) ;
200+
201+ expect ( saveTopicMock ) . toHaveBeenCalledWith (
202+ `${ SupportedNetwork . TESTNET } :0.0.123456` ,
203+ expect . objectContaining ( {
204+ topicId : '0.0.123456' ,
205+ adminKeyRefIds : [ MOCK_TOPIC_ADMIN_KEY_REF_ID ] ,
206+ submitKeyRefIds : [ MOCK_TOPIC_SUBMIT_KEY_REF_ID ] ,
207+ } ) ,
208+ ) ;
209+
210+ const output = assertOutput ( result . result , TopicImportOutputSchema ) ;
211+ expect ( output . adminKeyPresent ) . toBe ( true ) ;
212+ expect ( output . submitKeyPresent ) . toBe ( true ) ;
213+ expect ( output . adminKeysMatched ) . toBe ( 1 ) ;
214+ expect ( output . submitKeysMatched ) . toBe ( 1 ) ;
215+ } ) ;
216+
217+ test ( 'imports topic with admin_key when key is not in KMS' , async ( ) => {
218+ const logger = makeLogger ( ) ;
219+ const saveTopicMock = jest . fn ( ) . mockReturnValue ( undefined ) ;
220+
221+ MockedHelper . mockImplementation ( ( ) => ( {
222+ loadTopic : jest . fn ( ) . mockReturnValue ( null ) ,
223+ saveTopic : saveTopicMock ,
224+ } ) ) ;
225+
226+ const topicInfo = createMockTopicInfo ( {
227+ topic_id : '0.0.123456' ,
228+ created_timestamp : '1704067200.000000000' ,
229+ admin_key : { _type : 'ED25519' , key : ED25519_DER_PUBLIC_KEY } ,
230+ } ) ;
231+
232+ const mirrorMock = makeMirrorMock ( ) as Partial < HederaMirrornodeService > & {
233+ getTopicInfo : jest . Mock ;
234+ } ;
235+ mirrorMock . getTopicInfo = jest . fn ( ) . mockResolvedValue ( topicInfo ) ;
236+
237+ const kms = makeKmsMock ( ) ;
238+ kms . findByPublicKey . mockReturnValue ( undefined ) ;
239+
240+ const api : Partial < CoreApi > = {
241+ mirror : mirrorMock as HederaMirrornodeService ,
242+ network : makeNetworkMock ( SupportedNetwork . TESTNET ) as NetworkService ,
243+ alias : makeAliasMock ( ) ,
244+ logger,
245+ state : makeStateMock ( ) ,
246+ kms,
247+ } ;
248+
249+ const args = makeArgs ( api , logger , { topic : '0.0.123456' } ) ;
250+
251+ const result = await topicImport ( args ) ;
252+
253+ expect ( saveTopicMock ) . toHaveBeenCalledWith (
254+ `${ SupportedNetwork . TESTNET } :0.0.123456` ,
255+ expect . objectContaining ( {
256+ topicId : '0.0.123456' ,
257+ adminKeyRefIds : undefined ,
258+ } ) ,
259+ ) ;
260+
261+ const output = assertOutput ( result . result , TopicImportOutputSchema ) ;
262+ expect ( output . adminKeyPresent ) . toBe ( true ) ;
263+ expect ( output . adminKeysMatched ) . toBe ( 0 ) ;
264+ } ) ;
265+
266+ test ( 'imports topic with submit_key when key is in KMS' , async ( ) => {
267+ const logger = makeLogger ( ) ;
268+ const saveTopicMock = jest . fn ( ) . mockReturnValue ( undefined ) ;
269+
270+ MockedHelper . mockImplementation ( ( ) => ( {
271+ loadTopic : jest . fn ( ) . mockReturnValue ( null ) ,
272+ saveTopic : saveTopicMock ,
273+ } ) ) ;
274+
275+ const topicInfo = createMockTopicInfo ( {
276+ topic_id : '0.0.123456' ,
277+ created_timestamp : '1704067200.000000000' ,
278+ submit_key : { _type : 'ED25519' , key : ED25519_DER_PUBLIC_KEY } ,
279+ } ) ;
280+
281+ const mirrorMock = makeMirrorMock ( ) as Partial < HederaMirrornodeService > & {
282+ getTopicInfo : jest . Mock ;
283+ } ;
284+ mirrorMock . getTopicInfo = jest . fn ( ) . mockResolvedValue ( topicInfo ) ;
285+
286+ const kms = makeKmsMock ( ) ;
287+ kms . findByPublicKey . mockImplementation ( ( publicKey : string ) =>
288+ publicKey === ED25519_HEX_PUBLIC_KEY
289+ ? createMockKmsRecord ( MOCK_TOPIC_SUBMIT_KEY_REF_ID , publicKey )
290+ : undefined ,
291+ ) ;
292+
293+ const api : Partial < CoreApi > = {
294+ mirror : mirrorMock as HederaMirrornodeService ,
295+ network : makeNetworkMock ( SupportedNetwork . TESTNET ) as NetworkService ,
296+ alias : makeAliasMock ( ) ,
297+ logger,
298+ state : makeStateMock ( ) ,
299+ kms,
300+ } ;
301+
302+ const args = makeArgs ( api , logger , { topic : '0.0.123456' } ) ;
303+
304+ const result = await topicImport ( args ) ;
305+
306+ expect ( saveTopicMock ) . toHaveBeenCalledWith (
307+ `${ SupportedNetwork . TESTNET } :0.0.123456` ,
308+ expect . objectContaining ( {
309+ submitKeyRefIds : [ MOCK_TOPIC_SUBMIT_KEY_REF_ID ] ,
310+ } ) ,
311+ ) ;
312+
313+ const output = assertOutput ( result . result , TopicImportOutputSchema ) ;
314+ expect ( output . submitKeyPresent ) . toBe ( true ) ;
315+ expect ( output . submitKeysMatched ) . toBe ( 1 ) ;
316+ } ) ;
317+
147318 test ( 'throws when topic already exists in state' , async ( ) => {
148319 const logger = makeLogger ( ) ;
149320
0 commit comments