{"id":30737492,"url":"https://github.com/signor1/suiclient-error-decoder","last_synced_at":"2025-09-03T21:17:01.595Z","repository":{"id":301631986,"uuid":"1002847808","full_name":"Signor1/suiClient-Error-Decoder","owner":"Signor1","description":"A TypeScript library for decoding Sui blockchain transaction errors, including Move abort errors and custom error codes. Simplifies error handling for Sui dApps and smart contracts with a robust, extensible error decoder.","archived":false,"fork":false,"pushed_at":"2025-06-27T21:28:10.000Z","size":476,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-28T19:06:14.702Z","etag":null,"topics":["abort-errors","custom-errors","dapps","error-decoder","javascript","move-abort-errors","sui","sui-error-decoder","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/suiclient-error-decoder","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Signor1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-16T08:32:58.000Z","updated_at":"2025-06-29T06:51:15.000Z","dependencies_parsed_at":"2025-06-27T22:31:36.161Z","dependency_job_id":"cd75d547-635e-4ba7-98d0-b76210bd46b8","html_url":"https://github.com/Signor1/suiClient-Error-Decoder","commit_stats":null,"previous_names":["signor1/suiclient-error-decoder"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Signor1/suiClient-Error-Decoder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Signor1%2FsuiClient-Error-Decoder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Signor1%2FsuiClient-Error-Decoder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Signor1%2FsuiClient-Error-Decoder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Signor1%2FsuiClient-Error-Decoder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Signor1","download_url":"https://codeload.github.com/Signor1/suiClient-Error-Decoder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Signor1%2FsuiClient-Error-Decoder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273511110,"owners_count":25118661,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abort-errors","custom-errors","dapps","error-decoder","javascript","move-abort-errors","sui","sui-error-decoder","typescript"],"created_at":"2025-09-03T21:16:59.460Z","updated_at":"2025-09-03T21:17:01.581Z","avatar_url":"https://github.com/Signor1.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SuiClient Error Decoder\n\n[![npm version](https://img.shields.io/npm/v/suiclient-error-decoder.svg?style=flat-square)](https://www.npmjs.com/package/suiclient-error-decoder)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)\n[![Sui Blockchain](https://img.shields.io/badge/Built%20for-Sui%20Blockchain-6FBCF0.svg?style=flat-square)](https://sui.io)\n[![Move](https://img.shields.io/badge/Move-008080?style=flat-square\u0026logo=rust\u0026logoColor=white)](https://move-language.github.io/move/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?style=flat-square\u0026logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org)\n\n**SuiClient Error Decoder** is a robust error decoding toolkit for Sui blockchain developers. Intelligently parses Move abort codes, system errors, and transaction failures with zero dependencies. Features customizable error mappings, automatic error categorization, and Sui-specific pattern recognition to simplify debugging and improve user feedback in dApps.\n\n[npmjs.com/package/suiclient-error-decoder](https://www.npmjs.com/package/suiclient-error-decoder)\n\n## Features\n\n- 🔍 **Comprehensive Error Parsing**: Handles Move abort codes, named errors, and system errors\n- 🎯 **Custom Error Codes**: Add your own project-specific error codes\n- 📊 **Error Categorization**: Categorizes errors into move_abort, transaction, sui_system, or unknown\n- 🔄 **Updatable Defaults**: Built-in Sui error codes that can be updated\n- 💡 **Zero Dependencies**: Lightweight and easy to integrate\n\n## Installation\n\n```bash\nnpm install suiclient-error-decoder\n# or\nyarn add suiclient-error-decoder\n# or\npnpm add suiclient-error-decoder\n```\n\n## Quick Start\n\n```typescript\nimport { decodeSuiError, SuiClientErrorDecoder } from 'suiclient-error-decoder';\n\n// Quick one-liner decoding\ntry {\n  // Your Sui transaction code here\n  await suiClient.executeTransactionBlock(/* ... */);\n} catch (error) {\n  const humanReadableError = decodeSuiError(error);\n  console.error(humanReadableError);\n  // Output: \"Error Code 1001: Index out of bounds\"\n}\n```\n\n## Usage Examples\n\n### 1. Basic Setup and Usage\n\n```typescript\nimport { SuiClient } from \"@mysten/sui/client\";\nimport { Transaction } from \"@mysten/sui/transactions\";\nimport { SuiClientErrorDecoder } from 'suiclient-error-decoder';\n\n// Initialize the decoder\nconst errorDecoder = new SuiClientErrorDecoder();\nconst suiClient = new SuiClient({ url: getFullnodeUrl(\"testnet\") });\n\n// Example: Decoding a transaction error\nasync function transferSui(recipientAddress: string, amount: number) {\n  try {\n    const txb = new Transaction();\n    const [coin] = txb.splitCoins(txb.gas, [amount]);\n    txb.transferObjects([coin], recipientAddress);\n    \n    const result = await suiClient.executeTransactionBlock({\n      transactionBlock: txb,\n      signer: keypair, // your keypair\n    });\n    \n    console.log('Transfer successful:', result.digest);\n  } catch (error) {\n    // Raw error might be: \"MoveAbort(0x2::coin, 0) at instruction 15\"\n    const decodedError = errorDecoder.parseError(error);\n    \n    console.error('Transaction failed:');\n    console.error('- Code:', decodedError.code); // 0\n    console.error('- Message:', decodedError.message); // \"Error Code 0: Insufficient balance\"\n    console.error('- Category:', decodedError.category); // \"move_abort\"\n    console.error('- Known Error:', decodedError.isKnownError); // true\n  }\n}\n```\n\n### 2. DeFi Pool Interaction with Custom Errors\n\n```typescript\n// ...other imports\nimport { Transaction } from \"@mysten/sui/transactions\";\nimport { SuiClientErrorDecoder } from 'suiclient-error-decoder';\n\n// Setup decoder with DeFi-specific error codes\nconst defiDecoder = new SuiClientErrorDecoder({\n  customErrorCodes: {\n    // Pool-specific errors\n    100: \"Pool does not exist\",\n    101: \"Insufficient liquidity in pool\",\n    102: \"Slippage tolerance exceeded\",\n    103: \"Pool is paused for maintenance\",\n    104: \"Invalid token pair\",\n    \n    // Staking errors\n    200: \"Staking period not yet ended\",\n    201: \"Rewards already claimed\",\n    202: \"Minimum stake amount not met\",\n    203: \"Unstaking cooldown period active\",\n  }\n});\n\nasync function swapTokens(tokenA: string, tokenB: string, amountIn: number) {\n  try {\n    const txb = new Transaction();\n    \n    // Add your DeFi swap logic here\n    txb.moveCall({\n      target: '0x123::dex::swap',\n      arguments: [\n        txb.pure(tokenA),\n        txb.pure(tokenB),\n        txb.pure(amountIn)\n      ],\n      typeArguments: ['0x2::sui::SUI', '0x456::usdc::USDC']\n    });\n    \n    const result = await suiClient.signAndExecuteTransactionBlock({\n      transactionBlock: txb,\n      signer: keypair,\n      options: { showEffects: true }\n    });\n    \n    return result;\n  } catch (error) {\n    const decoded = defiDecoder.parseError(error);\n    \n    // Handle specific DeFi errors\n    if (decoded.code === 101) {\n      throw new Error('Not enough liquidity in the pool. Try a smaller amount.');\n    } else if (decoded.code === 102) {\n      throw new Error('Price moved too much. Increase slippage tolerance.');\n    } else {\n      throw new Error(`Swap failed: ${decoded.message}`);\n    }\n  }\n}\n```\n\n### 3. React Hook Integration\n\n```typescript\nimport { useState } from 'react';\nimport { Transaction } from \"@mysten/sui/transactions\";\nimport { useSignAndExecuteTransaction } from '@mysten/dapp-kit';\nimport { SuiClientErrorDecoder } from 'suiclient-error-decoder';\n\n// Custom hook for error handling\nfunction useErrorDecoder() {\n  const decoder = new SuiClientErrorDecoder({\n    customErrorCodes: {\n      404: \"NFT not found\",\n      405: \"NFT already minted\",\n      406: \"Mint limit exceeded\",\n    }\n  });\n  \n  return decoder;\n}\n\nfunction MintNFTComponent() {\n  const [isLoading, setIsLoading] = useState(false);\n  const [error, setError] = useState\u003cstring\u003e('');\n  const { mutateAsync: signAndExecute } = useSignAndExecuteTransaction();\n  const errorDecoder = useErrorDecoder();\n\n  const mintNFT = async () =\u003e {\n    setIsLoading(true);\n    setError('');\n    \n    try {\n      const txb = new Transaction();\n      txb.moveCall({\n        target: '0x123::nft::mint',\n        arguments: [txb.pure('My NFT Name')]\n      });\n      \n      const result = await signAndExecute({\n        transactionBlock: txb,\n        options: { showEffects: true }\n      });\n      \n      console.log('NFT minted successfully:', result.digest);\n    } catch (rawError) {\n      const decoded = errorDecoder.parseError(rawError);\n      \n      // Set user-friendly error message\n      setError(decoded.message);\n      \n      // Log detailed error for debugging\n      console.error('Mint failed:', {\n        code: decoded.code,\n        category: decoded.category,\n        isKnown: decoded.isKnownError,\n        original: decoded.originalError\n      });\n    } finally {\n      setIsLoading(false);\n    }\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton onClick={mintNFT} disabled={isLoading}\u003e\n        {isLoading ? 'Minting...' : 'Mint NFT'}\n      \u003c/button\u003e\n      {error \u0026\u0026 \u003cdiv className=\"error\"\u003e{error}\u003c/div\u003e}\n    \u003c/div\u003e\n  );\n}\n```\n\n### 4. Advanced Error Handling with Categorization\n\n```typescript\n// ...imports\nimport { Transaction } from \"@mysten/sui/transactions\";\nimport { SuiClientErrorDecoder } from 'suiclient-error-decoder';\n\nconst decoder = new SuiClientErrorDecoder();\n\nasync function handleComplexTransaction() {\n  try {\n    // Your complex transaction logic\n    const txb = new Transaction();\n    // ... transaction setup\n    \n    const result = await suiClient.executeTransactionBlock({\n      transactionBlock: txb,\n      signer: keypair\n    });\n    \n    return result;\n  } catch (error) {\n    const decoded = decoder.parseError(error);\n    \n    // Handle different error categories\n    switch (decoded.category) {\n      case 'move_abort':\n        console.error('Smart contract error:', decoded.message);\n        // Maybe retry with different parameters\n        break;\n        \n      case 'transaction':\n        console.error('Transaction processing error:', decoded.message);\n        // Maybe increase gas or check network\n        break;\n        \n      case 'sui_system':\n        console.error('Sui system error:', decoded.message);\n        // Maybe retry after some time\n        break;\n        \n      default:\n        console.error('Unknown error occurred:', decoded.message);\n        // Log for investigation\n        break;\n    }\n    \n    // Re-throw with user-friendly message\n    throw new Error(decoded.message);\n  }\n}\n```\n\n### 5. Batch Transaction Error Handling\n\n```typescript\nasync function processBatchTransactions(transactions: TransactionBlock[]) {\n  const decoder = new SuiClientErrorDecoder();\n  const results = [];\n  const errors = [];\n\n  for (let i = 0; i \u003c transactions.length; i++) {\n    try {\n      const result = await suiClient.executeTransactionBlock({\n        transactionBlock: transactions[i],\n        signer: keypair\n      });\n      \n      results.push({ index: i, success: true, result });\n    } catch (error) {\n      const decoded = decoder.parseError(error);\n      \n      errors.push({\n        index: i,\n        success: false,\n        error: {\n          code: decoded.code,\n          message: decoded.message,\n          category: decoded.category,\n          isKnown: decoded.isKnownError\n        }\n      });\n      \n      // Continue with next transaction instead of stopping\n      console.warn(`Transaction ${i} failed: ${decoded.message}`);\n    }\n  }\n\n  return { results, errors };\n}\n```\n\n### 6. Error Monitoring and Analytics\n\n```typescript\nimport { SuiClientErrorDecoder } from 'suiclient-error-decoder';\n\nclass ErrorAnalytics {\n  private decoder: SuiClientErrorDecoder;\n  private errorCounts: Map\u003cstring, number\u003e = new Map();\n\n  constructor() {\n    this.decoder = new SuiClientErrorDecoder();\n  }\n\n  async executeWithAnalytics(transactionFn: () =\u003e Promise\u003cany\u003e) {\n    try {\n      return await transactionFn();\n    } catch (error) {\n      const decoded = this.decoder.parseError(error);\n      \n      // Track error frequency\n      const errorKey = `${decoded.category}:${decoded.code || 'unknown'}`;\n      this.errorCounts.set(errorKey, (this.errorCounts.get(errorKey) || 0) + 1);\n      \n      // Send to analytics service\n      this.sendToAnalytics({\n        timestamp: Date.now(),\n        errorCode: decoded.code,\n        errorMessage: decoded.message,\n        category: decoded.category,\n        isKnownError: decoded.isKnownError\n      });\n      \n      throw error; // Re-throw the original error\n    }\n  }\n\n  private async sendToAnalytics(errorData: any) {\n    // Send to your analytics service\n    console.log('Error Analytics:', errorData);\n  }\n\n  getErrorStats() {\n    return Object.fromEntries(this.errorCounts);\n  }\n}\n\n// Usage\nconst analytics = new ErrorAnalytics();\n\nawait analytics.executeWithAnalytics(async () =\u003e {\n  // Your transaction code\n  return await performSuiTransaction();\n});\n\nconsole.log('Error statistics:', analytics.getErrorStats());\n```\n\n### 7. Testing Error Scenarios\n\n```typescript\nimport { SuiClientErrorDecoder } from 'suiclient-error-decoder';\n\ndescribe('Error Handling Tests', () =\u003e {\n  const decoder = new SuiClientErrorDecoder({\n    customErrorCodes: {\n      999: \"Test error for unit testing\"\n    }\n  });\n\n  test('should handle insufficient gas error', () =\u003e {\n    const mockError = new Error('InsufficientGas: Transaction needs more gas');\n    const decoded = decoder.parseError(mockError);\n    \n    expect(decoded.category).toBe('sui_system');\n    expect(decoded.isKnownError).toBe(true);\n    expect(decoded.message).toContain('gas');\n  });\n\n  test('should handle custom error codes', () =\u003e {\n    const mockError = new Error('MoveAbort(0x123, 999)');\n    const decoded = decoder.parseError(mockError);\n    \n    expect(decoded.code).toBe(999);\n    expect(decoded.message).toContain('Test error for unit testing');\n    expect(decoded.isKnownError).toBe(true);\n  });\n\n  test('should handle unknown errors gracefully', () =\u003e {\n    const mockError = new Error('Some unknown error');\n    const decoded = decoder.parseError(mockError);\n    \n    expect(decoded.category).toBe('unknown');\n    expect(decoded.isKnownError).toBe(false);\n    expect(typeof decoded.message).toBe('string');\n  });\n});\n```\n\n## API Reference\n\n### `SuiClientErrorDecoder`\n\n#### Constructor\n\n```typescript\nnew SuiClientErrorDecoder(options?: {\n  customErrorCodes?: Record\u003cnumber, string\u003e;\n  customTransactionErrors?: Record\u003cstring, string\u003e;\n  includeDefaults?: boolean; // Default: true\n})\n```\n\n#### Methods\n\n- `parseError(error: any): ParsedError` - The core method. Parses and categorizes an error into a `ParsedError` object.\n- `decodeError(error: any): string` - A convenience method that returns only the human-readable error message string.\n- `addErrorCodes(codes: Record\u003cnumber, string\u003e): void` - Adds or updates custom numeric error codes at runtime.\n- `addTransactionErrors(errors: Record\u003cstring, string\u003e): void` - Adds or updates custom string-based transaction errors at runtime.\n- `updateDefaultErrorCodes(defaultCodes: Record\u003cnumber, string\u003e): void` - Replaces the built-in default codes, preserving any custom codes you've added.\n- `updateDefaultTransactionErrors(defaultErrors: Record\u003cstring, string\u003e): void` - Replaces the built-in default transaction errors, preserving custom ones.\n- `getErrorCodes(): Record\u003cnumber, string\u003e` - Returns a copy of all numeric error codes currently in use (defaults + custom).\n- `getTransactionErrors(): Record\u003cstring, string\u003e` - Returns a copy of all transaction errors currently in use.\n- `getErrorMessage(code: number): string | null` - Gets the message for a specific numeric error code.\n- `getTransactionErrorMessage(errorType: string): string | null` - Gets the message for a specific transaction error type.\n- `isKnownErrorCode(code: number): boolean` - Checks if a numeric error code is in the map.\n- `isKnownTransactionError(errorType: string): boolean` - Checks if a transaction error type is in the map.\n\n### `ParsedError` Object\n\n```typescript\ninterface ParsedError {\n  code?: number;                    // Numeric error code (if available)\n  errorType?: string;              // Transaction error type (if available)\n  message: string;                 // Human-readable error message\n  isKnownError: boolean;          // Whether error is recognized\n  category: 'move_abort' | 'transaction' | 'sui_system' | 'unknown';\n  originalError: any;             // Original error object for debugging\n}\n```\n\n### Utility Functions\n\n```typescript\n// Quick error decoding without creating decoder instance\ndecodeSuiError(error: any, customCodes?: Record\u003cnumber, string\u003e, customTransactionErrors?: Record\u003cstring, string\u003e): string\n\n// Default decoder instance\nimport { defaultDecoder } from 'suiclient-error-decoder';\n```\n\n## Error Categories\n\n| Category       | Description                               | Example Error Codes |\n|----------------|-------------------------------------------|---------------------|\n| `move_abort`   | Errors from Move smart contracts          | 1000-1999          |\n| `sui_system`   | Sui node/system-level errors             | 2000-2999          |\n| `transaction`  | Transaction processing errors            | String-based       |\n| `unknown`      | Unrecognized error patterns              | N/A                |\n\n## Best Practices\n\n1. **Always handle errors**: Wrap your Sui transactions in try-catch blocks\n2. **Use specific error codes**: Define custom error codes for your smart contracts\n3. **Categorize handling**: Handle different error categories appropriately\n4. **Log for debugging**: Keep original error objects for development debugging\n5. **User-friendly messages**: Show decoded messages to users, not raw errors\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a PR:\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a pull request\n\n## Support\n\nFor support, please open an issue on our [GitHub repository](https://github.com/Signor1/suiClient-Error-Decoder/issues)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsignor1%2Fsuiclient-error-decoder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsignor1%2Fsuiclient-error-decoder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsignor1%2Fsuiclient-error-decoder/lists"}