From 31b302c9b5d8e36c88ba3c29d6e9860d6e4f32f7 Mon Sep 17 00:00:00 2001 From: nikugogoi Date: Tue, 23 Nov 2021 11:23:47 +0530 Subject: [PATCH] Implement eth_call for methods returning struct type (#59) * Handle tuple return type in ethereum host API * Update graph-cli version to fix eth_call error * Handle all types in struct based on abi Co-authored-by: prathamesh0 --- packages/graph-node/src/call-handler.test.ts | 22 +- packages/graph-node/src/eden.test.ts | 266 ++++++------------ packages/graph-node/src/loader.ts | 27 +- packages/graph-node/src/utils.ts | 49 +++- packages/graph-node/src/watcher.ts | 11 +- .../graph-node/test/contracts/Example.sol | 18 ++ .../test/subgraph/example1/abis/Example1.json | 60 ++++ .../example1/generated/Example1/Example1.ts | 81 ++++++ .../test/subgraph/example1/package.json | 2 +- .../test/subgraph/example1/src/mapping.ts | 16 ++ .../test/subgraph/example1/yarn.lock | 36 +-- 11 files changed, 341 insertions(+), 247 deletions(-) diff --git a/packages/graph-node/src/call-handler.test.ts b/packages/graph-node/src/call-handler.test.ts index 8da86bfe..fcc7b39b 100644 --- a/packages/graph-node/src/call-handler.test.ts +++ b/packages/graph-node/src/call-handler.test.ts @@ -5,8 +5,10 @@ import path from 'path'; import chai, { assert, expect } from 'chai'; import spies from 'chai-spies'; +import { utils } from 'ethers'; import { getDummyEventData, getTestDatabase } from '../test/utils'; +import abi from '../test/subgraph/example1/build/Example1/abis/Example1.json'; import { instantiate } from './loader'; import { createEvent, createBlock, Block } from './utils'; import { Database } from './database'; @@ -66,18 +68,14 @@ describe('call handler in mapping code', () => { _start(); // Create event params data. - dummyEventData.eventParams = [ - { - name: 'param1', - value: 'abc', - kind: 'string' - }, - { - name: 'param2', - value: BigInt(123), - kind: 'uint256' - } - ]; + const contractInterface = new utils.Interface(abi); + const eventFragment = contractInterface.getEvent('Test(string,uint8)'); + dummyEventData.inputs = eventFragment.inputs; + + dummyEventData.event = { + param1: 'abc', + param2: BigInt(123) + }; // Dummy contract address string. const contractAddress = '0xCA6D29232D1435D8198E3E5302495417dD073d61'; diff --git a/packages/graph-node/src/eden.test.ts b/packages/graph-node/src/eden.test.ts index a57c166f..9a22c175 100644 --- a/packages/graph-node/src/eden.test.ts +++ b/packages/graph-node/src/eden.test.ts @@ -3,7 +3,7 @@ // import assert from 'assert'; -import { ethers } from 'ethers'; +import { ethers, utils } from 'ethers'; import path from 'path'; import chai from 'chai'; import spies from 'chai-spies'; @@ -65,6 +65,8 @@ describe('eden wasm loader tests', async () => { } }; + const contractInterface = new utils.Interface(edenNetworkAbi); + it('should load the subgraph network wasm', async () => { const filePath = path.resolve(__dirname, '../test/subgraph/eden/EdenNetwork/EdenNetwork.wasm'); ({ exports } = await instantiate(db, { event: { block: dummyEventData.block } }, filePath, data)); @@ -78,43 +80,17 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy SlotClaimedEvent params. - dummyEventData.eventParams = [ - { - name: 'slot', - kind: 'uint8', - value: 0 - }, - { - name: 'owner', - kind: 'address', - value: ZERO_ADDRESS - }, - { - name: 'delegate', - kind: 'address', - value: ZERO_ADDRESS - }, - { - name: 'newBidAmount', - kind: 'uint128', - value: BigInt(1) - }, - { - name: 'oldBidAmount', - kind: 'uint128', - value: BigInt(1) - }, - { - name: 'taxNumerator', - kind: 'uint16', - value: 1 - }, - { - name: 'taxDenominator', - kind: 'uint16', - value: 1 - } - ]; + const eventFragment = contractInterface.getEvent('SlotClaimed(indexed uint8,indexed address,indexed address,uint128,uint128,uint16,uint16)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { + slot: 0, + owner: ZERO_ADDRESS, + delegate: ZERO_ADDRESS, + newBidAmount: BigInt(1), + oldBidAmount: BigInt(1), + taxNumerator: 1, + taxDenominator: 1 + }; // Create an ethereum event SlotClaimedEvent to be passed to handler. const slotClaimedEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -128,28 +104,14 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy SlotDelegateUpdatedEvent params. - dummyEventData.eventParams = [ - { - name: 'slot', - kind: 'uint8', - value: 0 - }, - { - name: 'owner', - kind: 'address', - value: ZERO_ADDRESS - }, - { - name: 'newDelegate', - kind: 'address', - value: ZERO_ADDRESS - }, - { - name: 'oldDelegate', - kind: 'address', - value: ZERO_ADDRESS - } - ]; + const eventFragment = contractInterface.getEvent('SlotDelegateUpdated(indexed uint8,indexed address,indexed address,address)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { + slot: 0, + owner: ZERO_ADDRESS, + newDelegate: ZERO_ADDRESS, + oldDelegate: ZERO_ADDRESS + }; // Create an ethereum event SlotDelegateUpdatedEvent to be passed to handler. const slotClaimedEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -163,18 +125,12 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy StakeEvent params. - dummyEventData.eventParams = [ - { - name: 'staker', - kind: 'address', - value: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc' - }, - { - name: 'stakeAmount', - kind: 'uint256', - value: BigInt(1) - } - ]; + const eventFragment = contractInterface.getEvent('Stake(indexed address,uint256)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { + staker: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc', + stakeAmount: BigInt(1) + }; // Create an ethereum event StakeEvent to be passed to handler. const stakeEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -188,18 +144,12 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy UnstakeEvent params. - dummyEventData.eventParams = [ - { - name: 'staker', - kind: 'address', - value: ZERO_ADDRESS - }, - { - name: 'unstakedAmount', - kind: 'uin256', - value: BigInt(1) - } - ]; + const eventFragment = contractInterface.getEvent('Unstake(indexed address,uint256)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { + staker: ZERO_ADDRESS, + unstakedAmount: BigInt(1) + }; // Create an ethereum event UnstakeEvent to be passed to handler. const unstakeEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -224,6 +174,8 @@ describe('eden wasm loader tests', async () => { } }; + const contractInterface = new utils.Interface(merkleDistributorAbi); + it('should load the subgraph network distribution wasm', async () => { const filePath = path.resolve(__dirname, '../test/subgraph/eden/EdenNetworkDistribution/EdenNetworkDistribution.wasm'); ({ exports } = await instantiate(db, { event: { block: dummyEventData.block } }, filePath, data)); @@ -237,28 +189,14 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy ClaimedEvent params. - dummyEventData.eventParams = [ - { - name: 'index', - kind: 'uint256', - value: BigInt(1) - }, - { - name: 'totalEarned', - kind: 'uint256', - value: BigInt(1) - }, - { - name: 'account', - kind: 'address', - value: ZERO_ADDRESS - }, - { - name: 'claimed', - kind: 'uint256', - value: BigInt(1) - } - ]; + const eventFragment = contractInterface.getEvent('Claimed(uint256,uint256,indexed address,uint256)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { + index: BigInt(1), + totalEarned: BigInt(1), + account: ZERO_ADDRESS, + claimed: BigInt(1) + }; // Create an ethereum event ClaimedEvent to be passed to handler. const claimedEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -272,18 +210,12 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy SlashedEvent params. - dummyEventData.eventParams = [ - { - name: 'account', - kind: 'address', - value: ZERO_ADDRESS - }, - { - name: 'slashed', - kind: 'uint256', - value: BigInt(1) - } - ]; + const eventFragment = contractInterface.getEvent('Slashed(indexed address,uint256)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { + account: ZERO_ADDRESS, + slashed: BigInt(1) + }; // Create an ethereum event SlashedEvent to be passed to handler. const slashedEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -297,23 +229,13 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy MerkleRootUpdatedEvent params. - dummyEventData.eventParams = [ - { - name: 'merkleRoot', - kind: 'bytes32', - value: ethers.utils.hexlify(ethers.utils.randomBytes(32)) - }, - { - name: 'distributionNumber', - kind: 'uint256', - value: BigInt(1) - }, - { - name: 'metadataURI', - kind: 'string', - value: 'abc' - } - ]; + const eventFragment = contractInterface.getEvent('MerkleRootUpdated(bytes32,uint256,string)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { + merkleRoot: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + distributionNumber: BigInt(1), + metadataURI: 'abc' + }; // Create an ethereum event MerkleRootUpdatedEvent to be passed to handler. const merkleRootUpdatedEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -327,23 +249,13 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy AccountUpdatedEvent params. - dummyEventData.eventParams = [ - { - name: 'account', - kind: 'address', - value: ZERO_ADDRESS - }, - { - name: 'totalClaimed', - kind: 'uint256', - value: BigInt(1) - }, - { - name: 'totalSlashed', - kind: 'uint256', - value: BigInt(1) - } - ]; + const eventFragment = contractInterface.getEvent('AccountUpdated(indexed address,uint256,uint256)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { + account: ZERO_ADDRESS, + totalClaimed: BigInt(1), + totalSlashed: BigInt(1) + }; // Create an ethereum event AccountUpdatedEvent to be passed to handler. const accountUpdatedEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -368,6 +280,8 @@ describe('eden wasm loader tests', async () => { } }; + const contractInterface = new utils.Interface(distributorGovernanceAbi); + it('should load the subgraph network governance wasm', async () => { const filePath = path.resolve(__dirname, '../test/subgraph/eden/EdenNetworkGovernance/EdenNetworkGovernance.wasm'); ({ exports } = await instantiate(db, { event: { block: dummyEventData.block } }, filePath, data)); @@ -381,13 +295,9 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy BlockProducerAddedEvent params. - dummyEventData.eventParams = [ - { - name: 'produces', - kind: 'address', - value: ZERO_ADDRESS - } - ]; + const eventFragment = contractInterface.getEvent('BlockProducerAdded(indexed address)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { produces: ZERO_ADDRESS }; // Create an ethereum event BlockProducerAddedEvent to be passed to handler. const blockProducerAddedEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -401,13 +311,9 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy BlockProducerRemovedEvent params. - dummyEventData.eventParams = [ - { - name: 'producer', - kind: 'address', - value: ZERO_ADDRESS - } - ]; + const eventFragment = contractInterface.getEvent('BlockProducerRemoved(indexed address)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { producer: ZERO_ADDRESS }; // Create an ethereum event BlockProducerRemovedEvent to be passed to handler. const blockProducerRemovedEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -421,23 +327,13 @@ describe('eden wasm loader tests', async () => { } = exports; // Create dummy BlockProducerRewardCollectorChangedEvent params. - dummyEventData.eventParams = [ - { - name: 'producer', - kind: 'address', - value: ZERO_ADDRESS - }, - { - name: 'collector', - kind: 'address', - value: ZERO_ADDRESS - }, - { - name: 'metadataURI', - kind: 'string', - value: 'abc' - } - ]; + const eventFragment = contractInterface.getEvent('BlockProducerRewardCollectorChanged(indexed address,indexed address)'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = { + producer: ZERO_ADDRESS, + collector: ZERO_ADDRESS, + metadataURI: 'abc' + }; // Create an ethereum event BlockProducerRewardCollectorChangedEvent to be passed to handler. const blockProducerRewardCollectorChangedEvent = await createEvent(exports, contractAddress, dummyEventData); @@ -450,7 +346,9 @@ describe('eden wasm loader tests', async () => { rewardScheduleChanged } = exports; - dummyEventData.eventParams = []; + const eventFragment = contractInterface.getEvent('RewardScheduleChanged()'); + dummyEventData.inputs = eventFragment.inputs; + dummyEventData.event = {}; // Create an ethereum event RewardScheduleChangedEvent to be passed to handler. const rewardScheduleChangedEvent = await createEvent(exports, contractAddress, dummyEventData); diff --git a/packages/graph-node/src/loader.ts b/packages/graph-node/src/loader.ts index 8f289957..4d1ae908 100644 --- a/packages/graph-node/src/loader.ts +++ b/packages/graph-node/src/loader.ts @@ -138,18 +138,27 @@ export const instantiate = async (database: Database, indexer: IndexerInterface, // TODO: Check for function overloading. let result = await contract[functionName](...functionParams); - if (!Array.isArray(result)) { + // TODO: Check for function overloading. + // Using function signature does not work. + const { outputs } = contract.interface.getFunction(functionName); + assert(outputs); + + // If method returns a single value, ethers returns it directly compared to returning multiple values in an array. + if (outputs.length === 1) { + // Put result in an array to map with the outputs array from abi. result = [result]; } - // TODO: Check for function overloading. - // Using function signature does not work. - const outputs = contract.interface.getFunction(functionName).outputs; - - const resultPtrArrayPromise = result.map(async (value: any, index: number) => { - assert(outputs); - return toEthereumValue(exports, value, outputs[index].type); - }); + const resultPtrArrayPromise = outputs.map( + async ( + output: any, + index: number + ) => toEthereumValue( + exports, + output, + result[index] + ) + ); const resultPtrArray: any[] = await Promise.all(resultPtrArrayPromise); const arrayEthereumValueId = await getIdOfType(TypeId.ArrayEthereumValue); diff --git a/packages/graph-node/src/utils.ts b/packages/graph-node/src/utils.ts index 3f021271..16b5f5cc 100644 --- a/packages/graph-node/src/utils.ts +++ b/packages/graph-node/src/utils.ts @@ -1,4 +1,4 @@ -import { BigNumber } from 'ethers'; +import { BigNumber, utils } from 'ethers'; import path from 'path'; import fs from 'fs-extra'; import debug from 'debug'; @@ -11,12 +11,6 @@ import { TypeId, EthereumValueKind, ValueKind } from './types'; const log = debug('vulcanize:utils'); -interface EventParam { - name: string; - value: any; - kind: string; -} - interface Transaction { hash: string; index: number; @@ -42,7 +36,8 @@ export interface Block { export interface EventData { block: Block; tx: Transaction; - eventParams: EventParam[]; + inputs: utils.ParamType[]; + event: { [key: string]: any } eventIndex: number; } @@ -102,16 +97,41 @@ export const fromEthereumValue = async (instanceExports: any, value: any): Promi * @param type * @returns */ -export const toEthereumValue = async (instanceExports: any, value: any, type: string): Promise => { +export const toEthereumValue = async (instanceExports: any, output: utils.ParamType, value: any): Promise => { const { __newString, + __newArray, ByteArray, Bytes, Address, ethereum, - BigInt + BigInt, + id_of_type: getIdOfType } = instanceExports; + const { type } = output; + + // For tuple type. + if (type === 'tuple') { + const arrayEthereumValueId = await getIdOfType(TypeId.ArrayEthereumValue); + + // Get values for struct elements. + const ethereumValuePromises = output.components + .map( + async (component: utils.ParamType) => toEthereumValue( + instanceExports, + component, + value[component.name] + ) + ); + + const ethereumValues: any[] = await Promise.all(ethereumValuePromises); + const ethereumValuesArrayPtr = await __newArray(arrayEthereumValueId, ethereumValues); + const ethereumTuple = await ethereum.Tuple.wrap(ethereumValuesArrayPtr); + + return ethereum.Value.fromTuple(ethereumTuple); + } + // For boolean type. if (type === 'bool') { return ethereum.Value.fromBoolean(value ? 1 : 0); @@ -163,7 +183,8 @@ export const createEvent = async (instanceExports: any, contractAddress: string, const { tx, eventIndex, - eventParams: eventParamsData, + inputs, + event, block: blockData } = eventData; @@ -214,10 +235,10 @@ export const createEvent = async (instanceExports: any, contractAddress: string, txinputPtr ); - const eventParamArrayPromise = eventParamsData.map(async data => { - const { name, value, kind } = data; + const eventParamArrayPromise = inputs.map(async input => { + const { name } = input; - const ethValue = await toEthereumValue(instanceExports, value, kind); + const ethValue = await toEthereumValue(instanceExports, input, event[name]); const namePtr = await __newString(name); return ethereum.EventParam.__new( diff --git a/packages/graph-node/src/watcher.ts b/packages/graph-node/src/watcher.ts index a1b21b50..57381d95 100644 --- a/packages/graph-node/src/watcher.ts +++ b/packages/graph-node/src/watcher.ts @@ -133,17 +133,10 @@ export class GraphWatcher { const eventFragment = contractInterface.getEvent(eventSignature); - const eventParams = eventFragment.inputs.map((input) => { - return { - name: input.name, - value: event[input.name], - kind: input.type - }; - }); - const data = { - eventParams: eventParams, block: blockData, + inputs: eventFragment.inputs, + event, tx, eventIndex }; diff --git a/packages/graph-node/test/contracts/Example.sol b/packages/graph-node/test/contracts/Example.sol index 37c0578e..ec6fd358 100644 --- a/packages/graph-node/test/contracts/Example.sol +++ b/packages/graph-node/test/contracts/Example.sol @@ -5,6 +5,11 @@ pragma solidity ^0.8.0; contract Example { uint256 private _test; + struct Bid { + uint128 bidAmount1; + uint128 bidAmount2; + } + event Test(string param1, uint8 param2); function getMethod() public view virtual returns (string memory) @@ -12,8 +17,21 @@ contract Example { return 'test'; } + function addMethod(uint128 bidAmount1, uint128 bidAmount2) public pure returns (uint) { + return bidAmount1 + bidAmount2; + } + + function structMethod(uint128 bidAmount1, uint128 bidAmount2) public pure returns (Bid memory) { + Bid memory bid; + bid.bidAmount1 = bidAmount2; + bid.bidAmount2 = bidAmount1; + + return bid; + } + function emitEvent() public virtual returns (bool) { emit Test('abc', 123); + return true; } } diff --git a/packages/graph-node/test/subgraph/example1/abis/Example1.json b/packages/graph-node/test/subgraph/example1/abis/Example1.json index 3233c3ce..45adb189 100644 --- a/packages/graph-node/test/subgraph/example1/abis/Example1.json +++ b/packages/graph-node/test/subgraph/example1/abis/Example1.json @@ -18,6 +18,30 @@ "name": "Test", "type": "event" }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "bidAmount1", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "bidAmount2", + "type": "uint128" + } + ], + "name": "addMethod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [], "name": "emitEvent", @@ -43,5 +67,41 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "bidAmount1", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "bidAmount2", + "type": "uint128" + } + ], + "name": "structMethod", + "outputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "bidAmount1", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "bidAmount2", + "type": "uint128" + } + ], + "internalType": "struct Example.Bid", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" } ] diff --git a/packages/graph-node/test/subgraph/example1/generated/Example1/Example1.ts b/packages/graph-node/test/subgraph/example1/generated/Example1/Example1.ts index 93ac3444..5375259e 100644 --- a/packages/graph-node/test/subgraph/example1/generated/Example1/Example1.ts +++ b/packages/graph-node/test/subgraph/example1/generated/Example1/Example1.ts @@ -32,11 +32,53 @@ export class Test__Params { } } +export class Example1__structMethodResultValue0Struct extends ethereum.Tuple { + get bidAmount1(): BigInt { + return this[0].toBigInt(); + } + + get bidAmount2(): BigInt { + return this[1].toBigInt(); + } +} + export class Example1 extends ethereum.SmartContract { static bind(address: Address): Example1 { return new Example1("Example1", address); } + addMethod(bidAmount1: BigInt, bidAmount2: BigInt): BigInt { + let result = super.call( + "addMethod", + "addMethod(uint128,uint128):(uint256)", + [ + ethereum.Value.fromUnsignedBigInt(bidAmount1), + ethereum.Value.fromUnsignedBigInt(bidAmount2) + ] + ); + + return result[0].toBigInt(); + } + + try_addMethod( + bidAmount1: BigInt, + bidAmount2: BigInt + ): ethereum.CallResult { + let result = super.tryCall( + "addMethod", + "addMethod(uint128,uint128):(uint256)", + [ + ethereum.Value.fromUnsignedBigInt(bidAmount1), + ethereum.Value.fromUnsignedBigInt(bidAmount2) + ] + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + emitEvent(): boolean { let result = super.call("emitEvent", "emitEvent():(bool)", []); @@ -66,6 +108,45 @@ export class Example1 extends ethereum.SmartContract { let value = result.value; return ethereum.CallResult.fromValue(value[0].toString()); } + + structMethod( + bidAmount1: BigInt, + bidAmount2: BigInt + ): Example1__structMethodResultValue0Struct { + let result = super.call( + "structMethod", + "structMethod(uint128,uint128):((uint128,uint128))", + [ + ethereum.Value.fromUnsignedBigInt(bidAmount1), + ethereum.Value.fromUnsignedBigInt(bidAmount2) + ] + ); + + return changetype( + result[0].toTuple() + ); + } + + try_structMethod( + bidAmount1: BigInt, + bidAmount2: BigInt + ): ethereum.CallResult { + let result = super.tryCall( + "structMethod", + "structMethod(uint128,uint128):((uint128,uint128))", + [ + ethereum.Value.fromUnsignedBigInt(bidAmount1), + ethereum.Value.fromUnsignedBigInt(bidAmount2) + ] + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + changetype(value[0].toTuple()) + ); + } } export class EmitEventCall extends ethereum.Call { diff --git a/packages/graph-node/test/subgraph/example1/package.json b/packages/graph-node/test/subgraph/example1/package.json index 02988042..9b23eff2 100644 --- a/packages/graph-node/test/subgraph/example1/package.json +++ b/packages/graph-node/test/subgraph/example1/package.json @@ -10,7 +10,7 @@ "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 example1" }, "dependencies": { - "@graphprotocol/graph-cli": "ssh://git@github.com:vulcanize/graph-cli.git#ng-add-exports", + "@graphprotocol/graph-cli": "ssh://git@github.com:vulcanize/graph-cli.git#graph-watcher", "@graphprotocol/graph-ts": "^0.22.1" } } diff --git a/packages/graph-node/test/subgraph/example1/src/mapping.ts b/packages/graph-node/test/subgraph/example1/src/mapping.ts index 588b4f8d..1315eee4 100644 --- a/packages/graph-node/test/subgraph/example1/src/mapping.ts +++ b/packages/graph-node/test/subgraph/example1/src/mapping.ts @@ -62,6 +62,22 @@ export function handleTest (event: Test): void { // Entities can be written to the store with `.save()` entity.save(); + const contractAddress = dataSource.address(); + const contract = Example1.bind(contractAddress); + + // Access functions by calling them. + const res1 = contract.try_addMethod(BigInt.fromString('10'), BigInt.fromString('20')); + if (res1.reverted) { + log.debug('Contract eth call reverted', []); + } else { + log.debug('Contract eth call result: {}', [res1.value.toString()]); + } + + // Access functions by calling them. + const res = contract.structMethod(BigInt.fromString('1000'), BigInt.fromString('500')); + + log.debug('Contract eth call result: {}', [res.bidAmount1.toString()]); + // Note: If a handler doesn't require existing field values, it is faster // _not_ to load the entity from the store. Instead, create it fresh with // `new Entity(...)`, set the fields that should be updated and save the diff --git a/packages/graph-node/test/subgraph/example1/yarn.lock b/packages/graph-node/test/subgraph/example1/yarn.lock index ce423f2a..eb58178a 100644 --- a/packages/graph-node/test/subgraph/example1/yarn.lock +++ b/packages/graph-node/test/subgraph/example1/yarn.lock @@ -23,9 +23,9 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@graphprotocol/graph-cli@ssh://git@github.com:vulcanize/graph-cli.git#ng-add-exports": - version "0.22.1" - resolved "ssh://git@github.com:vulcanize/graph-cli.git#cae2627e27df7215b8485060fa491fc9854e8dfa" +"@graphprotocol/graph-cli@ssh://git@github.com:vulcanize/graph-cli.git#graph-watcher": + version "0.22.4" + resolved "ssh://git@github.com:vulcanize/graph-cli.git#0f68b8901349493bff3e85072e8cb43fab7b9101" dependencies: assemblyscript "0.19.10" binary-install-raw "0.0.13" @@ -75,14 +75,14 @@ "@types/range-parser" "*" "@types/lodash@^4.14.159": - version "4.14.176" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.176.tgz#641150fc1cda36fbfa329de603bbb175d7ee20c0" - integrity sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ== + version "4.14.177" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.177.tgz#f70c0d19c30fab101cad46b52be60363c43c4578" + integrity sha512-0fDwydE2clKe9MNfvXHBHF9WEahRuj+msTuQqOmAApNORFvhMYZKNGGJdCzuhheVjMps/ti0Ak/iJPACMaevvw== "@types/node@*": - version "16.11.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.7.tgz#36820945061326978c42a01e56b61cd223dfdc42" - integrity sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw== + version "16.11.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.9.tgz#879be3ad7af29f4c1a5c433421bf99fab7047185" + integrity sha512-MKmdASMf3LtPzwLyRrFjtFFZ48cMf8jmX5VRYrDQiJa8Ybu5VAmkqBWqKU8fdCwD8ysw4mQ9nrEHvzg6gunR7A== "@types/node@^12.12.54": version "12.20.37" @@ -1371,9 +1371,9 @@ is-circular@^1.0.2: integrity sha512-YttjnrswnUYRVJvxCvu8z+PGMUSzC2JttP0OEXezlAEdp3EXzhf7IZ3j0gRAybJBQupedIZFhY61Tga6E0qASA== is-electron@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.0.tgz#8943084f09e8b731b3a7a0298a7b5d56f6b7eef0" - integrity sha512-SpMppC2XR3YdxSzczXReBjqs2zGscWQpBIKqwXYBFic0ERaxNVgwLCHwOLZeESfdJQjX0RDvrJ1lBXX2ij+G1Q== + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.1.tgz#751b1dd8a74907422faa5c35aaa0cf66d98086e9" + integrity sha512-r8EEQQsqT+Gn0aXFx7lTFygYQhILLCB+wn0WCDL5LZRINeLH/Rvw1j2oKodELLXYNImQ3CRlVsY8wW4cGOsyuw== is-extglob@^2.1.1: version "2.1.1" @@ -1665,9 +1665,9 @@ libp2p-crypto@~0.16.1: ursa-optional "~0.10.0" lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lodash.camelcase@^4.3.0: version "4.3.0" @@ -2506,9 +2506,9 @@ side-channel@^1.0.4: object-inspect "^1.9.0" signal-exit@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" - integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== signed-varint@^2.0.1: version "2.0.1"