Skip to content

Commit

Permalink
Merge pull request #1 from brunobar79/v2
Browse files Browse the repository at this point in the history
v2
  • Loading branch information
Bruno Barbieri authored Dec 6, 2019
2 parents ecb2595 + c95ef2a commit c273164
Show file tree
Hide file tree
Showing 4 changed files with 2,294 additions and 108 deletions.
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,10 @@ ethCommerce.render(

## Methods

### render(options, errorCallback, successCallback, tryMetamascara = false)
### render(options, errorCallback, successCallback)

options, errorCallback and successCallback are required

Metamascara feature is experimental. It allows you to render the button without having metamask installed.
Learn more [here](https://github.com/MetaMask/mascara)

Renders a button based on the options and executes the corresponding callbacks after placing and confirm transaction

### getEtherPriceIn(currency)
Expand All @@ -67,5 +64,4 @@ Then executes the success callback
- [ ] Add support for React Native
- [ ] Add tests
- [ ] Store the current state in localStorage to be able to restore it in case of page reload
- [ ] Suggest a way for generating ethereum addresses for merchants that are currently without one (example: MEW, MyCrypto, MetaMask, Coinbase)

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eth-commerce",
"version": "1.0.5",
"version": "2.0.1",
"description": "\"Javascript library that allows you to accept Ethereum payments on your website or mobile app\"",
"main": "dist/index.js",
"directories": {
Expand Down
159 changes: 57 additions & 102 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,72 +26,28 @@ class EthCommerce {
}
}

//metamascara is not working ATM, so we're defaulting to false for now...
render(options, errorCallback, successCallback, tryMetamascara = false) {
const { targetElement, amount, address, currency, custom, type } = options;
render(options, errorCallback, successCallback) {
const { targetElement } = options;

this.errorCallback = errorCallback;
this.successCallback = successCallback;

window.addEventListener("load", _ => {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
// Checking if Web3 has been injected by the browser (MetaMask)
if (typeof web3 !== "undefined") {
// Use Mist/MetaMask's provider
const provider = new Web3(web3.currentProvider);
// Use the browser's ethereum provider
provider.eth.getAccounts((err, accounts) => {
this.renderButton({
...options,
account: accounts[0]
});
});
} else {
//Fallback to metamascara
if (tryMetamascara) {
console.log("trying metamascara");
this.injectMetamascara(options);
} else {
console.log("no web 3");
if (this.config.HANDLE_UI) {
this.renderNoWeb3(targetElement);
}
this.errorCallback({ error: "no web3 detected" });
if (this.config.HANDLE_UI) {
this.renderNoWeb3(targetElement);
}
this.errorCallback({ error: "no web3 detected" });
}
});
}

injectMetamascara(options) {
const metamascara = document.createElement("script");
metamascara.type = "text/javascript";
metamascara.src = "https://wallet.metamask.io/metamascara.js";
const ref = document.querySelector("script");
ref.parentNode.insertBefore(metamascara, ref);
metamascara.addEventListener("load", _ => {
console.log("metamascara injected");

const ethJsScript = document.createElement("script");
ethJsScript.type = "text/javascript";
ethJsScript.src =
"https://cdn.jsdelivr.net/npm/ethjs@0.3.0/dist/ethjs.min.js";
const ref = document.querySelector("script");
ref.parentNode.insertBefore(ethJsScript, ref);
ethJsScript.addEventListener("load", __ => {
console.log("ethJS injected");
const provider = metamask.createDefaultProvider();
const eth = new Eth(provider);
eth.accounts((err, accounts) => {
this.renderButton({
...options,
account: accounts[0]
});
});
});

this.render(options, this.successCallback, this.errorCallback, false);
});
}

renderNoWeb3(targetElement) {
this.renderStyles();

Expand Down Expand Up @@ -119,7 +75,6 @@ class EthCommerce {
)
.then(response => response.json())
.then(data => {
console.log("GOT ETH PRICE", data);
resolve(data[currency]);
})
.catch(e => {
Expand Down Expand Up @@ -189,52 +144,58 @@ class EthCommerce {
let amountIntETH = parseFloat(amount / price);
const amountToReceive = web3.toWei(amountIntETH, "ether");

this.sendTransaction(account, address, amountToReceive)
.then(tx => {
if (document.getElementById("eth-btn-text")) {
document
.getElementById("eth-btn-text")
.classList.add("waiting");
}

if (this.config.HANDLE_UI) {
document.getElementById("eth-btn-text").textContent =
"Waiting for confirmation";
const waiting = document.createElement("p");
waiting.classList.add("eth-waiting");
waiting.id = "hold-tight";
waiting.textContent = "Hold tight! This might take a while...";
document.getElementById(targetElement).appendChild(waiting);
}
this.waitForConfirmation(
tx,
this.config.MIN_CONFIRMATIONS,
this.config.INTERVAL
);
})
.catch(e => {
console.log("Error sending transaction", e);

if (this.config.HANDLE_UI) {
document.getElementById("eth-icon-svg").src = this.getImage(
"ETHEREUM_ICON"
);
document.getElementById("eth-btn-text").textContent =
"Pay with Ethereum";
}

if (document.getElementById("eth-btn-text")) {
document
.getElementById("eth-btn-text")
.classList.remove("waiting");
}

this.errorCallback(e);
this.loading = false;
});
return web3.currentProvider.send('eth_requestAccounts', []).then(response => {
if(response.result && response.result.length){
const account = response.result[0];

this.sendTransaction(account, address, amountToReceive)
.then(tx => {
if (document.getElementById("eth-btn-text")) {
document
.getElementById("eth-btn-text")
.classList.add("waiting");
}

if (this.config.HANDLE_UI) {
document.getElementById("eth-btn-text").textContent =
"Waiting for confirmation";
const waiting = document.createElement("p");
waiting.classList.add("eth-waiting");
waiting.id = "hold-tight";
waiting.textContent = "Hold tight! This might take a while...";
document.getElementById(targetElement).appendChild(waiting);
}
this.waitForConfirmation(
tx,
this.config.MIN_CONFIRMATIONS,
this.config.INTERVAL
);
})
.catch(e => {
console.error("Error sending transaction", e);

if (this.config.HANDLE_UI) {
document.getElementById("eth-icon-svg").src = this.getImage(
"ETHEREUM_ICON"
);
document.getElementById("eth-btn-text").textContent =
"Pay with Ethereum";
}

if (document.getElementById("eth-btn-text")) {
document
.getElementById("eth-btn-text")
.classList.remove("waiting");
}

this.errorCallback(e);
this.loading = false;
});
}
})
})
.catch(e => {
console.log("Error getting ETH price", e);
console.error("Error", e);
if (this.config.HANDLE_UI) {
document.getElementById("eth-icon-svg").src = this.getImage(
"ETHEREUM_ICON"
Expand Down Expand Up @@ -360,20 +321,16 @@ class EthCommerce {
web3.eth.getBlockNumber((error, currentBlockNumber) => {
if (!error) {
const confirmations = currentBlockNumber - txBlockNumber;
console.log(confirmations, "confirmations");
if (confirmations >= minConfirmations) {
const delta = (Date.now() - start_time) / 1000;
console.log(`Transaction took ${delta} seconds to confirm`);
clearInterval(checkConfirmations);
this.onTransactionConfirmed(result);
}
} else {
this.errorCallback(error);
}
});
} else {
console.log("block height: pending");
}
}
} else {
this.errorCallback(error);
}
Expand All @@ -383,7 +340,6 @@ class EthCommerce {

sendTransaction(account, address, amount) {
let tData = { from: account, to: address, value: amount };
console.log("About to send tx data:", tData);
return new Promise((resolve, reject) => {
web3.eth.estimateGas(tData, (error, gas) => {
if (!error) {
Expand All @@ -401,7 +357,6 @@ class EthCommerce {
if (error) {
reject(error);
} else {
console.log("Submitted tx", txID);
resolve(txID);
}
}
Expand Down
Loading

0 comments on commit c273164

Please sign in to comment.