@@ -890,7 +890,17 @@ class AleoNetworkClient {
890
890
/**
891
891
* Returns the source code of a program given a program ID.
892
892
*
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.)
894
904
* @returns {Promise<string> } Source code of the program
895
905
*
896
906
* @example
@@ -903,22 +913,57 @@ class AleoNetworkClient {
903
913
* 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"
904
914
* assert.equal(program, expectedSource);
905
915
*/
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 > {
907
949
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" ) ;
910
952
} catch ( error ) {
911
953
throw new Error ( `Error fetching program ${ programId } : ${ error } ` ) ;
912
954
} finally {
913
955
this . ctx = { } ;
914
956
}
915
957
}
916
958
959
+
960
+
917
961
/**
918
962
* Returns a program object from a program ID or program source code.
919
963
*
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.
922
967
*
923
968
* @example
924
969
* import { AleoNetworkClient } from "@provablehq/sdk/mainnet.js";
@@ -936,20 +981,16 @@ class AleoNetworkClient {
936
981
* // Both program objects should be equal
937
982
* assert(programObjectFromID.to_string() === programObjectFromSource.to_string());
938
983
*/
939
- async getProgramObject ( inputProgram : string ) : Promise < Program > {
984
+ async getProgramObject ( inputProgram : string , edition ?: number ) : Promise < Program > {
940
985
try {
941
986
this . ctx = { "X-ALEO-METHOD" : "getProgramObject" } ;
942
- return Program . fromString ( inputProgram ) ;
987
+ return Program . fromString (
988
+ < string > await this . getProgram ( inputProgram , edition ) ,
989
+ ) ;
943
990
} 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
+ ) ;
953
994
} finally {
954
995
this . ctx = { } ;
955
996
}
@@ -985,40 +1026,49 @@ class AleoNetworkClient {
985
1026
* programImports = await networkClient.getProgramImports(double_test);
986
1027
* assert.deepStrictEqual(programImports, expectedImports);
987
1028
*/
988
- async getProgramImports (
989
- inputProgram : Program | string ,
990
- ) : Promise < ProgramImports > {
1029
+ async getProgramImports ( inputProgram : Program | string ) : Promise < ProgramImports > {
991
1030
try {
992
1031
this . ctx = { "X-ALEO-METHOD" : "getProgramImports" } ;
993
1032
const imports : ProgramImports = { } ;
994
1033
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
+ }
1000
1051
1001
1052
// Get the list of programs that the program imports
1002
1053
const importList = program . getImports ( ) ;
1003
1054
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
1005
1056
for ( let i = 0 ; i < importList . length ; i ++ ) {
1006
1057
const import_id = importList [ i ] ;
1007
1058
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
+
1014
1062
for ( const key in nestedImports ) {
1015
1063
if ( ! imports . hasOwnProperty ( key ) ) {
1016
1064
imports [ key ] = nestedImports [ key ] ;
1017
1065
}
1018
1066
}
1067
+
1019
1068
imports [ import_id ] = programSource ;
1020
1069
}
1021
1070
}
1071
+
1022
1072
return imports ;
1023
1073
} catch ( error : any ) {
1024
1074
logAndThrow ( "Error fetching program imports: " + error . message ) ;
@@ -1027,6 +1077,7 @@ class AleoNetworkClient {
1027
1077
}
1028
1078
}
1029
1079
1080
+
1030
1081
/**
1031
1082
* Get a list of the program names that a program imports.
1032
1083
*
@@ -1094,7 +1145,7 @@ class AleoNetworkClient {
1094
1145
) ;
1095
1146
} catch ( error ) {
1096
1147
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 } ` ,
1098
1149
) ;
1099
1150
} finally {
1100
1151
this . ctx = { } ;
@@ -1133,7 +1184,7 @@ class AleoNetworkClient {
1133
1184
) ;
1134
1185
} catch ( error ) {
1135
1186
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 } ` ,
1137
1188
) ;
1138
1189
} finally {
1139
1190
this . ctx = { } ;
0 commit comments