Skip to content

Commit

Permalink
Decode function details by contract calldata
Browse files Browse the repository at this point in the history
  • Loading branch information
davidyuk committed Nov 30, 2024
1 parent 7ba052a commit eafa4cd
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/AciContractCallEncoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,29 @@ class AciContractCallEncoder {
return this._byteArrayEncoder.decodeWithType(data, calldataType)
}

/**
* Decodes function details by contract calldata
*
* @example
* const data = encoder.decodeFunction('cb_KxHwzCuVGyl3aG9vbHltb2x5zwMSnw==')
* console.log(`Decoded data: ${data}`)
* // Outputs:
* // Decoded data: {
* // contractName: "Test",
* // functionName: "test_string",
* // functionId: "f0cc2b95",
* // }
*
* @param {string} data - Encoded calldata in canonical format.
* @returns {object} Decoded function details
*/
decodeFunction(data) {
const {functionId} = this._byteArrayEncoder.decodeWithType(data, FateTypeCalldata())
const {contractName, functionName} = this._typeResolver.getFunction(functionId)

return {contractName, functionName, functionId}
}

/**
* Decodes successful (resultType = ok) contract call return data
*
Expand Down
14 changes: 14 additions & 0 deletions src/AciTypeResolver.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import TypeResolver from './TypeResolver.js'
import TypeResolveError from './Errors/TypeResolveError.js'
import {FateTypeEvent} from './FateTypes.js'
import {symbolIdentifier} from './utils/hash.js'
import {byteArray2Hex} from './utils/int2ByteArray.js'

const isObject = (value) => {
return value && typeof value === 'object' && value.constructor === Object
Expand Down Expand Up @@ -140,6 +142,18 @@ class AciTypeResolver extends TypeResolver {

return [typeDef, vars]
}

getFunction(functionId) {
const { contract } = this.aci.at(-1)
const functionName = contract.functions
.map(e => e.name)
.find((name) => byteArray2Hex(symbolIdentifier(name)) === functionId)
if (functionName == null) {
throw new TypeResolveError(`Unknown function id ${functionId}`)
}

return { contractName: contract.name, functionName }
}
}

export default AciTypeResolver
20 changes: 20 additions & 0 deletions src/api/AciContractCallEncoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,26 @@ class AciContractCallEncoder {
return this._internalEncoder.decodeCall(contract, funName, data)
}

/**
* * Decodes function details by contract calldata
*
* @example
* const data = encoder.decodeFunction('cb_KxHwzCuVGyl3aG9vbHltb2x5zwMSnw==')
* console.log(`Decoded data: ${data}`)
* // Outputs:
* // Decoded data: {
* // contractName: "Test",
* // functionName: "test_string",
* // functionId: "f0cc2b95",
* // }
*
* @param {string} data - Encoded calldata in canonical format.
* @returns {object} Decoded function details
*/
decodeFunction(data) {
return this._internalEncoder.decodeFunction(data)
}

/**
* Decodes successful (resultType = ok) contract call return data
*
Expand Down
6 changes: 6 additions & 0 deletions src/main.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ export class AciContractCallEncoder {
args: any[];
};

decodeFunction(data: `cb_${string}`): {
contractName: string;
functionName: string;
functionId: string;
};

decodeResult(
contract: string,
funName: string,
Expand Down
16 changes: 16 additions & 0 deletions tests/AciContractCallEncoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,22 @@ test('Decode calldata', t => {
)
})

test('Decode calldata without function name', t => {
t.plan(1)
const decoded = encoder.decodeFunction(
'cb_KxGu5Sw8G6+CAAQBSzsrAgQGCK+EAAABAAIbFCg7KwIEBgj8xaf6',
)

t.deepEqual(
decoded,
{
contractName: CONTRACT,
functionName: 'test_template_maze',
functionId: 'aee52c3c',
}
)
})

test('Decode implicit init (void) result', t => {
t.plan(1)
t.is(
Expand Down

0 comments on commit eafa4cd

Please sign in to comment.