@@ -890,7 +890,17 @@ class AleoNetworkClient {
890890 /**
891891 * Returns the source code of a program given a program ID.
892892 *
893- * @param {string } programId The program ID of a program deployed to the Aleo Network
893+ * @param {string } programId The program ID of a program deployed to the Aleo Network.
894+ * @param {number | undefined } edition The edition of the program to fetch. When this is undefined it will fetch the latest version.
895+ * @returns {Promise<string> } The source code of the program.
896+ *
897+ * @example
898+ * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
899+ *
900+ * // Create a network client.
901+ * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
902+ *
903+ * // Get the source code of a program.)
894904 * @returns {Promise<string> } Source code of the program
895905 *
896906 * @example
@@ -903,22 +913,57 @@ class AleoNetworkClient {
903913 * const expectedSource = "program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n"
904914 * assert.equal(program, expectedSource);
905915 */
906- async getProgram ( programId : string ) : Promise < string > {
916+ async getProgram ( programId : string , edition ?: number ) : Promise < string > {
917+ try {
918+ this . ctx = { "X-ALEO-METHOD" : "getProgramVersion" } ;
919+ if ( typeof edition === "number" ) {
920+ return await this . fetchData < string > (
921+ `/program/${ programId } /${ edition } ` ,
922+ ) ;
923+ } else {
924+ return await this . fetchData < string > ( "/program/" + programId ) ;
925+ }
926+ } catch ( error ) {
927+ throw new Error ( `Error fetching program ${ programId } : ${ error } ` ) ;
928+ } finally {
929+ this . ctx = { } ;
930+ }
931+ }
932+
933+ /**
934+ * Returns the current program edition deployed on the Aleo network.
935+ *
936+ * @param {string } programId The program ID of a program deployed to the Aleo Network.
937+ * @returns {Promise<number> } The edition of the program.
938+ *
939+ * @example
940+ * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
941+ *
942+ * // Create a network client.
943+ * const networkClient = new AleoNetworkClient("http://api.explorer.provable.com/v1", undefined);
944+ *
945+ * const programVersion = networkClient.getLatestProgramEdition("hello_hello.aleo");
946+ * assert.equal(programVersion, 1);
947+ */
948+ async getLatestProgramEdition ( programId : string ) : Promise < number > {
907949 try {
908- this . ctx = { "X-ALEO-METHOD" : "getProgram " } ;
909- return await this . fetchData < string > ( "/program/" + programId ) ;
950+ this . ctx = { "X-ALEO-METHOD" : "getLatestProgramEdition " } ;
951+ return await this . fetchData < number > ( "/program/" + programId + "/latest_edition" ) ;
910952 } catch ( error ) {
911953 throw new Error ( `Error fetching program ${ programId } : ${ error } ` ) ;
912954 } finally {
913955 this . ctx = { } ;
914956 }
915957 }
916958
959+
960+
917961 /**
918962 * Returns a program object from a program ID or program source code.
919963 *
920- * @param {string } inputProgram The program ID or program source code of a program deployed to the Aleo Network
921- * @returns {Promise<Program> } Source code of the program
964+ * @param {string } inputProgram The program ID or program source code of a program deployed to the Aleo Network.
965+ * @param {number | undefined } edition The edition of the program to fetch. When this is undefined it will fetch the latest version.
966+ * @returns {Promise<Program> } Source code of the program.
922967 *
923968 * @example
924969 * import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
@@ -936,20 +981,16 @@ class AleoNetworkClient {
936981 * // Both program objects should be equal
937982 * assert(programObjectFromID.to_string() === programObjectFromSource.to_string());
938983 */
939- async getProgramObject ( inputProgram : string ) : Promise < Program > {
984+ async getProgramObject ( inputProgram : string , edition ?: number ) : Promise < Program > {
940985 try {
941986 this . ctx = { "X-ALEO-METHOD" : "getProgramObject" } ;
942- return Program . fromString ( inputProgram ) ;
987+ return Program . fromString (
988+ < string > await this . getProgram ( inputProgram , edition ) ,
989+ ) ;
943990 } catch ( error ) {
944- try {
945- return Program . fromString (
946- < string > await this . getProgram ( inputProgram ) ,
947- ) ;
948- } catch ( error ) {
949- throw new Error (
950- `${ inputProgram } is neither a program name or a valid program: ${ error } ` ,
951- ) ;
952- }
991+ throw new Error (
992+ `${ inputProgram } is neither a program name or a valid program: ${ error } ` ,
993+ ) ;
953994 } finally {
954995 this . ctx = { } ;
955996 }
@@ -985,40 +1026,49 @@ class AleoNetworkClient {
9851026 * programImports = await networkClient.getProgramImports(double_test);
9861027 * assert.deepStrictEqual(programImports, expectedImports);
9871028 */
988- async getProgramImports (
989- inputProgram : Program | string ,
990- ) : Promise < ProgramImports > {
1029+ async getProgramImports ( inputProgram : Program | string ) : Promise < ProgramImports > {
9911030 try {
9921031 this . ctx = { "X-ALEO-METHOD" : "getProgramImports" } ;
9931032 const imports : ProgramImports = { } ;
9941033
995- // Get the program object or fail if the program is not valid or does not exist
996- const program =
997- inputProgram instanceof Program
998- ? inputProgram
999- : < Program > await this . getProgramObject ( inputProgram ) ;
1034+ // Normalize input to a Program object
1035+ let program : Program ;
1036+ if ( inputProgram instanceof Program ) {
1037+ program = inputProgram ;
1038+ } else {
1039+ try {
1040+ program = Program . fromString ( inputProgram ) ;
1041+ } catch {
1042+ try {
1043+ program = await this . getProgramObject ( inputProgram ) ;
1044+ } catch ( error2 ) {
1045+ throw new Error (
1046+ `${ inputProgram } is neither a program name nor a valid program: ${ error2 } ` ,
1047+ ) ;
1048+ }
1049+ }
1050+ }
10001051
10011052 // Get the list of programs that the program imports
10021053 const importList = program . getImports ( ) ;
10031054
1004- // Recursively get any imports that the imported programs have in a depth first search order
1055+ // Recursively get any imports that the imported programs have in a depth- first search
10051056 for ( let i = 0 ; i < importList . length ; i ++ ) {
10061057 const import_id = importList [ i ] ;
10071058 if ( ! imports . hasOwnProperty ( import_id ) ) {
1008- const programSource = < string > (
1009- await this . getProgram ( import_id )
1010- ) ;
1011- const nestedImports = < ProgramImports > (
1012- await this . getProgramImports ( import_id )
1013- ) ;
1059+ const programSource = < string > await this . getProgram ( import_id ) ;
1060+ const nestedImports = < ProgramImports > await this . getProgramImports ( import_id ) ;
1061+
10141062 for ( const key in nestedImports ) {
10151063 if ( ! imports . hasOwnProperty ( key ) ) {
10161064 imports [ key ] = nestedImports [ key ] ;
10171065 }
10181066 }
1067+
10191068 imports [ import_id ] = programSource ;
10201069 }
10211070 }
1071+
10221072 return imports ;
10231073 } catch ( error : any ) {
10241074 logAndThrow ( "Error fetching program imports: " + error . message ) ;
@@ -1027,6 +1077,7 @@ class AleoNetworkClient {
10271077 }
10281078 }
10291079
1080+
10301081 /**
10311082 * Get a list of the program names that a program imports.
10321083 *
@@ -1094,7 +1145,7 @@ class AleoNetworkClient {
10941145 ) ;
10951146 } catch ( error ) {
10961147 throw new Error (
1097- `Error fetching mappings for program ${ programId } - ensure the program exists on chain before trying again` ,
1148+ `Error fetching mappings for program ${ programId } - ensure the program exists on chain before trying again: ${ error } ` ,
10981149 ) ;
10991150 } finally {
11001151 this . ctx = { } ;
@@ -1133,7 +1184,7 @@ class AleoNetworkClient {
11331184 ) ;
11341185 } catch ( error ) {
11351186 throw new Error (
1136- `Error fetching value for key '${ key } ' in mapping '${ mappingName } ' in program '${ programId } ' - ensure the mapping exists and the key is correct` ,
1187+ `Error fetching value for key '${ key } ' in mapping '${ mappingName } ' in program '${ programId } ' - ensure the mapping exists and the key is correct: ${ error } ` ,
11371188 ) ;
11381189 } finally {
11391190 this . ctx = { } ;
0 commit comments