navskit
Version:
Deploy TypeScript logic on Ethereum. Includes core library, CLI tools, and utilities.
127 lines (126 loc) • 4.69 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeTaskResult = decodeTaskResult;
exports.decodeValue = decodeValue;
exports.encodeArgs = encodeArgs;
exports.createDecoder = createDecoder;
/**
* Utilities for encoding and decoding data
*/
const viem_1 = require("viem");
const typeUtils_1 = require("./typeUtils");
/**
* Decodes a task result from its binary form
*
* @param type The return type of the function
* @param data The encoded result data
* @returns The decoded result value
*/
function decodeTaskResult(type, data) {
return decodeValue(type, data);
}
/**
* Decodes a value from its encoded form based on the type
*
* @param type The type to decode to (can be Promise<T> which will be unwrapped to T)
* @param data The encoded result data
* @returns The decoded value
*/
function decodeValue(type, data) {
// Unwrap Promise types - store "string" instead of "Promise<string>"
let actualType = type;
if (type.startsWith('Promise<') && type.endsWith('>')) {
actualType = type.slice(8, -1); // Remove "Promise<" and ">"
}
const mapping = (0, typeUtils_1.getTypeMapping)(actualType);
try {
const abiParams = [{
name: 'result',
type: mapping.abiType
}];
const [decodedValue] = (0, viem_1.decodeAbiParameters)(abiParams, data);
return mapping.decoder(decodedValue);
}
catch (error) {
// If standard decoding fails, handle object/JSON cases
if (actualType === 'object' || actualType === 'array') {
try {
// For objects, the result might be encoded as a string
const stringParams = [{
name: 'result',
type: 'string'
}];
const [stringValue] = (0, viem_1.decodeAbiParameters)(stringParams, data);
return JSON.parse(stringValue);
}
catch (jsonError) {
throw new Error(`Failed to decode result as ${actualType}: ${jsonError.message}`);
}
}
throw new Error(`Failed to decode result of type ${actualType}: ${error.message}`);
}
}
/**
* Helper function to encode function arguments to bytes
*
* @param types Array of parameter types
* @param values Array of values to encode
* @returns Encoded bytes as a hex string
*/
function encodeArgs(types, values) {
// Convert types and values to arrays that can be used with encodeAbiParameters
const abiParams = types.map((type, index) => {
const mapping = (0, typeUtils_1.getTypeMapping)(type);
return {
name: `param${index}`,
type: mapping.abiType
};
});
// Encode values with proper type conversion
const encodedValues = values.map((val, i) => {
const mapping = (0, typeUtils_1.getTypeMapping)(types[i]);
return mapping.encoder(val);
});
// Encode all values in a single call using encodeAbiParameters instead of encodePacked
return (0, viem_1.encodeAbiParameters)(abiParams, encodedValues);
}
/**
* Creates a function to decode encoded bytes back into appropriate arguments
* using viem's decodeAbiParameters
*
* @param types Array of parameter types
* @returns A function that decodes bytes into an array of typed arguments
*/
function createDecoder(types) {
return (encodedArgs) => {
if (!encodedArgs || encodedArgs === '0x') {
if (types.length === 0) {
return []; // No arguments expected, no data provided
}
throw new Error('No encoded arguments provided');
}
// Convert our type system to ABI param types
const abiParams = types.map((type, index) => {
const mapping = (0, typeUtils_1.getTypeMapping)(type);
return {
name: `param${index}`,
type: mapping.abiType
};
});
try {
// Use viem's decodeAbiParameters to decode the args
const decoded = (0, viem_1.decodeAbiParameters)(abiParams, encodedArgs);
// Apply type-specific decoders to the decoded values
return decoded.map((value, index) => {
const mapping = (0, typeUtils_1.getTypeMapping)(types[index]);
return mapping.decoder(value);
});
}
catch (error) {
console.error('Decoding error:', error);
console.error('Types:', types);
console.error('Encoded args:', encodedArgs);
throw new Error(`Failed to decode arguments: ${error.message}`);
}
};
}