Skip to content

Commit 5602bd2

Browse files
filled in missing API encapsulation in network-client and added context to errors returned by the network client
1 parent 1bcd379 commit 5602bd2

File tree

1 file changed

+133
-34
lines changed

1 file changed

+133
-34
lines changed

sdk/src/network-client.ts

Lines changed: 133 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class AleoNetworkClient {
9292
try {
9393
return parseJSON(await this.fetchRaw(url));
9494
} catch (error) {
95-
throw new Error("Error fetching data.");
95+
throw new Error(`Error fetching data: ${error}`);
9696
}
9797
}
9898

@@ -113,7 +113,7 @@ class AleoNetworkClient {
113113
});
114114
return await response.text();
115115
} catch (error) {
116-
throw new Error("Error fetching data.");
116+
throw new Error(`Error fetching data: ${error}`);
117117
}
118118
}
119119

@@ -185,10 +185,10 @@ class AleoNetworkClient {
185185
if (typeof blockHeight === "number") {
186186
latestHeight = blockHeight;
187187
} else {
188-
throw new Error("Error fetching latest block height.");
188+
throw new Error(`Error fetching latest block height: Expected type 'number' got '${typeof blockHeight}'`);
189189
}
190190
} catch (error) {
191-
throw new Error("Error fetching latest block height.");
191+
throw new Error(`Error fetching latest block height: ${error}`);
192192
}
193193

194194
// If no end height is specified or is greater than the latest height, set the end height to the latest height
@@ -324,10 +324,26 @@ class AleoNetworkClient {
324324
const block = await this.fetchData<BlockJSON>("/block/" + height);
325325
return block;
326326
} catch (error) {
327-
throw new Error("Error fetching block.");
327+
throw new Error(`Error fetching block ${height}: ${error}`);
328328
}
329329
}
330330

331+
/**
332+
* Returns the contents of the block with the specified hash.
333+
*
334+
* @param {string} hash
335+
* @example
336+
* const block = networkClient.getBlockByHash("ab19dklwl9vp63zu3hwg57wyhvmqf92fx5g8x0t6dr72py8r87pxupqfne5t9");
337+
*/
338+
async getBlockByHash(hash: string): Promise<BlockJSON> {
339+
try {
340+
const block = await this.fetchData<BlockJSON>(`/block/${hash}`);
341+
return block;
342+
} catch (error) {
343+
throw new Error(`Error fetching block ${hash}: ${error}`);
344+
}
345+
}
346+
331347
/**
332348
* Returns a range of blocks between the specified block heights.
333349
*
@@ -339,9 +355,8 @@ class AleoNetworkClient {
339355
async getBlockRange(start: number, end: number): Promise<Array<BlockJSON>> {
340356
try {
341357
return await this.fetchData<Array<BlockJSON>>("/blocks?start=" + start + "&end=" + end);
342-
} catch (error) {
343-
const errorMessage = `Error fetching blocks between ${start} and ${end}.`;
344-
throw new Error(errorMessage);
358+
} catch (error) {;
359+
throw new Error(`Error fetching blocks between ${start} and ${end}: ${error}`);
345360
}
346361
}
347362

@@ -353,13 +368,13 @@ class AleoNetworkClient {
353368
*/
354369
async getDeploymentTransactionIDForProgram(program: Program | string): Promise<string> {
355370
if (program instanceof Program) {
356-
program = program.toString();
371+
program = program.id();
357372
}
358373
try {
359374
const id = await this.fetchData<string>("/find/transactionID/deployment/" + program);
360375
return id.replace("\"", "")
361376
} catch (error) {
362-
throw new Error("Error fetching deployment transaction for program.");
377+
throw new Error(`Error fetching deployment transaction for program ${program}: ${error}`);
363378
}
364379
}
365380

@@ -370,11 +385,14 @@ class AleoNetworkClient {
370385
* @returns {TransactionJSON}
371386
*/
372387
async getDeploymentTransactionForProgram(program: Program | string): Promise<TransactionJSON> {
388+
if (program instanceof Program) {
389+
program = program.id();
390+
}
373391
try {
374392
const transaction_id = <string>await this.getDeploymentTransactionIDForProgram(program);
375393
return <TransactionJSON>await this.getTransaction(transaction_id);
376394
} catch (error) {
377-
throw new Error("Error fetching deployment transaction for program.");
395+
throw new Error(`Error fetching deployment transaction for program ${program}: ${error}`);
378396
}
379397
}
380398

@@ -385,11 +403,29 @@ class AleoNetworkClient {
385403
* @returns {TransactionJSON}
386404
*/
387405
async getDeploymentTransactioObjectnForProgram(program: Program | string): Promise<Transaction> {
406+
if (program instanceof Program) {
407+
program = program.id();
408+
}
388409
try {
389410
const transaction_id = <string>await this.getDeploymentTransactionIDForProgram(program);
390411
return await this.getTransactionObject(transaction_id);
391412
} catch (error) {
392-
throw new Error("Error fetching deployment transaction for program.");
413+
throw new Error(`Error fetching deployment transaction for program ${program}: ${error}`);
414+
}
415+
}
416+
417+
/**
418+
* Returns the deployment transaction associated with a specified program as a wasm object.
419+
*
420+
* @param {Program | string} program
421+
* @returns {TransactionJSON}
422+
*/
423+
async getDeploymentTransactioObjectForProgram(program: Program | string): Promise<Transaction> {
424+
try {
425+
const transaction_id = <string>await this.getDeploymentTransactionIDForProgram(program);
426+
return await this.getTransactionObject(transaction_id);
427+
} catch (error) {
428+
throw new Error(`Error fetching deployment transaction for program ${program}: ${error}`);
393429
}
394430
}
395431

@@ -403,7 +439,7 @@ class AleoNetworkClient {
403439
try {
404440
return await this.fetchData<BlockJSON>("/block/latest") as BlockJSON;
405441
} catch (error) {
406-
throw new Error("Error fetching latest block.");
442+
throw new Error(`Error fetching latest block: ${error}`);
407443
}
408444
}
409445

@@ -416,7 +452,25 @@ class AleoNetworkClient {
416452
try {
417453
return await this.fetchData<object>("/committee/latest");
418454
} catch (error) {
419-
throw new Error("Error fetching latest block.");
455+
throw new Error(`Error fetching latest committee: ${error}`);
456+
}
457+
}
458+
459+
/**
460+
* Returns the committe at the specified block height.
461+
*
462+
* @param {number} height
463+
*
464+
* @returns {Promise<object>} A javascript object containing the committee
465+
*
466+
* @example
467+
* const committee = await networkClient.getCommitteByBlockHeight(1234);
468+
*/
469+
async getCommitteeByBlockHeight(height: number): Promise<object> {
470+
try {
471+
return await this.fetchData<object>(`/committee/${height}`);
472+
} catch (error) {
473+
throw new Error(`Error fetching committee at height ${height}: ${error}`);
420474
}
421475
}
422476

@@ -430,7 +484,21 @@ class AleoNetworkClient {
430484
try {
431485
return Number(await this.fetchData<bigint>("/block/height/latest"));
432486
} catch (error) {
433-
throw new Error("Error fetching latest height.");
487+
throw new Error(`Error fetching latest height: ${error}`);
488+
}
489+
}
490+
491+
/**
492+
* Returns the latest block hash.
493+
*
494+
* @example
495+
* const latestHash - newtworkClient.getLatestHash();
496+
*/
497+
async getLatestHash(): Promise<string> {
498+
try {
499+
return String(await this.fetchData<string>("/block/hash/latest"));
500+
} catch (error) {
501+
throw new Error(`Error fetching latest hash: ${error}`);
434502
}
435503
}
436504

@@ -449,7 +517,7 @@ class AleoNetworkClient {
449517
try {
450518
return await this.fetchData<string>("/program/" + programId)
451519
} catch (error) {
452-
throw new Error("Error fetching program");
520+
throw new Error(`Error fetching program ${programId}: ${error}`);
453521
}
454522
}
455523

@@ -477,7 +545,7 @@ class AleoNetworkClient {
477545
try {
478546
return Program.fromString(<string>(await this.getProgram(inputProgram)));
479547
} catch (error) {
480-
throw new Error(`${inputProgram} is neither a program name or a valid program`);
548+
throw new Error(`${inputProgram} is neither a program name or a valid program: ${error}`);
481549
}
482550
}
483551
}
@@ -553,7 +621,7 @@ class AleoNetworkClient {
553621
const program = inputProgram instanceof Program ? inputProgram : <Program>(await this.getProgramObject(inputProgram));
554622
return program.getImports();
555623
} catch (error: any) {
556-
throw new Error("Error fetching program imports with error: " + error.message);
624+
throw new Error(`Error fetching imports for program ${inputProgram instanceof Program ? inputProgram.id() : inputProgram}: ${error.message}`);
557625
}
558626
}
559627

@@ -568,9 +636,9 @@ class AleoNetworkClient {
568636
*/
569637
async getProgramMappingNames(programId: string): Promise<Array<string>> {
570638
try {
571-
return await this.fetchData<Array<string>>("/program/" + programId + "/mappings")
639+
return await this.fetchData<Array<string>>(`/program/${programId}/mappings`)
572640
} catch (error) {
573-
throw new Error("Error fetching program mappings - ensure the program exists on chain before trying again");
641+
throw new Error(`Error fetching mappings for program ${programId} - ensure the program exists on chain before trying again`);
574642
}
575643
}
576644

@@ -591,9 +659,9 @@ class AleoNetworkClient {
591659
async getProgramMappingValue(programId: string, mappingName: string, key: string | Plaintext): Promise<string> {
592660
try {
593661
const keyString = key instanceof Plaintext ? key.toString() : key;
594-
return await this.fetchData<string>("/program/" + programId + "/mapping/" + mappingName + "/" + keyString)
662+
return await this.fetchData<string>(`/program/${programId}/mapping/${mappingName}/${keyString}`);
595663
} catch (error) {
596-
throw new Error("Error fetching mapping value - ensure the mapping exists and the key is correct");
664+
throw new Error(`Error fetching value for key '${key}' in mapping '${mappingName}' in program '${programId}' - ensure the mapping exists and the key is correct`);
597665
}
598666
}
599667

@@ -632,40 +700,56 @@ class AleoNetworkClient {
632700
*/
633701
async getProgramMappingPlaintext(programId: string, mappingName: string, key: string | Plaintext): Promise<Plaintext> {
634702
try {
635-
const keyString = key instanceof Plaintext ? key.toString() : key;
636-
const value = await this.fetchRaw("/program/" + programId + "/mapping/" + mappingName + "/" + keyString);
703+
const value = await this.getProgramMappingValue(programId, mappingName, key);
637704
return Plaintext.fromString(JSON.parse(value));
638705
} catch (error) {
639-
throw new Error("Failed to fetch mapping value." + error);
706+
throw new Error(`${error}`);
640707
}
641708
}
642709

643710
/**
644711
* Returns the latest state/merkle root of the Aleo blockchain.
645712
*
713+
* @param {number} height - The height for which the state root is fetched, if blank then the latest state root will be returned.
714+
*
646715
* @example
647716
* const stateRoot = networkClient.getStateRoot();
648717
*/
649-
async getStateRoot(): Promise<string> {
718+
async getStateRoot(height?: number): Promise<string> {
650719
try {
651-
return await this.fetchData<string>("/stateRoot/latest");
720+
return await this.fetchData<string>(`/stateRoot/${height ?? "latest"}`);
652721
} catch (error) {
653-
throw new Error("Error fetching Aleo state root");
722+
throw new Error(`Error fetching ${height === undefined || height === null ? 'latest state root' : `state root at block ${height}`}: ${error}`);
654723
}
655724
}
656725

657726
/**
658727
* Returns a transaction by its unique identifier.
659728
*
660-
* @param {string} id
729+
* @param {string} transactionId
661730
* @example
662731
* const transaction = networkClient.getTransaction("at1handz9xjrqeynjrr0xay4pcsgtnczdksz3e584vfsgaz0dh0lyxq43a4wj");
663732
*/
664733
async getTransaction(transactionId: string): Promise<TransactionJSON> {
665734
try {
666735
return await this.fetchData<TransactionJSON>("/transaction/" + transactionId);
667736
} catch (error) {
668-
throw new Error("Error fetching transaction.");
737+
throw new Error(`Error fetching transaction ${transactionId}: ${error}`);
738+
}
739+
}
740+
741+
/**
742+
* Returns a confirmed transaction by its unique identifier.
743+
*
744+
* @param {string} transactionId
745+
* @example
746+
* const transaction = networkClient.getConfirmedTransaction("at1handz9xjrqeynjrr0xay4pcsgtnczdksz3e584vfsgaz0dh0lyxq43a4wj");
747+
*/
748+
async getConfirmedTransaction(transactionId: string): Promise<ConfirmedTransactionJSON> {
749+
try {
750+
return await this.fetchData<ConfirmedTransactionJSON>(`/transaction/confirmed/${transactionId}`);
751+
} catch (error) {
752+
throw new Error(`Error fetching confirmed transaction ${transactionId}: ${error}`);
669753
}
670754
}
671755

@@ -700,7 +784,7 @@ class AleoNetworkClient {
700784
const transaction = await this.fetchRaw("/transaction/" + transactionId);
701785
return Transaction.fromString(transaction);
702786
} catch (error) {
703-
throw new Error("Error fetching transaction.");
787+
throw new Error(`Error fetching transaction object ${transactionId}: ${error}`);
704788
}
705789
}
706790

@@ -715,7 +799,22 @@ class AleoNetworkClient {
715799
try {
716800
return await this.fetchData<Array<ConfirmedTransactionJSON>>("/block/" + height.toString() + "/transactions");
717801
} catch (error) {
718-
throw new Error("Error fetching transactions. " + error);
802+
throw new Error(`Error fetching transactions: ${error}`);
803+
}
804+
}
805+
806+
/**
807+
* Returns the transactions present in the block with the specified hash.
808+
*
809+
* @param {string} hash
810+
* @example
811+
* const transactions = networkClient.getTransactionsByHash("ab19dklwl9vp63zu3hwg57wyhvmqf92fx5g8x0t6dr72py8r87pxupqfne5t9");
812+
*/
813+
async getTransactionsByHash(hash: string): Promise<Array<ConfirmedTransactionJSON>> {
814+
try {
815+
return await this.fetchData<Array<ConfirmedTransactionJSON>>(`/block/${hash}/transactions`);
816+
} catch (error) {
817+
throw new Error(`Error fetching transactions for block ${hash}: ${error}`);
719818
}
720819
}
721820

@@ -729,7 +828,7 @@ class AleoNetworkClient {
729828
try {
730829
return await this.fetchData<Array<TransactionJSON>>("/memoryPool/transactions");
731830
} catch (error) {
732-
throw new Error("Error fetching transactions from mempool.");
831+
throw new Error(`Error fetching transactions from mempool: ${error}`);
733832
}
734833
}
735834

@@ -744,7 +843,7 @@ class AleoNetworkClient {
744843
try {
745844
return await this.fetchData<string>("/find/transitionID/" + inputOrOutputID);
746845
} catch (error) {
747-
throw new Error("Error fetching transition ID.");
846+
throw new Error(`Error fetching transition ID for input/output ${inputOrOutputID}: ${error}`);
748847
}
749848
}
750849

0 commit comments

Comments
 (0)