Skip to content

Commit 2edac83

Browse files
committed
Structure result to allow for conditions based on output
1 parent 0007d7a commit 2edac83

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

plugins/web3/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ const web3Plugin: IntegrationPlugin = {
5959
category: "Web3",
6060
stepFunction: "readContractStep",
6161
stepImportPath: "read-contract",
62+
outputFields: [
63+
{
64+
field: "success",
65+
description: "Whether the contract call succeeded",
66+
},
67+
{
68+
field: "result",
69+
description: "The contract function return value (structured based on ABI outputs)",
70+
},
71+
{
72+
field: "error",
73+
description: "Error message if the call failed",
74+
},
75+
],
6276
configFields: [
6377
{
6478
key: "contractAddress",

plugins/web3/steps/read-contract.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ async function stepHandler(
8181
};
8282
}
8383

84+
// Find the selected function in the ABI to get output structure
85+
const functionAbi = parsedAbi.find(
86+
(item: { type: string; name: string }) =>
87+
item.type === "function" && item.name === abiFunction
88+
);
89+
90+
if (!functionAbi) {
91+
console.error("[Read Contract] Function not found in ABI:", abiFunction);
92+
return {
93+
success: false,
94+
error: `Function '${abiFunction}' not found in ABI`,
95+
};
96+
}
97+
8498
// Parse function arguments
8599
let args: unknown[] = [];
86100
if (functionArgs && functionArgs.trim() !== "") {
@@ -161,9 +175,37 @@ async function stepHandler(
161175
)
162176
);
163177

178+
// Transform array results into named objects based on ABI outputs
179+
let structuredResult = serializedResult;
180+
181+
// Check if function has outputs defined in ABI
182+
const outputs = (functionAbi as { outputs?: Array<{ name?: string; type: string }> }).outputs;
183+
184+
if (outputs && outputs.length > 0) {
185+
if (outputs.length === 1) {
186+
// Single output: return the value directly if unnamed, or as object if named
187+
const outputName = outputs[0].name?.trim();
188+
if (outputName) {
189+
// Named single output: wrap in object
190+
structuredResult = { [outputName]: Array.isArray(serializedResult) ? serializedResult[0] : serializedResult };
191+
} else {
192+
// Unnamed single output: return raw value
193+
structuredResult = Array.isArray(serializedResult) ? serializedResult[0] : serializedResult;
194+
}
195+
} else if (Array.isArray(serializedResult)) {
196+
// Multiple outputs: always map to object with field names (named or generated)
197+
structuredResult = {};
198+
outputs.forEach((output, index) => {
199+
const fieldName = output.name?.trim() || `unnamedOutput${index}`;
200+
structuredResult[fieldName] = serializedResult[index];
201+
});
202+
console.log("[Read Contract] Structured result:", structuredResult);
203+
}
204+
}
205+
164206
return {
165207
success: true,
166-
result: serializedResult,
208+
result: structuredResult,
167209
};
168210
} catch (error) {
169211
console.error("[Read Contract] Function call failed:", error);

0 commit comments

Comments
 (0)