Created
June 1, 2018 05:40
-
-
Save nicovalencia/476a00568f9ca7fb39cdea7b0ba7326a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Web3 = require('web3'); | |
const fetch = require('node-fetch'); | |
const ipfsAPI = require('ipfs-api'); | |
const ipfs = ipfsAPI('localhost', '5002'); | |
const POLLING_INTERVAL = 5000; | |
const EVENTS = { | |
Transfer: {} | |
}; | |
var TOKEN_INDEX_HASH = ''; | |
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545")); | |
function loadContractInstance({ abiPath, address }) { | |
return new Promise((resolve, reject) => { | |
fetch(abiPath).then((resp) => { | |
return resp.json(); | |
}).then(data => { | |
let contractInstance = new web3.eth.Contract(data.abi, address); | |
resolve(contractInstance); | |
}); | |
}); | |
} | |
class WorldCupPlayerTokenInterface { | |
constructor(contractInstance) { | |
this.instance = contractInstance; | |
this.getTotalSupply = this.getTotalSupply.bind(this); | |
this.getTokenIdByIndex = this.getTokenIdByIndex.bind(this); | |
this.getOwnerOf = this.getOwnerOf.bind(this); | |
this.getTokenURI = this.getTokenURI.bind(this); | |
this.getPlayerId = this.getPlayerId.bind(this); | |
} | |
async getTotalSupply() { | |
return new Promise(resolve => { | |
this.instance.methods.totalSupply().call((error, supply) => { | |
resolve(supply); | |
}); | |
}); | |
} | |
async getTokenIdByIndex(index) { | |
return new Promise(resolve => { | |
this.instance.methods.tokenByIndex(index).call((error, tokenId) => { | |
resolve(tokenId); | |
}); | |
}); | |
} | |
async getOwnerOf(tokenId) { | |
return new Promise(resolve => { | |
this.instance.methods.ownerOf(tokenId).call((error, owner) => { | |
resolve(owner); | |
}); | |
}); | |
} | |
async getTokenURI(tokenId) { | |
return new Promise(resolve => { | |
this.instance.methods.tokenURI(tokenId).call((error, tokenURI) => { | |
resolve(tokenURI); | |
}); | |
}); | |
} | |
async getPlayerId(tokenId) { | |
return new Promise(resolve => { | |
this.instance.methods.playerId(tokenId).call((error, playerId) => { | |
resolve(playerId); | |
}); | |
}); | |
} | |
} | |
async function rebuildTokenIndex({ contractInstance, event }) { | |
let tokens = {}; | |
let interface = new WorldCupPlayerTokenInterface(contractInstance); | |
let supply = await interface.getTotalSupply(); | |
let chain = Promise.resolve(); | |
for (let i = 0; i < supply; i++) { | |
chain = chain.then(() => { | |
return new Promise(async (resolve, reject) => { | |
let tokenId = await interface.getTokenIdByIndex(i); | |
let owner = await interface.getOwnerOf(tokenId); | |
let tokenURI = await interface.getTokenURI(tokenId); | |
let playerId = await interface.getPlayerId(tokenId); | |
tokens[tokenId] = { | |
owner, | |
tokenURI, | |
playerId, | |
}; | |
resolve(); | |
}); | |
}); | |
} | |
await chain; | |
let buffer = Buffer.from(JSON.stringify({ | |
tokens | |
})); | |
ipfs.add(buffer, {}, (error, resp) => { | |
TOKEN_INDEX_HASH = resp[0].hash; | |
console.log('Rebuilt token index:', TOKEN_INDEX_HASH) | |
}); | |
} | |
function pollForEvent({ contractInstance, eventName, processCb }) { | |
setTimeout(() => pollForEvent(...arguments), POLLING_INTERVAL); | |
// Have to poll in dev until ganache supports WebSockets transport: | |
// https://github.com/trufflesuite/ganache-cli/issues/257 | |
contractInstance.getPastEvents(eventName, { | |
fromBlock: 0, | |
}, (error, events) => { | |
events.forEach(event => { | |
if (!EVENTS[eventName][event.transactionHash]) { | |
EVENTS[eventName][event.transactionHash] = event; | |
processCb({ contractInstance, event }); | |
} else { | |
// console.log('...duplicate event'); | |
} | |
}); | |
}); | |
} | |
//TODO: build initial indices, then begin poller: | |
loadContractInstance({ | |
abiPath: 'http://localhost:3000/abis/WorldCupPlayerToken.json', | |
address: '0x9a2b051b106f0d3be0a72defcad9799b27a3f46b', | |
}).then((contractInstance) => { | |
pollForEvent({ | |
contractInstance, | |
eventName: 'Transfer', | |
processCb: rebuildTokenIndex, | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment