From 25ac860709b51e7cecbda6ac0d15c16e0a2bd9df Mon Sep 17 00:00:00 2001 From: Jake Hein Date: Mon, 12 Sep 2022 12:38:51 -0700 Subject: [PATCH 1/7] added multicall interface and functions --- frontend/src/interfaces/Multicall.ts | 21 +++++++++++++++++++++ frontend/src/interfaces/index.ts | 1 + frontend/src/utils/multicall.ts | 13 +++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 frontend/src/interfaces/Multicall.ts create mode 100644 frontend/src/utils/multicall.ts diff --git a/frontend/src/interfaces/Multicall.ts b/frontend/src/interfaces/Multicall.ts new file mode 100644 index 000000000..43e2cea7a --- /dev/null +++ b/frontend/src/interfaces/Multicall.ts @@ -0,0 +1,21 @@ +import { Web3JsAbiCall } from '../../../abi-common'; + +export interface getNFTCall { + abi: any; + calls: callData[]; +} + +export interface callData { + address: string; + name: string; + params: string[]; +} + +export interface returnData { + blockNumber: number; + returnData: string[]; +} + +export interface MultiCall { + aggregate(calldata: string[]): Web3JsAbiCall; +} diff --git a/frontend/src/interfaces/index.ts b/frontend/src/interfaces/index.ts index edeed76db..0609c491a 100644 --- a/frontend/src/interfaces/index.ts +++ b/frontend/src/interfaces/index.ts @@ -4,3 +4,4 @@ export * from './State'; export * from './Target'; export * from './Weapon'; export * from './Contracts'; +export * from './Multicall'; diff --git a/frontend/src/utils/multicall.ts b/frontend/src/utils/multicall.ts new file mode 100644 index 000000000..92aff2c0e --- /dev/null +++ b/frontend/src/utils/multicall.ts @@ -0,0 +1,13 @@ +import { callData, getNFTCall } from '@/interfaces'; + +export function getNFTCall(abi: any, address: any, name: string, params: any[]): getNFTCall { + const calls: callData[] = params.map((param: string[]) => ({ + address, + name, + params: param, + })); + return { + abi, + calls, + }; +} From c753bedddcb8318cabc2042b39422aacd04b4eb7 Mon Sep 17 00:00:00 2001 From: Jake Hein Date: Mon, 12 Sep 2022 13:07:58 -0700 Subject: [PATCH 2/7] more scaffolding work for multiCall (see CBM) --- frontend/src/contracts.ts | 7 +++++- frontend/src/data/Multicall.json | 32 ++++++++++++++++++++++++++++ frontend/src/interfaces/Contracts.ts | 2 ++ frontend/src/store/store.ts | 1 + 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 frontend/src/data/Multicall.json diff --git a/frontend/src/contracts.ts b/frontend/src/contracts.ts index f3dd90a7a..c1af1538f 100644 --- a/frontend/src/contracts.ts +++ b/frontend/src/contracts.ts @@ -72,6 +72,7 @@ import { StakingContractEntry, stakingContractsInfo, nftStakingContractsInfo } f import {raid, pvp, quests, burningManager} from './feature-flags'; import {currentChainSupportsPvP, currentChainSupportsQuests} from '@/utils/common'; +import multicallAbi from '@/data/MultiCall.json'; interface RaidContracts { Raid1?: Contracts['Raid1']; @@ -368,6 +369,9 @@ export async function setUpContracts(web3: Web3): Promise { const treasuryContractAddr = getConfigValue('VUE_APP_TREASURY_CONTRACT_ADDRESS') || (treasuryNetworks as Networks)[networkId]!.address; const Treasury = new web3.eth.Contract(treasuryAbi as Abi, treasuryContractAddr); + const multicallAddr = getConfigValue('VUE_APP_CONTRACT_ADDRESS'); + const MultiCall = new web3.eth.Contract(multicallAbi as Abi, multicallAddr); + let BurningManager; if(burningManager) { const burningManagerContractAddr = getConfigValue('VUE_APP_BURNING_MANAGER_CONTRACT_ADDRESS') || (burningManagerNetworks as Networks)[networkId]!.address; @@ -413,6 +417,7 @@ export async function setUpContracts(web3: Web3): Promise { KingStakingRewardsUpgradeable, KingStakingRewardsUpgradeable90, KingStakingRewardsUpgradeable180, - SpecialWeaponsManager + SpecialWeaponsManager, + MultiCall }; } diff --git a/frontend/src/data/Multicall.json b/frontend/src/data/Multicall.json new file mode 100644 index 000000000..e7c5b8bbd --- /dev/null +++ b/frontend/src/data/Multicall.json @@ -0,0 +1,32 @@ +[ + { + "constant": true, + "inputs": [ + { + "components": [ + { "name": "target", "type": "address" }, + { "name": "callData", "type": "bytes" } + ], + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate", + "outputs": [ + { "name": "blockNumber", "type": "uint256" }, + { "name": "returnData", "type": "bytes[]" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "addr", "type": "address" }], + "name": "getEthBalance", + "outputs": [{ "name": "balance", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/frontend/src/interfaces/Contracts.ts b/frontend/src/interfaces/Contracts.ts index f6058460b..42846ca35 100644 --- a/frontend/src/interfaces/Contracts.ts +++ b/frontend/src/interfaces/Contracts.ts @@ -8,6 +8,7 @@ import type { WeaponCosmetics, CharacterCosmetics, NFTStorage, CBKLandSale, CBKLand, Treasury, Promos, BurningManager, SimpleQuests, PartnerVault, SpecialWeaponsManager, PvpCore, PvpRankings, TokensManager } from '../../../build/abi-interfaces'; +import { MultiCall } from './Multicall'; import { StakeType, NftStakeType } from './State'; interface TypeSafeContract { @@ -70,4 +71,5 @@ export interface Contracts { SimpleQuests?: Contract; PartnerVault?: Contract; SpecialWeaponsManager?: Contract; + MultiCall: Contract; } diff --git a/frontend/src/store/store.ts b/frontend/src/store/store.ts index 00d1e68ad..043bfefe1 100644 --- a/frontend/src/store/store.ts +++ b/frontend/src/store/store.ts @@ -16,6 +16,7 @@ import {burningManager as featureFlagBurningManager} from '@/feature-flags'; import {ERC20, IERC721, INftStakingRewards, IStakingRewards} from '@/../../build/abi-interfaces'; import {stakeTypeThatCanHaveUnclaimedRewardsStakedTo} from '@/stake-types'; import {Nft} from '@/interfaces/Nft'; +import {getNFTCall} from '@/utils/multicall'; import {Element} from '@/enums/Element'; import {getWeaponNameFromSeed} from '@/weapon-name'; import axios from 'axios'; From d6570bee2e9211284217f45c7b2d57ebc2222aae Mon Sep 17 00:00:00 2001 From: Jake Hein Date: Mon, 12 Sep 2022 15:06:39 -0700 Subject: [PATCH 3/7] build errors fixed. Next up is changing store.ts --- frontend/src/contracts.ts | 2 +- frontend/src/data/Multicall.json | 67 +++++++++++++++++--------------- frontend/src/store/store.ts | 15 ++++++- 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/frontend/src/contracts.ts b/frontend/src/contracts.ts index c1af1538f..20c4b4d05 100644 --- a/frontend/src/contracts.ts +++ b/frontend/src/contracts.ts @@ -72,7 +72,7 @@ import { StakingContractEntry, stakingContractsInfo, nftStakingContractsInfo } f import {raid, pvp, quests, burningManager} from './feature-flags'; import {currentChainSupportsPvP, currentChainSupportsQuests} from '@/utils/common'; -import multicallAbi from '@/data/MultiCall.json'; +import {abi as multicallAbi} from './data/MultiCall.json'; interface RaidContracts { Raid1?: Contracts['Raid1']; diff --git a/frontend/src/data/Multicall.json b/frontend/src/data/Multicall.json index e7c5b8bbd..10f11d911 100644 --- a/frontend/src/data/Multicall.json +++ b/frontend/src/data/Multicall.json @@ -1,32 +1,35 @@ -[ - { - "constant": true, - "inputs": [ - { - "components": [ - { "name": "target", "type": "address" }, - { "name": "callData", "type": "bytes" } - ], - "name": "calls", - "type": "tuple[]" - } - ], - "name": "aggregate", - "outputs": [ - { "name": "blockNumber", "type": "uint256" }, - { "name": "returnData", "type": "bytes[]" } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [{ "name": "addr", "type": "address" }], - "name": "getEthBalance", - "outputs": [{ "name": "balance", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - } -] +{ + "contractName": "MultiCall", + "abi": [ + { + "constant": true, + "inputs": [ + { + "components": [ + { "name": "target", "type": "address" }, + { "name": "callData", "type": "bytes" } + ], + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate", + "outputs": [ + { "name": "blockNumber", "type": "uint256" }, + { "name": "returnData", "type": "bytes[]" } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "addr", "type": "address" }], + "name": "getEthBalance", + "outputs": [{ "name": "balance", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + } + ] +} diff --git a/frontend/src/store/store.ts b/frontend/src/store/store.ts index 043bfefe1..2dcf49cf1 100644 --- a/frontend/src/store/store.ts +++ b/frontend/src/store/store.ts @@ -16,7 +16,8 @@ import {burningManager as featureFlagBurningManager} from '@/feature-flags'; import {ERC20, IERC721, INftStakingRewards, IStakingRewards} from '@/../../build/abi-interfaces'; import {stakeTypeThatCanHaveUnclaimedRewardsStakedTo} from '@/stake-types'; import {Nft} from '@/interfaces/Nft'; -import {getNFTCall} from '@/utils/multicall'; +//import {getNFTCall} from '@/utils/multicall'; +import { Interface } from '@ethersproject/abi'; import {Element} from '@/enums/Element'; import {getWeaponNameFromSeed} from '@/weapon-name'; import axios from 'axios'; @@ -2770,5 +2771,17 @@ export default new Vuex.Store({ return CryptoBlades.methods.getMintCharacterFee().call(defaultCallOptions(state)); }, + + async multicall({state}, {abi, calls}) { + const { MultiCall } = state.contracts(); + const itf = new Interface(abi); + const data = calls.map((call: any) => [ + call.address.toLowerCase(), + itf.encodeFunctionData(call.name, call.params), + ]); + const { returnData } = await MultiCall.methods.aggregate(data).call(defaultCallOptions(state)); + const res = returnData.map((call, i) => itf.decodeFunctionResult(calls[i].name, call)); + return res; + }, } }); From 5dcdd6ceb9b8fe5858f9c20f8f340c47ac4a33a3 Mon Sep 17 00:00:00 2001 From: Jake Hein Date: Wed, 14 Sep 2022 12:23:23 -0700 Subject: [PATCH 4/7] added multicall to functions --- frontend/src/store/store.ts | 147 ++++++++++++++++++++++++++++++------ 1 file changed, 122 insertions(+), 25 deletions(-) diff --git a/frontend/src/store/store.ts b/frontend/src/store/store.ts index 2dcf49cf1..5ac0f5cb8 100644 --- a/frontend/src/store/store.ts +++ b/frontend/src/store/store.ts @@ -2,7 +2,13 @@ import Vue from 'vue'; import Vuex from 'vuex'; import Web3 from 'web3'; import _ from 'lodash'; -import {bnMinimum, currentChainSupportsDrawbridge, currentChainSupportsPvP, currentChainSupportsQuests, toBN} from '@/utils/common'; +import { + bnMinimum, + currentChainSupportsDrawbridge, + currentChainSupportsPvP, + currentChainSupportsQuests, + toBN, +} from '@/utils/common'; import {getConfigValue, setUpContracts} from '@/contracts'; @@ -16,13 +22,18 @@ import {burningManager as featureFlagBurningManager} from '@/feature-flags'; import {ERC20, IERC721, INftStakingRewards, IStakingRewards} from '@/../../build/abi-interfaces'; import {stakeTypeThatCanHaveUnclaimedRewardsStakedTo} from '@/stake-types'; import {Nft} from '@/interfaces/Nft'; -//import {getNFTCall} from '@/utils/multicall'; import { Interface } from '@ethersproject/abi'; import {Element} from '@/enums/Element'; import {getWeaponNameFromSeed} from '@/weapon-name'; import axios from 'axios'; import {abi as erc20Abi} from '@/../../build/contracts/ERC20.json'; import {abi as erc721Abi} from '@/../../build/contracts/IERC721.json'; +import { abi as charactersAbi } from '@/../../build/contracts/Characters.json'; +import { abi as weaponsAbi } from '@/../../build/contracts/Weapons.json'; +import { abi as shieldsAbi } from '@/../../build/contracts/Shields.json'; +import { abi as marketAbi } from '@/../../build/contracts/NFTMarket.json'; +import { abi as raidTrinketsAbi } from '@/../../build/contracts/RaidTrinket.json'; +import { abi as junkAbi } from '@/../../build/contracts/Junk.json'; import BigNumber from 'bignumber.js'; import bridge from './bridge'; import pvp from './pvp'; @@ -33,6 +44,7 @@ import land from './land'; import treasury from './treasury'; import specialWeaponsManager from './specialWeaponsManager'; import combat from './combat'; +import { getNFTCall } from '@/utils/multicall'; const transakAPIURL = process.env.VUE_APP_TRANSAK_API_URL || 'https://staging-global.transak.com'; const transakAPIKey = process.env.VUE_APP_TRANSAK_API_KEY || '90167697-74a7-45f3-89da-c24d32b9606c'; @@ -1087,23 +1099,51 @@ export default new Vuex.Store({ await dispatch('fetchSkillBalance'); }, - async fetchCharacters({ dispatch }, characterIds: (string | number)[]) { - await Promise.all(characterIds.map(id => dispatch('fetchCharacter', { characterId: id }))); + async fetchCharacters({ state, dispatch }, characterIds: (string | number)[]) { + const { Characters } = state.contracts(); + if (!Characters) return; + + const multiCharacterDatas: string[] = await dispatch( + 'multicall', + getNFTCall(charactersAbi, Characters?.options.address, 'get', characterIds.map(characterId => [characterId]))); + + characterIds.forEach((characterId, i) => { + dispatch('fetchCharacter', { characterId, characterData: multiCharacterDatas[i] }); + }); }, - async fetchGarrisonCharacters({ dispatch }, garrisonCharacterIds: (string | number)[]) { - await Promise.all(garrisonCharacterIds.map(id => dispatch('fetchCharacter', { characterId: id, inGarrison: true }))); + async fetchGarrisonCharacters({ state, dispatch }, garrisonCharacterIds: (string | number)[]) { + const { Characters } = state.contracts(); + if (!Characters) return; + + const multiCharacterDatas: string[] = await dispatch( + 'multicall', + getNFTCall(charactersAbi, Characters?.options.address, 'get', garrisonCharacterIds.map(garrisonCharacterId => [garrisonCharacterId]))); + + garrisonCharacterIds.forEach((garrisonCharacterId, i) => { + dispatch('fetchCharacter', { characterId: garrisonCharacterId, characterData: multiCharacterDatas[i], inGarrison: true }); + }); }, - async fetchCharacter({ state, commit, dispatch }, { characterId, inGarrison = false }: { characterId: string | number, inGarrison: boolean}) { + /** + * + * @param characterId characterId of the character being fetched + * @param characterData the optional character data gotten from use of multiCall + * @param inGarrison true if from fetchGarrisonCharacters + */ + async fetchCharacter( + { state, commit, dispatch }, + { characterId, characterData = [], inGarrison = false }: + { characterId: string | number, characterData: string[], inGarrison: boolean}) { + const { Characters } = state.contracts(); - if(!Characters) return; + if (!Characters) return; await Promise.all([ (async () => { const character = characterFromContract( characterId, - await Characters.methods.get('' + characterId).call(defaultCallOptions(state)) + characterData.length > 0 ? characterData : await Characters.methods.get('' + characterId).call(defaultCallOptions(state)) ); await dispatch('fetchCharacterPower', characterId); await dispatch('getIsCharacterInArena', characterId); @@ -1132,11 +1172,25 @@ export default new Vuex.Store({ } }, - async fetchWeapons({ dispatch }, weaponIds: (string | number)[]) { - await Promise.all(weaponIds.map(id => dispatch('fetchWeapon', id))); + async fetchWeapons({ state, dispatch }, weaponIds: (string | number)[]) { + const { Weapons } = state.contracts(); + if(!Weapons) return; + + const multiWeaponDatas: string[] = await dispatch( + 'multicall', + getNFTCall(weaponsAbi, Weapons?.options.address, 'get', weaponIds.map(weaponId => [weaponId]))); + + weaponIds.forEach((weaponId, i) => { + dispatch('fetchCharacter', { weaponId, weaponData: multiWeaponDatas[i] }); + }); }, - async fetchWeapon({ state, commit, dispatch }, weaponId: string | number) { + /** + * + * @param weaponId weaponId of the weapon being fetched + * @param weaponData the optional weapon data gotten from use of multiCall + */ + async fetchWeapon({ state, commit, dispatch }, weaponId: string | number, weaponData: string[] = []) { const { Weapons } = state.contracts(); if(!Weapons) return; @@ -1144,7 +1198,7 @@ export default new Vuex.Store({ (async () => { const weapon = weaponFromContract( weaponId, - await Weapons.methods.get('' + weaponId).call(defaultCallOptions(state)) + weaponData.length > 0 ? weaponData : await Weapons.methods.get('' + weaponId).call(defaultCallOptions(state)) ); commit('updateWeapon', { weaponId, weapon }); @@ -1157,11 +1211,26 @@ export default new Vuex.Store({ if(!Shields || !state.defaultAccount) return; return await Shields.methods.getNftVar(shieldId, 2).call(defaultCallOptions(state)); }, - async fetchShields({ dispatch }, shieldIds: (string | number)[]) { - await Promise.all(shieldIds.map(id => dispatch('fetchShield', id))); + + async fetchShields({ state, dispatch }, shieldIds: (string | number)[]) { + const { Shields } = state.contracts(); + if(!Shields) return; + + const multiShieldDatas: string[] = await dispatch( + 'multicall', + getNFTCall(shieldsAbi, Shields?.options.address, 'get', shieldIds.map(shieldId => [shieldId]))); + + shieldIds.forEach((shieldId, i) => { + dispatch('fetchShield', { shieldId, shieldData: multiShieldDatas[i] }); + }); }, - async fetchShield({ state, commit }, shieldId: string | number) { + /** + * + * @param shieldId shieldId of the shield being fetched + * @param shieldData the optional shield data gotten from use of multiCall + */ + async fetchShield({ state, commit }, shieldId: string | number, shieldData: string[] = []) { const { Shields } = state.contracts(); if(!Shields) return; @@ -1169,7 +1238,7 @@ export default new Vuex.Store({ (async () => { const shield = shieldFromContract( shieldId, - await Shields.methods.get('' + shieldId).call(defaultCallOptions(state)) + shieldData.length > 0 ? shieldData : await Shields.methods.get('' + shieldId).call(defaultCallOptions(state)) ); commit('updateShield', { shieldId, shield }); @@ -1177,11 +1246,25 @@ export default new Vuex.Store({ ]); }, - async fetchTrinkets({ dispatch }, trinketIds: (string | number)[]) { - await Promise.all(trinketIds.map(id => dispatch('fetchTrinket', id))); + async fetchTrinkets({ state, dispatch }, trinketIds: (string | number)[]) { + const { RaidTrinket } = state.contracts(); + if(!RaidTrinket) return; + + const multiTrinketDatas: string[] = await dispatch( + 'multicall', + getNFTCall(raidTrinketsAbi, RaidTrinket?.options.address, 'get', trinketIds.map(trinketId => [trinketId]))); + + trinketIds.forEach((trinketId, i) => { + dispatch('fetchTrinket', { trinketId, trinketData: multiTrinketDatas[i] }); + }); }, - async fetchTrinket({ state, commit }, trinketId: string | number) { + /** + * + * @param trinketId trinketId of the trinket being fetched + * @param trinketData the optional trinket data gotten from use of multiCall + */ + async fetchTrinket({ state, commit }, trinketId: string | number, trinketData: string[] = []) { const { RaidTrinket } = state.contracts(); if(!RaidTrinket) return; @@ -1189,7 +1272,7 @@ export default new Vuex.Store({ (async () => { const trinket = trinketFromContract( trinketId, - await RaidTrinket.methods.get('' + trinketId).call(defaultCallOptions(state)) + trinketData.length > 0 ? trinketData : await RaidTrinket.methods.get('' + trinketId).call(defaultCallOptions(state)) ); commit('updateTrinket', { trinketId, trinket }); @@ -1197,11 +1280,25 @@ export default new Vuex.Store({ ]); }, - async fetchJunks({ dispatch }, junkIds: (string | number)[]) { - await Promise.all(junkIds.map(id => dispatch('fetchJunk', id))); + async fetchJunks({ state, dispatch }, junkIds: (string | number)[]) { + const { Junk } = state.contracts(); + if(!Junk) return; + + const multiJunkDatas = await dispatch( + 'multicall', + getNFTCall(junkAbi, Junk?.options.address, 'get', junkIds.map(junkId => [junkId]))); + + junkIds.forEach((junkId, i) => { + dispatch('fetchJunk', { junkId, junkData: multiJunkDatas[i] }); + }); }, - async fetchJunk({ state, commit }, junkId: string | number) { + /** + * + * @param junkId junkId of the junk being fetched + * @param junkData the optional junk data gotten from use of multiCall + */ + async fetchJunk({ state, commit }, junkId: string | number, junkData: string = '') { const { Junk } = state.contracts(); if(!Junk) return; @@ -1209,7 +1306,7 @@ export default new Vuex.Store({ (async () => { const junk = junkFromContract( junkId, - await Junk.methods.get('' + junkId).call(defaultCallOptions(state)) + junkData ? junkData : await Junk.methods.get('' + junkId).call(defaultCallOptions(state)) ); commit('updateJunk', { junkId, junk }); From def7ef75d675c99f7d259bbf09413aac9bbf05d5 Mon Sep 17 00:00:00 2001 From: Jake Hein Date: Wed, 14 Sep 2022 15:50:16 -0700 Subject: [PATCH 5/7] debugging --- frontend/src/contracts.ts | 2 +- frontend/src/store/store.ts | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/frontend/src/contracts.ts b/frontend/src/contracts.ts index 20c4b4d05..2110a9c02 100644 --- a/frontend/src/contracts.ts +++ b/frontend/src/contracts.ts @@ -72,7 +72,7 @@ import { StakingContractEntry, stakingContractsInfo, nftStakingContractsInfo } f import {raid, pvp, quests, burningManager} from './feature-flags'; import {currentChainSupportsPvP, currentChainSupportsQuests} from '@/utils/common'; -import {abi as multicallAbi} from './data/MultiCall.json'; +import {abi as multicallAbi} from './data/Multicall.json'; interface RaidContracts { Raid1?: Contracts['Raid1']; diff --git a/frontend/src/store/store.ts b/frontend/src/store/store.ts index 5ac0f5cb8..9d2d03d8e 100644 --- a/frontend/src/store/store.ts +++ b/frontend/src/store/store.ts @@ -31,7 +31,6 @@ import {abi as erc721Abi} from '@/../../build/contracts/IERC721.json'; import { abi as charactersAbi } from '@/../../build/contracts/Characters.json'; import { abi as weaponsAbi } from '@/../../build/contracts/Weapons.json'; import { abi as shieldsAbi } from '@/../../build/contracts/Shields.json'; -import { abi as marketAbi } from '@/../../build/contracts/NFTMarket.json'; import { abi as raidTrinketsAbi } from '@/../../build/contracts/RaidTrinket.json'; import { abi as junkAbi } from '@/../../build/contracts/Junk.json'; import BigNumber from 'bignumber.js'; @@ -1103,13 +1102,17 @@ export default new Vuex.Store({ const { Characters } = state.contracts(); if (!Characters) return; + console.log('fetch 1'); + console.log('address: ', Characters?.options.address); + console.log('getNFTCall: ', getNFTCall(charactersAbi, Characters?.options.address, 'get', characterIds.map(characterId => [characterId]))); const multiCharacterDatas: string[] = await dispatch( 'multicall', getNFTCall(charactersAbi, Characters?.options.address, 'get', characterIds.map(characterId => [characterId]))); - + console.log('fetch 2'); characterIds.forEach((characterId, i) => { dispatch('fetchCharacter', { characterId, characterData: multiCharacterDatas[i] }); }); + console.log('fetch 3'); }, async fetchGarrisonCharacters({ state, dispatch }, garrisonCharacterIds: (string | number)[]) { @@ -2870,14 +2873,21 @@ export default new Vuex.Store({ }, async multicall({state}, {abi, calls}) { + console.log('in multiCall'); const { MultiCall } = state.contracts(); const itf = new Interface(abi); const data = calls.map((call: any) => [ call.address.toLowerCase(), itf.encodeFunctionData(call.name, call.params), ]); - const { returnData } = await MultiCall.methods.aggregate(data).call(defaultCallOptions(state)); + const a = MultiCall.methods.aggregate(data); + console.log('a: ', a); + // a.call(defaultCallOptions(state)); + console.log('defaultCallOptions: ', defaultCallOptions(state)); + const { returnData } = await MultiCall.methods.aggregate(data).call(defaultCallOptions(state)) || []; + console.log('6'); const res = returnData.map((call, i) => itf.decodeFunctionResult(calls[i].name, call)); + console.log(res); return res; }, } From 9d341bca049cd9e5532b476f5fcd1addadbb9f92 Mon Sep 17 00:00:00 2001 From: Jake Hein Date: Wed, 14 Sep 2022 16:12:30 -0700 Subject: [PATCH 6/7] getting errors from contracts.ts ln 372, no addr --- frontend/src/contracts.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/contracts.ts b/frontend/src/contracts.ts index 2110a9c02..ecf400bc8 100644 --- a/frontend/src/contracts.ts +++ b/frontend/src/contracts.ts @@ -369,7 +369,8 @@ export async function setUpContracts(web3: Web3): Promise { const treasuryContractAddr = getConfigValue('VUE_APP_TREASURY_CONTRACT_ADDRESS') || (treasuryNetworks as Networks)[networkId]!.address; const Treasury = new web3.eth.Contract(treasuryAbi as Abi, treasuryContractAddr); - const multicallAddr = getConfigValue('VUE_APP_CONTRACT_ADDRESS'); + const multicallAddr = getConfigValue('VUE_APP_MULTICALL_CONTRACT_ADDRESS'); + console.log('multicallAddr', multicallAddr); const MultiCall = new web3.eth.Contract(multicallAbi as Abi, multicallAddr); let BurningManager; From 1748391e230390533271ee3926294d6355854931 Mon Sep 17 00:00:00 2001 From: Jake Hein Date: Wed, 14 Sep 2022 16:41:21 -0700 Subject: [PATCH 7/7] debugging, removed some comments --- frontend/src/store/store.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/frontend/src/store/store.ts b/frontend/src/store/store.ts index 9d2d03d8e..d8d4165f5 100644 --- a/frontend/src/store/store.ts +++ b/frontend/src/store/store.ts @@ -1130,9 +1130,11 @@ export default new Vuex.Store({ /** * - * @param characterId characterId of the character being fetched - * @param characterData the optional character data gotten from use of multiCall - * @param inGarrison true if from fetchGarrisonCharacters + * @param param0 object containing references to relevant globals + * @param param1 object containing the main params. They are: + * - characterId: characterId of the character being fetched + * - characterData: the optional character data gotten from use of multiCall + * - inGarrison: true if from fetchGarrisonCharacters */ async fetchCharacter( { state, commit, dispatch }, @@ -2880,14 +2882,8 @@ export default new Vuex.Store({ call.address.toLowerCase(), itf.encodeFunctionData(call.name, call.params), ]); - const a = MultiCall.methods.aggregate(data); - console.log('a: ', a); - // a.call(defaultCallOptions(state)); - console.log('defaultCallOptions: ', defaultCallOptions(state)); const { returnData } = await MultiCall.methods.aggregate(data).call(defaultCallOptions(state)) || []; - console.log('6'); const res = returnData.map((call, i) => itf.decodeFunctionResult(calls[i].name, call)); - console.log(res); return res; }, }