graph-tooling
graph-tooling copied to clipboard
Can't handle two dimensional array rightly in codegen from solidity
Which packages are impacted by your issue?
@graphprotocol/graph-cli
Describe the issue
codegen from solidity func like :
function getPositionsByTokenIds(uint256[] memory) public view returns (Position.PositionInfo[][] memory)
The Solidity function return type:Position.PositionInfo[][] is a two-dimensional array. PositionInfo[][] is a two-dimensional array. Each element itself is also a Position.PositionInfo[] array.
TypeScript mapping type: Reader__getPositionsByTokenIdsResultValue0Struct[] is a one-dimensional array. This means that the return type expected by TypeScript is an array of Reader__getPositionsByTokenIdsResultValue0Struct objects, not an array of arrays (a two-dimensional array).
Reproduction
graph codegen
Steps to Reproduce the Bug or Issue
gen code:
getPositionsByTokenIds( tokenIds: Array<BigInt> ): Array<Array<Reader__getPositionsByTokenIdsResultValue0Struct>> { let result = super.call( "getPositionsByTokenIds", "getPositionsByTokenIds(uint256[]):((((uint256,address,address,bool,uint256),uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,bool,(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256)),(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256))),address)[][])", [ethereum.Value.fromUnsignedBigIntArray(tokenIds)] ); return result[0].toTupleMatrix<>(); }
try_getPositionsByTokenIds(tokenIds: Array<BigInt>): ethereum.CallResult<Array<Reader__getPositionsByTokenIdsResultValue0Struct>> { let result = super.tryCall( "getPositionsByTokenIds", "getPositionsByTokenIds(uint256[]):((((uint256,address,address,bool,uint256),uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,bool,(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256)),(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256))),address)[][])", [ethereum.Value.fromUnsignedBigIntArray(tokenIds)] ); if (result.reverted) { return new ethereum.CallResult(); } let value = result.value; return ethereum.CallResult.fromValue(value[0].toTupleMatrix<>()); }
Expected behavior
Screenshots or Videos
No response
Platform
- OS: [e.g. macOS, Windows, Linux]
- NodeJS: [e.g. 18.5.0]
-
@graphprotocol/*
version(s): [e.g. 2.6.2]
Subgraph Manifest
No response
Subgraph GraphQL Schema
No response
Additional context
No response
can you share the ABI or the contract address?
Thx for reply. Here's the function abi gened by solc 0.8.20:
{
"inputs": [
{
"internalType": "uint256[]",
"name": "tokenIds",
"type": "uint256[]"
}
],
"name": "getPositionsByTokenIds",
"outputs": [
{
"components": [
{
"components": [
{
"components": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "contract IVault",
"name": "collateralTokenVault",
"type": "address"
},
{
"internalType": "address",
"name": "indexToken",
"type": "address"
},
{
"internalType": "bool",
"name": "isLong",
"type": "bool"
},
{
"internalType": "uint256",
"name": "giantTokenId",
"type": "uint256"
}
],
"internalType": "struct Keys.PositionKeyInfo",
"name": "keyInfo",
"type": "tuple"
},
{
"internalType": "uint256",
"name": "giantTokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "size",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "collateral",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "averagePrice",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "fundingPerSize",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "claimableFundingPerSize",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "accBorrowingRate",
"type": "uint256"
},
{
"internalType": "int256",
"name": "realisedPnL",
"type": "int256"
},
{
"internalType": "uint256",
"name": "shares",
"type": "uint256"
},
{
"internalType": "bool",
"name": "isLong",
"type": "bool"
},
{
"components": [
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
},
{
"components": [
{
"internalType": "uint256",
"name": "min",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "max",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "blockNumber",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"internalType": "struct Market.Price",
"name": "collateralTokenPrice",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint256",
"name": "min",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "max",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "blockNumber",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"internalType": "struct Market.Price",
"name": "indexTokenPrice",
"type": "tuple"
}
],
"internalType": "struct Position.UpdateInfo",
"name": "increasedInfo",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
},
{
"components": [
{
"internalType": "uint256",
"name": "min",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "max",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "blockNumber",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"internalType": "struct Market.Price",
"name": "collateralTokenPrice",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint256",
"name": "min",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "max",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "blockNumber",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"internalType": "struct Market.Price",
"name": "indexTokenPrice",
"type": "tuple"
}
],
"internalType": "struct Position.UpdateInfo",
"name": "decreasedInfo",
"type": "tuple"
}
],
"internalType": "struct Position.Props",
"name": "position",
"type": "tuple"
},
{
"internalType": "address",
"name": "collateralToken",
"type": "address"
}
],
"internalType": "struct Position.PositionInfo[][]",
"name": "",
"type": "tuple[][]"
}
],
"stateMutability": "view",
"type": "function"
},
It gens ts code:
getPositionsByTokenIds(
tokenIds: Array<BigInt>
): Array<Reader__getPositionsByTokenIdsResultValue0Struct> {
let result = super.call(
"getPositionsByTokenIds",
"getPositionsByTokenIds(uint256[]):((((uint256,address,address,bool,uint256),uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,bool,(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256)),(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256))),address)[][])",
[ethereum.Value.fromUnsignedBigIntArray(tokenIds)]
);
return result[0].toTupleMatrix<>();
}
try_getPositionsByTokenIds(
tokenIds: Array<BigInt>
): ethereum.CallResult<
Array<Reader__getPositionsByTokenIdsResultValue0Struct>
> {
let result = super.tryCall(
"getPositionsByTokenIds",
"getPositionsByTokenIds(uint256[]):((((uint256,address,address,bool,uint256),uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,bool,(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256)),(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256))),address)[][])",
[ethereum.Value.fromUnsignedBigIntArray(tokenIds)]
);
if (result.reverted) {
return new ethereum.CallResult();
}
let value = result.value;
return ethereum.CallResult.fromValue(value[0].toTupleMatrix<>());
}
static error in return
:
It is not possible to assign type "CallResult<Tuple[][]>" to type "CallResult<Reader__getPositionsByTokenIdsResultValue0Struct[]>". ]>".
Type "Tuple[][]" cannot be assigned to type "Reader__getPositionsByTokenIdsResultValue0Struct[]". ts(2322)