mirror of https://github.com/BTCPrivate/copay.git
Merge pull request #7688 from Gamboster/feat/shapeshift1
[V4] Feat: shapeshift implementation
This commit is contained in:
commit
4ed4abe5f7
|
@ -14,6 +14,7 @@ import { CoinbaseProvider } from '../providers/coinbase/coinbase';
|
|||
import { AmazonProvider } from '../providers/amazon/amazon';
|
||||
import { BitPayCardProvider } from '../providers/bitpay-card/bitpay-card';
|
||||
import { MercadoLibreProvider } from '../providers/mercado-libre/mercado-libre';
|
||||
import { ShapeshiftProvider } from '../providers/shapeshift/shapeshift';
|
||||
|
||||
//pages
|
||||
import { TabsPage } from '../pages/tabs/tabs';
|
||||
|
@ -42,7 +43,8 @@ export class CopayApp {
|
|||
private coinbaseProvider: CoinbaseProvider,
|
||||
private amazonProvider: AmazonProvider,
|
||||
private bitPayCardProvider: BitPayCardProvider,
|
||||
private mercadoLibreProvider: MercadoLibreProvider
|
||||
private mercadoLibreProvider: MercadoLibreProvider,
|
||||
private shapeshiftProvider: ShapeshiftProvider,
|
||||
) {
|
||||
|
||||
this.initializeApp();
|
||||
|
@ -111,5 +113,6 @@ export class CopayApp {
|
|||
this.glideraProvider.register();
|
||||
this.coinbaseProvider.setCredentials();
|
||||
this.coinbaseProvider.register();
|
||||
this.shapeshiftProvider.register();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,10 @@ import { BuyMercadoLibrePage } from '../pages/integrations/mercado-libre/buy-mer
|
|||
import { MercadoLibreCardDetailsPage } from '../pages/integrations/mercado-libre/mercado-libre-card-details/mercado-libre-card-details';
|
||||
import { MercadoLibreCardsPage } from '../pages/integrations/mercado-libre/mercado-libre-cards/mercado-libre-cards';
|
||||
import { MercadoLibrePage } from '../pages/integrations/mercado-libre/mercado-libre';
|
||||
// Integrations: ShapeShift
|
||||
import { ShapeshiftConfirmPage } from '../pages/integrations/shapeshift/shapeshift-confirm/shapeshift-confirm';
|
||||
import { ShapeshiftPage } from '../pages/integrations/shapeshift/shapeshift';
|
||||
import { ShapeshiftShiftPage } from '../pages/integrations/shapeshift/shapeshift-shift/shapeshift-shift';
|
||||
|
||||
/*Includes */
|
||||
import { FeedbackCardPage } from '../pages/includes/feedback-card/feedback-card';
|
||||
|
@ -176,6 +180,7 @@ import { ProfileProvider } from '../providers/profile/profile';
|
|||
import { PushNotificationsProvider } from '../providers/push-notifications/push-notifications';
|
||||
import { RateProvider } from '../providers/rate/rate';
|
||||
import { ReleaseProvider } from '../providers/release/release';
|
||||
import { ShapeshiftProvider } from '../providers/shapeshift/shapeshift';
|
||||
import { ScanProvider } from '../providers/scan/scan';
|
||||
import { TimeProvider } from '../providers/time/time';
|
||||
import { TouchIdProvider } from '../providers/touchid/touchid';
|
||||
|
@ -251,11 +256,14 @@ let pages: any = [
|
|||
PinModalPage,
|
||||
ProposalsPage,
|
||||
ReceivePage,
|
||||
SendPage,
|
||||
ScanPage,
|
||||
SendPage,
|
||||
SettingsPage,
|
||||
SellCoinbasePage,
|
||||
SellGlideraPage,
|
||||
ShapeshiftConfirmPage,
|
||||
ShapeshiftPage,
|
||||
ShapeshiftShiftPage,
|
||||
TermsOfUsePage,
|
||||
MercadoLibreCardDetailsPage,
|
||||
MercadoLibreCardsPage,
|
||||
|
@ -323,6 +331,7 @@ let providers: any = [
|
|||
PushNotificationsProvider,
|
||||
RateProvider,
|
||||
ReleaseProvider,
|
||||
ShapeshiftProvider,
|
||||
StatusBar,
|
||||
SplashScreen,
|
||||
ScanProvider,
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 223 223" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,0,-65)">
|
||||
<g transform="matrix(0.557484,0,0,0.553806,46,81.643)">
|
||||
<path d="M216,82.1L230.5,-0.7L169.9,24.6L103.3,24.6L42.7,-0.8L57.3,82.1L43.6,128.3L56.5,136.4L0,186L0,232.6L64.6,321.6L125.5,342L125.6,342.1L173.2,317.7L173.3,317.6L173.3,281.5L146.3,266.7L188.7,153.8L188.4,153.8L229.6,128.3L216,82.1Z" style="fill:rgb(39,60,81);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.547536,0,0,0.548347,46,83.5105)">
|
||||
<clipPath id="_clip1">
|
||||
<path d="M97.7,100.3L0,186L136.1,264.3L136.6,102.9L97.7,100.3Z" clip-rule="nonzero"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip1)">
|
||||
<g transform="matrix(1.82636,-0,-0,1.82366,-84.0127,-33.757)">
|
||||
<use xlink:href="#_Image2" x="45.123" y="72.564" width="76.792px" height="91.93px" transform="matrix(0.997298,0,0,0.999243,0,0)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M83.8,153.3L136.2,293.4L136.6,161.1L83.8,153.3Z" style="fill:rgb(70,98,132);fill-rule:nonzero;"/>
|
||||
<path d="M188.7,153.8L136.2,293.4L136.6,161.1L188.7,153.8Z" style="fill:rgb(53,77,106);fill-rule:nonzero;"/>
|
||||
<clipPath id="_clip3">
|
||||
<path d="M230.5,-0.7L178.4,26.7L136.7,35.8L94.6,26.7L42.7,-0.8L60.6,81.9L43.6,128.3L103.2,165.3L136.3,201.3L136.3,201.6L136.5,201.4L136.7,201.6L136.7,201.3L169.8,165.3L229.6,128.3L212.6,82L230.5,-0.7Z" clip-rule="nonzero"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip3)">
|
||||
<g transform="matrix(1.82636,-0,-0,1.82366,-84.0127,-33.757)">
|
||||
<use xlink:href="#_Image4" x="68.494" y="17.073" width="104.826px" height="112.987px" transform="matrix(0.998341,0,0,0.999884,0,0)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M230.5,-0.7L216,82.1L229.6,128.3L212.6,82L230.5,-0.7Z" style="fill:url(#_Linear5);fill-rule:nonzero;"/>
|
||||
<path d="M42.7,-0.8L57.3,82.1L43.6,128.3L60.6,81.9L42.7,-0.8Z" style="fill:url(#_Linear6);fill-rule:nonzero;"/>
|
||||
<clipPath id="_clip7">
|
||||
<path d="M42.7,-0.8L103.3,24.6L169.9,24.6L230.5,-0.7L178.4,26.7L136.7,35.8L94.6,26.7L42.7,-0.8Z" clip-rule="nonzero"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip7)">
|
||||
<g transform="matrix(1.82636,-0,-0,1.82366,-84.0127,-33.757)">
|
||||
<use xlink:href="#_Image8" x="68.494" y="17.79" width="104.826px" height="22.071px" transform="matrix(0.998341,0,0,0.959608,0,0)"/>
|
||||
</g>
|
||||
</g>
|
||||
<clipPath id="_clip9">
|
||||
<path d="M60.6,81.9L57.6,90.2L120.5,32.2L60.6,81.9Z" clip-rule="nonzero"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip9)">
|
||||
<g transform="matrix(1.82636,-0,-0,1.82366,-84.0127,-33.757)">
|
||||
<use xlink:href="#_Image10" x="77.718" y="35.369" width="36.439px" height="33.806px" transform="matrix(0.984826,0,0,0.994282,0,0)"/>
|
||||
</g>
|
||||
</g>
|
||||
<clipPath id="_clip11">
|
||||
<path d="M212.6,82L153,32.2L215.5,89.8L212.6,82Z" clip-rule="nonzero"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip11)">
|
||||
<g transform="matrix(1.82636,-0,-0,1.82366,-84.0127,-33.757)">
|
||||
<use xlink:href="#_Image12" x="131.549" y="35.6" width="36.22px" height="33.586px" transform="matrix(0.978906,0,0,0.987831,0,0)"/>
|
||||
</g>
|
||||
</g>
|
||||
<clipPath id="_clip13">
|
||||
<path d="M0,186L146.3,266.7L164.8,313L125.6,327.9L64.6,321.6L0,232.6L0,186Z" clip-rule="nonzero"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip13)">
|
||||
<g transform="matrix(1.82636,-0,-0,1.82366,-84.0127,-33.757)">
|
||||
<use xlink:href="#_Image14" x="45.375" y="119.784" width="92.232px" height="79.812px" transform="matrix(0.991747,0,0,0.997649,0,0)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M121.1,252.8L64.8,321.4L64.6,321.6L125.5,342L125.6,342.1L173.2,317.7L173.3,317.6L173.3,281.5L121.1,252.8Z" style="fill:white;fill-rule:nonzero;"/>
|
||||
<clipPath id="_clip15">
|
||||
<path d="M212.6,82L230.5,-0.7L178.4,26.7L153,32.2L212.6,82Z" clip-rule="nonzero"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip15)">
|
||||
<g transform="matrix(1.82636,-0,-0,1.82366,-84.0127,-33.757)">
|
||||
<use xlink:href="#_Image16" x="130.418" y="17.361" width="44.433px" height="47.35px" transform="matrix(0.987391,0,0,0.986453,0,0)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M136.6,201.6L120.1,183.5L136.6,165.3L153.2,183.5L136.6,201.6Z" style="fill:white;fill-rule:nonzero;"/>
|
||||
<path d="M135,35.4L136.7,35.8L138.2,35.5L136.6,141L135,35.4Z" style="fill:url(#_Linear17);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<image id="_Image2" width="77px" height="92px" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCABcAE0DAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDiGSvpLHhjClFgGFKQxjJSsBGUoAYUoHcYUpANKUWAYUpDGlKQXOkZK3sZXGNHSGRslADGSlYYxkoAYyUhkbJSsAxkoAYUoHcYUpWA6ZkraxlcYyUAMZKQxjJRYLkbJSGMZKAGMlKwyNkoAYUpDGFKVgOmKitzIYUosAxo6Vh3GMntSsFxhSgBjJSGRslFguMZKQxjJQAwx+1Kw7m5mtTMXNABwaAGlaAGlKQDGjoAYye1Kw7kZSgBjJSGMMftRYLmgGBqiRQaAFzTAWgBc0AHBoAaVoAaUpWAY0dAEZT2pWHcYso9aLjJFk96LisPD0wsPDCgQoNAC5pgLQAuaADANADdtFgMFLj3rG5rYnSf3qrisTJN707isSrKD3p3ESLJ70XFYkD0wsODCgQ7NABmmAtAHDx3XvXIpHRYsx3PvVJisWY7n3qkybE6T+9O4rE6T+9VcLEyTU7isTLID3p3ESK/vRcVh4emKw4MKAPPa4jqFVmHQ07gSpcMOtO4rFiO696pSFYsx3PvTuTYsx3PvVJisTpP707isTpP71VxWJkmp3FYlEox1p3A4auM6AoAKACgByuw6GncRKlww607hYsR3XvVKQrFmO596q5NixHcD1p3FYnWfjrTuKxzFc5sFABQAUAFABQAUAOV2HQ00xFmKRvWqTEyyjtjrTuKx//Z"/>
|
||||
<image id="_Image4" width="105px" height="113px" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCABxAGkDAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDgq+iPEFUZNAE6CmBMgqhEyCmSyVRTAeKYhwoAcBTEOpgFABQAUAFAHO1zmpLGKYE6CmhEyCqESoKBEgpiHAUwHCgQ4UwFpgFABQAUALigDnkGTXOak6CqAmQUySZBTESgUxDhTAcBQA8UxC0wCgAoAKAFFABQBhIKwNSdBTQiZBVCZKopiHigQ4CmA8UCHUwCmAUAFAAKAFoAKAMZBWJqTIKZJMgpiJAKYhwpgPAoAcKYhaYBQAUAFACigAoAKAMpBWRoSoKZLJlFMBwpiHigBwFMQ6gApgFABQACgBaACgAoAzUFZFkyCmIkFMQ4CmA4UCHCmAtMAoAKACgBaACgAoAKAKCCsyiVRTEPFMBwoAcBTEOpgFABQAUAKKACgAoAKACgCogrMoeKYhwFMBwoEOFMBaYBQAUAFAC0AFABQAUAFAFYCoGOFMB4FADhTELTAKACgAoAUUAFABQAUAFABQBXFQMeBTAcKBDqYBTAKACgAFAC0AFABQAUAFABQBABUjHigBwpiFpgFABQAUAKKACgAoAKACgAoAKAIhUjHAUxDqYBQAUAFAAKAFoAKACgAoAKACgAoAjFSMcKYhaYBQAUAFAC0AFABQAUAFABQAUAFADB0qRjqYgpgFABQACgBaACgAoAKACgAoAKACgD/9k="/>
|
||||
<linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-192.064,2.35211e-14,-2.35211e-14,-192.064,342.528,63.8296)"><stop offset="0" style="stop-color:rgb(32,52,76);stop-opacity:1"/><stop offset="0.25" style="stop-color:rgb(32,52,76);stop-opacity:1"/><stop offset="0.41" style="stop-color:rgb(39,61,87);stop-opacity:1"/><stop offset="0.67" style="stop-color:rgb(57,83,115);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(84,118,158);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(198.562,0,0,198.562,-74.3281,63.7777)"><stop offset="0" style="stop-color:rgb(84,118,158);stop-opacity:1"/><stop offset="0.25" style="stop-color:rgb(84,118,158);stop-opacity:1"/><stop offset="0.41" style="stop-color:rgb(77,110,147);stop-opacity:1"/><stop offset="0.69" style="stop-color:rgb(60,87,119);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(35,56,80);stop-opacity:1"/></linearGradient>
|
||||
<image id="_Image8" width="105px" height="23px" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGkAAAAXCAYAAAAIqmGLAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB6klEQVRogdVZS7LEIAjEqhztnWTuMufOW0xVEhWlhdYkvZpMBeTTIsT09/nukiF1ngJ4nqL4ypApcXs32a85SiKS56zIoN8GUxGK0t5xU0w0FFUuQMGJO77tWZIuvxPo8qANvH3wbkLp/+jYdsWiJCL5DhtR2QfN/wWEEmF5re8olFRbnQxNmLNtXTCiNJNQIiyvy2N/jFRFuUMWGQ+AKkEqPW8i1PFK1Qf0cSQJixkQAEWRKjEtjjFCqVLEsyx/BSPUUe6qV1XDgLKygMQzCSWa1BJCibQMUhsHVb5CPwgzp5k3EaqxcuMt3SC1ccDQLysU/2llxt5Vy0jVXKgdT7Bx6MFxUDuCHwuifU6FSTWRUIQknfJp4rzCqUxrCDUi1lf004KXO2DVOuH3fWfTUfRWCKmc7IiT6iRUu3EIrxqfV9wpRjf04LyyFqdt4XLXdi0eAKyLQwQtcAZgl5eAUKC7+8GW9s8rjsVM2G0D5zRh+kRoHC4gzCuzi47diD+PUFiSUvfxBGFeWfbVjTQAr5ivNscHp0AgFxzUilooH6qU7ekKUnHLHYw8ANRbaMUdn4fPIRScJK6Z+YUdZMFNtw/ajqKRCiQU3N25YgQZOmcAnnbtdwOpfOWO0OHoKngXdq5RCVLML4OWln+0j7xUBJmB9gAAAABJRU5ErkJggg=="/>
|
||||
<image id="_Image10" width="37px" height="34px" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAiCAYAAADYmxC7AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAByUlEQVRYhc2WUXLFIAhFr+ytK+laum76oRFEUJKXpJ3JREYETkCM5ev7h4HSnjoCBaUUAABKaVMFTRK5r62j+BCbwUe3h/LVfIgCxMwAuD11BBh1HgBzm2I0SeS+FsaH2Aw+uj2ULz1UHyS2GTA8BKY1LJnKgXEazGY5AoMBA3qmVmC4BOaV3wNjA8YAqKcuBNP6w4sBAxs5nsuAkf6KLNjp5rDl1ZlzwMhL71tgHIARTKcI4N+BkQT+P2A0Br4TzDZHBGbWgkET+QRm9VkwT++BCdkhk3/4bVJuAgtABhxK74NRHDgPduseRDvRw1ov98LhGLeD0a7Wsd7L6D1gNAb2yd8Gm/59b4Gt4rr/vjfAVnGnf98dYKKPwKx+jEsZ8rNg/l1ql1GJS81Nf6O/eZRNJuLm+Bwsf8kLu8jLaAQ2l9oDGzb6bBSBZUrtgfl70ILROOkZeWDZPQilX4PpjNbyPQp2vjmkfCkwjGC75ui6eW6QDZiUz9R1V3+dnTCjySzqj2OwOqecFs6ArU7tU2DzRr8OxqfArN4HI1k3g8nCuaOugXn6GWy4eVqw7b06BYYkmMSrl7xHwc43h1zyUmD7TXrE+qQ5fgFUaJJhxBls6wAAAABJRU5ErkJggg=="/>
|
||||
<image id="_Image12" width="37px" height="34px" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAiCAYAAADYmxC7AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAChElEQVRYhb2XYVIFIQyDY6/oWbyNd60/HpQ0tPDWGXUcRRbhaxLq+vH59e3uDgCAO14jH58y7/Pp63msmPPuY+34Pte4rz3HeK0d+8c8YJMnznkABJ5PQLxXB4QFhAUEOGyHwPpg4kROIKDD+HlSQoCiOCqCVLV06KaGWHUCcl4n1iQlClVlD7vnRUQrgMaZvTWarwKIXbHwvgSi+TmKYZOVizVsaVTDRbhmqgNS+zgrEKCTNUl2VtUD6BX0p0C0JltTAIUSEdB09XcgjJbA1nRAbLHfskLWHHpR2iP2nkpF1Qegd5tjaU0BBAbKCsJ9v320Ex1SWUNqbNZIViBAjYJzLveplJ15CB3GwK01rHZ3A5eC6RaPOdtFqYFmZstKkxKFqkWDhRTKgbdkD5DHXS/irFwCXzXH9gYOQSykTvbxgQJ0tYYzultzvIHjLPv/5ogCKKtqGxBWpX/THDlLpCpFxZZ5TRVNVgKmvIGFNQwUgSdVyRlb/qsSD5sjCGhT4p3Ar9+xGih0a6ypAt83x6oXtar6vH3SM0prroFnILXmQeDhsOcvahXQyZoOSIGXgut96lfWzC+nwMteReATsPP71LvW3ALf3sAilxQVVs5KWVPgxZpi4zIrUCAqaouKp7HVWUGq4vfWdDdQ19DYff4zerKmAdqUqKyhvSBFRHYTL4DZ0bmKLisQoAa4voGSL4mKPovmeb+BaIGyNZCDFUijIrBOf2ayEkXgj9Z0gRcVWMEiS3PO9iq8BeqtaYASMLbDwUBYkNYDzdx31lS9SIBC1f3w+bPeVjhG8/RcfbImAu8XoJxL+CqqOryee51jM0tt4EtrkCuuAq8KaH5yLAMI7vgBdTzcL9uCvFAAAAAASUVORK5CYII="/>
|
||||
<image id="_Image14" width="93px" height="80px" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCABQAF0DAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDFr6o+fCgAoAKACgBDSAQ0ANNIBhoGNNIBp6UhjTQBdrQkKACgAoAKAENIBppANNADDQMaaQDTSGNoAvVoSFABQAUABpANNADTSAa1ADDSGNNIBpoGNNAF+tCQoAKACgBDSAQ0AMNIBpoGNNIBppDGGgBtAGhWhIUAFABQAhpANNIBpoAYaBjTSAaaQxhoAaaANGtCQoAKAA0gGmgBppAMNADT1pDGmgBppDGmgBpoGjRrQgKACgBDSAaaQDTQA00DGHpSAQ0hjDQA00ANPWkM0q1ICgApAIaAGnpSAY1ADTQMaaQDTSGMNADTQCGmkM061ICgANIBpoAaaQDDQA00hjTSAaaBjTQAw0hjT1oA1K1ICgBD1pANNIBpoAYaBjTSAaaQxpoAaaAGGkMaaAP/2Q=="/>
|
||||
<image id="_Image16" width="45px" height="48px" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAwCAYAAACFUvPfAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE80lEQVRoga1YbXLrQAjj4Sv2LD1Oj7q8H8uHYMFO0nYm09axEwFCgv1Hv/z5+v5hIrqI5CKhi4hYiC6/RmTX7RoT0SV+XeI9kUuIWH/r//a5wiL7Xv4DwEwkTEJ8AzjuM8BUAJOw7HsccHxuABaRz0F/ff/8UyCeScnZ9EAQoN7DJGLv7WA16yJ07fcErsmuoD7zEWgFXCmRsplfDtiCSe+LZlXEnlfwG7AGZZX7INMBmGZKbFpgEBZU5bFmL7LqvPYgjCq7AkLyUaY1W1Ip4UBIWkp4Q5FTQqBam7+pEXcQdo2tKd8C/fX905cbgETpBRqQvKEoUYIUqDAJqVK4grA2J6rIe5kGwJGRyt0A7A3YSJs3FEraBi5QRW9KDSKa/iXQRdqAEp1SQDYbSgA/FahlWlIFrCmlBvFKpqt5AOAAWNSArPEKJcA0CiVyBaSARGV51GkAjJprGZ3Mo1cTwoaiCwAf5oGmgk0p+l0jaDAPb67G7SbzuEbzON3uAsBAQa8su4LcZboxj1MpXNY6t8tN2pjH5HapAoKZFr23Aw3mUd2ulDvxOhzxffOYmjObigKeMm0fNPETlaIzD+f4rXnUII7mjAoo4P03FdCNeaRsRiZLEFkpGCgBZS7mobocDoh6DUFbhklfmOnBPLKBNG7XzcXF7YCnRXdDBkEtkOs7swZWA9jqoYAn86iU6NwOzePO7Zynd+aBei3QgPY3g9tN5tFRwgBP5lHcLldAmzN4XczD7jUuI2Cjh3OPCF/HqhSai7NAbx7F7WR2OzMbMI8mu/v5kDwnfmceVw2iVRPU3dM8btyOMq/13kqHgx7F7ap5dG5XLR22DBgph1Upu11REGg2kzoHvBvSJQ9XpWoe3oiDebj1itOlbyhquQ7Xh+xSpx4P5pENpne7uO5SaZl2tXgyj9xs5GBbumD5W6XIlOhXpWq94nr/lnmwlT8AaiWBKgY6uDuvSnfmMa1Kh3mE/B1cvVIA/lotZZq5eFyVOCgxmgdsIEkGL6BRcL0vP3cBoF4XpTjMA90Op66HValMdqYsjXkMDahcp049uB6cVPOobtc0FDblYB4+7FMCDPI2BLCSeuA8jUrx4jlbDFb35lFXpdDfkl1Odq3VmeaPwTw+PWd7XpVu3Y7kyurRBISN+DfnbHRwva5KFM0GI6pT4BiOagAii9ERJ/N465ytmkddlRxMYx4Y0AB4c/qX52zYnGkpLdOar0rudvfqoddW17RcV6V3zOPG7ZrZgbLWnvLW6TXZMyyy2BRlGICezMOb8nlVeszmaR4RZADV35bpY1W6APDb52zRnJTcrarBk3rEMyvxHCQvrUoMCuDzyGge46q0mlmisetTPRizGmAN/FYPnBGmczYG+btm83helQSyOjfkYlknLcjUI5nHuSpdkD2mUoGoTDIPP4wpYJJ6HHqd6ZBokd5fwlaiT8/ZeDaPFYDL+BnZJQSP3AWwOdtbPR7O2SzTZbLLptJx12eVU2ejAgufgUBtjnagSUW4NQ8I4oVV6Y6rfUCNXmvj7u9aOTj/LL3+V+dszaqUzGPUawii1WSkhdEFAf/JORuCO+QtV4QDbG2+TAeliwfgDYXDz2/O2eL/Zm5I6pGAHgaS6HIstn98zhZfcqxKIIdSgUa21+rpsoIuXLN3rErZPLrsTuaR1AOeYTWPgxYk6yW6/AdyxQlNZJfFBgAAAABJRU5ErkJggg=="/>
|
||||
<linearGradient id="_Linear17" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.71996e-14,-444.203,444.203,2.71996e-14,136.61,347.973)"><stop offset="0" style="stop-color:rgb(84,118,158);stop-opacity:1"/><stop offset="0.25" style="stop-color:rgb(84,118,158);stop-opacity:1"/><stop offset="0.41" style="stop-color:rgb(77,110,147);stop-opacity:1"/><stop offset="0.68" style="stop-color:rgb(60,87,119);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(34,54,78);stop-opacity:1"/></linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,147 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 1050 350" style="enable-background:new 0 0 1050 350;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#273C51;}
|
||||
.st2{fill:url(#SVGID_1_);}
|
||||
.st3{fill:#466284;}
|
||||
.st4{fill:#354D6A;}
|
||||
.st5{fill:url(#SVGID_2_);}
|
||||
.st6{fill:url(#SVGID_3_);}
|
||||
.st7{fill:url(#SVGID_4_);}
|
||||
.st8{fill:url(#SVGID_5_);}
|
||||
.st9{fill:url(#SVGID_6_);}
|
||||
.st10{fill:url(#SVGID_7_);}
|
||||
.st11{fill:url(#SVGID_8_);}
|
||||
.st12{fill:url(#SVGID_9_);}
|
||||
.st13{fill:url(#SVGID_10_);}
|
||||
.st14{fill:none;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M280.6,198.7c-15.2,0-31.5,6-31.5,20.6c0,13,14.9,16.8,32.6,19.7c24,3.8,47.6,8.6,47.6,35.6
|
||||
c-0.2,26.9-25.9,35.6-48.8,35.6c-21.2,0-41.5-7.7-50.7-27.8l12.3-7.2c7.7,14.2,23.8,21.1,38.6,21.1c14.6,0,33.9-4.6,33.9-22.3
|
||||
c0.2-14.9-16.6-19.2-34.6-21.9c-23.1-3.6-45.6-8.9-45.6-33.2c-0.3-25,25.2-33.6,45.9-33.6c17.8,0,34.8,3.6,45.4,21.8l-11.3,7
|
||||
C307.9,203.7,294,198.9,280.6,198.7z"/>
|
||||
<path class="st0" d="M353.8,188.1v49.2c7.2-11.1,18.5-14.9,29.3-15.1c23.8,0,35.5,15.8,35.5,39.1v46.6h-13.9v-46.4
|
||||
c0-16.6-8.6-26-24-26S354,247.5,354,263v44.9h-14V187.9h13.9V188.1z"/>
|
||||
<path class="st0" d="M504.4,308.2l-0.3-15.4c-6.7,11.7-19.5,17.1-31.2,17.1c-24.3,0-43.3-16.8-43.3-44.4
|
||||
c0-27.4,19.4-43.9,43.5-43.7c12.7,0,25.2,5.8,31.4,16.8l0.2-15.4h13.7v84.6h-13.5L504.4,308.2z M473.5,235.2
|
||||
c-16.8,0-30.3,12-30.3,30.8s13.5,31,30.3,31c40.8,0,40.8-62,0.2-62L473.5,235.2z"/>
|
||||
<path class="st0" d="M529.5,223.6h13.4l0.7,16.3c6.7-11.3,19.2-17.8,32.6-17.8c24.3,0.5,42.1,17.6,42.1,43.7
|
||||
c0,26.7-17.6,44-43,44c-12,0-25.4-5.1-32-17.1v55.2h-13.7V223.6z M604.2,266c0-19-12.5-30.3-29.8-30.3c-17.6,0-29.6,13-29.6,30.3
|
||||
s12.5,30.3,29.6,30.5C591.3,296.5,604.2,285.1,604.2,266z"/>
|
||||
<path class="st0" d="M708.9,294.3c-8.6,10.1-23.3,15.1-36.5,15.1c-26.2,0-44.5-17.3-44.5-44.2c0-25.5,18.3-43.9,43.9-43.9
|
||||
c25.9,0,45.6,15.9,42.3,49.7h-72c1.5,15.6,14.4,25.4,30.7,25.4c9.6,0,21.2-3.8,26.9-10.6l9.4,8.6H708.9z M700.6,259.4
|
||||
c-0.7-16.4-12-25.4-28.6-25.4c-14.7,0-27.6,8.9-30,25.2h58.6V259.4z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M771.2,198.7c-15.2,0-31.5,6-31.5,20.6c0,13,14.9,16.8,32.6,19.7c24,3.8,47.6,8.6,47.6,35.6
|
||||
c-0.2,26.9-25.9,35.6-48.8,35.6c-21.2,0-41.5-7.7-50.7-27.8l12.3-7.2c7.7,14.2,23.8,21.1,38.6,21.1c14.6,0,33.9-4.6,33.9-22.3
|
||||
c0.2-14.9-16.6-19.2-34.6-21.9c-23.1-3.6-45.6-8.9-45.6-33.2c-0.3-25,25.2-33.6,45.9-33.6c17.8,0,34.8,3.6,45.4,21.8l-11.3,7
|
||||
C798.5,203.7,784.6,198.9,771.2,198.7z"/>
|
||||
<path class="st0" d="M844.4,188.1v49.2c7.2-11.1,18.5-14.9,29.3-15.1c23.8,0,35.5,15.8,35.5,39.1v46.6h-13.9v-46.4
|
||||
c0-16.6-8.6-26-24-26s-26.7,12.2-26.7,27.6v44.9h-14V187.9h13.9V188.1z"/>
|
||||
<path class="st0" d="M920.6,307.8h14v-83.4h-14V307.8z M927.8,211.7l-11.1-12.2l11.1-12.2l11.1,12.2L927.8,211.7z"/>
|
||||
<g>
|
||||
<polygon class="st0" points="960.8,308 960.8,307.8 960.7,307.8 "/>
|
||||
<path class="st0" d="M974.7,217.6c0-12.7,5.8-18.3,14.9-18.3c0.2,0,0.4,0,0.5,0l3.2-12.1c-1.3-0.2-2.7-0.3-4-0.3
|
||||
c-17.8,0-28.4,11.3-28.4,30.7v6.7h-16.6v12.3h16.6v71.3h13.9v-71.3h16.8v-12.3h-16.8V217.6z"/>
|
||||
</g>
|
||||
<path class="st0" d="M1046.1,296.1c-1.1,0.2-2.2,0.3-3.3,0.3c-10.1,0-13.4-6.3-13.4-16.3v-43.6h18v-12.2h-17.9v-25.8l-14,1.5
|
||||
v24.2h-17v12.2h17v43.6c0,18.7,8.6,29.3,26.7,29c2.2-0.1,4.4-0.3,6.5-0.8L1046.1,296.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
<polygon class="st1" points="216,82.1 230.5,-0.7 169.9,24.6 103.3,24.6 42.7,-0.8 57.3,82.1 43.6,128.3 56.5,136.4 0,186 0,232.6
|
||||
64.6,321.6 125.5,342 125.6,342.1 173.2,317.7 173.3,317.6 173.3,281.5 146.3,266.7 146.3,266.7 146.3,266.7 188.7,153.8
|
||||
188.4,153.8 229.6,128.3 "/>
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="136.7364" y1="25.9921" x2="60.3198" y2="247.6647">
|
||||
<stop offset="0.1345" style="stop-color:#2B415B"/>
|
||||
<stop offset="0.3762" style="stop-color:#3B5676"/>
|
||||
<stop offset="0.6923" style="stop-color:#54769E"/>
|
||||
<stop offset="0.7901" style="stop-color:#52749B"/>
|
||||
<stop offset="0.8614" style="stop-color:#4D6C92"/>
|
||||
<stop offset="0.9244" style="stop-color:#436082"/>
|
||||
<stop offset="0.9822" style="stop-color:#364F6C"/>
|
||||
<stop offset="1" style="stop-color:#314863"/>
|
||||
</linearGradient>
|
||||
<polygon class="st2" points="97.7,100.3 0,186 136.1,264.3 136.6,102.9 "/>
|
||||
<polygon class="st3" points="83.8,153.3 136.2,293.4 136.6,161.1 "/>
|
||||
<polygon class="st4" points="188.7,153.8 136.2,293.4 136.6,161.1 "/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="230.1033" y1="127.4219" x2="34.0475" y2="14.229">
|
||||
<stop offset="0" style="stop-color:#54769E"/>
|
||||
<stop offset="0.4802" style="stop-color:#53749C"/>
|
||||
<stop offset="0.6878" style="stop-color:#4F6F95"/>
|
||||
<stop offset="0.8423" style="stop-color:#486588"/>
|
||||
<stop offset="0.9095" style="stop-color:#435F80"/>
|
||||
</linearGradient>
|
||||
<polygon class="st5" points="230.5,-0.7 178.4,26.7 136.7,35.8 94.6,26.7 42.7,-0.8 60.6,81.9 43.6,128.3 103.2,165.3
|
||||
136.3,201.3 136.3,201.6 136.5,201.4 136.7,201.6 136.7,201.3 169.8,165.3 229.6,128.3 212.6,82 "/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="342.5284" y1="63.8296" x2="150.4648" y2="63.8296">
|
||||
<stop offset="0.2539" style="stop-color:#20344C"/>
|
||||
<stop offset="0.4072" style="stop-color:#273D57"/>
|
||||
<stop offset="0.6733" style="stop-color:#395373"/>
|
||||
<stop offset="1" style="stop-color:#54769E"/>
|
||||
</linearGradient>
|
||||
<polygon class="st6" points="230.5,-0.7 216,82.1 229.6,128.3 212.6,82 "/>
|
||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-74.3281" y1="63.7777" x2="124.2335" y2="63.7777">
|
||||
<stop offset="0.2539" style="stop-color:#54769E"/>
|
||||
<stop offset="0.4133" style="stop-color:#4D6E93"/>
|
||||
<stop offset="0.6897" style="stop-color:#3C5777"/>
|
||||
<stop offset="1" style="stop-color:#233850"/>
|
||||
</linearGradient>
|
||||
<polygon class="st7" points="42.7,-0.8 57.3,82.1 43.6,128.3 60.6,81.9 "/>
|
||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="138.4299" y1="-77.4169" x2="134.5027" y2="85.5632">
|
||||
<stop offset="6.545247e-03" style="stop-color:#54769E"/>
|
||||
<stop offset="0.1993" style="stop-color:#507198"/>
|
||||
<stop offset="0.4502" style="stop-color:#466488"/>
|
||||
<stop offset="0.7318" style="stop-color:#354F6D"/>
|
||||
<stop offset="1" style="stop-color:#21354D"/>
|
||||
</linearGradient>
|
||||
<polygon class="st8" points="42.7,-0.8 103.3,24.6 169.9,24.6 230.5,-0.7 178.4,26.7 136.7,35.8 94.6,26.7 "/>
|
||||
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="173.2798" y1="-23.2345" x2="12.7505" y2="132.5687">
|
||||
<stop offset="0.2539" style="stop-color:#54769E"/>
|
||||
<stop offset="0.4102" style="stop-color:#4D6E93"/>
|
||||
<stop offset="0.6813" style="stop-color:#3C5777"/>
|
||||
<stop offset="1" style="stop-color:#22364E"/>
|
||||
</linearGradient>
|
||||
<polygon class="st9" points="60.6,81.9 57.6,90.2 120.5,32.2 "/>
|
||||
<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="114.997" y1="-2.4443" x2="248.7759" y2="116.8474">
|
||||
<stop offset="0.2539" style="stop-color:#54769E"/>
|
||||
<stop offset="0.4102" style="stop-color:#4D6E93"/>
|
||||
<stop offset="0.6813" style="stop-color:#3C5777"/>
|
||||
<stop offset="1" style="stop-color:#22364E"/>
|
||||
</linearGradient>
|
||||
<polygon class="st10" points="212.6,82 153,32.2 215.5,89.8 "/>
|
||||
<linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="-31.9333" y1="230.8414" x2="255.118" y2="333.2895">
|
||||
<stop offset="0.2664" style="stop-color:#54769E"/>
|
||||
<stop offset="1" style="stop-color:#425E7F"/>
|
||||
</linearGradient>
|
||||
<polygon class="st11" points="0,186 146.3,266.7 164.8,313 125.6,327.9 64.6,321.6 0,232.6 "/>
|
||||
<polygon class="st0" points="121.1,252.8 64.8,321.4 64.6,321.6 125.5,342 125.6,342.1 173.2,317.7 173.3,317.6 173.3,281.5 "/>
|
||||
<linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="97.761" y1="-67.9411" x2="268.6103" y2="84.2801">
|
||||
<stop offset="0.4609" style="stop-color:#54769E;stop-opacity:0"/>
|
||||
<stop offset="0.5699" style="stop-color:#52739A;stop-opacity:0.2156"/>
|
||||
<stop offset="0.6764" style="stop-color:#4A698E;stop-opacity:0.4266"/>
|
||||
<stop offset="0.782" style="stop-color:#3D597B;stop-opacity:0.6356"/>
|
||||
<stop offset="0.8863" style="stop-color:#2C435F;stop-opacity:0.8422"/>
|
||||
<stop offset="0.9661" style="stop-color:#1B2E45"/>
|
||||
</linearGradient>
|
||||
<polygon class="st12" points="212.6,82 230.5,-0.7 178.4,26.7 153,32.2 "/>
|
||||
<polygon class="st0" points="136.6,201.6 120.1,183.5 136.6,165.3 153.2,183.5 "/>
|
||||
<linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="136.6099" y1="347.9733" x2="136.6099" y2="-96.2296">
|
||||
<stop offset="0.2539" style="stop-color:#54769E"/>
|
||||
<stop offset="0.4102" style="stop-color:#4D6E93"/>
|
||||
<stop offset="0.6813" style="stop-color:#3C5777"/>
|
||||
<stop offset="1" style="stop-color:#22364E"/>
|
||||
</linearGradient>
|
||||
<polygon class="st13" points="135,35.4 136.7,35.8 138.2,35.5 136.6,141 "/>
|
||||
<path class="st14" d="M77.6,35.5"/>
|
||||
<path class="st14" d="M75.1,35.5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 136 KiB |
|
@ -11,6 +11,7 @@ import { CopayersPage } from '../add/copayers/copayers';
|
|||
import { GlideraPage } from '../integrations/glidera/glidera';
|
||||
import { MercadoLibrePage } from '../integrations/mercado-libre/mercado-libre';
|
||||
import { ProposalsPage } from './proposals/proposals';
|
||||
import { ShapeshiftPage } from '../integrations/shapeshift/shapeshift';
|
||||
import { TxDetailsPage } from '../tx-details/tx-details';
|
||||
import { TxpDetailsPage } from '../txp-details/txp-details';
|
||||
import { WalletDetailsPage } from '../wallet-details/wallet-details';
|
||||
|
@ -360,9 +361,6 @@ export class HomePage {
|
|||
|
||||
public goTo(page): void {
|
||||
switch (page) {
|
||||
case 'MercadoLibrePage':
|
||||
this.navCtrl.push(MercadoLibrePage);
|
||||
break;
|
||||
case 'AmazonPage':
|
||||
this.navCtrl.push(AmazonPage);
|
||||
break;
|
||||
|
@ -375,6 +373,12 @@ export class HomePage {
|
|||
case 'GlideraPage':
|
||||
this.navCtrl.push(GlideraPage);
|
||||
break;
|
||||
case 'MercadoLibrePage':
|
||||
this.navCtrl.push(MercadoLibrePage);
|
||||
break;
|
||||
case 'ShapeshiftPage':
|
||||
this.navCtrl.push(ShapeshiftPage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>{{'Confirm'|translate}}</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<div class="sending-label">
|
||||
<img src="assets/img/shapeshift/icon-shapeshift.svg" alt="shapeshift">
|
||||
<span translate>Shift</span>
|
||||
</div>
|
||||
<div class="amount-label">
|
||||
<div class="amount">{{amountStr}}</div>
|
||||
<div class="alternative" *ngIf="fiatAmount">{{fiatAmount | currency}} {{currencyIsoCode}}</div>
|
||||
</div>
|
||||
</ion-item>
|
||||
|
||||
<div class="info">
|
||||
<ion-item>
|
||||
<span translate>From</span>
|
||||
<img item-end *ngIf="fromWallet.coin == 'btc'" src="assets/img/icon-bitcoin.svg" width="18">
|
||||
<img item-end *ngIf="fromWallet.coin == 'bch'" src="assets/img/bitcoin-cash-logo.svg" width="22">
|
||||
</ion-item>
|
||||
<ion-item class="wallet-selector">
|
||||
<img src="assets/img/icon-wallet.svg" class="icon-wallet" />
|
||||
<div class="wallet-balance">
|
||||
<span>
|
||||
{{fromWallet ? fromWallet.name : '...'}}
|
||||
</span>
|
||||
</div>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<span translate>To</span>
|
||||
<img item-end *ngIf="toWallet.coin == 'btc'" src="assets/img/icon-bitcoin.svg" width="18">
|
||||
<img item-end *ngIf="toWallet.coin == 'bch'" src="assets/img/bitcoin-cash-logo.svg" width="22">
|
||||
</ion-item>
|
||||
<ion-item class="wallet-selector">
|
||||
<img src="assets/img/icon-wallet.svg" class="icon-wallet" />
|
||||
<div class="wallet-balance">
|
||||
<span>
|
||||
{{toWallet ? toWallet.name : '...'}}
|
||||
</span>
|
||||
</div>
|
||||
</ion-item>
|
||||
</div>
|
||||
|
||||
<ion-item *ngIf="fiatFee && feeRatePerStr">
|
||||
{{'Fee'|translate}}
|
||||
<ion-note item-end>
|
||||
<span>
|
||||
{{feeStr}} ({{fiatFee | currency}} {{currencyIsoCode}}, {{feeRatePerStr}})
|
||||
</span>
|
||||
</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item *ngIf="fiatTotalAmount">
|
||||
{{'Total'|translate}}
|
||||
<ion-note item-end>
|
||||
<span>
|
||||
{{totalAmountStr}} ({{fiatTotalAmount | currency}} {{currencyIsoCode}})
|
||||
</span>
|
||||
</ion-note>
|
||||
</ion-item>
|
||||
|
||||
</ion-list>
|
||||
|
||||
<p class="text-confirm" *ngIf="withdrawalStr">
|
||||
A total of {{amountStr}} ({{fiatAmount | currency}} {{currencyIsoCode}}) will be exchanged for {{withdrawalStr}} ({{fiatWithdrawal
|
||||
| currency}} {{currencyIsoCode}}). Would you like to proceed?
|
||||
</p>
|
||||
|
||||
</ion-content>
|
||||
|
||||
<ion-footer *ngIf="fromWallet && toWallet && totalAmountStr">
|
||||
<button ion-button block class="button-footer" (click)="confirmTx()" [disabled]="!fromWallet || !totalAmountStr" translate>
|
||||
Click to shift
|
||||
</button>
|
||||
</ion-footer>
|
||||
|
||||
<ion-footer *ngIf="sendStatus === 'success'">
|
||||
<button ion-button block class="button-footer" (click)="goBackHome()" [disabled]="!(wallet && totalAmountStr)" translate>
|
||||
Transaction Sent
|
||||
</button>
|
||||
</ion-footer>
|
|
@ -0,0 +1,44 @@
|
|||
page-shapeshift-confirm {
|
||||
.sending-label {
|
||||
display: flex;
|
||||
font-size: 18px;
|
||||
align-items: center;
|
||||
margin-bottom: 1.8rem;
|
||||
|
||||
img {
|
||||
margin-right: 1rem;
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
}
|
||||
|
||||
.big-icon-svg {
|
||||
margin-right: 0.6rem;
|
||||
}
|
||||
|
||||
}
|
||||
.amount-label{
|
||||
line-height: 30px;
|
||||
.amount{
|
||||
font-size: 38px;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
.alternative {
|
||||
font-size: 12px;
|
||||
color: #9B9B9B;
|
||||
}
|
||||
}
|
||||
.info {
|
||||
.wallet-selector {
|
||||
ion-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.wallet-balance {
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.text-confirm {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,356 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { NavController, NavParams } from 'ionic-angular';
|
||||
import { Logger } from '@nsalaun/ng-logger';
|
||||
import * as moment from 'moment';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
// Pages
|
||||
import { ShapeshiftPage } from '../shapeshift';
|
||||
|
||||
// Providers
|
||||
import { BwcProvider } from '../../../../providers/bwc/bwc';
|
||||
import { BwcErrorProvider } from '../../../../providers/bwc-error/bwc-error';
|
||||
import { ConfigProvider } from '../../../../providers/config/config';
|
||||
import { ExternalLinkProvider } from '../../../../providers/external-link/external-link';
|
||||
import { OnGoingProcessProvider } from "../../../../providers/on-going-process/on-going-process";
|
||||
import { PlatformProvider } from '../../../../providers/platform/platform';
|
||||
import { PopupProvider } from '../../../../providers/popup/popup';
|
||||
import { ProfileProvider } from '../../../../providers/profile/profile';
|
||||
import { ShapeshiftProvider } from '../../../../providers/shapeshift/shapeshift';
|
||||
import { TxFormatProvider } from '../../../../providers/tx-format/tx-format';
|
||||
import { WalletProvider } from '../../../../providers/wallet/wallet';
|
||||
|
||||
@Component({
|
||||
selector: 'page-shapeshift-confirm',
|
||||
templateUrl: 'shapeshift-confirm.html',
|
||||
})
|
||||
export class ShapeshiftConfirmPage {
|
||||
|
||||
private amount: number;
|
||||
private currency: string;
|
||||
private fromWalletId: string;
|
||||
private toWalletId: string;
|
||||
private createdTx: any;
|
||||
private message: string;
|
||||
private configWallet: any;
|
||||
private bitcore: any;
|
||||
private bitcoreCash: any;
|
||||
private useSendMax: boolean;
|
||||
|
||||
public currencyIsoCode: string;
|
||||
public isCordova: boolean;
|
||||
public sendStatus: string;
|
||||
public toWallet: any;
|
||||
public fromWallet: any;
|
||||
public fiatWithdrawal: number;
|
||||
public fiatAmount: number;
|
||||
public fiatFee: number;
|
||||
public fiatTotalAmount: number;
|
||||
public shapeInfo: any;
|
||||
public amountUnitStr: string;
|
||||
public feeRatePerStr: string;
|
||||
public amountStr: string;
|
||||
public withdrawalStr: string;
|
||||
public feeStr: string;
|
||||
public totalAmountStr: string;
|
||||
public txSent: any;
|
||||
public network: string;
|
||||
|
||||
constructor(
|
||||
private bwcProvider: BwcProvider,
|
||||
private bwcErrorProvider: BwcErrorProvider,
|
||||
private configProvider: ConfigProvider,
|
||||
private externalLinkProvider: ExternalLinkProvider,
|
||||
private onGoingProcessProvider: OnGoingProcessProvider,
|
||||
private logger: Logger,
|
||||
private navCtrl: NavController,
|
||||
private navParams: NavParams,
|
||||
private platformProvider: PlatformProvider,
|
||||
private popupProvider: PopupProvider,
|
||||
private profileProvider: ProfileProvider,
|
||||
private shapeshiftProvider: ShapeshiftProvider,
|
||||
private txFormatProvider: TxFormatProvider,
|
||||
private walletProvider: WalletProvider
|
||||
) {
|
||||
this.configWallet = this.configProvider.get().wallet;
|
||||
this.currencyIsoCode = 'USD'; // Only USD
|
||||
this.isCordova = this.platformProvider.isCordova;
|
||||
this.bitcore = this.bwcProvider.getBitcore();
|
||||
this.bitcoreCash = this.bwcProvider.getBitcoreCash();
|
||||
|
||||
this.useSendMax = this.navParams.data.useSendMax ? true : false;
|
||||
|
||||
this.amount = this.navParams.data.amount / 1e8;
|
||||
this.currency = this.navParams.data.currency;
|
||||
this.fromWalletId = this.navParams.data.walletId;
|
||||
this.toWalletId = this.navParams.data.toWalletId;
|
||||
|
||||
this.network = this.shapeshiftProvider.getNetwork();
|
||||
this.fromWallet = this.profileProvider.getWallet(this.fromWalletId);
|
||||
this.toWallet = this.profileProvider.getWallet(this.toWalletId);
|
||||
|
||||
if (_.isEmpty(this.fromWallet) || _.isEmpty(this.toWallet)) {
|
||||
this.showErrorAndBack(null, 'No wallet found'); // TODO: gettextCatalog
|
||||
return;
|
||||
}
|
||||
|
||||
this.shapeshiftProvider.getLimit(this.getCoinPair(), (err: any, lim: any) => {
|
||||
let min = Number(lim.min);
|
||||
let max = Number(lim.limit);
|
||||
|
||||
if (this.useSendMax) this.amount = max;
|
||||
|
||||
let amountNumber = Number(this.amount);
|
||||
|
||||
if (amountNumber < min) {
|
||||
this.showErrorAndBack(null, 'Minimum amount required is ' + min); // TODO: gettextCatalog
|
||||
return;
|
||||
}
|
||||
if (amountNumber > max) {
|
||||
this.showErrorAndBack(null, 'Maximum amount allowed is ' + max); // TODO: gettextCatalog
|
||||
return;
|
||||
}
|
||||
this.createShift();
|
||||
});
|
||||
}
|
||||
|
||||
ionViewDidLoad() {
|
||||
this.logger.info('ionViewDidLoad ShapeshiftConfirmPage');
|
||||
}
|
||||
|
||||
public openExternalLink(url: string) {
|
||||
this.externalLinkProvider.open(url);
|
||||
};
|
||||
|
||||
private showErrorAndBack(title: string, msg: any) {
|
||||
title = title ? title : 'Error'; // TODO: gettextCatalog
|
||||
this.sendStatus = '';
|
||||
this.logger.error(msg);
|
||||
msg = (msg && msg.errors) ? msg.errors[0].message : msg;
|
||||
this.popupProvider.ionicAlert(title, msg).then(() => {
|
||||
this.navCtrl.pop();
|
||||
});
|
||||
};
|
||||
|
||||
private publishAndSign(wallet: any, txp: any, onSendStatusChange: any): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!wallet.canSign() && !wallet.isPrivKeyExternal()) {
|
||||
let err = 'No signing proposal: No private key'; // TODO: gettextCatalog
|
||||
this.logger.info(err);
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
this.walletProvider.publishAndSign(wallet, txp, onSendStatusChange).then((txp: any) => {
|
||||
return resolve(txp);
|
||||
}).catch((err: any) => {
|
||||
return reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private statusChangeHandler(processName: string, showName: string, isOn: boolean) {
|
||||
this.logger.debug('statusChangeHandler: ', processName, showName, isOn);
|
||||
if (processName == 'sendingTx' && !isOn) {
|
||||
this.sendStatus = 'success';
|
||||
} else if (showName) {
|
||||
this.sendStatus = showName;
|
||||
}
|
||||
}
|
||||
|
||||
private satToFiat(coin: string, sat: number, isoCode: string): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.txFormatProvider.toFiat(coin, sat, isoCode).then((value: any) => {
|
||||
return resolve(value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private setFiatTotalAmount(amountSat: number, feeSat: number, withdrawalSat: number) {
|
||||
this.satToFiat(this.toWallet.coin, withdrawalSat, this.currencyIsoCode, ).then((w: any) => {
|
||||
this.fiatWithdrawal = Number(w);
|
||||
|
||||
this.satToFiat(this.fromWallet.coin, amountSat, this.currencyIsoCode, ).then((a: any) => {
|
||||
this.fiatAmount = Number(a);
|
||||
|
||||
this.satToFiat(this.fromWallet.coin, feeSat, this.currencyIsoCode, ).then((i: any) => {
|
||||
this.fiatFee = Number(i);
|
||||
|
||||
this.fiatTotalAmount = this.fiatAmount + this.fiatFee;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private saveShapeshiftData(): void {
|
||||
let address = this.shapeInfo.deposit;
|
||||
let now = moment().unix() * 1000;
|
||||
|
||||
this.shapeshiftProvider.getStatus(address, (err: any, st: any) => {
|
||||
let newData = {
|
||||
address: address,
|
||||
status: st.status,
|
||||
date: now,
|
||||
amount: this.amountStr,
|
||||
title: this.fromWallet.coin.toUpperCase() + ' to ' + this.toWallet.coin.toUpperCase()
|
||||
};
|
||||
|
||||
this.shapeshiftProvider.saveShapeshift(newData, null, (err: any) => {
|
||||
this.logger.debug("Saved shift with status: " + newData.status);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private createTx(wallet: any, toAddress: string): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let parsedAmount = this.txFormatProvider.parseAmount(wallet.coin, this.amount, this.currency);
|
||||
this.amountUnitStr = parsedAmount.amountUnitStr;
|
||||
|
||||
this.message = 'ShapeShift: ' + this.fromWallet.coin.toUpperCase() + ' to ' + this.toWallet.coin.toUpperCase();
|
||||
let outputs = [];
|
||||
|
||||
outputs.push({
|
||||
'toAddress': toAddress,
|
||||
'amount': parsedAmount.amountSat,
|
||||
'message': this.message
|
||||
});
|
||||
|
||||
let txp = {
|
||||
toAddress: toAddress,
|
||||
amount: parsedAmount.amountSat,
|
||||
outputs: outputs,
|
||||
message: this.message,
|
||||
excludeUnconfirmedUtxos: this.configWallet.spendUnconfirmed ? false : true,
|
||||
feeLevel: this.configWallet.settings.feeLevel || 'normal',
|
||||
customData: {
|
||||
'shapeShift': toAddress
|
||||
}
|
||||
};
|
||||
|
||||
this.walletProvider.createTx(wallet, txp).then((ctxp: any) => {
|
||||
return resolve(ctxp);
|
||||
}).catch((err: any) => {
|
||||
return reject({
|
||||
title: 'Could not create transaction', // TODO: gettextCatalog
|
||||
message: this.bwcErrorProvider.msg(err)
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private getLegacyAddressFormat(addr: string, coin: string): string {
|
||||
if (coin == 'btc') return addr;
|
||||
let a = this.bitcoreCash.Address(addr).toObject();
|
||||
return this.bitcore.Address.fromObject(a).toString();
|
||||
}
|
||||
|
||||
private getNewAddressFormat(addr: string, coin: string): string {
|
||||
if (coin == 'btc') return addr;
|
||||
let a = this.bitcore.Address(addr).toObject();
|
||||
return this.bitcoreCash.Address.fromObject(a).toString();
|
||||
}
|
||||
|
||||
private getCoinPair(): string {
|
||||
return this.fromWallet.coin + '_' + this.toWallet.coin;
|
||||
}
|
||||
|
||||
private createShift(): void {
|
||||
this.onGoingProcessProvider.set('connectingShapeshift', true);
|
||||
|
||||
this.walletProvider.getAddress(this.toWallet, false).then((withdrawalAddress: string) => {
|
||||
withdrawalAddress = this.getLegacyAddressFormat(withdrawalAddress, this.toWallet.coin);
|
||||
|
||||
this.walletProvider.getAddress(this.fromWallet, false).then((returnAddress: string) => {
|
||||
returnAddress = this.getLegacyAddressFormat(returnAddress, this.fromWallet.coin);
|
||||
|
||||
let data = {
|
||||
withdrawal: withdrawalAddress,
|
||||
pair: this.getCoinPair(),
|
||||
returnAddress: returnAddress
|
||||
}
|
||||
this.shapeshiftProvider.shift(data, (err: any, shapeData: any) => {
|
||||
if (err || shapeData.error) {
|
||||
this.onGoingProcessProvider.set('connectingShapeshift', false);
|
||||
this.showErrorAndBack(null, err || shapeData.error);
|
||||
return;
|
||||
}
|
||||
|
||||
let toAddress = this.getNewAddressFormat(shapeData.deposit, this.fromWallet.coin);
|
||||
|
||||
this.createTx(this.fromWallet, toAddress).then((ctxp: any) => {
|
||||
// Save in memory
|
||||
this.createdTx = ctxp;
|
||||
this.shapeInfo = shapeData;
|
||||
|
||||
this.shapeshiftProvider.getRate(this.getCoinPair(), (err: any, r: any) => {
|
||||
this.onGoingProcessProvider.set('connectingShapeshift', false);
|
||||
let rateUnit = r.rate;
|
||||
let amountUnit = this.txFormatProvider.satToUnit(ctxp.amount);
|
||||
let withdrawalSat = Number((rateUnit * amountUnit * 100000000).toFixed());
|
||||
|
||||
// Fee rate
|
||||
let per = (ctxp.fee / (ctxp.amount + ctxp.fee) * 100);
|
||||
this.feeRatePerStr = per.toFixed(2) + '%';
|
||||
|
||||
// Amount + Unit
|
||||
this.amountStr = this.txFormatProvider.formatAmountStr(this.fromWallet.coin, ctxp.amount);
|
||||
this.withdrawalStr = this.txFormatProvider.formatAmountStr(this.toWallet.coin, withdrawalSat);
|
||||
this.feeStr = this.txFormatProvider.formatAmountStr(this.fromWallet.coin, ctxp.fee);
|
||||
this.totalAmountStr = this.txFormatProvider.formatAmountStr(this.fromWallet.coin, ctxp.amount + ctxp.fee);
|
||||
|
||||
// Convert to fiat
|
||||
this.setFiatTotalAmount(ctxp.amount, ctxp.fee, withdrawalSat);
|
||||
});
|
||||
}).catch((err: any) => {
|
||||
this.onGoingProcessProvider.set('connectingShapeshift', false);
|
||||
this.showErrorAndBack(err.title, err.message);
|
||||
return;
|
||||
});
|
||||
});
|
||||
}).catch((err: any) => {
|
||||
this.onGoingProcessProvider.set('connectingShapeshift', false);
|
||||
this.showErrorAndBack(null, 'Could not get address');
|
||||
return;
|
||||
});
|
||||
}).catch((err: any) => {
|
||||
this.onGoingProcessProvider.set('connectingShapeshift', false);
|
||||
this.showErrorAndBack(null, 'Could not get address');
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
public confirmTx(): void {
|
||||
if (!this.createdTx) {
|
||||
this.showErrorAndBack(null, 'Transaction has not been created'); // TODO: gettextCatalog
|
||||
return;
|
||||
}
|
||||
let fromCoin = this.fromWallet.coin.toUpperCase();
|
||||
let toCoin = this.toWallet.coin.toUpperCase();
|
||||
let title = 'Confirm to shift ' + fromCoin + ' to ' + toCoin; // TODO: gettextCatalog
|
||||
let okText = 'OK'; // TODO: gettextCatalog
|
||||
let cancelText = 'Cancel'; // TODO: gettextCatalog
|
||||
this.popupProvider.ionicConfirm(title, '', okText, cancelText).then((ok: any) => {
|
||||
if (!ok) {
|
||||
this.sendStatus = '';
|
||||
return;
|
||||
}
|
||||
|
||||
this.onGoingProcessProvider.set('sendingTx', true, this.statusChangeHandler);
|
||||
this.publishAndSign(this.fromWallet, this.createdTx, function () { }).then((txSent: any) => {
|
||||
this.onGoingProcessProvider.set('sendingTx', false, this.statusChangeHandler);
|
||||
this.txSent = txSent;
|
||||
this.saveShapeshiftData();
|
||||
}).catch((err: any) => {
|
||||
this.showErrorAndBack(null, 'Could not send transaction'), err; // TODO: gettextCatalog
|
||||
return;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
public goBackHome() {
|
||||
this.sendStatus = '';
|
||||
this.navCtrl.remove(3, 1);
|
||||
this.navCtrl.pop();
|
||||
this.navCtrl.push(ShapeshiftPage);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
<ion-header>
|
||||
<ion-navbar>
|
||||
<ion-title>Shift</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
|
||||
<ion-content>
|
||||
<ion-list *ngIf="fromWallets.length > 0 && toWallets.length > 0">
|
||||
<div *ngIf="fromWallets.length > 0">
|
||||
<ion-item>
|
||||
<span translate>From</span>
|
||||
<img item-end *ngIf="fromWallet.coin == 'btc'" src="assets/img/icon-bitcoin.svg" width="18">
|
||||
<img item-end *ngIf="fromWallet.coin == 'bch'" src="assets/img/bitcoin-cash-logo.svg" width="22">
|
||||
</ion-item>
|
||||
<button ion-item class="wallet-selector" (click)="showWallets('from')">
|
||||
<img *ngIf="fromWallet.network != 'testnet'" src="assets/img/icon-wallet.svg" class="icon-wallet" />
|
||||
<div class="wallet-balance">
|
||||
<span>
|
||||
{{fromWallet.name || fromWallet.id}}
|
||||
</span>
|
||||
<p>
|
||||
<span *ngIf="!fromWallet.isComplete()" class="assertive" translate>
|
||||
Incomplete
|
||||
</span>
|
||||
<span *ngIf="fromWallet.isComplete()">
|
||||
<span *ngIf="!fromWallet.balanceHidden && !fromWallet.scanning"> {{fromWallet.status.totalBalanceStr ? fromWallet.status.totalBalanceStr : ( fromWallet.cachedBalance ? fromWallet.cachedBalance
|
||||
+ (fromWallet.cachedBalanceUpdatedOn ? ' · ' + ( fromWallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo)
|
||||
: '') : '' ) }} </span>
|
||||
<span *ngIf="fromWallet.scanning" translate> Scanning funds... </span>
|
||||
|
||||
<span *ngIf="fromWallet.balanceHidden && !fromWallet.scanning" translate>[Balance Hidden]</span>
|
||||
<span *ngIf="fromWallet.n > 1">
|
||||
{{fromWallet.m}}-of-{{fromWallet.n}}
|
||||
</span>
|
||||
<ion-icon *ngIf="!fromWallet.balanceHidden && (fromWallet.status.totalBalanceSat != fromWallet.status.spendableAmount)" name="ios-timer-outline"></ion-icon>
|
||||
<span class="assertive" *ngIf="fromWallet.error">{{fromWallet.error}}</span>
|
||||
</span>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="toWallets.length > 0">
|
||||
<ion-item>
|
||||
<span translate>To</span>
|
||||
<img item-end *ngIf="toWallet.coin == 'btc'" src="assets/img/icon-bitcoin.svg" width="18">
|
||||
<img item-end *ngIf="toWallet.coin == 'bch'" src="assets/img/bitcoin-cash-logo.svg" width="22">
|
||||
</ion-item>
|
||||
<button ion-item class="wallet-selector" (click)="showWallets('to')">
|
||||
<img *ngIf="fromWallet.network != 'testnet'" src="assets/img/icon-wallet.svg" class="icon-wallet" />
|
||||
<div class="wallet-balance">
|
||||
<span>
|
||||
{{toWallet.name || toWallet.id}}
|
||||
</span>
|
||||
<p>
|
||||
<span *ngIf="!toWallet.isComplete()" class="assertive" translate>
|
||||
Incomplete
|
||||
</span>
|
||||
<span *ngIf="toWallet.isComplete()">
|
||||
<span *ngIf="!toWallet.balanceHidden && !toWallet.scanning"> {{toWallet.status.totalBalanceStr ? toWallet.status.totalBalanceStr : ( toWallet.cachedBalance ? toWallet.cachedBalance
|
||||
+ (toWallet.cachedBalanceUpdatedOn ? ' · ' + ( toWallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo)
|
||||
: '') : '' ) }} </span>
|
||||
<span *ngIf="toWallet.scanning" translate> Scanning funds... </span>
|
||||
|
||||
<span *ngIf="toWallet.balanceHidden && !toWallet.scanning" translate>[Balance Hidden]</span>
|
||||
<span class="tab-home__wallet__multisig-number" *ngIf="toWallet.n > 1">
|
||||
{{toWallet.m}}-of-{{toWallet.n}}
|
||||
</span>
|
||||
<ion-icon *ngIf="!fromWallet.balanceHidden && (fromWallet.status.totalBalanceSat != fromWallet.status.spendableAmount)" name="ios-timer-outline"></ion-icon>
|
||||
<span class="assertive" *ngIf="toWallet.error">{{toWallet.error}}</span>
|
||||
</span>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ion-item-divider color="light"></ion-item-divider>
|
||||
|
||||
<ion-item>
|
||||
Rate
|
||||
<ion-note item-end>
|
||||
<span *ngIf="!rate">...</span>
|
||||
<span *ngIf="rate">
|
||||
{{rate.rate}} {{toWallet.coin | uppercase}} per {{fromWallet.coin | uppercase}}
|
||||
</span>
|
||||
</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
Limit
|
||||
<ion-note item-end>
|
||||
<span *ngIf="!limit">...</span>
|
||||
<span *ngIf="limit">
|
||||
{{limit.limit}} {{fromWallet.coin | uppercase}}
|
||||
</span>
|
||||
</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
Minimum
|
||||
<ion-note item-end>
|
||||
<span *ngIf="!limit">...</span>
|
||||
<span *ngIf="limit">
|
||||
{{limit.min}} {{fromWallet.coin | uppercase}}
|
||||
</span>
|
||||
</ion-note>
|
||||
</ion-item>
|
||||
|
||||
</ion-list>
|
||||
|
||||
<div class="buttons-container">
|
||||
<!-- TODO: noLowFee -->
|
||||
<button ion-button type="button" *ngIf="fromWallets.length > 0 && toWallets.length > 0" [disabled]="!fromWallet || !toWallet"
|
||||
(click)="setAmount()">
|
||||
Continue
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</ion-content>
|
|
@ -0,0 +1,23 @@
|
|||
page-shapeshift-shift {
|
||||
.wallet-selector {
|
||||
ion-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.wallet-balance {
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
}
|
||||
.buttons-container {
|
||||
position: absolute;
|
||||
bottom: 5vh;
|
||||
width: 100%;
|
||||
button {
|
||||
width: 85%;
|
||||
max-width: 300px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { NavController, ActionSheetController } from 'ionic-angular';
|
||||
import { Logger } from '@nsalaun/ng-logger';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
// Pages
|
||||
import { AmountPage } from './../../../send/amount/amount';
|
||||
|
||||
// Providers
|
||||
import { PopupProvider } from '../../../../providers/popup/popup';
|
||||
import { ProfileProvider } from '../../../../providers/profile/profile';
|
||||
import { ShapeshiftProvider } from '../../../../providers/shapeshift/shapeshift';
|
||||
|
||||
@Component({
|
||||
selector: 'page-shapeshift-shift',
|
||||
templateUrl: 'shapeshift-shift.html',
|
||||
})
|
||||
export class ShapeshiftShiftPage {
|
||||
|
||||
private walletsBtc: Array<any>;
|
||||
private walletsBch: Array<any>;
|
||||
|
||||
public toWallets: Array<any>;
|
||||
public fromWallets: Array<any>;
|
||||
public fromWallet: any;
|
||||
public toWallet: any;
|
||||
public rate: number;
|
||||
public limit: any;
|
||||
public network: string;
|
||||
public fromWalletSelectorTitle: string;
|
||||
public toWalletSelectorTitle: string;
|
||||
|
||||
constructor(
|
||||
private actionSheetCtrl: ActionSheetController,
|
||||
private logger: Logger,
|
||||
private navCtrl: NavController,
|
||||
private popupProvider: PopupProvider,
|
||||
private profileProvider: ProfileProvider,
|
||||
private shapeshiftProvider: ShapeshiftProvider
|
||||
) {
|
||||
this.walletsBtc = [];
|
||||
this.walletsBch = [];
|
||||
this.fromWalletSelectorTitle = 'From';
|
||||
this.toWalletSelectorTitle = 'To';
|
||||
this.network = this.shapeshiftProvider.getNetwork();
|
||||
|
||||
this.walletsBtc = this.profileProvider.getWallets({
|
||||
onlyComplete: true,
|
||||
network: this.network,
|
||||
coin: 'btc'
|
||||
});
|
||||
|
||||
this.walletsBch = this.profileProvider.getWallets({
|
||||
onlyComplete: true,
|
||||
network: this.network,
|
||||
coin: 'bch'
|
||||
});
|
||||
|
||||
if (_.isEmpty(this.walletsBtc) || _.isEmpty(this.walletsBch)) {
|
||||
this.showErrorAndBack(null, 'No wallets available to use ShapeShift'); // TODO: gettextCatalog
|
||||
return;
|
||||
}
|
||||
|
||||
this.fromWallets = _.filter(this.walletsBtc.concat(this.walletsBch), (w: any) => {
|
||||
// Available balance and 1-signature wallet
|
||||
return w.status.balance.availableAmount > 0 && w.credentials.m == 1;
|
||||
});
|
||||
|
||||
this.onFromWalletSelect(this.fromWallets[0]);
|
||||
}
|
||||
|
||||
ionViewDidLoad() {
|
||||
this.logger.info('ionViewDidLoad ShapeshiftShiftPage');
|
||||
}
|
||||
|
||||
private showErrorAndBack(title: string, msg: any): void {
|
||||
title = title ? title : 'Error'; // TODO: gettextCatalog
|
||||
this.logger.error(msg);
|
||||
msg = (msg && msg.errors) ? msg.errors[0].message : msg;
|
||||
this.popupProvider.ionicAlert(title, msg).then(() => {
|
||||
this.navCtrl.pop();
|
||||
});
|
||||
}
|
||||
|
||||
private showToWallets(): void {
|
||||
this.toWallets = this.fromWallet.coin == 'btc' ? this.walletsBch : this.walletsBtc;
|
||||
this.onToWalletSelect(this.toWallets[0]);
|
||||
|
||||
let pair = this.fromWallet.coin + '_' + this.toWallet.coin;
|
||||
this.shapeshiftProvider.getRate(pair, (err: any, rate: number) => {
|
||||
this.rate = rate;
|
||||
});
|
||||
this.shapeshiftProvider.getLimit(pair, (err: any, limit: any) => {
|
||||
this.limit = limit;
|
||||
});
|
||||
}
|
||||
|
||||
public onFromWalletSelect(wallet: any): void {
|
||||
this.fromWallet = wallet;
|
||||
this.showToWallets();
|
||||
}
|
||||
|
||||
public onToWalletSelect(wallet: any): void {
|
||||
this.toWallet = wallet;
|
||||
}
|
||||
|
||||
public setAmount(): void {
|
||||
this.navCtrl.push(AmountPage, {
|
||||
nextPage: 'ShapeshiftConfirmPage',
|
||||
fixedUnit: true,
|
||||
coin: this.fromWallet.coin,
|
||||
walletId: this.fromWallet.id,
|
||||
toWalletId: this.toWallet.id,
|
||||
currency: this.fromWallet.coin.toUpperCase(),
|
||||
shiftMax: this.limit.limit + ' ' + this.fromWallet.coin.toUpperCase(),
|
||||
shiftMin: this.limit.min + ' ' + this.fromWallet.coin.toUpperCase()
|
||||
});
|
||||
}
|
||||
|
||||
public showWallets(selector: string): void {
|
||||
let buttons: Array<any> = [];
|
||||
let walletsForActionSheet: Array<any> = [];
|
||||
|
||||
if (selector == 'from') {
|
||||
walletsForActionSheet = this.fromWallets;
|
||||
} else if (selector == 'to') {
|
||||
walletsForActionSheet = this.toWallets;
|
||||
}
|
||||
|
||||
_.each(walletsForActionSheet, (w: any) => {
|
||||
let walletButton: Object = {
|
||||
text: w.credentials.walletName,
|
||||
cssClass: 'wallet-' + w.network,
|
||||
icon: 'wallet',
|
||||
handler: () => {
|
||||
this.onWalletSelect(w, selector);
|
||||
}
|
||||
}
|
||||
buttons.push(walletButton);
|
||||
});
|
||||
|
||||
const actionSheet = this.actionSheetCtrl.create({
|
||||
title: selector == 'from' ? this.fromWalletSelectorTitle : this.toWalletSelectorTitle,
|
||||
buttons: buttons
|
||||
});
|
||||
|
||||
actionSheet.present();
|
||||
}
|
||||
|
||||
public onWalletSelect(wallet: any, selector: string): void {
|
||||
if (selector == 'from') {
|
||||
this.onFromWalletSelect(wallet);
|
||||
} else if (selector == 'to') {
|
||||
this.onToWalletSelect(wallet);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<ion-header>
|
||||
<ion-navbar transparent>
|
||||
<ion-title>shapeShift</ion-title>
|
||||
</ion-navbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content *ngIf="!shifts.data">
|
||||
<div class="box-notification warning" *ngIf="network == 'testnet'">
|
||||
Sandbox version. Only for testing purpose.
|
||||
</div>
|
||||
<div class="integration-onboarding">
|
||||
<div class="integration-onboarding-logo">
|
||||
<img src="assets/img/shapeshift/logo-shapeshift.svg" width="200" alt="Shapeshift">
|
||||
</div>
|
||||
<div class="integration-onboarding-description">
|
||||
<h4>The Safest, Fastest Asset Exchange on Earth</h4>
|
||||
<p>Trade any leading blockchain asset for any other. Protection by Design. No Account Needed.</p>
|
||||
</div>
|
||||
<div class="integration-onboarding-cta">
|
||||
<!-- TODO: no-low-fee -->
|
||||
<button ion-button (click)="goTo('Shift')">Start</button>
|
||||
<button ion-button (click)="openExternalLink('https://shapeshift.io')">Visit Shapeshift.io →</button>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
|
||||
|
||||
<ion-content *ngIf="shifts.data">
|
||||
|
||||
<div class="main-header" (click)="update()">
|
||||
<img src="assets/img/shapeshift/logo-shapeshift.svg" width="200">
|
||||
</div>
|
||||
|
||||
<ion-list class="shift">
|
||||
<button ion-item (click)="goTo('Shift')">
|
||||
<!-- TODO: no-low-fee -->
|
||||
<img src="assets/img/shapeshift/icon-shapeshift.svg">
|
||||
<span>Shift</span>
|
||||
</button>
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<ion-item-divider color="light">
|
||||
Transactions
|
||||
</ion-item-divider>
|
||||
|
||||
<button ion-item *ngFor="let item of shifts.data | keys">
|
||||
<div class="shapeshift-address">
|
||||
<h2 copy-to-clipboard="{{item.value.address}}">
|
||||
<span class="item-amount">{{ item.value.amount }}</span>
|
||||
<span class="ellipsis">{{item.value.title || item.value.address}}</span>
|
||||
</h2>
|
||||
<ion-note>{{item.value.date | amTimeAgo}}</ion-note>
|
||||
<span>
|
||||
<span class="assertive" *ngIf="item.value.status == 'failed'">Failed</span>
|
||||
<span class="balanced" *ngIf="item.value.status == 'complete'">Completed</span>
|
||||
<span class="dark" *ngIf="item.value.status == 'received'">Pending</span>
|
||||
<span class="text-gray" *ngIf="item.value.status == 'no_deposits'">Pending</span>
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</ion-list>
|
||||
</ion-content>
|
|
@ -0,0 +1,66 @@
|
|||
page-shapeshift {
|
||||
.toolbar {
|
||||
background-color: #28394d;
|
||||
.back-button, &-title {
|
||||
color: white;
|
||||
}
|
||||
.back-button:hover {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
.integration-onboarding {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
background: url('../assets/img/shapeshift/shapeshift_background.jpg') center center no-repeat #28394d;
|
||||
&-logo {
|
||||
display: inline-block;
|
||||
margin-bottom: 1em;
|
||||
img {
|
||||
max-width: 170px;
|
||||
}
|
||||
}
|
||||
&-description {
|
||||
color: white;
|
||||
margin-top: 0;
|
||||
margin-left: 2rem;
|
||||
margin-right: 2rem;
|
||||
margin-bottom: 130px;
|
||||
opacity: .6;
|
||||
max-width: 300px;
|
||||
}
|
||||
&-cta {
|
||||
position: absolute;
|
||||
bottom: 5vh;
|
||||
width: 100%;
|
||||
button {
|
||||
width: 85%;
|
||||
max-width: 300px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
.main-header {
|
||||
height: 120px;
|
||||
background: url('../assets/img/shapeshift/shapeshift_background.jpg') center center no-repeat #28394d;
|
||||
text-align: center;
|
||||
img {
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
.shift {
|
||||
margin: 0rem;
|
||||
img {
|
||||
width: 30px;
|
||||
}
|
||||
ion-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { NavController, Events } from 'ionic-angular';
|
||||
import { Logger } from '@nsalaun/ng-logger';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
// Pages
|
||||
import { ShapeshiftShiftPage } from './shapeshift-shift/shapeshift-shift';
|
||||
|
||||
// Providers
|
||||
import { ShapeshiftProvider } from '../../../providers/shapeshift/shapeshift';
|
||||
import { ExternalLinkProvider } from '../../../providers/external-link/external-link';
|
||||
|
||||
@Component({
|
||||
selector: 'page-shapeshift',
|
||||
templateUrl: 'shapeshift.html',
|
||||
})
|
||||
export class ShapeshiftPage {
|
||||
|
||||
public shifts: any;
|
||||
public network: string;
|
||||
|
||||
constructor(
|
||||
private events: Events,
|
||||
private externalLinkProvider: ExternalLinkProvider,
|
||||
private logger: Logger,
|
||||
private navCtrl: NavController,
|
||||
private shapeshiftProvider: ShapeshiftProvider
|
||||
) {
|
||||
this.network = this.shapeshiftProvider.getNetwork();
|
||||
this.shifts = { data: {} };
|
||||
this.init();
|
||||
}
|
||||
|
||||
ionViewDidLoad() {
|
||||
this.logger.info('ionViewDidLoad ShapeshiftPage');
|
||||
}
|
||||
|
||||
ionViewWillEnter() {
|
||||
this.events.subscribe('bwsEvent', (walletId: string, type: string, n: any) => {
|
||||
if (type == 'NewBlock') this.updateShift(this.shifts);
|
||||
});
|
||||
}
|
||||
|
||||
ionViewWillLeave() {
|
||||
this.events.unsubscribe('bwsEvent');
|
||||
}
|
||||
|
||||
public openExternalLink(url: string): void {
|
||||
this.externalLinkProvider.open(url);
|
||||
}
|
||||
|
||||
private updateShift = _.debounce((shifts: any) => {
|
||||
if (_.isEmpty(shifts.data)) return;
|
||||
_.forEach(shifts.data, (dataFromStorage: any) => {
|
||||
this.shapeshiftProvider.getStatus(dataFromStorage.address, (err: any, st: any) => {
|
||||
if (err) return;
|
||||
|
||||
this.shifts.data[st.address]['status'] = st.status;
|
||||
this.shapeshiftProvider.saveShapeshift(this.shifts.data[st.address], null, (err: any) => {
|
||||
this.logger.debug("Saved shift with status: " + st.status);
|
||||
});
|
||||
});
|
||||
});
|
||||
}, 1000, {
|
||||
'leading': true
|
||||
});
|
||||
|
||||
private init(): void {
|
||||
this.shapeshiftProvider.getShapeshift((err: any, ss: any) => {
|
||||
if (err) this.logger.error(err);
|
||||
this.shifts = { data: ss };
|
||||
this.updateShift(this.shifts);
|
||||
});
|
||||
}
|
||||
|
||||
public update(): void {
|
||||
this.updateShift(this.shifts);
|
||||
}
|
||||
|
||||
public goTo(page: string): void {
|
||||
switch (page) {
|
||||
case 'Shift':
|
||||
this.navCtrl.push(ShapeshiftShiftPage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -44,6 +44,11 @@
|
|||
<span translate>Amount</span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="shiftMin && shiftMax">
|
||||
<div>Min: {{shiftMin}}</div>
|
||||
<div>Max: {{shiftMax}}</div>
|
||||
</div>
|
||||
|
||||
<div class="amount-content">
|
||||
<div class="expression">{{expression || '0.00'}}
|
||||
<a class="unit-button" (click)="updateUnit()">{{unit}}</a>
|
||||
|
|
|
@ -15,6 +15,7 @@ import { SellGlideraPage } from '../../integrations/glidera/sell-glidera/sell-gl
|
|||
import { ConfirmPage } from '../confirm/confirm';
|
||||
import { CustomAmountPage } from '../../receive/custom-amount/custom-amount';
|
||||
import { BuyMercadoLibrePage } from '../../integrations/mercado-libre/buy-mercado-libre/buy-mercado-libre';
|
||||
import { ShapeshiftConfirmPage } from '../../integrations/shapeshift/shapeshift-confirm/shapeshift-confirm';
|
||||
|
||||
@Component({
|
||||
selector: 'page-amount',
|
||||
|
@ -33,6 +34,9 @@ export class AmountPage {
|
|||
public expression: any;
|
||||
public amount: any;
|
||||
public showExpressionResult: boolean;
|
||||
public shiftMax: number;
|
||||
public shiftMin: number;
|
||||
public showSendMax: boolean;
|
||||
|
||||
public allowSend: boolean;
|
||||
public recipientType: string;
|
||||
|
@ -46,6 +50,7 @@ export class AmountPage {
|
|||
public useSendMax: boolean;
|
||||
public config: any;
|
||||
public showRecipient: boolean;
|
||||
public toWalletId: string;
|
||||
|
||||
private walletId: any;
|
||||
|
||||
|
@ -58,6 +63,7 @@ export class AmountPage {
|
|||
private configProvider: ConfigProvider,
|
||||
private rateProvider: RateProvider,
|
||||
) {
|
||||
this.showSendMax = false;
|
||||
this.config = this.configProvider.get();
|
||||
this.recipientType = this.navParams.data.recipientType;
|
||||
this.showRecipient = true;
|
||||
|
@ -80,15 +86,18 @@ export class AmountPage {
|
|||
this.reOp = /^[\*\+\-\/]$/;
|
||||
this.nextView = this.getNextView();
|
||||
|
||||
// Use only with ShapeShift
|
||||
this.toWalletId = this.navParams.data.toWalletId;
|
||||
this.shiftMax = this.navParams.data.shiftMax;
|
||||
this.shiftMin = this.navParams.data.shiftMin;
|
||||
|
||||
let unit = this.navParams.data.currency ? this.navParams.data.currency : this.config.wallet.settings.alternativeIsoCode;
|
||||
this.availableUnits.push(this.coin.toUpperCase());
|
||||
this.availableUnits.push(unit);
|
||||
|
||||
if (this.navParams.data.currency) {
|
||||
this.availableUnits.push(this.coin.toUpperCase());
|
||||
this.availableUnits.push(this.navParams.data.currency);
|
||||
this.unit = this.navParams.data.currency;
|
||||
}
|
||||
else {
|
||||
let unit = this.config.wallet.settings.alternativeIsoCode;
|
||||
this.availableUnits.push(this.coin.toUpperCase());
|
||||
this.availableUnits.push(unit);
|
||||
} else {
|
||||
this.unit = this.availableUnits[0];
|
||||
}
|
||||
this.isFiatAmount = this.unit != 'BCH' && this.unit != 'BTC' ? true : false;
|
||||
|
@ -138,7 +147,13 @@ export class AmountPage {
|
|||
this.showRecipient = false;
|
||||
nextPage = BuyMercadoLibrePage;
|
||||
break;
|
||||
case 'ShapeshiftConfirmPage':
|
||||
this.showSendMax = true;
|
||||
this.showRecipient = false;
|
||||
nextPage = ShapeshiftConfirmPage;
|
||||
break;
|
||||
default:
|
||||
this.showSendMax = true;
|
||||
nextPage = ConfirmPage;
|
||||
}
|
||||
return nextPage;
|
||||
|
@ -269,7 +284,8 @@ export class AmountPage {
|
|||
coin: this.coin,
|
||||
network: this.network,
|
||||
useSendMax: this.useSendMax,
|
||||
walletId: this.walletId
|
||||
walletId: this.walletId,
|
||||
toWalletId: this.toWalletId ? this.toWalletId : null
|
||||
}
|
||||
this.navCtrl.push(this.nextView, data);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Logger } from '@nsalaun/ng-logger';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
//providers
|
||||
import { HomeIntegrationsProvider } from '../home-integrations/home-integrations';
|
||||
import { PersistenceProvider } from '../persistence/persistence';
|
||||
import { NextStepsProvider } from '../next-steps/next-steps';
|
||||
|
||||
import * as _ from 'lodash';
|
||||
|
||||
@Injectable()
|
||||
export class AmazonProvider {
|
||||
|
@ -76,12 +76,10 @@ export class AmazonProvider {
|
|||
}
|
||||
|
||||
inv = JSON.stringify(inv);
|
||||
this.persistenceProvider.setAmazonGiftCards(network, inv).then((err) => {
|
||||
|
||||
this.homeIntegrationsProvider.register(this.homeItem);
|
||||
this.nextStepsProvider.unregister(this.nextStepItem.name);
|
||||
return cb(err);
|
||||
});
|
||||
this.persistenceProvider.setAmazonGiftCards(network, inv);
|
||||
this.homeIntegrationsProvider.register(this.homeItem);
|
||||
this.nextStepsProvider.unregister(this.nextStepItem.name);
|
||||
return cb(null);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -474,16 +474,28 @@ export class PersistenceProvider {
|
|||
});
|
||||
};
|
||||
|
||||
setMercadoLibreGiftCards(network, gcs): Promise<void> {
|
||||
setMercadoLibreGiftCards(network: string, gcs): Promise<void> {
|
||||
return this.storage.set((Keys.MERCADO_LIBRE(network)), gcs);
|
||||
};
|
||||
|
||||
getMercadoLibreGiftCards(network): Promise<void> {
|
||||
getMercadoLibreGiftCards(network: string): Promise<void> {
|
||||
return this.storage.get((Keys.MERCADO_LIBRE(network)));
|
||||
};
|
||||
|
||||
removeMercadoLibreGiftCards(network): Promise<void> {
|
||||
removeMercadoLibreGiftCards(network: string): Promise<void> {
|
||||
return this.storage.remove((Keys.MERCADO_LIBRE(network)));
|
||||
};
|
||||
|
||||
setShapeshift(network: string, gcs: any): Promise<void> {
|
||||
return this.storage.set('shapeShift-' + network, gcs);
|
||||
};
|
||||
|
||||
getShapeshift(network: string): Promise<void> {
|
||||
return this.storage.get('shapeShift-' + network);
|
||||
};
|
||||
|
||||
removeShapeshift(network: string): Promise<void> {
|
||||
return this.storage.remove('shapeShift-' + network);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Logger } from '@nsalaun/ng-logger';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
//providers
|
||||
import { AppProvider } from '../app/app';
|
||||
import { HomeIntegrationsProvider } from '../home-integrations/home-integrations';
|
||||
import { NextStepsProvider } from '../next-steps/next-steps';
|
||||
import { PersistenceProvider } from '../persistence/persistence';
|
||||
|
||||
@Injectable()
|
||||
export class ShapeshiftProvider {
|
||||
|
||||
private credentials: any;
|
||||
private homeItem: any;
|
||||
|
||||
constructor(
|
||||
private appProvider: AppProvider,
|
||||
private homeIntegrationsProvider: HomeIntegrationsProvider,
|
||||
private http: HttpClient,
|
||||
private logger: Logger,
|
||||
private nextStepsProvider: NextStepsProvider,
|
||||
private persistenceProvider: PersistenceProvider
|
||||
) {
|
||||
this.logger.info('Hello ShapeshiftProvider Provider');
|
||||
this.credentials = {};
|
||||
|
||||
// (Optional) Affiliate PUBLIC KEY, for volume tracking, affiliate payments, split-shifts, etc.
|
||||
if (this.appProvider.servicesInfo && this.appProvider.servicesInfo.shapeshift) {
|
||||
this.credentials.API_KEY = this.appProvider.servicesInfo.shapeshift.api_key || null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Development: 'testnet'
|
||||
* Production: 'livenet'
|
||||
*/
|
||||
this.credentials.NETWORK = 'livenet';
|
||||
//credentials.NETWORK = 'testnet';
|
||||
|
||||
if (this.credentials.NETWORK == 'testnet') {
|
||||
this.credentials.API_URL = "";
|
||||
} else {
|
||||
// CORS: cors.shapeshift.io
|
||||
this.credentials.API_URL = "https://shapeshift.io";
|
||||
}
|
||||
|
||||
this.homeItem = {
|
||||
name: 'shapeshift',
|
||||
title: 'ShapeShift',
|
||||
icon: 'assets/img/shapeshift/icon-shapeshift.svg',
|
||||
page: 'ShapeshiftPage',
|
||||
};
|
||||
}
|
||||
|
||||
public getNetwork() {
|
||||
return this.credentials.NETWORK;
|
||||
}
|
||||
|
||||
public shift(data: any, cb): any {
|
||||
|
||||
let dataSrc = {
|
||||
withdrawal: data.withdrawal,
|
||||
pair: data.pair,
|
||||
returnAddress: data.returnAddress,
|
||||
apiKey: this.credentials.API_KEY
|
||||
};
|
||||
|
||||
this.http.post(this.credentials.API_URL + '/shift', dataSrc).subscribe((data: any) => {
|
||||
this.logger.info('Shapeshift SHIFT: SUCCESS');
|
||||
return cb(null, data);
|
||||
}, (data) => {
|
||||
this.logger.error('Shapeshift SHIFT ERROR: ' + data.error.message);
|
||||
return cb(data);
|
||||
});
|
||||
}
|
||||
|
||||
public saveShapeshift(data: any, opts: any, cb): void {
|
||||
let network = this.getNetwork();
|
||||
this.persistenceProvider.getShapeshift(network).then((oldData: any) => {
|
||||
if (_.isString(oldData)) {
|
||||
oldData = JSON.parse(oldData);
|
||||
}
|
||||
if (_.isString(data)) {
|
||||
data = JSON.parse(data);
|
||||
}
|
||||
let inv = oldData ? oldData : {};
|
||||
inv[data.address] = data;
|
||||
if (opts && (opts.error || opts.status)) {
|
||||
inv[data.address] = _.assign(inv[data.address], opts);
|
||||
}
|
||||
if (opts && opts.remove) {
|
||||
delete (inv[data.address]);
|
||||
}
|
||||
|
||||
inv = JSON.stringify(inv);
|
||||
|
||||
this.persistenceProvider.setShapeshift(network, inv);
|
||||
this.homeIntegrationsProvider.register(this.homeItem);
|
||||
this.nextStepsProvider.unregister(this.homeItem.name);
|
||||
return cb(null);
|
||||
}).catch((err: any) => {
|
||||
return cb(err);
|
||||
});
|
||||
}
|
||||
|
||||
public getShapeshift(cb) {
|
||||
var network = this.getNetwork();
|
||||
this.persistenceProvider.getShapeshift(network).then((ss: any) => {
|
||||
var _gcds = ss ? JSON.parse(ss) : null;
|
||||
return cb(null, _gcds);
|
||||
}).catch((err: any) => {
|
||||
return cb(err, null);
|
||||
});
|
||||
}
|
||||
|
||||
public getRate(pair: string, cb) {
|
||||
this.http.get(this.credentials.API_URL + '/rate/' + pair).subscribe((data: any) => {
|
||||
this.logger.info('Shapeshift PAIR: SUCCESS');
|
||||
return cb(null, data);
|
||||
}, (data: any) => {
|
||||
this.logger.error('Shapeshift PAIR ERROR: ' + data.error.message);
|
||||
return cb(data);
|
||||
});
|
||||
}
|
||||
|
||||
public getLimit(pair: string, cb) {
|
||||
this.http.get(this.credentials.API_URL + '/limit/' + pair).subscribe((data: any) => {
|
||||
this.logger.info('Shapeshift LIMIT: SUCCESS');
|
||||
return cb(null, data);
|
||||
}, (data: any) => {
|
||||
this.logger.error('Shapeshift LIMIT ERROR: ' + data.error.message);
|
||||
return cb(data);
|
||||
});
|
||||
}
|
||||
|
||||
public getStatus(addr: string, cb) {
|
||||
this.http.get(this.credentials.API_URL + '/txStat/' + addr).subscribe((data: any) => {
|
||||
this.logger.info('Shapeshift STATUS: SUCCESS');
|
||||
return cb(null, data);
|
||||
}, (data: any) => {
|
||||
this.logger.error('Shapeshift STATUS ERROR: ' + data.error.message);
|
||||
return cb(data);
|
||||
});
|
||||
}
|
||||
|
||||
public register(): void {
|
||||
this.persistenceProvider.getShapeshift(this.getNetwork()).then((ss: any) => {
|
||||
if (ss) {
|
||||
this.homeIntegrationsProvider.register(this.homeItem);
|
||||
} else {
|
||||
this.nextStepsProvider.register(this.homeItem);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue