diff --git a/package-lock.json b/package-lock.json index 565d4175..469fe2b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "hasInstallScript": true, "dependencies": { - "@algorandfoundation/algokit-subscriber": "3.0.1", + "@algorandfoundation/algokit-subscriber": "^3.0.2", "@algorandfoundation/algokit-utils": "^8.1.0", "@auth0/auth0-react": "^2.2.4", "@blockshake/defly-connect": "^1.2.1", @@ -167,9 +167,9 @@ "license": "MIT" }, "node_modules/@algorandfoundation/algokit-subscriber": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-subscriber/-/algokit-subscriber-3.0.1.tgz", - "integrity": "sha512-NJ2Vasu4IUQcROUScpqMW8LBXAURGlKMOeFLpgKX6SXRW/SlmmyGNp1m+WbxKRcIhvAvLVDCARJYUGhsarSBxA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-subscriber/-/algokit-subscriber-3.0.2.tgz", + "integrity": "sha512-mJN+r6CtAamk2f7zh037/gmktJJa7Ox2cunq//6agDNZEVv3X4q73jDLv9RRnNva93VYjDPSyJM+WUHkWx1W3Q==", "dependencies": { "js-sha512": "^0.9.0" }, diff --git a/package.json b/package.json index 84514e59..f6ec0d0e 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "postinstall": "patch-package" }, "dependencies": { - "@algorandfoundation/algokit-subscriber": "3.0.1", + "@algorandfoundation/algokit-subscriber": "^3.0.2", "@algorandfoundation/algokit-utils": "^8.1.0", "@auth0/auth0-react": "^2.2.4", "@blockshake/defly-connect": "^1.2.1", @@ -197,4 +197,4 @@ "overrides": { "ws@>7.0.0 <7.5.9": "7.5.10" } -} +} \ No newline at end of file diff --git a/src/features/abi-methods/utils/parse-errors.ts b/src/features/abi-methods/utils/parse-errors.ts index ddae40c9..a41c9e1c 100644 --- a/src/features/abi-methods/utils/parse-errors.ts +++ b/src/features/abi-methods/utils/parse-errors.ts @@ -1,5 +1,6 @@ import { getApplicationResultAtom } from '@/features/applications/data' import { dataStore } from '@/features/common/data/data-store' +import { asAlgosdkTransactions } from '@/features/transaction-wizard/mappers' import { BuildableTransactionType, BuildMethodCallTransactionResult, BuildTransactionResult } from '@/features/transaction-wizard/models' import { asError } from '@/utils/error' import { AppClient } from '@algorandfoundation/algokit-utils/types/app-client' @@ -8,12 +9,7 @@ import algosdk from 'algosdk' type URLTokenBaseHTTPError = { name: 'URLTokenBaseHTTPError' response: { - body: { - data: { - ['app-index']: number - ['group-index']: number - } - } + text: string } } @@ -23,12 +19,7 @@ type SimulateError = Error & { // eslint-disable-next-line @typescript-eslint/no-explicit-any const isURLTokenBaseHTTPError = (e: any): e is URLTokenBaseHTTPError => { - return ( - e.name === 'URLTokenBaseHTTPError' && - e.response?.body?.data && - e.response.body.data['app-index'] !== undefined && - e.response.body.data['group-index'] !== undefined - ) + return e.name === 'URLTokenBaseHTTPError' && e.response?.text } // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -36,13 +27,41 @@ const isSimulateError = (e: any): e is SimulateError => { return e.simulateResponse !== undefined } +/** + * The supplied transactions array may contain transactions passed as ABI method call args, which become group transactions. + * This function flattens any such args into the transaction group and finds the transaction by group index. + */ +const findTransactionInGroup = async (transactions: BuildTransactionResult[], groupIndex: number) => { + const indexMap: number[] = [] + + for (const [i, transaction] of transactions.entries()) { + // Flattens out transactions passed as ABI method call args + const txns = await asAlgosdkTransactions(transaction) + txns.forEach((_) => { + indexMap.push(i) + }) + } + + const index = indexMap[groupIndex] + if (index === undefined) { + return undefined + } + return transactions[index] +} + export const parseCallAbiMethodError = async (e: unknown, transactions: BuildTransactionResult[]): Promise => { if (!isURLTokenBaseHTTPError(e)) { return asError(e) } - const groupIndex = e.response.body.data['group-index'] - const transaction = transactions[groupIndex] + const errorBody = JSON.parse(e.response.text) + const groupIndex = + errorBody && errorBody.data && errorBody.data['group-index'] !== undefined ? (errorBody.data['group-index'] as number) : undefined + if (groupIndex === undefined) { + return asError(e) + } + + const transaction = await findTransactionInGroup(transactions, groupIndex) if (!transaction || transaction.type !== BuildableTransactionType.MethodCall) { return asError(e) } @@ -62,7 +81,7 @@ export const parseSimulateAbiMethodError = async (e: unknown, transactions: Buil // When there are multiple errors, the failedAt array will only have one element const groupIndex = Number(e.simulateResponse.txnGroups[0].failedAt[0]) - const transaction = transactions[groupIndex] + const transaction = await findTransactionInGroup(transactions, groupIndex) if (!transaction || transaction.type !== BuildableTransactionType.MethodCall) { return asError(e) } @@ -91,7 +110,7 @@ const parseErrorForTransaction = async (e: unknown, groupIndex: number, transact return asError(e) } - return new Error(`Error in transaction ${groupIndex + 1}: ${tealErrorMessage}`) + return new Error(`Error in transaction at index ${groupIndex}: ${tealErrorMessage}`) } const extractErrorMessage = (errorString: string): string | undefined => { diff --git a/src/features/transaction-wizard/utils/transform-search-params-transactions.ts b/src/features/transaction-wizard/utils/transform-search-params-transactions.ts index 15e06682..f0bff532 100644 --- a/src/features/transaction-wizard/utils/transform-search-params-transactions.ts +++ b/src/features/transaction-wizard/utils/transform-search-params-transactions.ts @@ -52,11 +52,11 @@ export function transformSearchParamsTransactions(searchParamTransactions: BaseS } catch (error) { if (error instanceof z.ZodError) { const badPaths = error.errors.map((e) => e.path.join('-')) - errors.push(`Error in transaction ${index} in the following fields: ${badPaths.join(', ')}`) + errors.push(`Error in transaction at index ${index} in the following fields: ${badPaths.join(', ')}`) continue } if (error instanceof Error) { - errors.push(`Error in transaction ${index}: ${error.message}`) + errors.push(`Error in transaction at index ${index}: ${error.message}`) } } }