epistery 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -700,14 +700,20 @@ export class Utils {
700
700
  // Use helper functions
701
701
  const gasPrice = await this.getGasPriceWithBuffer(ownerWallet, Utils.GAS_PRICE_BUFFER_PERCENT);
702
702
 
703
- // Estimate gas for the contract write
703
+ // Estimate gas for the contract write - this will fail early if contract will revert
704
704
  let gasLimit: ethers.BigNumber;
705
705
  try {
706
706
  const estimatedGas = await agentContract.estimateGas.addToWhitelist(listName, addressToAdd, name, role, meta);
707
707
  gasLimit = this.addGasBuffer(estimatedGas, Utils.GAS_LIMIT_BUFFER_PERCENT);
708
708
  console.log(`Contract addToWhitelist - Estimated Gas: ${estimatedGas.toString()}, With Buffer: ${gasLimit.toString()}`);
709
709
  }
710
- catch (error) {
710
+ catch (estimateError: any) {
711
+ // Gas estimation failure often means the transaction will revert
712
+ // Try to extract the revert reason
713
+ const revertReason = this.extractRevertReason(estimateError);
714
+ if (revertReason) {
715
+ throw new Error(revertReason);
716
+ }
711
717
  console.warn('Gas estimation for contract addToWhitelist failed, using default limit');
712
718
  gasLimit = ethers.BigNumber.from(Utils.FALLBACK_GAS_LIMIT);
713
719
  }
@@ -721,17 +727,83 @@ export class Utils {
721
727
  console.log(`Waiting for confirmation...`);
722
728
 
723
729
  const receipt = await tx.wait();
730
+
731
+ // Check if transaction was successful
732
+ if (receipt.status === 0) {
733
+ throw new Error('Transaction reverted');
734
+ }
735
+
724
736
  console.log(`Transaction confirmed in block ${receipt.blockNumber}`);
725
737
  console.log(`Gas used: ${receipt.gasUsed.toString()}`);
726
738
 
727
739
  return receipt;
728
740
  }
729
- catch (error) {
741
+ catch (error: any) {
742
+ // Try to extract a meaningful revert reason from the error
743
+ const revertReason = this.extractRevertReason(error);
744
+ if (revertReason) {
745
+ console.error('Whitelist operation failed:', revertReason);
746
+ throw new Error(revertReason);
747
+ }
730
748
  console.error('Error adding to whitelist:', error);
731
- throw new Error(`Failed to add to whitelist: ${error}`);
749
+ throw new Error(`Failed to add to whitelist: ${error.message || error}`);
732
750
  }
733
751
  }
734
752
 
753
+ /**
754
+ * Extract revert reason from various error formats
755
+ */
756
+ private static extractRevertReason(error: any): string | null {
757
+ if (!error) return null;
758
+
759
+ // Check for common revert reason locations
760
+ const errorString = error.toString();
761
+ const errorMessage = error.message || '';
762
+ const reason = error.reason;
763
+
764
+ // Known revert messages from our contract
765
+ const knownRevertMessages = [
766
+ 'Address already in whitelist',
767
+ 'List name cannot be empty',
768
+ 'Address cannot be zero',
769
+ 'Invalid role',
770
+ 'Address not in whitelist'
771
+ ];
772
+
773
+ // Check if error contains any known revert message
774
+ for (const msg of knownRevertMessages) {
775
+ if (errorString.includes(msg) || errorMessage.includes(msg) || reason?.includes(msg)) {
776
+ return msg;
777
+ }
778
+ }
779
+
780
+ // Try to decode from error data if available
781
+ if (error.data && typeof error.data === 'string' && error.data.length > 2) {
782
+ try {
783
+ // Error data format: 0x08c379a0 + offset + length + message (for Error(string))
784
+ if (error.data.startsWith('0x08c379a0')) {
785
+ const abiCoder = new ethers.utils.AbiCoder();
786
+ const decoded = abiCoder.decode(['string'], '0x' + error.data.slice(10));
787
+ if (decoded[0]) return decoded[0];
788
+ }
789
+ } catch {
790
+ // Decoding failed, continue
791
+ }
792
+ }
793
+
794
+ // Check nested error structures
795
+ if (error.error) {
796
+ return this.extractRevertReason(error.error);
797
+ }
798
+
799
+ // Return the reason if it exists and is meaningful
800
+ if (reason && reason !== 'null' && reason !== null) {
801
+ return reason;
802
+ }
803
+
804
+ return null;
805
+ }
806
+
735
807
  public static async RemoveFromWhitelist(ownerWallet: Wallet, listName: string, addressToRemove: string, contractAddress?: string): Promise<any> {
736
808
  try {
737
809
  const agentContractAddress = contractAddress || process.env.AGENT_CONTRACT_ADDRESS;
@@ -837,6 +909,36 @@ export class Utils {
837
909
  }
838
910
  }
839
911
 
912
+ public static async GetListsForMember(wallet: Wallet, ownerAddress: string, memberAddress: string, contractAddress?: string): Promise<any[]> {
913
+ try {
914
+ const agentContractAddress = contractAddress || process.env.AGENT_CONTRACT_ADDRESS;
915
+ if (!agentContractAddress || agentContractAddress === '0x0000000000000000000000000000000000000000') {
916
+ throw new Error('Agent contract address not configured');
917
+ }
918
+
919
+ const agentContract = new ethers.Contract(
920
+ agentContractAddress,
921
+ AgentArtifact.abi,
922
+ wallet
923
+ );
924
+
925
+ const memberships = await agentContract.getListsForMember(ownerAddress, memberAddress);
926
+
927
+ // Normalize the response
928
+ const plainMemberships = memberships.map((entry: any) => ({
929
+ listName: entry.listName,
930
+ role: entry.role,
931
+ addedAt: entry.addedAt.toNumber ? entry.addedAt.toNumber() : Number(entry.addedAt)
932
+ }));
933
+
934
+ return plainMemberships;
935
+ }
936
+ catch (error) {
937
+ console.error('Error getting lists for member:', error);
938
+ throw new Error(`Failed to get lists for member: ${error}`);
939
+ }
940
+ }
941
+
840
942
  public static async CreateApproval(requestorWallet: Wallet, approverAddress: string, fileName: string, fileHash: string, domain: string): Promise<any> {
841
943
  try {
842
944
  const agentContractAddress = process.env.AGENT_CONTRACT_ADDRESS;