@@ -16,6 +16,7 @@ import {
1616 Balance ,
1717 CID ,
1818 MixDescriptor ,
19+ Network ,
1920 Node ,
2021 TreasuryId ,
2122 client ,
@@ -60,6 +61,19 @@ const getPrivateKeyFromFile = async (path: string): Promise<PrivateKey> => {
6061 }
6162} ;
6263
64+ const getBytesFromFile = async ( path : string ) : Promise < Uint8Array > => {
65+ const f = path . replace ( / ^ f i l e : \/ \/ / , "" ) ;
66+ return await fs . readFile ( f ) ;
67+ } ;
68+
69+ const putBytesToFile = async (
70+ path : string ,
71+ data : Uint8Array ,
72+ ) : Promise < void > => {
73+ const f = path . replace ( / ^ f i l e : \/ \/ / , "" ) ;
74+ return await fs . writeFile ( f , data ) ;
75+ } ;
76+
6377const program = new Command ( ) ;
6478program . name ( "cli" ) . description ( "appchain cli" ) ;
6579
@@ -130,6 +144,7 @@ console.log("opts", opts);
130144await client . start ( ) ;
131145const admin = client . runtime . resolve ( "Admin" ) ;
132146const faucet = client . runtime . resolve ( "Faucet" ) ;
147+ const networks = client . runtime . resolve ( "Networks" ) ;
133148const nodes = client . runtime . resolve ( "Nodes" ) ;
134149const pki = client . runtime . resolve ( "Pki" ) ;
135150const token = client . runtime . resolve ( "Token" ) ;
@@ -303,6 +318,104 @@ const executeCommand = async (
303318 } ) ;
304319 }
305320
321+ const commandNetworks = program
322+ . command ( "networks" )
323+ . description ( "networks commands" ) ;
324+ commandNetworks
325+ . command ( "register <identifier> [file://]" )
326+ . description ( "register a network <parameters := file:// OR payload>" )
327+ . action ( async ( identifier : string , file ?: string ) => {
328+ if ( ! ipfsNode ) return callback ( responses . IPFS_NOT_STARTED ) ;
329+
330+ // get network parameters from file or payload
331+ const _payload = file ? await getBytesFromFile ( file ) : payload ;
332+ if ( ! _payload ) return callback ( responses . PAYLOAD_UNDEFINED ) ;
333+
334+ const parametersCID = await ipfsNode . putBytes ( _payload ) ;
335+
336+ const r = await txer ( async ( ) => {
337+ await networks . register (
338+ new Network ( {
339+ identifier : CircuitString . fromString ( identifier ) ,
340+ parametersCID : CID . fromString ( parametersCID ) ,
341+ } ) ,
342+ ) ;
343+ } ) ;
344+
345+ const debug = { identifier, cid : parametersCID , tx : r . tx } ;
346+ callback ( { id, ...r } , debug ) ;
347+ } ) ;
348+ commandNetworks
349+ . command ( "getActive" )
350+ . description ( "get the identifier of the active network(s)" )
351+ . action ( async ( ) => {
352+ const nid = ( await client . query . runtime . Networks . activeNetwork . get ( ) ) as
353+ | Field
354+ | undefined ;
355+ if ( ! nid ) return callback ( responses . RECORD_NOT_FOUND ) ;
356+
357+ // retrieve the string form of the network identifier
358+ const n = await client . query . runtime . Networks . networks . get ( nid ) ;
359+ if ( ! n ) return callback ( responses . RECORD_NOT_FOUND ) ;
360+
361+ callback ( { id, status : SUCCESS , data : n . identifier . toString ( ) } ) ;
362+ } ) ;
363+ commandNetworks
364+ . command ( "getNetwork <identifier> [file://]" )
365+ . description (
366+ 'get network by id; "_" for active, optionally save params to file' ,
367+ )
368+ . action ( async ( identifier : string , file ?: string ) => {
369+ if ( ! ipfsNode ) return callback ( responses . IPFS_NOT_STARTED ) ;
370+
371+ var networkID : Field ;
372+ if ( identifier === "_" ) {
373+ const nid =
374+ ( await client . query . runtime . Networks . activeNetwork . get ( ) ) as
375+ | Field
376+ | undefined ;
377+ if ( ! nid ) return callback ( responses . RECORD_NOT_FOUND ) ;
378+ networkID = nid ;
379+ } else {
380+ networkID = Network . getID ( CircuitString . fromString ( identifier ) ) ;
381+ }
382+
383+ const network = ( await client . query . runtime . Networks . networks . get (
384+ networkID ,
385+ ) ) as Network | undefined ;
386+ if ( ! network ) return callback ( responses . RECORD_NOT_FOUND ) ;
387+
388+ const cid = network . parametersCID . toString ( ) ;
389+ const parameters = await ipfsNode . getBytes ( cid ) ;
390+ if ( file ) await putBytesToFile ( file , parameters ) ;
391+
392+ const { parametersCID, ...rest } = Network . toObject ( network ) ;
393+ const data = {
394+ parameters,
395+ ...rest ,
396+ } ;
397+
398+ const debug = { identifier, cid, network : rest } ;
399+ callback (
400+ {
401+ id,
402+ status : SUCCESS ,
403+ data : opts . socketFormat === "cbor" ? cbor . encode ( data ) : data ,
404+ } ,
405+ debug ,
406+ ) ;
407+ } ) ;
408+ commandNetworks
409+ . command ( "setActive <identifier>" )
410+ . description ( "set the active network" )
411+ . action ( async ( identifier : string ) => {
412+ const networkID = Network . getID ( CircuitString . fromString ( identifier ) ) ;
413+ const r = await txer ( async ( ) => {
414+ await networks . setActiveNetwork ( networkID ) ;
415+ } ) ;
416+ callback ( { id, ...r } ) ;
417+ } ) ;
418+
306419 const commandNodes = program . command ( "nodes" ) . description ( "nodes commands" ) ;
307420 commandNodes
308421 . command ( "isRegistrationOpen" )
0 commit comments