Skip to content

Commit

Permalink
Yaruo revert and BCH (monya-wallet#40)
Browse files Browse the repository at this point in the history
* Support for CashAddr of BCH

Be careful when you use Uint8Array.slice !

* Switches Legacy or CashAddr for block chain explorers

CashAddr is preferred when both are supported

* History value calculation is now valid

* Optimization

* Fix how to get hash part of an address

* Sweep function fixed

* Use Legacy address for display

Still supports CashAddress too for sending or Atomic Swaps

* Move caching point

* Support for Bitpay address

* Fix some with requests

* Forgot to apply merge

* Revert 🤔 to Yaruo

* History calculation fixed

* ZEC will no longer get detected as BCH

Probably a bug in cashaddrjs
  • Loading branch information
Lesmiscore authored and MissMonacoin committed Jul 28, 2018
1 parent 5adabad commit 9b3aa97
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 18,661 deletions.
28 changes: 19 additions & 9 deletions component/atomicswap.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const bip39 = require("@missmonacoin/bip39-eng")
const BigNumber = require('bignumber.js');
const coinUtil = require("../js/coinUtil")
const qrcode = require("qrcode")
const { isCashAddress, toLegacyAddress }=require("bchaddrjs");

const getPriv = (coinId,change,index,password)=>storage.get("keyPairs").then((cipher)=>{
const cur = currencyList.get(coinId)
Expand Down Expand Up @@ -347,8 +348,8 @@ module.exports=require("../js/lang.js")({ja:require("./ja/atomicswap.html"),en:r
if (this.secret) {
this.myP2SH=createContract(
atomicSwapContract(
giveCur.lib.address.fromBase58Check(this.refundAddressWithSecret).hash,
giveCur.lib.address.fromBase58Check(this.redeemAddressWOSecret).hash,
getHashFromAddress(giveCur,this.refundAddressWithSecret).hash,
getHashFromAddress(giveCur,this.redeemAddressWOSecret).hash,
this.lockTime,
Buffer.from(this.secretHash,"hex"),
this.contractType,
Expand All @@ -359,8 +360,8 @@ module.exports=require("../js/lang.js")({ja:require("./ja/atomicswap.html"),en:r
);
this.opponentP2SH = createContract(
atomicSwapContract(
getCur.lib.address.fromBase58Check(this.refundAddressWOSecret).hash,
getCur.lib.address.fromBase58Check(this.redeemAddressWithSecret).hash,
getHashFromAddress(getCur,this.refundAddressWOSecret).hash,
getHashFromAddress(getCur,this.redeemAddressWithSecret).hash,
this.lockTime,
Buffer.from(this.secretHash,"hex"),
this.contractType,
Expand All @@ -372,8 +373,8 @@ module.exports=require("../js/lang.js")({ja:require("./ja/atomicswap.html"),en:r
}else{
this.opponentP2SH=createContract(
atomicSwapContract(
getCur.lib.address.fromBase58Check(this.refundAddressWithSecret).hash,
getCur.lib.address.fromBase58Check(this.redeemAddressWOSecret).hash,
getHashFromAddress(getCur,this.refundAddressWithSecret).hash,
getHashFromAddress(getCur,this.redeemAddressWOSecret).hash,
this.lockTime,
Buffer.from(this.secretHash,"hex"),
this.contractType,
Expand All @@ -383,8 +384,8 @@ module.exports=require("../js/lang.js")({ja:require("./ja/atomicswap.html"),en:r
);
this.myP2SH =createContract(
atomicSwapContract(
giveCur.lib.address.fromBase58Check(this.refundAddressWOSecret).hash,
giveCur.lib.address.fromBase58Check(this.redeemAddressWithSecret).hash,
getHashFromAddress(giveCur,this.refundAddressWOSecret).hash,
getHashFromAddress(giveCur,this.redeemAddressWithSecret).hash,
this.lockTime,
Buffer.from(this.secretHash,"hex"),
this.contractType,
Expand All @@ -398,7 +399,16 @@ module.exports=require("../js/lang.js")({ja:require("./ja/atomicswap.html"),en:r
this.isRefund=0 // to emit an event

},

getHashFromAddress(coin,address){
if(coin.coinId=="bch"){
// remove if lib supports
if(isCashAddress(address)){
// convert CashAddr to Legacy
address=toLegacyAddress(address)
}
}
return coin.lib.address.fromBase58Check(address)
},
buildNormalTransaction(inAddr,outAddr,coinId,isRefund){
const cur =currencyList.get(coinId||this.getCoinId)
return cur.getUtxos([inAddr],true).then(res=>{
Expand Down
2 changes: 1 addition & 1 deletion component/send.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ module.exports=require("../js/lang.js")({ja:require("./ja/send.html"),en:require
return
}else{
currencyList.eachWithPub((cur)=>{
const ver = coinUtil.getAddrVersion(this.address)
//const ver = coinUtil.getAddrVersion(this.address)
if(cur.isValidAddress(this.address)){
this.possibility.push({
name:cur.coinScreenName,
Expand Down
86 changes: 80 additions & 6 deletions js/currency.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ const zecLib = require("@missmonacoin/bitcoinjs-lib-zcash")
const bchLib = require("@missmonacoin/bitcoincashjs-lib")
const blkLib = require("@missmonacoin/blackcoinjs-lib")
const jp = require('jsonpath')
const { toCashAddress, toLegacyAddress, isLegacyAddress, isCashAddress }=require("bchaddrjs");

if("function"!==typeof Uint8Array.prototype.slice0){
// workaround for slice bug; DO NOT REMOVE OR BCH DETECTON WOULD BREAK
// You can move it, but you MUST NOT REMOVE
Uint8Array.prototype.slice0=Uint8Array.prototype.slice
Uint8Array.prototype.slice=function(start,end){
if(end<0){
return this.slice0(start,this.length+end)
}else{
return this.slice0(start,end)
}
}
}

module.exports=class{

constructor(opt){
Expand All @@ -53,6 +68,7 @@ module.exports=class{
this.opReturnLength=(opt.opReturnLength<0) ? 40 : opt.opReturnLength
this.isAtomicSwapAvailable=!!opt.isAtomicSwapAvailable
this.libName = opt.lib
this.addressType = ""
switch(opt.lib){
case "zec":
this.lib=zecLib
Expand Down Expand Up @@ -118,9 +134,28 @@ module.exports=class{
return adrss
}
getIndexFromAddress(addr){
for(let p in this.addresses){
if(this.addresses[p]===addr){
return p.split(",")
if(this.coinId=="bch"){
const wasCashAddrSpecified=isCashAddress(addr)
if(wasCashAddrSpecified && addr.indexOf(":")>=0){
addr=addr.split(":")[1]
}
for(let p in this.addresses){
let address=this.addresses[p]
if(wasCashAddrSpecified){
address=toCashAddress(address).split(":")[1]
}else{
address=toLegacyAddress(address)
}
if(address===addr){
return p.split(",")
}
}
}else{
for(let p in this.addresses){
let address=this.addresses[p]
if(address===addr){
return p.split(",")
}
}
}
return false
Expand Down Expand Up @@ -175,6 +210,11 @@ module.exports=class{
}

getUtxos(addressList,includeUnconfirmedFunds=false,fallback=true){
if(this.coinId=="bch"){
// ok, convert our address to appropriate format
const mapFunction=(this.addressType=="cashaddr")?toCashAddress:toLegacyAddress;
addressList=addressList.map(mapFunction)
}
let promise
if(typeof(addressList[0])==="string"){//address mode
promise=this.fbGet("/addrs/"+addressList.join(",")+"/utxo",fallback)
Expand Down Expand Up @@ -218,14 +258,24 @@ module.exports=class{
throw new errors.InvalidIndexError()
}
const addrKey = (change|0).toString()+","+(index|0).toString()
let candidate
if(this.addresses[addrKey]){
return this.addresses[addrKey]
candidate = this.addresses[addrKey]
}else{
if(this.enableSegwit==="legacy"){
return (this.addresses[addrKey]=this.getSegwitLegacyAddress(change,index))
candidate = this.getSegwitLegacyAddress(change,index)
}else{
candidate = this.hdPubNode.derive(change).derive(index).getAddress()
}
return (this.addresses[addrKey]=this.hdPubNode.derive(change).derive(index).getAddress())
this.addresses[addrKey]=candidate
}
// for all cases, candidate is set
/*if(this.coinId=="bch"){
return toCashAddress(candidate).split(":")[1]
}else{
return candidate
}*/
return candidate
}
getPubKey(change,index){
if(this.dummy){return}
Expand Down Expand Up @@ -361,6 +411,10 @@ module.exports=class{
if (!output.address) {
output.address = this.getAddress(1,(this.changeIndex+1)%coinUtil.GAP_LIMIT_FOR_CHANGE)
}
if(this.coinId=="bch"){
// force convert to Legacy address; remove when lib supports
output.address = toLegacyAddress(output.address)
}

txb.addOutput(output.address, output.value)
})
Expand Down Expand Up @@ -656,6 +710,13 @@ module.exports=class{
r.utxos.forEach((v,i)=>{
txb.addInput(v.txId,v.vout)
})
if(coin.coinId=="bch"){
// remove if lib supports
if(!isLegacyAddress(addr)){
// convert CashAddr to Legacy
addr=toLegacyAddress(addr)
}
}
txb.addOutput(addr,(new BigNumber(r.balance)).minus(fee).times(100000000).toNumber())
r.utxos.forEach((v,i)=>{
if(this.enableSegwit){
Expand Down Expand Up @@ -697,6 +758,9 @@ module.exports=class{
if(a.explorer){
this.explorer = a.explorer
}
if(a.addressType){
this.addressType = a.addressType
}
if(a.socket){
this.socketEndpoint = a.socket
}
Expand All @@ -709,6 +773,16 @@ module.exports=class{
}
}
isValidAddress(address){
if(this.coinId=="bch"){
// if i am BCH, test for CashAddr format
try{
// lets test
toCashAddress(address)
return true
}catch(e){
// not a CashAddr
}
}
try{
const ver = this.getAddrVersion(address) //throws if not correct version
if(ver===this.network.pubKeyHash||ver===this.network.scriptHash){
Expand Down
16 changes: 10 additions & 6 deletions js/currencyList.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,13 +332,17 @@ const defaultCoins = [{
icon: require("../res/coins/bch.png"),
apiEndpoints: [{
explorer: "https://bitcoincash.blockexplorer.com",
url: "https://bitcoincash.blockexplorer.com/api"
url: "https://bitcoincash.blockexplorer.com/api",
addressType: "cashaddr"
},{
explorer: "https://explorer.bitcoin.com/bch",
url: "https://explorer.bitcoin.com/api/bch"
},{
explorer: "https://cash.insight.publicnodejp.cf/insight",
url: "https://cash.insight.publicnodejp.cf/insight-api",
explorer: "https://explorer.bitcoin.com/bch",
url: "https://explorer.bitcoin.com/api/bch",
addressType: "legacy"
},
{
url: "https://bch-insight.bitpay.com/api",
explorer: "https://bch-insight.bitpay.com",
addressType: "cashaddr"
}],
network: {
messagePrefix: '\x18Bitcoin Signed Message:\n',
Expand Down
Loading

0 comments on commit 9b3aa97

Please sign in to comment.