From ac44eadcdd6d4260348ee188a9e40bc4f488059c Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 23 Apr 2018 17:06:30 -0400 Subject: [PATCH 1/4] Add expected delivery date to trade and quote --- app/templates/exchange/confirm.pug | 2 +- .../js/controllers/sfox/sfoxBuyCheckout.controller.js | 10 ++++++++-- .../js/controllers/sfox/sfoxTradeDetails.controller.js | 9 ++++++++- assets/js/services/sfox.service.js | 9 ++++++++- locales/en-human.json | 1 + rootApp/Resources/wallet-options.json | 4 ++-- 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/app/templates/exchange/confirm.pug b/app/templates/exchange/confirm.pug index 20eb3705de..1a3b408fa6 100644 --- a/app/templates/exchange/confirm.pug +++ b/app/templates/exchange/confirm.pug @@ -23,7 +23,7 @@ form.bc-form.pv-20( div span(translate="{{namespace + type + field.key}}") {{field.key}} helper-button(ng-show="field.key === '.TX_FEE'" content="{{namespace + type + '.TRANSACTION_FEE_HELPER'}}") - helper-button(ng-show="field.key === '.TRADING_FEE'" content="{{namespace + '.TRADING_FEE_HELPER'}}") + helper-button(ng-show="field.key === '.TRADING_FEE'" content="{{namespace + '.TRADING_FEE_HELPER'}}") span {{ field.val }} .flex-row.flex-align-start .pts diff --git a/assets/js/controllers/sfox/sfoxBuyCheckout.controller.js b/assets/js/controllers/sfox/sfoxBuyCheckout.controller.js index 93e04856dc..fd52c63948 100644 --- a/assets/js/controllers/sfox/sfoxBuyCheckout.controller.js +++ b/assets/js/controllers/sfox/sfoxBuyCheckout.controller.js @@ -24,7 +24,10 @@ function SfoxBuyCheckoutController ($scope, $timeout, $stateParams, $q, Wallet, $scope.prepareBuy = (quote) => { $scope.checkout.quote = quote; - return $q.resolve(sfox.buyTradeDetails($scope.checkout.quote)) + let minutesInADay = 1440; + let profile = exchange.profile; + let expectedDelivery = profile.processingTimes && profile.processingTimes.usd.buy / minutesInADay + ' Days'; + return $q.resolve(sfox.buyTradeDetails($scope.checkout.quote, null, null, expectedDelivery)) .then(details => { $scope.checkout.tradeDetails = details; $scope.checkout.type = 'buy'; @@ -34,7 +37,10 @@ function SfoxBuyCheckoutController ($scope, $timeout, $stateParams, $q, Wallet, }; $scope.checkout.buyHandler = (quote) => sfox.buy($scope.checkout.state.account, quote) - .then(trade => $scope.checkout.trade = trade) + .then(trade => { + $scope.checkout.trade = trade + $scope.checkout.expectedDelivery = trade.expectedDelivery + }) .then(sfox.fetchTrades) .then(() => exchange.fetchProfile()) .then(enableSiftScience) diff --git a/assets/js/controllers/sfox/sfoxTradeDetails.controller.js b/assets/js/controllers/sfox/sfoxTradeDetails.controller.js index dfda80727c..fa53314a1c 100644 --- a/assets/js/controllers/sfox/sfoxTradeDetails.controller.js +++ b/assets/js/controllers/sfox/sfoxTradeDetails.controller.js @@ -17,8 +17,15 @@ function SfoxTradeDetailsController ($scope, MyWallet, Exchange, currency, sfox, $scope.state = '.' + trade.state; $scope.type = trade.isBuy ? '.buy' : '.sell'; + let expectedDelivery; + if ($scope.checkout && $scope.checkout.expectedDelivery) { + expectedDelivery = new Date($scope.checkout.expectedDelivery).toDateString() + } else { + expectedDelivery = new Date(trade.expectedDelivery).toDateString() + } + if ($scope.type === '.buy') { - $q.resolve(sfox.buyTradeDetails(null, trade, tx)) + $q.resolve(sfox.buyTradeDetails(null, trade, tx, expectedDelivery)) .then(details => $scope.tradeDetails = details); } else { $scope.tradeDetails = sfox.sellTradeDetails(null, null, trade, tx); diff --git a/assets/js/services/sfox.service.js b/assets/js/services/sfox.service.js index 8c6dc2f1cc..6e072ab914 100644 --- a/assets/js/services/sfox.service.js +++ b/assets/js/services/sfox.service.js @@ -234,7 +234,7 @@ function sfox ($q, MyWallet, MyWalletHelpers, Alerts, modals, Env, Exchange, cur }; } - function buyTradeDetails (quote, trade, tx) { + function buyTradeDetails (quote, trade, tx, expectedDelivery) { let buyTxFee; return Env.then(env => { buyTxFee = env.partners.sfox.buyTransactionFeeInSatoshi; @@ -287,6 +287,13 @@ function sfox ($q, MyWallet, MyWalletHelpers, Alerts, modals, Env, Exchange, cur }; } + if (expectedDelivery) { + details.expectedDelivery = { + key: '.EXPECTED_DELIVERY', + val: expectedDelivery + }; + } + return details; }); } diff --git a/locales/en-human.json b/locales/en-human.json index e604373ea5..3e1104fdc4 100644 --- a/locales/en-human.json +++ b/locales/en-human.json @@ -1964,6 +1964,7 @@ "TRADING_FEE": "@:SFOX.sell.TRADING_FEE", "TX_FEE": "@:SFOX.sell.TX_FEE", "NOW_SUPPORTING": "This Just In!", + "EXPECTED_DELIVERY": "Estimated Delivery of Funds", "ANNOUNCEMENT": "Buy has arrived. You can now swiftly buy bitcoin directly from within your Blockchain wallet!", "GET_STARTED": "Begin Buying", "COMING_SOON": "We are working hard to bring buy bitcoin functionality to your wallet very soon.", diff --git a/rootApp/Resources/wallet-options.json b/rootApp/Resources/wallet-options.json index a397c1df5d..b15c73b18c 100644 --- a/rootApp/Resources/wallet-options.json +++ b/rootApp/Resources/wallet-options.json @@ -44,9 +44,9 @@ "showBuyFraction": 1, "inviteFormFraction": 0.1, "buyTransactionFeeInSatoshi": false, - "apiKey": "6fbfb80536564af8bbedb7e3be4ec439", + "apiKey": "f31614a7-5074-49f2-8c2a-bfb8e55de2bd", "plaid": "0b041cd9e9fbf1e7d93a0d5a39f5b9", - "plaidEnv": "tartan", + "plaidEnv": "production", "siftScience": "3884e5fae5", "surveyLinks": ["https://blockchain.co1.qualtrics.com/jfe/form/SV_9BuZyJxdOT0Psb3", "https://blockchain.co1.qualtrics.com/jfe/form/SV_8cE4saqzhlLXngN", From 81e906857a1e35bef738bf277799b8e2e6b417a5 Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 23 Apr 2018 17:11:59 -0400 Subject: [PATCH 2/4] feat(SFOX): Add expectedDelivery to details --- app/partials/sfox/details.pug | 2 +- locales/en-human.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/partials/sfox/details.pug b/app/partials/sfox/details.pug index d6a6ab629f..2a9e504c81 100644 --- a/app/partials/sfox/details.pug +++ b/app/partials/sfox/details.pug @@ -3,7 +3,7 @@ div(ng-controller="SfoxTradeDetailsController") span.f-16.em-500.pl-30.no-padding-mobile(translate="{{namespace + type + state + '.HEADER'}}" class="{{classHelper(trade)}}") .ph-30.pt-20.ph-10-mobile.pv-20-mobile .f-13.mb-10 - span(translate="{{namespace + type + state + '.BODY'}}" translate-values="{tradeId: tradeId}") + span(translate="{{namespace + type + state + '.BODY'}}" translate-values="{tradeId: tradeId, expectedDelivery: tradeDetails.expectedDelivery.val}") div(ng-if="tradeAccount") .flex-end.flex-row.mb-5.mt-5 span.mid-grey.f-12 1 BTC = {{ rate }} diff --git a/locales/en-human.json b/locales/en-human.json index 3e1104fdc4..a9f267783e 100644 --- a/locales/en-human.json +++ b/locales/en-human.json @@ -1943,7 +1943,7 @@ "DISPLAY": "Pending Buy", "HEADER": "Buy Order in Progress", "ACTION": "@:EXCHANGE.ACTIONS.VIEW_DETAILS", - "BODY": "Your buy trade has been initiated. You will receive your bitcoin in 3-7 business days. Your order ID is: SFX-{{::tradeId}}" + "BODY": "Your buy trade has been initiated. You will receive your bitcoin on {{::expectedDelivery}}. Your order ID is: SFX-{{::tradeId}}" }, "rejected": { "DISPLAY": "Rejected Buy", From 390fb7ca445b626d90d89a72f6b756020deeba0c Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 23 Apr 2018 17:23:59 -0400 Subject: [PATCH 3/4] feat(SFOX): sell expected delivery --- .../controllers/sfox/sfoxSellCheckout.controller.js | 6 +++++- .../controllers/sfox/sfoxTradeDetails.controller.js | 2 +- assets/js/services/sfox.service.js | 13 +++++++++++-- locales/en-human.json | 5 +++-- rootApp/Resources/wallet-options.json | 4 ++-- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/assets/js/controllers/sfox/sfoxSellCheckout.controller.js b/assets/js/controllers/sfox/sfoxSellCheckout.controller.js index 988d491794..5fab74c4b5 100644 --- a/assets/js/controllers/sfox/sfoxSellCheckout.controller.js +++ b/assets/js/controllers/sfox/sfoxSellCheckout.controller.js @@ -38,12 +38,15 @@ function SfoxSellCheckoutController ($scope, $timeout, $stateParams, $q, Wallet, $scope.payment.amount(amt); $scope.payment.updateFeePerKb(Exchange.sellFee || 2); $scope.payment.from(Wallet.my.wallet.hdwallet.defaultAccountIndex); + let minutesInADay = 1440; + let profile = exchange.profile; + let expectedDelivery = profile.processingTimes && profile.processingTimes.usd.sell / minutesInADay + ' Days'; $scope.payment.sideEffect((payment) => { $scope.checkout.quote = quote; $scope.checkout.type = 'sell'; $scope.checkout.goTo('confirm'); - $scope.checkout.tradeDetails = sfox.sellTradeDetails($scope.checkout.quote, payment); + $scope.checkout.tradeDetails = sfox.sellTradeDetails($scope.checkout.quote, payment, null, null, expectedDelivery); Wallet.api.incrementPartnerTrade('sfox', 'sell', $scope.checkout.quote.baseCurrency, $scope.checkout.quote.quoteCurrency); }); @@ -58,6 +61,7 @@ function SfoxSellCheckoutController ($scope, $timeout, $stateParams, $q, Wallet, let submitTx = (trade) => { $scope.checkout.trade = trade; + $scope.checkout.expectedDelivery = trade.expectedDelivery; $scope.payment.to(trade.receiveAddress); return Wallet.askForSecondPasswordIfNeeded().then((pw) => { return $scope.payment.build().sign(pw).publish().payment; diff --git a/assets/js/controllers/sfox/sfoxTradeDetails.controller.js b/assets/js/controllers/sfox/sfoxTradeDetails.controller.js index fa53314a1c..c8b436f2df 100644 --- a/assets/js/controllers/sfox/sfoxTradeDetails.controller.js +++ b/assets/js/controllers/sfox/sfoxTradeDetails.controller.js @@ -28,7 +28,7 @@ function SfoxTradeDetailsController ($scope, MyWallet, Exchange, currency, sfox, $q.resolve(sfox.buyTradeDetails(null, trade, tx, expectedDelivery)) .then(details => $scope.tradeDetails = details); } else { - $scope.tradeDetails = sfox.sellTradeDetails(null, null, trade, tx); + $scope.tradeDetails = sfox.sellTradeDetails(null, null, trade, tx, expectedDelivery); } $scope.rate = $scope.type === '.buy' diff --git a/assets/js/services/sfox.service.js b/assets/js/services/sfox.service.js index 6e072ab914..b1f5036b8b 100644 --- a/assets/js/services/sfox.service.js +++ b/assets/js/services/sfox.service.js @@ -195,7 +195,7 @@ function sfox ($q, MyWallet, MyWalletHelpers, Alerts, modals, Env, Exchange, cur return localStorageService.get('hasSeenSfoxBuyIntro'); } - function sellTradeDetails (quote, payment, trade, tx) { + function sellTradeDetails (quote, payment, trade, tx, expectedDelivery) { let { formatCurrencyForView, convertFromSatoshi } = currency; let fiat = currency.currencies.find((curr) => curr.code === 'USD'); let btc = currency.bitCurrencies.find((curr) => curr.code === 'BTC'); @@ -209,7 +209,7 @@ function sfox ($q, MyWallet, MyWalletHelpers, Alerts, modals, Env, Exchange, cur : (trade.receiveAmount).toFixed(2); let amountKey = quote || payment ? '.AMT' : '.AMT_SOLD'; - return { + let details = { txAmt: { key: amountKey, val: isNaN(amount) ? amount : formatCurrencyForView(convertFromSatoshi(amount, btc), btc, true) @@ -232,6 +232,15 @@ function sfox ($q, MyWallet, MyWalletHelpers, Alerts, modals, Env, Exchange, cur tip: () => console.log('Clicked tooltip') } }; + + if (expectedDelivery) { + details.expectedDelivery = { + key: '.EXPECTED_DELIVERY', + val: expectedDelivery + }; + } + + return details; } function buyTradeDetails (quote, trade, tx, expectedDelivery) { diff --git a/locales/en-human.json b/locales/en-human.json index a9f267783e..0ff478020e 100644 --- a/locales/en-human.json +++ b/locales/en-human.json @@ -1902,7 +1902,7 @@ "DISPLAY": "Pending Sell", "ACTION": "@:EXCHANGE.ACTIONS.VIEW_DETAILS", "HEADER": "Sell Order in Progress", - "BODY": "Your sell trade has been initiated. Your funds will be deposited into your bank account within 3-5 business days. Your order ID is: SFX-{{::tradeId}}" + "BODY": "Your sell trade has been initiated. Your funds will be deposited into your bank account by {{::expectedDelivery}}. Your order ID is: SFX-{{::tradeId}}" }, "failed": { "DISPLAY": "Failed Sell", @@ -1927,6 +1927,7 @@ "TX_FEE": "Transaction Fee", "TOTAL": "Total Outgoing Bitcoin", "INTRODUCING_HEADER": "Sell Bitcoin", + "EXPECTED_DELIVERY": "Estimated Delivery of Funds", "INTRODUCING_BODY": "Selling bitcoin is simple, seamless, and secure. Thanks to our partnership with SFOX, you can sell bitcoin directly from your Blockchain wallet.

Tips for getting started:
The minimum amount you can sell is $10. Your daily maximum can be found under the local currency field.

Currently, your Blockchain wallet supports linking only one bank account. If you would like to change your synced account, please email support@sfox.com. Please note: selling with a credit card is not supported at this time.", "TRADING_FEE": "Trading Fee", "TO_BE_RECEIVED": "USD To Be Received", @@ -1964,7 +1965,7 @@ "TRADING_FEE": "@:SFOX.sell.TRADING_FEE", "TX_FEE": "@:SFOX.sell.TX_FEE", "NOW_SUPPORTING": "This Just In!", - "EXPECTED_DELIVERY": "Estimated Delivery of Funds", + "EXPECTED_DELIVERY": "@:SFOX.sell.EXPECTED_DELIVERY", "ANNOUNCEMENT": "Buy has arrived. You can now swiftly buy bitcoin directly from within your Blockchain wallet!", "GET_STARTED": "Begin Buying", "COMING_SOON": "We are working hard to bring buy bitcoin functionality to your wallet very soon.", diff --git a/rootApp/Resources/wallet-options.json b/rootApp/Resources/wallet-options.json index b15c73b18c..a397c1df5d 100644 --- a/rootApp/Resources/wallet-options.json +++ b/rootApp/Resources/wallet-options.json @@ -44,9 +44,9 @@ "showBuyFraction": 1, "inviteFormFraction": 0.1, "buyTransactionFeeInSatoshi": false, - "apiKey": "f31614a7-5074-49f2-8c2a-bfb8e55de2bd", + "apiKey": "6fbfb80536564af8bbedb7e3be4ec439", "plaid": "0b041cd9e9fbf1e7d93a0d5a39f5b9", - "plaidEnv": "production", + "plaidEnv": "tartan", "siftScience": "3884e5fae5", "surveyLinks": ["https://blockchain.co1.qualtrics.com/jfe/form/SV_9BuZyJxdOT0Psb3", "https://blockchain.co1.qualtrics.com/jfe/form/SV_8cE4saqzhlLXngN", From 7aae2ccba8745cfed6fdc365e0585ecfa3f7461e Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 23 Apr 2018 17:27:58 -0400 Subject: [PATCH 4/4] feat(SFOX): add pending trades to checkout page --- app/partials/sfox/checkout.pug | 6 +++++- assets/js/controllers/sfox/sfoxCheckout.controller.js | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/partials/sfox/checkout.pug b/app/partials/sfox/checkout.pug index 9e479f7c35..b6e228ca16 100644 --- a/app/partials/sfox/checkout.pug +++ b/app/partials/sfox/checkout.pug @@ -58,7 +58,7 @@ bc-tabs(tab="tabs.selectedTab" tab-options="tabs.options" on-select="tabs.select trade-account="checkout.state.account" handle-quote="sellQuoteHandler(amount, baseCurr, quoteCurr)" on-success="selling().verificationRequired ? checkout.openSfoxSignup() : buildPayment(quote)") - .flex-column.width-50.pl-30.prn.pv-10-mobile.no-margin-mobile.hidden-xs(ng-if="checkout.onStep('create') && !checkout.hasDismissedSellIntro()") + .flex-column.width-50.pl-30.prn.pv-10-mobile.no-margin-mobile.hidden-xs(ng-if="checkout.onStep('create') && !checkout.hasDismissedSellIntro() && !pendingSellTrades().length") .flex-between span.f-24.blue.f-14-mobile i.icon-buy-sell.h3.mrm @@ -66,6 +66,10 @@ bc-tabs(tab="tabs.selectedTab" tab-options="tabs.options" on-select="tabs.select span i.pointer.ti-close.f-14.mid-grey(ng-click="checkout.dismissSellIntro()") p.f-12.mt-10(translate="SFOX.sell.INTRODUCING_BODY") + .width-50.pl-30.prn.pv-10-mobile.no-margin-mobile(ng-if="pendingSellTrades().length") + span You have {{ pendingSellTrades().length }} pending sell {{ pendingSellTrades().length === 1 ? 'transaction' : 'transactions' }} for a total of {{ pendingSellTradesTotal() }} USD. You can see more details in your + |   + a(ng-click="tabs.select('ORDER_HISTORY')") Order History. .flex-row.pbvl(ng-if="checkout.onStep('confirm')") exchange-confirm.width-55.border-desktop( type="checkout.type" diff --git a/assets/js/controllers/sfox/sfoxCheckout.controller.js b/assets/js/controllers/sfox/sfoxCheckout.controller.js index 31dc64aad8..55ead8e581 100644 --- a/assets/js/controllers/sfox/sfoxCheckout.controller.js +++ b/assets/js/controllers/sfox/sfoxCheckout.controller.js @@ -10,7 +10,9 @@ function SfoxCheckoutController ($scope, $timeout, $stateParams, $q, Wallet, MyW $scope.showBuy = () => MyWallet.wallet.accountInfo.invited.sfoxBuy; $scope.pendingBuyTrades = () => $scope.pendingTrades().filter((t) => t.isBuy); + $scope.pendingSellTrades = () => $scope.pendingTrades().filter((t) => !t.isBuy); $scope.pendingBuyTradesTotal = () => $scope.pendingBuyTrades().map((t) => t.receiveAmount).reduce((acc, amt) => acc + amt); + $scope.pendingSellTradesTotal = () => $scope.pendingSellTrades().map((t) => t.receiveAmount).reduce((acc, amt) => acc + amt).toFixed(2); this.handleCancel = (skipConfirm, type, step) => { if (skipConfirm) $scope.checkout.goTo('create');