Skip to content
Open
47 changes: 46 additions & 1 deletion src/js/controllers/tab-send.controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

angular.module('copayApp.controllers').controller('tabSendController', function(bitcoinUriService, $scope, $log, $timeout, $ionicScrollDelegate, addressbookService, profileService, lodash, $state, walletService, platformInfo, sendFlowService, gettextCatalog, configService, $ionicPopup, $ionicNavBarDelegate, clipboardService, incomingDataService) {
angular.module('copayApp.controllers').controller('tabSendController', function(bitcoinUriService, $scope, $log, $timeout, $ionicScrollDelegate, $ionicPopover, addressbookService, profileService, lodash, $state, walletService, platformInfo, sendFlowService, gettextCatalog, configService, $ionicPopup, $ionicNavBarDelegate, clipboardService, incomingDataService, ionicToast, opencapService) {
var clipboardHasAddress = false;
var clipboardHasContent = false;
var originalList;
Expand Down Expand Up @@ -61,6 +61,49 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
});
});

$scope.closePopover = function() {
$scope.popover.hide();
};

$scope.$on('$destroy', function() {
$scope.popover.remove();
});

$scope.confirmOpenapAddress = function(address, coin){
$scope.popover.remove();
var params = sendFlowService.state.getClone();
params.data = address;
params.coin = coin;
sendFlowService.start(params, function onError() {
return
});
}

$scope.resolveOpencapAlias = function(alias){
opencapService.getAddress(alias)
.then(result => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : => : lambda expression is not supported for old javascript engine.
Should be :

function onThen() {
}

if (typeof $scope.fromWallet !== 'undefined'){
if ($scope.fromWallet.coin === 'bch'){
result.addresses = {bch: result.addresses.bch};
}
if ($scope.fromWallet.coin === 'btc'){
result.addresses = {btc: result.addresses.btc};
}
}

$scope.opencapAddresses = result.addresses;
$scope.opencapDnssec = result.dnssec;
$ionicPopover.fromTemplateUrl('templates/popoverOpencapSend.html', {scope: $scope})
.then(function(popover) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : function(
Should be : function onThen(

$scope.popover = popover;
popover.show(angular.element(document.querySelector('#search-input')))
});
})
.catch(status => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : => : lambda expression is not supported for old javascript engine.
Should be :

function onCatch() {
}

// do nothing because they may have been typing
});
}

$scope.findContact = function(search) {
if (!search || search.length < 1) {
$scope.list = originalList;
Expand All @@ -70,6 +113,8 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
return;
}

$scope.resolveOpencapAlias(search);

var params = sendFlowService.state.getClone();
params.data = search;
sendFlowService.start(params, function onError() {
Expand Down
130 changes: 130 additions & 0 deletions src/js/services/opencap.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
'use strict';

(function() {
angular.module('bitcoincom.services').factory('opencapService', function($q, $http) {
function getAddress(alias) {
let aliasData = validateAlias(alias);
if (aliasData.username === '' || aliasData.domain === '') {
return $q((resolve, reject) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : => : lambda expression is not supported for old javascript engine.
Should be :

function onQ() {
}

return reject('Invalid OpenCAP alias');
});
}

let deferred = $q.defer();
$http
.get(`https://dns.google.com/resolve?name=_opencap._tcp.${aliasData.domain}&type=SRV`)
.then(function(response) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : function(
Should be : function onThen(

deferred.resolve(
parseSRV(response.data)
.then(data => getAddresses(alias, data.host, data.dnssec))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : => : lambda expression is not supported for old javascript engine.
Should be :

function onThen() {
}

.catch(function(error) {
return $q((resolve, reject) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : => : lambda expression is not supported for old javascript engine.
Should be :

function onQ() {
}

reject(error);
});
})
);
})
.catch(function(response) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : function(
Should be : function onCatch(

deferred.reject('Couldn\'t find srv record for the provided domain');
});
return deferred.promise;
}

var parseSRV = function(respData) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : var parseSRV = function(
Should be : function parseSRV(

return $q((resolve, reject) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : => : lambda expression is not supported for old javascript engine.
Should be :

function onQ() {
}

let dnssec = respData.AD;

if (typeof respData.Answer === 'undefined') {
return reject('Error contacting google dns server, no srv data');
}
if (respData.Answer.length < 1) {
return reject('Error contacting google dns server, not enough srv data');
}

let record = respData.Answer[0].data.split(' ');
if (record.length != 4) {
return reject('Error contacting google dns server, improper srv data');
}

if (record[3].slice(-1) == '.') {
record[3] = record[3].substring(0, record[3].length - 1);
}

return resolve({ host: record[3], dnssec });
});
};

var getAddresses = function(alias, host, dnssec) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : var getAddresses = function(
Should be : function getAddresses(

let deferred = $q.defer();
$http
.get(`https://${host}/v1/addresses?alias=${alias}`)
.then(function(response) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : function(
Should be : function onThen(

deferred.resolve(parseAddresses(response.data, dnssec).then());
})
.catch(function(response) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : function(
Should be : function onCatch(

deferred.reject('Address not found for the specified alias');
});
return deferred.promise;
};

var parseAddresses = function(respData, dnssec) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : var parseAddresses = function(
Should be : function parseAddresses(

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I got it all addressed

let addresses = {}
return $q((resolve, reject) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now : => : lambda expression is not supported for old javascript engine.
Should be :

function onQ() {
}

for (let i = 0; i < respData.length; i++) {
if (respData[i].address_type === 'undefined') {
continue;
}
if (respData[i].address === 'undefined') {
continue;
}
// Take the last BCH address we hit, shouldn't matter which one
if (respData[i].address_type == 200 || respData[i].address_type == 201 || respData[i].address_type == 202) {
addresses.bch = respData[i].address;
}
// Take the last BTC address we hit, shouldn't matter which one
if (respData[i].address_type == 100 || respData[i].address_type == 101) {
addresses.btc = respData[i].address;
}
}

if (addresses.btc === 'undefined' && addresses.btc === 'undefined'){
return reject('Error contacting opencap server, no response');
}

return resolve({addresses, dnssec});
});
};

function validateUsername(username) {
return /^[a-z0-9._-]{1,25}$/.test(username);
}

function validateDomain(username) {
return /^[a-z0-9.\-]+\.[a-z]{2,4}$/.test(username);
}

function validateAlias(alias) {
let splitAlias = alias.split('$');
if (splitAlias.length != 2) {
return { username: '', domain: '' };
}
let username = splitAlias[0];
let domain = splitAlias[1];

if (!validateUsername(username)) {
return { username: '', domain: '' };
}
if (!validateDomain(domain)) {
return { username: '', domain: '' };
}

return { username, domain };
}

var service = {
getAddress,
};

return service;
});
})();
21 changes: 21 additions & 0 deletions www/templates/popoverOpencapSend.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<ion-popover-view style="height: 0px">
<div class="card" style="text-align: center">
<div class="item item-heading">
<span translate>Alias found!</span>
</div>
<div class="list">
<div class="item" ng-if="opencapAddresses.bch">
<span>{{opencapAddresses.bch}}</span>
<button ng-click="confirmOpenapAddress(opencapAddresses.bch, 'bch')" class="button button-standard button-primary button-outline" translate>Send BCH</button>
</div>
<div class="item" ng-if="opencapAddresses.btc">
<span>{{opencapAddresses.btc}}</span>
<button ng-click="confirmOpenapAddress(opencapAddresses.btc, 'btc')" class="button button-standard button-primary button-outline" translate>Send BTC</button>
</div>
<span class="item" ng-if="!opencapDnssec" style="color: red; " translate>
DNSSEC not used
</span>
</div>
</div>
</div>
</ion-popover-view>
4 changes: 2 additions & 2 deletions www/views/tab-send.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ <h2>{{fromWallet.name}}</h2>
<div class="send-wrapper item">
<div class="row">
<div class="input" ng-class="{'focus': searchFocus}">
<input type="text" class="search-input" placeholder="{{'Search or enter bitcoin address' | translate}}"
<input type="text" class="search-input" placeholder="{{'Search or enter bitcoin address or alias' | translate}}"
ng-model="formData.search" ng-change="findContact(formData.search)" ng-model-onblur
ng-focus="searchInFocus()" ng-blur="searchBlurred()">
ng-focus="searchInFocus()" ng-blur="searchBlurred()" id="search-input">
</div>
</div>
<div class="buttons">
Expand Down