Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
dapp-scratch-wrapper
14 changes: 14 additions & 0 deletions lib/contracts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* The file enables `/dapp-scratch-wrapper/index.js` to import all contract modules
* in a one-shot manner. There should not be any reason to edit this file.
*/

const files = require.context('.', false, /\.js$/)
const modules = {}

files.keys().forEach(key => {
if (key === './index.js') return
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
})

export default modules
20 changes: 13 additions & 7 deletions lib/dapp-scratch.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ class DappScratch {
.then(this.wrapperReplaceName.bind(this))
.then(this.buildFunctions.bind(this))
.then(this.writeWrapper.bind(this))
.then(resolve)
.then(this.copyStaticFiles.bind(this))
// .then(resolve)
.catch((err) => {
reject(new Error(err))
})
Expand All @@ -94,10 +95,8 @@ class DappScratch {

writeWrapper () {
return new Promise((resolve, reject) => {
if (fs.existsSync('./dapp-scratch-wrapper')) fs.removeSync('./dapp-scratch-wrapper')
fs.mkdirSync('./dapp-scratch-wrapper')
fs.mkdirSync('./dapp-scratch-wrapper/' + this.projectName)
this.path = './dapp-scratch-wrapper/' + this.projectName + '/index.js'
fs.mkdirsSync('./dapp-scratch-wrapper/contracts')
this.path = `./dapp-scratch-wrapper/contracts/${this.projectName}.js`
fs.writeFile(this.path, this.wrapperFile, (err) => {
if (err) {
reject(new Error(err))
Expand All @@ -108,6 +107,13 @@ class DappScratch {
})
}

copyStaticFiles () {
return new Promise((resolve, reject) => {
fs.copySync(`${__dirname}/index.js`, './dapp-scratch-wrapper/index.js')
fs.copySync(`${__dirname}/contracts/index.js`, './dapp-scratch-wrapper/contracts/index.js')
resolve()
})
}


getAbi () {
Expand Down Expand Up @@ -248,7 +254,7 @@ class DappScratch {
all += functions + ') {\n'

if (info.stateMutability === 'nonpayable') {
all += ' if (!this.account) return new Error(\'Unlock Wallet\')\n'
all += ' if (!this.contractManager.account) return new Error(\'Unlock Wallet\')\n'
}

all += ' return this.' + this.projectName + '.methods.' + info.name + '(' + typedFunctions + ')'
Expand All @@ -257,7 +263,7 @@ class DappScratch {
all += '.call()\n'
break
case('nonpayable'):
all += '.send({from: this.account})\n'
all += '.send({from: this.contractManager.account})\n'
all += ' .on(\'transactionHash\', (hash) => {\n'
all += ' console.log(hash)\n'
all += ' this.loading = true\n'
Expand Down
161 changes: 161 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@

import Web3 from 'web3'
const BN = Web3.utils.BN
import ZeroClientProvider from 'web3-provider-engine/zero.js'
import IdManagerProvider from '@aeternity/id-manager-provider'
import contracts from './contracts'

class ContractManager {
constructor (options) {
this.pollingInterval = null
this.account = null
this.unlocked = false
this.balanceWei = 0
this.balance = 0
this.genesisBlock = 0
this.loading = false
this.options = {
autoInit: true,
connectionRetries: 3
}
this.identityObservers = []

Object.assign(this.options, options)
if (this.options.autoInit) this.initWeb3()
}

/*
* Connect
*/

initWeb3 () {
return new Promise((resolve, reject) => {

let web3Provider = false
let idManager = new IdManagerProvider({
rpcUrl: 'http://localhost:9545',
skipSecurity: true,

})

idManager.checkIdManager().then((idManagerPresent)=>{
// check for aedentity app
if (idManagerPresent) {
web3Provider = idManager.web3.currentProvider

// check for metamask
} else if (global.web3) {
web3Provider = web3.currentProvider

// attempt to try again if no aedentity app or metamask
} else if (this.options.connectionRetries > 0){
this.options.connectionRetries -= 1
setTimeout(() => {
this.initWeb3().then(resolve).catch((error) => {
reject(new Error(error))
})
}, 1000)
// revert to a read only version using infura endpoint
} else {
this.readOnly = true
web3Provider = ZeroClientProvider({
getAccounts: function(){},
rpcUrl: 'https://mainnet.infura.io',
// rpcUrl: 'https://testnet.infura.io',
// rpcUrl: 'https://rinkeby.infura.io',
// rpcUrl: 'https://kovan.infura.io',
})
}

if (web3Provider) {
global.web3 = new Web3(web3Provider)
this.startChecking()

if (this.options.getPastEvents) this.getPastEvents()
if (this.options.watchFutureEvents) this.watchFutureEvents()
}
})
})
}

/*
* Check every second for switching network or wallet
*/

startChecking () {
if (this.pollingInterval) clearInterval(this.pollingInterval)
this.getGenesisBlock()
.then(() => {
this.pollingInterval = setInterval(this.check.bind(this), 1000)
})
.catch((err) => {
throw new Error(err)
})
}

check () {
this.checkNetwork()
.then(this.checkAccount.bind(this))
.catch((error) => {
console.error(error)
throw new Error(error)
})
}

checkNetwork () {
return global.web3.eth.net.getId((err, netId) => {
if (err) console.error(err)
if (!err && this.network !== netId) {
this.network = netId
return this.deployContracts()
}
})
}

deployContracts () {
for (const contract in contracts) {
if (contracts.hasOwnProperty(contract)) {
this[contract] = new contracts[contract](this)
}
}
}

checkAccount () {
return global.web3.eth.getAccounts((error, accounts) => {
if (error) throw new Error(error)
if (accounts.length && this.account !== accounts[0]) {
this.unlocked = true
this.account = accounts[0]

for (let i in this.identityObservers) {
this.identityObservers[i](this.account)
}

} else if (!accounts.length) {
this.unlocked = false
this.account = null
}
})
}


/*
* Not Yet Implemented vvvv
*/

getGenesisBlock () {
return new Promise((resolve, reject) => {
resolve()
})
}

addIdentityObserver (observer) {
this.identityObservers.push(observer)
if (this.address) {
observer(this.account)
}
}

}

export default ContractManager
137 changes: 7 additions & 130 deletions lib/starterTemplate.js
Original file line number Diff line number Diff line change
@@ -1,152 +1,29 @@

import __NAME__Artifacts from '../../build/contracts/__NAME__.json'

import Web3 from 'web3'
const BN = Web3.utils.BN
import ZeroClientProvider from 'web3-provider-engine/zero.js'
import IdManagerProvider from '@aeternity/id-manager-provider'

class __NAME__ {
constructor (options) {

this.__NAME__ = null
constructor (contractManager, options) {

this.pollingInterval = null
this.account = null
this.unlocked = false
this.balanceWei = 0
this.balance = 0
this.contractManager = contractManager
this.address = __ADDRESS__
this.genesisBlock = 0
this.loading = false
this.options = {
autoInit: true,
getPastEvents: false,
watchFutureEvents: false,
connectionRetries: 3
watchFutureEvents: false
}
Object.assign(this.options, options)
if (this.options.autoInit) this.initWeb3()
}

// hello world : )
helloWorld () {
console.log('hello world!')
}

/*
* Connect
*/

initWeb3 () {
return new Promise((resolve, reject) => {

let web3Provider = false
let idManager = new IdManagerProvider()

idManager.checkIdManager().then((idManagerPresent)=>{
// check for aedentity app
if (idManagerPresent) {
web3Provider = idManager.web3.currentProvider

// check for metamask
} else if (global.web3) {
web3Provider = web3.currentProvider

// attempt to try again if no aedentity app or metamask
} else if (this.options.connectionRetries > 0){
this.options.connectionRetries -= 1
setTimeout(() => {
this.initWeb3().then(resolve).catch((error) => {
reject(new Error(error))
})
}, 1000)
// revert to a read only version using infura endpoint
} else {
this.readOnly = true
web3Provider = ZeroClientProvider({
getAccounts: function(){},
rpcUrl: 'https://mainnet.infura.io',
// rpcUrl: 'https://testnet.infura.io',
// rpcUrl: 'https://rinkeby.infura.io',
// rpcUrl: 'https://kovan.infura.io',
})
}

if (web3Provider) {
global.web3 = new Web3(web3Provider)
this.startChecking()

if (this.options.getPastEvents) this.getPastEvents()
if (this.options.watchFutureEvents) this.watchFutureEvents()
}
})
})
}

/*
* Check every second for switching network or wallet
*/

startChecking () {
if (this.pollingInterval) clearInterval(this.pollingInterval)
this.getGenesisBlock()
.then(() => {
this.pollingInterval = setInterval(this.check.bind(this), 1000)
})
.catch((err) => {
throw new Error(err)
})
}

check () {
this.checkNetwork()
.then(this.checkAccount.bind(this))
.catch((error) => {
console.error(error)
throw new Error(error)
})
}

checkNetwork () {
return global.web3.eth.net.getId((err, netId) => {
if (err) console.error(err)
if (!err && this.network !== netId) {
this.network = netId
return this.deployContract()
}
})
}

deployContract () {
if (!this.address || this.address === 'REPLACE_WITH_CONTRACT_ADDRESS') return new Error('Please provide a contract address')
this.__NAME__ = new global.web3.eth.Contract(__NAME__Artifacts.abi, this.address)
}

checkAccount () {
return global.web3.eth.getAccounts((error, accounts) => {
if (error) throw new Error(error)
if (accounts.length && this.account !== accounts[0]) {
this.unlocked = true
this.account = accounts[0]
} else if (!accounts.length) {
this.unlocked = false
this.account = null
}
})
}

// hello world : )
helloWorld () {
console.log('hello world!')
}

/*
* Not Yet Implemented vvvv
*/

getGenesisBlock () {
return new Promise((resolve, reject) => {
resolve()
})
}

getPastEvents () {
return new Promise((resolve, reject) => {
resolve()
Expand Down
Loading