diff --git a/packages/codegen/src/templates/indexer-template.handlebars b/packages/codegen/src/templates/indexer-template.handlebars index 4b7d88d1..0a9f8f9f 100644 --- a/packages/codegen/src/templates/indexer-template.handlebars +++ b/packages/codegen/src/templates/indexer-template.handlebars @@ -591,7 +591,7 @@ export class Indexer implements IndexerInterface { eventInfo = { {{#each event.params}} {{#if (compare this.type 'bigint')}} - {{this.name}}: BigInt(ethers.BigNumber.from({{this.name}}).toString()) + {{this.name}}: BigInt({{this.name}}.toString()) {{~else}} {{this.name}} {{~/if}} diff --git a/packages/eden-watcher/src/indexer.ts b/packages/eden-watcher/src/indexer.ts index 843eade6..d98eac70 100644 --- a/packages/eden-watcher/src/indexer.ts +++ b/packages/eden-watcher/src/indexer.ts @@ -624,7 +624,7 @@ export class Indexer implements IndexerInterface { eventInfo = { from, to, - value: BigInt(ethers.BigNumber.from(value).toString()) + value: BigInt(value.toString()) }; break; @@ -635,7 +635,7 @@ export class Indexer implements IndexerInterface { eventInfo = { owner, spender, - value: BigInt(ethers.BigNumber.from(value).toString()) + value: BigInt(value.toString()) }; break; @@ -679,8 +679,8 @@ export class Indexer implements IndexerInterface { slot, owner, delegate, - newBidAmount, - oldBidAmount, + newBidAmount: BigInt(newBidAmount.toString()), + oldBidAmount: BigInt(oldBidAmount.toString()), taxNumerator, taxDenominator }; @@ -704,7 +704,7 @@ export class Indexer implements IndexerInterface { const { staker, stakeAmount } = logDescription.args; eventInfo = { staker, - stakeAmount: BigInt(ethers.BigNumber.from(stakeAmount).toString()) + stakeAmount: BigInt(stakeAmount.toString()) }; break; @@ -714,7 +714,7 @@ export class Indexer implements IndexerInterface { const { staker, unstakedAmount } = logDescription.args; eventInfo = { staker, - unstakedAmount: BigInt(ethers.BigNumber.from(unstakedAmount).toString()) + unstakedAmount: BigInt(unstakedAmount.toString()) }; break; @@ -724,7 +724,7 @@ export class Indexer implements IndexerInterface { const { withdrawer, withdrawalAmount } = logDescription.args; eventInfo = { withdrawer, - withdrawalAmount: BigInt(ethers.BigNumber.from(withdrawalAmount).toString()) + withdrawalAmount: BigInt(withdrawalAmount.toString()) }; break; @@ -748,7 +748,7 @@ export class Indexer implements IndexerInterface { eventInfo = { from, to, - tokenId: BigInt(ethers.BigNumber.from(tokenId).toString()) + tokenId: BigInt(tokenId.toString()) }; break; @@ -759,7 +759,7 @@ export class Indexer implements IndexerInterface { eventInfo = { owner, approved, - tokenId: BigInt(ethers.BigNumber.from(tokenId).toString()) + tokenId: BigInt(tokenId.toString()) }; break; @@ -813,10 +813,10 @@ export class Indexer implements IndexerInterface { eventName = logDescription.name; const { index, totalEarned, account, claimed } = logDescription.args; eventInfo = { - index: BigInt(ethers.BigNumber.from(index).toString()), - totalEarned: BigInt(ethers.BigNumber.from(totalEarned).toString()), + index: BigInt(index.toString()), + totalEarned: BigInt(totalEarned.toString()), account, - claimed: BigInt(ethers.BigNumber.from(claimed).toString()) + claimed: BigInt(claimed.toString()) }; break; @@ -826,7 +826,7 @@ export class Indexer implements IndexerInterface { const { account, slashed } = logDescription.args; eventInfo = { account, - slashed: BigInt(ethers.BigNumber.from(slashed).toString()) + slashed: BigInt(slashed.toString()) }; break; @@ -836,7 +836,7 @@ export class Indexer implements IndexerInterface { const { merkleRoot, distributionNumber, metadataURI } = logDescription.args; eventInfo = { merkleRoot, - distributionNumber: BigInt(ethers.BigNumber.from(distributionNumber).toString()), + distributionNumber: BigInt(distributionNumber.toString()), metadataURI }; @@ -847,8 +847,8 @@ export class Indexer implements IndexerInterface { const { account, totalClaimed, totalSlashed } = logDescription.args; eventInfo = { account, - totalClaimed: BigInt(ethers.BigNumber.from(totalClaimed).toString()), - totalSlashed: BigInt(ethers.BigNumber.from(totalSlashed).toString()) + totalClaimed: BigInt(totalClaimed.toString()), + totalSlashed: BigInt(totalSlashed.toString()) }; break; @@ -858,7 +858,7 @@ export class Indexer implements IndexerInterface { const { value, id } = logDescription.args; eventInfo = { value, - id: BigInt(ethers.BigNumber.from(id).toString()) + id: BigInt(id.toString()) }; break; @@ -877,7 +877,7 @@ export class Indexer implements IndexerInterface { eventName = logDescription.name; const { updateThreshold } = logDescription.args; eventInfo = { - updateThreshold: BigInt(ethers.BigNumber.from(updateThreshold).toString()) + updateThreshold: BigInt(updateThreshold.toString()) }; break; diff --git a/packages/eden-watcher/src/resolvers.ts b/packages/eden-watcher/src/resolvers.ts index de06a341..c72019d7 100644 --- a/packages/eden-watcher/src/resolvers.ts +++ b/packages/eden-watcher/src/resolvers.ts @@ -5,6 +5,8 @@ import assert from 'assert'; import BigInt from 'apollo-type-bigint'; import debug from 'debug'; +import Decimal from 'decimal.js'; +import { GraphQLScalarType } from 'graphql'; import { BlockHeight } from '@vulcanize/util'; @@ -38,6 +40,19 @@ export const createResolvers = async (indexer: Indexer, eventWatcher: EventWatch return { BigInt: new BigInt('bigInt'), + BigDecimal: new GraphQLScalarType({ + name: 'BigDecimal', + description: 'BigDecimal custom scalar type', + parseValue (value) { + // value from the client + return new Decimal(value); + }, + serialize (value: Decimal) { + // value sent to the client + return value.toFixed(); + } + }), + Event: { __resolveType: (obj: any) => { assert(obj.__typename); diff --git a/packages/graph-node/src/call-handler.test.ts b/packages/graph-node/src/call-handler.test.ts index fcc7b39b..2ac5260b 100644 --- a/packages/graph-node/src/call-handler.test.ts +++ b/packages/graph-node/src/call-handler.test.ts @@ -35,11 +35,16 @@ describe('call handler in mapping code', () => { sandbox.on(db, 'fromGraphEntity', async (instanceExports: any, block: Block, entity: string, entityInstance: any) => { const entityFields = [ - { type: 'varchar', propertyName: 'blockHash' }, - { type: 'integer', propertyName: 'blockNumber' }, + { type: 'varchar', propertyName: 'id' }, { type: 'bigint', propertyName: 'count' }, - { type: 'varchar', propertyName: 'param1' }, - { type: 'integer', propertyName: 'param2' } + { type: 'varchar', propertyName: 'paramString' }, + { type: 'integer', propertyName: 'paramInt' }, + { type: 'bigint', propertyName: 'paramBigInt' }, + { type: 'boolean', propertyName: 'paramBoolean' }, + { type: 'varchar', propertyName: 'paramBytes' }, + { type: 'numeric', propertyName: 'paramBigDecimal' }, + { type: 'varchar', propertyName: 'related' }, + { type: 'varchar', propertyName: 'manyRelated' } ]; return db.getEntityValues(instanceExports, block, entityInstance, entityFields); @@ -69,12 +74,13 @@ describe('call handler in mapping code', () => { // Create event params data. const contractInterface = new utils.Interface(abi); - const eventFragment = contractInterface.getEvent('Test(string,uint8)'); + const eventFragment = contractInterface.getEvent('Test(string,uint8,uint256)'); dummyEventData.inputs = eventFragment.inputs; dummyEventData.event = { param1: 'abc', - param2: BigInt(123) + param2: BigInt(150), + param3: BigInt(564894232132154) }; // Dummy contract address string. diff --git a/packages/graph-node/src/loader.ts b/packages/graph-node/src/loader.ts index f5bc03d2..b24c6c96 100644 --- a/packages/graph-node/src/loader.ts +++ b/packages/graph-node/src/loader.ts @@ -11,7 +11,6 @@ import { Contract, ContractInterface } from 'ethers'; -import Decimal from 'decimal.js'; import JSONbig from 'json-bigint'; import BN from 'bn.js'; @@ -19,7 +18,7 @@ import loader from '@vulcanize/assemblyscript/lib/loader'; import { IndexerInterface } from '@vulcanize/util'; import { TypeId } from './types'; -import { Block, fromEthereumValue, toEthereumValue, resolveEntityFieldConflicts } from './utils'; +import { Block, fromEthereumValue, toEthereumValue, resolveEntityFieldConflicts, GraphDecimal, digitsToString } from './utils'; import { Database } from './database'; const NETWORK_URL = 'http://127.0.0.1:8081'; @@ -238,12 +237,12 @@ export const instantiate = async ( // Creating decimal x. const xBigDecimal = await BigDecimal.wrap(x); const xStringPtr = await xBigDecimal.toString(); - const xDecimal = new Decimal(__getString(xStringPtr)); + const xDecimal = new GraphDecimal(__getString(xStringPtr)); // Create decimal y. const yBigDecimal = await BigDecimal.wrap(y); const yStringPtr = await yBigDecimal.toString(); - const yDecimal = new Decimal(__getString(yStringPtr)); + const yDecimal = new GraphDecimal(__getString(yStringPtr)); // Performing the decimal division operation. const divResult = xDecimal.dividedBy(yDecimal); @@ -267,17 +266,19 @@ export const instantiate = async ( const expStringPtr = await expBigInt.toString(); const exp = __getString(expStringPtr); - const decimal = new Decimal(`${digits}e${exp}`); + const decimal = new GraphDecimal(`${digits}e${exp}`); const ptr = __newString(decimal.toFixed()); return ptr; }, 'bigDecimal.fromString': async (s: number) => { const string = __getString(s); - const decimal = new Decimal(string); + + // Creating a decimal with the configured precision applied. + const decimal = new GraphDecimal(string).toSignificantDigits(); // Convert from digits array to BigInt. - const digits = decimal.d.join(''); + const digits = digitsToString(decimal.d); const digitsBigNumber = BigNumber.from(digits); const signBigNumber = BigNumber.from(decimal.s); const digitsStringPtr = await __newString(digitsBigNumber.mul(signBigNumber).toString()); @@ -305,7 +306,7 @@ export const instantiate = async ( const yDecimalString = __getString(yStringPtr); // Perform the decimal sum operation. - const sumResult = Decimal.sum(xDecimalString, yDecimalString); + const sumResult = GraphDecimal.sum(xDecimalString, yDecimalString); const ptr = await __newString(sumResult.toString()); const sumResultBigDecimal = await BigDecimal.fromString(ptr); @@ -323,7 +324,7 @@ export const instantiate = async ( const yDecimalString = __getString(yStringPtr); // Perform the decimal sub operation. - const subResult = Decimal.sub(xDecimalString, yDecimalString); + const subResult = GraphDecimal.sub(xDecimalString, yDecimalString); const ptr = await __newString(subResult.toString()); const subResultBigDecimal = await BigDecimal.fromString(ptr); @@ -341,7 +342,7 @@ export const instantiate = async ( const yDecimalString = __getString(yStringPtr); // Perform the decimal mul operation. - const mulResult = Decimal.mul(xDecimalString, yDecimalString); + const mulResult = GraphDecimal.mul(xDecimalString, yDecimalString); const ptr = await __newString(mulResult.toString()); const mulResultBigDecimal = await BigDecimal.fromString(ptr); @@ -431,12 +432,12 @@ export const instantiate = async ( // Create a decimal out of bigInt x. const xBigInt = await BigInt.wrap(x); const xStringPtr = await xBigInt.toString(); - const xDecimal = new Decimal(__getString(xStringPtr)); + const xDecimal = new GraphDecimal(__getString(xStringPtr)); // Create decimal y. const yBigDecimal = await BigDecimal.wrap(y); const yStringPtr = await yBigDecimal.toString(); - const yDecimal = new Decimal(__getString(yStringPtr)); + const yDecimal = new GraphDecimal(__getString(yStringPtr)); // Perform the decimal division operation. const divResult = xDecimal.dividedBy(yDecimal); diff --git a/packages/graph-node/src/numbers.test.ts b/packages/graph-node/src/numbers.test.ts index 8995e27c..6d411eda 100644 --- a/packages/graph-node/src/numbers.test.ts +++ b/packages/graph-node/src/numbers.test.ts @@ -90,23 +90,23 @@ describe('numbers wasm tests', () => { }); it('should execute bigInt dividedByDecimal for positive dividend and positive divisor', async () => { - const ptr = await testBigIntDividedByDecimal(await __newString('2315432122132354'), await __newString('54652.65645')); - expect(__getString(ptr)).to.equal('42366323478.725506672'); + const ptr = await testBigIntDividedByDecimal(await __newString('231543212213235645154'), await __newString('552.65645')); + expect(__getString(ptr)).to.equal('418964100053904455.7500414588484401'); }); it('should execute bigInt dividedByDecimal for negative dividend and positive divisor', async () => { - const ptr = await testBigIntDividedByDecimal(await __newString('-2315432122132354'), await __newString('54652.65645')); - expect(__getString(ptr)).to.equal('-42366323478.725506672'); + const ptr = await testBigIntDividedByDecimal(await __newString('-231543212213235645154'), await __newString('552.65645')); + expect(__getString(ptr)).to.equal('-418964100053904455.7500414588484401'); }); it('should execute bigInt dividedByDecimal for positive dividend and negative divisor', async () => { - const ptr = await testBigIntDividedByDecimal(await __newString('2315432122132354'), await __newString('-54652.65645')); - expect(__getString(ptr)).to.equal('-42366323478.725506672'); + const ptr = await testBigIntDividedByDecimal(await __newString('231543212213235645154'), await __newString('-552.65645')); + expect(__getString(ptr)).to.equal('-418964100053904455.7500414588484401'); }); it('should execute bigInt dividedByDecimal for negative dividend and negative divisor', async () => { - const ptr = await testBigIntDividedByDecimal(await __newString('-2315432122132354'), await __newString('-54652.65645')); - expect(__getString(ptr)).to.equal('42366323478.725506672'); + const ptr = await testBigIntDividedByDecimal(await __newString('-231543212213235645154'), await __newString('-552.65645')); + expect(__getString(ptr)).to.equal('418964100053904455.7500414588484401'); }); }); @@ -121,7 +121,7 @@ describe('numbers wasm tests', () => { const { testBigDecimalToString, __newString, __getString } = exports; const ptr = await testBigDecimalToString(await __newString('-5032485723458348569331745849735.3343434634691214453454356561')); - expect(__getString(ptr)).to.equal('-5032485723458348569331745849735.3343434634691214453454356561'); + expect(__getString(ptr)).to.equal('-5032485723458348569331745849735.334'); }); describe('should execute bigDecimal fromString API', () => { @@ -138,7 +138,7 @@ describe('numbers wasm tests', () => { it('should get bigDecimal for numbers with decimals', async () => { const ptr = await testBigDecimalFromString(await __newString('-5032485723458348569331745849735.3343434634691214453454356561')); - expect(__getString(ptr)).to.equal('-5032485723458348569331745849735.3343434634691214453454356561'); + expect(__getString(ptr)).to.equal('-5032485723458348569331745849735.334'); }); }); @@ -160,13 +160,13 @@ describe('numbers wasm tests', () => { const { testBigDecimalTimes, __getString, __newString } = exports; const ptr = await testBigDecimalTimes(await __newString('231543212.2132354'), await __newString('54652.65645')); - expect(__getString(ptr)).to.equal('12654451630419.398459'); + expect(__getString(ptr)).to.equal('12654451630419.39845917833'); }); it('should execute bigDecimal dividedBy API', async () => { const { testBigDecimalDividedBy, __getString, __newString } = exports; const ptr = await testBigDecimalDividedBy(await __newString('231543212.2132354'), await __newString('54652.65645')); - expect(__getString(ptr)).to.equal('4236.6323478725506672'); + expect(__getString(ptr)).to.equal('4236.632347872550667205491344419362'); }); }); diff --git a/packages/graph-node/src/utils.ts b/packages/graph-node/src/utils.ts index 16b5f5cc..8290f546 100644 --- a/packages/graph-node/src/utils.ts +++ b/packages/graph-node/src/utils.ts @@ -11,6 +11,13 @@ import { TypeId, EthereumValueKind, ValueKind } from './types'; const log = debug('vulcanize:utils'); +// Customize Decimal according the limits of IEEE-754 decimal128. +// Reference: https://github.com/graphprotocol/graph-node/blob/v0.24.2/graph/src/data/store/scalar.rs#L42 +export const GraphDecimal = Decimal.clone({ minE: -6143, maxE: 6144, precision: 34 }); + +// Constant used in function digitsToString. +const LOG_BASE = 7; + interface Transaction { hash: string; index: number; @@ -436,7 +443,7 @@ const parseEntityValue = async (instanceExports: any, valuePtr: number) => { const bigDecimal = BigDecimal.wrap(bigDecimalPtr); const bigDecimalStringPtr = await bigDecimal.toString(); - return new Decimal(__getString(bigDecimalStringPtr)); + return new GraphDecimal(__getString(bigDecimalStringPtr)).toFixed(); } case ValueKind.ARRAY: { @@ -542,3 +549,40 @@ export const resolveEntityFieldConflicts = (entity: any): any => { return entity; }; + +// Get digits in a string from an array of digit numbers (Decimal().d) +// https://github.com/MikeMcl/decimal.js/blob/master/decimal.mjs#L2516 +export function digitsToString (d: any) { + let i, k, ws; + const indexOfLastWord = d.length - 1; + let str = ''; + let w = d[0]; + + if (indexOfLastWord > 0) { + str += w; + for (i = 1; i < indexOfLastWord; i++) { + ws = d[i] + ''; + k = LOG_BASE - ws.length; + if (k) str += getZeroString(k); + str += ws; + } + + w = d[i]; + ws = w + ''; + k = LOG_BASE - ws.length; + if (k) str += getZeroString(k); + } else if (w === 0) { + return '0'; + } + + // Remove trailing zeros of last w. + for (; w % 10 === 0;) w /= 10; + + return str + w; +} + +function getZeroString (k: any) { + let zs = ''; + for (; k--;) zs += '0'; + return zs; +} diff --git a/packages/graph-node/test/contracts/Example.sol b/packages/graph-node/test/contracts/Example.sol index ec6fd358..6f9faeaf 100644 --- a/packages/graph-node/test/contracts/Example.sol +++ b/packages/graph-node/test/contracts/Example.sol @@ -10,7 +10,7 @@ contract Example { uint128 bidAmount2; } - event Test(string param1, uint8 param2); + event Test(string param1, uint8 param2, uint256 param3); function getMethod() public view virtual returns (string memory) { @@ -30,7 +30,7 @@ contract Example { } function emitEvent() public virtual returns (bool) { - emit Test('abc', 123); + emit Test('abc', 150, 564894232132154); 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 45adb189..df17d1b9 100644 --- a/packages/graph-node/test/subgraph/example1/abis/Example1.json +++ b/packages/graph-node/test/subgraph/example1/abis/Example1.json @@ -13,6 +13,12 @@ "internalType": "uint8", "name": "param2", "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "param3", + "type": "uint256" } ], "name": "Test", 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 5375259e..12555d96 100644 --- a/packages/graph-node/test/subgraph/example1/generated/Example1/Example1.ts +++ b/packages/graph-node/test/subgraph/example1/generated/Example1/Example1.ts @@ -30,6 +30,10 @@ export class Test__Params { get param2(): i32 { return this._event.parameters[1].value.toI32(); } + + get param3(): BigInt { + return this._event.parameters[2].value.toBigInt(); + } } export class Example1__structMethodResultValue0Struct extends ethereum.Tuple { diff --git a/packages/graph-node/test/subgraph/example1/generated/schema.ts b/packages/graph-node/test/subgraph/example1/generated/schema.ts index 866bf97a..2c186824 100644 --- a/packages/graph-node/test/subgraph/example1/generated/schema.ts +++ b/packages/graph-node/test/subgraph/example1/generated/schema.ts @@ -105,6 +105,7 @@ export class Author extends Entity { this.set("name", Value.fromString("")); this.set("rating", Value.fromBigDecimal(BigDecimal.zero())); this.set("paramInt", Value.fromI32(0)); + this.set("paramBigInt", Value.fromBigInt(BigInt.zero())); this.set("paramBytes", Value.fromBytes(Bytes.empty())); } @@ -170,6 +171,15 @@ export class Author extends Entity { this.set("paramInt", Value.fromI32(value)); } + get paramBigInt(): BigInt { + let value = this.get("paramBigInt"); + return value!.toBigInt(); + } + + set paramBigInt(value: BigInt) { + this.set("paramBigInt", Value.fromBigInt(value)); + } + get paramBytes(): Bytes { let value = this.get("paramBytes"); return value!.toBytes(); diff --git a/packages/graph-node/test/subgraph/example1/schema.graphql b/packages/graph-node/test/subgraph/example1/schema.graphql index c36ee617..7ed5ab16 100644 --- a/packages/graph-node/test/subgraph/example1/schema.graphql +++ b/packages/graph-node/test/subgraph/example1/schema.graphql @@ -18,6 +18,7 @@ type Author @entity { name: String! # string rating: BigDecimal! paramInt: Int! # uint8 + paramBigInt: BigInt! # uint256 paramBytes: Bytes! blogs: [Blog!]! @derivedFrom(field: "author") } diff --git a/packages/graph-node/test/subgraph/example1/src/mapping.ts b/packages/graph-node/test/subgraph/example1/src/mapping.ts index 959fd2be..45a0b71a 100644 --- a/packages/graph-node/test/subgraph/example1/src/mapping.ts +++ b/packages/graph-node/test/subgraph/example1/src/mapping.ts @@ -10,6 +10,7 @@ export function handleTest (event: Test): void { log.debug('event.address: {}', [event.address.toHexString()]); log.debug('event.params.param1: {}', [event.params.param1]); log.debug('event.params.param2: {}', [event.params.param2.toString()]); + log.debug('event.params.param3: {}', [event.params.param3.toString()]); log.debug('event.block.hash: {}', [event.block.hash.toHexString()]); log.debug('event.block.stateRoot: {}', [event.block.stateRoot.toHexString()]); @@ -32,8 +33,9 @@ export function handleTest (event: Test): void { // Entity fields can be set based on event parameters author.name = event.params.param1; author.paramInt = event.params.param2; + author.paramBigInt = event.params.param3; author.paramBytes = event.address; - author.rating = BigDecimal.fromString('4'); + author.rating = BigDecimal.fromString('3.2132354'); // Entities can be written to the store with `.save()` author.save(); diff --git a/packages/graph-node/test/subgraph/example1/subgraph.yaml b/packages/graph-node/test/subgraph/example1/subgraph.yaml index 569c08de..67ec9c72 100644 --- a/packages/graph-node/test/subgraph/example1/subgraph.yaml +++ b/packages/graph-node/test/subgraph/example1/subgraph.yaml @@ -19,7 +19,7 @@ dataSources: - name: Example1 file: ./abis/Example1.json eventHandlers: - - event: Test(string,uint8) + - event: Test(string,uint8,uint256) handler: handleTest blockHandlers: - handler: handleBlock diff --git a/packages/graph-test-watcher/src/artifacts/Example.json b/packages/graph-test-watcher/src/artifacts/Example.json index f48d9df3..294f2acc 100644 --- a/packages/graph-test-watcher/src/artifacts/Example.json +++ b/packages/graph-test-watcher/src/artifacts/Example.json @@ -14,11 +14,41 @@ "internalType": "uint8", "name": "param2", "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "param3", + "type": "uint256" } ], "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", @@ -44,6 +74,42 @@ ], "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" } ], "storageLayout": { diff --git a/packages/graph-test-watcher/src/entity/Author.ts b/packages/graph-test-watcher/src/entity/Author.ts index 5981e743..4f1ed612 100644 --- a/packages/graph-test-watcher/src/entity/Author.ts +++ b/packages/graph-test-watcher/src/entity/Author.ts @@ -27,6 +27,9 @@ export class Author { @Column('integer') paramInt!: number + @Column('bigint', { transformer: bigintTransformer }) + paramBigInt!: number + @Column('varchar') paramBytes!: string diff --git a/packages/graph-test-watcher/src/indexer.ts b/packages/graph-test-watcher/src/indexer.ts index 7dbe2089..c447e440 100644 --- a/packages/graph-test-watcher/src/indexer.ts +++ b/packages/graph-test-watcher/src/indexer.ts @@ -584,10 +584,11 @@ export class Indexer implements IndexerInterface { switch (logDescription.name) { case TEST_EVENT: { eventName = logDescription.name; - const { param1, param2 } = logDescription.args; + const { param1, param2, param3 } = logDescription.args; eventInfo = { param1, - param2 + param2, + param3: BigInt(param3.toString()) }; break; diff --git a/packages/graph-test-watcher/src/resolvers.ts b/packages/graph-test-watcher/src/resolvers.ts index fd5fd8fe..866c6b7b 100644 --- a/packages/graph-test-watcher/src/resolvers.ts +++ b/packages/graph-test-watcher/src/resolvers.ts @@ -5,6 +5,8 @@ import assert from 'assert'; import BigInt from 'apollo-type-bigint'; import debug from 'debug'; +import Decimal from 'decimal.js'; +import { GraphQLScalarType } from 'graphql'; import { ValueResult, BlockHeight } from '@vulcanize/util'; @@ -23,6 +25,19 @@ export const createResolvers = async (indexer: Indexer, eventWatcher: EventWatch return { BigInt: new BigInt('bigInt'), + BigDecimal: new GraphQLScalarType({ + name: 'BigDecimal', + description: 'BigDecimal custom scalar type', + parseValue (value) { + // value from the client + return new Decimal(value); + }, + serialize (value: Decimal) { + // value sent to the client + return value.toFixed(); + } + }), + Event: { __resolveType: (obj: any) => { assert(obj.__typename); diff --git a/packages/graph-test-watcher/src/schema.gql b/packages/graph-test-watcher/src/schema.gql index 99ee2d99..e96a1eb5 100644 --- a/packages/graph-test-watcher/src/schema.gql +++ b/packages/graph-test-watcher/src/schema.gql @@ -62,6 +62,7 @@ union Event = TestEvent type TestEvent { param1: String! param2: Int! + param3: BigInt! } type ResultIPLDBlock { @@ -110,6 +111,7 @@ type Author { name: String! rating: BigDecimal! paramInt: Int! + paramBigInt: BigInt! paramBytes: Bytes! blogs: [Blog!]! }