Compare commits

..

661 commits

Author SHA1 Message Date
A R Hansen
8e73e4c16d Merge branch 'develop' 2018-10-12 12:50:54 +02:00
A R Hansen
06f1f4df91 - ll - 2018-10-12 12:48:15 +02:00
A R Hansen
70f520ea43 adding instructions 2018-10-12 12:46:09 +02:00
A R Hansen
f1d2b00b2b set up my own bitcore server and changed the url. for some reason Bitcoin.com's server won't accept 0 fee txs. 2018-10-12 11:53:16 +02:00
A R Hansen
4e524a7500 Not needed. 2018-10-08 02:16:43 +02:00
A R Hansen
c0a14fe11c Merge ZeroFeeTxs 2018-10-08 02:01:15 +02:00
A R Hansen
d47393f160 .. 2018-10-08 02:00:36 +02:00
A R Hansen
898b7d03fe 0 fee transaction feature added. 2018-10-08 01:55:55 +02:00
Jean-Baptiste Dominguez
49a6711970
Merge branch 'wallet/prod' into master 2018-09-22 10:59:24 +02:00
Brendon Duncan
d72a71d920 RC version. 2018-09-21 17:21:59 -07:00
Brendon Duncan
4d623d51d7 Merged sprint 21. 2018-09-21 17:16:18 -07:00
Brendon Duncan
ff40317d87 Merged fix for wallet transaction history. 2018-09-21 16:45:46 -07:00
Brendon Duncan
2e1cc9fa87 Showing cached history first when entering Wallet Details screen. 2018-09-21 16:43:27 -07:00
Brendon Duncan
cecad4a072 Merged 575. 2018-09-21 14:58:39 -07:00
Brendon Duncan
61c91d518a Merge branch 'wallet/sprint/21'. 2018-09-21 14:50:47 -07:00
Brendon Duncan
a17c3518c3 Manual merge from Sprint 22 for 575. 2018-09-21 14:38:28 -07:00
Brendon Duncan
6554b385cb
Merge pull request #345 from Bitcoin-com/wallet/task/591
591 - Wallet balance directive fails to get fiat balance sometimes
2018-09-21 12:53:46 -07:00
Brendon Duncan
c0912c5f17 IIFE for reviewController to make merging easier. 2018-09-21 12:31:55 -07:00
Brendon Duncan
e7eac1ee16
Merge pull request #335 from Bitcoin-com/wallet/task/586
Bug - 586 - Reconnect WebSocket when connection is failing or lost.
2018-09-21 11:35:27 -07:00
Brendon Duncan
46413fa6aa
Merge pull request #346 from Bitcoin-com/wallet/task/593
Bug - 593 - Update confirmations on cached transactions
2018-09-21 11:29:30 -07:00
Brendon Duncan
fb2802f392
Merge pull request #347 from Bitcoin-com/wallet/task/546
546 - Fix modal & shapeshift
2018-09-21 11:26:08 -07:00
Brendon Duncan
ea51e035ab Fixed updating of confirmations of cached transactions. Cache now properly cleared on first fetch from Wallet Details screen. 2018-09-21 03:56:51 -07:00
Brendon Duncan
0c8d145f73 Check validity of cachedStatus. 2018-09-21 02:54:06 -07:00
Jean-Baptiste Dominguez
977d03429d
Merge pull request #343 from Bitcoin-com/wallet/task/590
590 - The Personal Note field is not cleared between transactions.
2018-09-21 11:47:28 +02:00
Jean-Baptiste Dominguez
a8e5c212f0 Fix : Check if the status could be set before checking the balance. 2018-09-21 11:41:20 +02:00
Jean-Baptiste Dominguez
4250a98718 walletStatus worst case, IIFE for both controllers. 2018-09-21 11:31:27 +02:00
Brendon Duncan
a3614566e3 Reconnecting socket based on CloseEvent.code. 2018-09-21 02:27:34 -07:00
Jean-Baptiste Dominguez
5cb3d7521d Fix modal 2018-09-21 10:23:02 +02:00
Sebastiaan Pasma
3cad7d7ad8
Update confirmations on cached transactions 2018-09-20 15:58:42 +02:00
Brendon Duncan
4d6aeb4f91 Renamed directive and replaced old variable references with new ones. 2018-09-18 15:26:30 -07:00
Sebastiaan Pasma
78e4942fd6
Merge pull request #339 from Bitcoin-com/wallet/task/589
589 - Fix mobile build scripts
2018-09-18 13:51:54 +02:00
Brendon Duncan
7b6efaa1db Clear memo before entering Review screen. 2018-09-17 21:26:21 -07:00
Brendon Duncan
ebc32a2d85 Added 'default' to mobile debug build configs. 2018-09-16 21:04:41 -07:00
Brendon Duncan
e02368ea3c Incremented version for release candidate. 2018-09-15 18:05:39 +12:00
Brendon Duncan
92c1b4b346 Merged translations from sprint. 2018-09-15 18:02:00 +12:00
Brendon Duncan
8bf31f97d8 Updated translations from Crowdin. 2018-09-15 18:00:34 +12:00
Brendon Duncan
f3902ba3f0 Merged sprint to get fix for Wallet Details transaction list. 2018-09-15 17:32:55 +12:00
Brendon Duncan
6aa7ee2bbb
Merge pull request #338 from Bitcoin-com/wallet/task/588
588 - Transaction list in Wallet Details disappearing and reappearing
2018-09-15 17:29:56 +12:00
Brendon Duncan
ac82b51848 Takes into account size of current transaction list when determining if overlap in transactions is enough to assume all have been retrieved. 2018-09-15 14:45:39 +12:00
Sebastiaan Pasma
e6d8ddb360
update wallets in the promise callback 2018-09-13 09:54:53 +02:00
Sebastiaan Pasma
eb3067d369
Use cachedStatus when available and a fix for the review controller 2018-09-13 09:47:45 +02:00
Sebastiaan Pasma
908dcbf968
Add the received wallet status to the wallet API object 2018-09-12 16:50:26 +02:00
Sebastiaan Pasma
6692812d55
Websocket reconnect (and close old connection on leave) 2018-09-12 15:09:21 +02:00
Brendon Duncan
9438960e24 Hotfix version. 2018-09-12 18:39:56 +12:00
Brendon Duncan
d55fc70e7d Remove Games link. 2018-09-12 18:13:50 +12:00
Sebastiaan Pasma
ad4aa76902
Empty origin wallet screen bug 2018-09-11 14:55:22 +02:00
Brendon Duncan
c1f6e56b56 Increment version. 2018-09-11 15:37:47 +12:00
Brendon Duncan
7d29490b0f Merged sprint. 2018-09-11 15:33:26 +12:00
Sebastiaan Pasma
a54b30f6ae
Merge pull request #334 from Bitcoin-com/wallet/task/583
583 - Remove Games Link from Google Play app
2018-09-10 10:45:56 +02:00
Brendon Duncan
319a5c86ec Merge language fix. 2018-09-10 20:28:18 +12:00
Brendon Duncan
8bc73353d5 Run command for Android emulator. 2018-09-10 20:26:33 +12:00
Brendon Duncan
101e33ec36 Remove Games link on Android. 2018-09-10 20:26:13 +12:00
Jean-Baptiste Dominguez
51c35101a6 appConfig beta release 2018-09-07 17:08:39 +09:00
Jean-Baptiste Dominguez
3d3fdd7425 Fix languages 2018-09-07 15:31:54 +09:00
Jean-Baptiste Dominguez
d361956290
Merge pull request #331 from Bitcoin-com/wallet/sprint/21
Wallet/sprint/21
2018-09-07 01:43:15 +09:00
Jean-Baptiste Dominguez
46b5317f5e
Merge pull request #307 from Bitcoin-com/wallet/task/518
518 - Add true pagination to the Wallet Detail screens
2018-09-07 01:41:39 +09:00
Jean-Baptiste Dominguez
230b6e2228 Merge 2018-09-07 01:41:13 +09:00
Jean-Baptiste Dominguez
81852836dd Fix : callback the newHistory 2018-09-07 01:18:54 +09:00
Jean-Baptiste Dominguez
9c0b54a7ce
Merge pull request #326 from Bitcoin-com/wallet/task/562
Bug - 562 - No notification when a new release version is available (Mac OSX github)
2018-09-06 22:12:45 +09:00
Jean-Baptiste Dominguez
47e1d0bdc7
Merge pull request #325 from Bitcoin-com/wallet/task/576
Bug - 576 - Android KitKat (4.4) interface fixes
2018-09-06 21:34:36 +09:00
Jean-Baptiste Dominguez
5386c5f7a6
Merge pull request #328 from Bitcoin-com/wallet/task/572
572 - Adhere to Shapeshift max amounts.
2018-09-06 20:30:43 +09:00
Jean-Baptiste Dominguez
6a8f8ca33b Fix to send the amount if shapeshift case 2018-09-06 20:29:50 +09:00
Sebastiaan Pasma
828cb927dc
refactor latestReleaseService to new format 2018-09-06 13:16:32 +02:00
Jean-Baptiste Dominguez
176f0c3141 Fix to provide an amount (canSendMax was never set to false when shapeshift) 2018-09-06 20:16:25 +09:00
Sebastiaan Pasma
c14820ea34
Shim for Array.includes (fixing receive notifications) + Android KitKat fixes (effect on slide + received payment notification) 2018-09-06 13:04:19 +02:00
Jean-Baptiste Dominguez
57ce93ccb8 fix parenthesis 2018-09-06 18:28:27 +09:00
Jean-Baptiste Dominguez
b6f63706f3 Resolution conflicts 2018-09-06 18:21:04 +09:00
Brendon Duncan
b0fba31040 Fix fee display on Android 4.4 KitKat. 2018-09-06 20:18:31 +12:00
Jean-Baptiste Dominguez
b0178c0673
Merge pull request #327 from Bitcoin-com/wallet/task/567
Improvement - 567 - Stuttering animation when scrolling transaction history.
2018-09-06 17:16:53 +09:00
Jean-Baptiste Dominguez
b2e22647e2
Merge pull request #293 from Bitcoin-com/wallet/task/555
555 - Include version number in Android apk filename.
2018-09-06 17:16:27 +09:00
Jean-Baptiste Dominguez
688f2b97bc
Merge pull request #324 from Bitcoin-com/wallet/task/546
546 - revamp shapeshift service
2018-09-06 17:13:05 +09:00
Brendon Duncan
c79ca6d1af More specific Shapeshift error handling. 2018-09-06 18:34:59 +12:00
Jean-Baptiste Dominguez
71e530f535 Unify the translation service 2018-09-06 15:31:22 +09:00
Jean-Baptiste Dominguez
a397e83cf0 error case without .message 2018-09-06 15:24:16 +09:00
Jean-Baptiste Dominguez
1905be6f14
Merge branch 'wallet/sprint/21' into wallet/task/555 2018-09-06 15:19:34 +09:00
Jean-Baptiste Dominguez
98e6e8ac75 Recommendation #brendon :) 2018-09-06 15:17:37 +09:00
Brendon Duncan
0d8812509d Updated readme. 2018-09-06 15:45:20 +12:00
Brendon Duncan
3de34dbf15 Renaming to follow new convention. 2018-09-06 11:34:00 +12:00
Brendon Duncan
394317bc46 Better default error message for Shapeshift error. 2018-09-06 11:27:48 +12:00
Sebastiaan Pasma
f52b2e7f09
Better fix for KitKat 4.4 2018-09-05 16:44:33 +02:00
Sebastiaan Pasma
525afac92e
scss var name change 2018-09-05 16:36:53 +02:00
Sebastiaan Pasma
22e1c397d0
Removed duplicate android header + refactored animation to use CSS animations instead of javascript calculated animations 2018-09-05 16:19:31 +02:00
Sebastiaan Pasma
74a9fe9691
Merge branch 'wallet/sprint/21' into wallet/task/567 2018-09-05 14:11:51 +02:00
Sebastiaan Pasma
70663492eb
Merge branch 'wallet/sprint/21' into wallet/task/562
# Conflicts:
#	src/js/controllers/tab-home.controller.js
2018-09-05 14:07:23 +02:00
Sebastiaan Pasma
477a9b6995
Android KitKat (4.4) fixes 2018-09-05 14:03:01 +02:00
Jean-Baptiste Dominguez
2d6a1528c1 handle errors properly 2018-09-05 17:23:09 +09:00
Jean-Baptiste Dominguez
3b6bb1fcdd ionicModal using for all devices 2018-09-05 16:10:21 +09:00
Jean-Baptiste Dominguez
2a607d245d using ionicModal for all devices 2018-09-05 16:10:05 +09:00
Jean-Baptiste Dominguez
fa8ce4779f async series with shapeshift & fee calculation 2018-09-05 15:32:47 +09:00
Brendon Duncan
d01baa6060 Better handling of Shapeshift error. 2018-09-05 18:16:01 +12:00
Brendon Duncan
ce02025991 Merge for building pkg. 2018-09-05 18:03:49 +12:00
Brendon Duncan
d2715016b5 Merge for building pkg. 2018-09-05 18:00:45 +12:00
Jean-Baptiste Dominguez
2c398bbe03 Fix amount check 2018-09-05 14:51:06 +09:00
Jean-Baptiste Dominguez
9128d3ebe2 Migrate to our new standard for services 2018-09-05 14:43:16 +09:00
Jean-Baptiste Dominguez
887270bfa9 clean ";" 2018-09-05 14:42:27 +09:00
Jean-Baptiste Dominguez
f7cde7a071 clean up, migrate to no-fix amount 2018-09-05 12:45:20 +09:00
Brendon Duncan
3afbdf73d3
Merge pull request #323 from Bitcoin-com/wallet/hotfix/578
578 - Shapeshift item on home tab now links to the Shapeshift website.
2018-09-05 15:30:09 +12:00
Brendon Duncan
00e4f8ac39 Hotfix version. 2018-09-05 15:28:10 +12:00
Jean-Baptiste Dominguez
5e034e7b8b clean up 2018-09-05 11:37:29 +09:00
Jean-Baptiste Dominguez
c553b51817 clean up 2018-09-05 11:02:10 +09:00
Jean-Baptiste Dominguez
c40eabf807 Clean shapeshift service and add the correct callback 2018-09-05 10:59:09 +09:00
Jean-Baptiste Dominguez
9ff9e2ea91 tab missing 2018-09-05 10:30:06 +09:00
Jean-Baptiste Dominguez
5c5558fbd4 remove final 2018-09-05 10:28:01 +09:00
Brendon Duncan
8c62bc445a Shapeshift item on home tab now goes to the Shapeshift website. 2018-09-05 12:37:39 +12:00
Brendon Duncan
ba2fa1f26e Fixed start:ios and put Grunt tasks in alphabetical order to make it easier to find definitions. 2018-09-05 10:33:47 +12:00
Brendon Duncan
8dedc04fe8 Edited obsolete comment. 2018-09-05 10:03:00 +12:00
Brendon Duncan
ea23b26795 Removed duplicate logging for Android, and created start:android-log. 2018-09-05 09:56:19 +12:00
Brendon Duncan
2121655249 Grouping scripts in alphabetical order so it is easier to find things, and know what is there. 2018-09-05 09:48:42 +12:00
Sebastiaan Pasma
001cd82afb
getMarketData can return an error 2018-09-04 17:52:53 +02:00
Sebastiaan Pasma
793bfee6a2
Changed wallet details transition behaviour 2018-09-04 16:36:05 +02:00
Brendon Duncan
6c8a1cfd5a Bugfix for using cached status in Enter Amount screen. 2018-09-04 20:48:16 +12:00
Brendon Duncan
3ab535a36b Improved handling of available funds below min amount. 2018-09-04 19:47:50 +12:00
Jean-Baptiste Dominguez
8b505141d7 renaming, clean up 2018-09-04 16:45:52 +09:00
Jean-Baptiste Dominguez
d934a9241a Organize the package.json and grunt file. Some optimizations and renaming. 2018-09-04 15:54:24 +09:00
Jean-Baptiste Dominguez
ce3fcacac3
Merge pull request #308 from Bitcoin-com/wallet/task/490
Bug - 490 - Korean Won isn't automatically selected when phone is in Korean (fiat currency)
2018-09-04 15:27:32 +09:00
Jean-Baptiste Dominguez
4c14bdcce0
Merge pull request #315 from Bitcoin-com/wallet/task/500
500 - detect addresses such as "bitcoin-cash:" and "bitcoincash://"
2018-09-04 14:39:12 +09:00
Jean-Baptiste Dominguez
e06613eaee
Merge pull request #322 from Bitcoin-com/wallet/task/546
Wallet/task/546
2018-09-04 14:37:51 +09:00
Jean-Baptiste Dominguez
2cec6a476b
Merge pull request #294 from Bitcoin-com/wallet/task/556
Improvement - 556 - Make "Share the Wallet App" translatable
2018-09-04 14:33:15 +09:00
Jean-Baptiste Dominguez
b766f2723c
Merge pull request #290 from Bitcoin-com/wallet/task/501
501 - Fix text when sweeping paper wallet
2018-09-04 14:31:40 +09:00
Jean-Baptiste Dominguez
911247e463
Merge branch 'wallet/sprint/21' into wallet/task/501 2018-09-04 14:31:22 +09:00
Jean-Baptiste Dominguez
8b38cb2d21
Merge pull request #305 from Bitcoin-com/wallet/task/335
Wallet/task/335
2018-09-04 14:17:50 +09:00
Jean-Baptiste Dominguez
57efbc3c63
Merge pull request #319 from Bitcoin-com/wallet/task/566
Bug - 566 - Fees hidden on iPhone X
2018-09-04 14:14:41 +09:00
Jean-Baptiste Dominguez
7353e0ff06
Merge pull request #320 from Bitcoin-com/wallet/task/492
492 - Fix typo in English original source
2018-09-04 14:08:42 +09:00
Jean-Baptiste Dominguez
7b1597e229
Merge pull request #321 from Bitcoin-com/wallet/task/568
Bug - 568 - Wrong display of multi-line texts in buttons
2018-09-04 14:08:24 +09:00
Jean-Baptiste Dominguez
38037f34fe
Merge pull request #292 from Bitcoin-com/wallet/task/554
554 - All Images for iOS App Icon
2018-09-04 14:03:19 +09:00
Jean-Baptiste Dominguez
1453a74302
Merge pull request #313 from Bitcoin-com/wallet/task/546
546 Enhancement "send flow" architecture
2018-09-04 13:55:41 +09:00
Jean-Baptiste Dominguez
2a017bc999 Remove duplicate data. 2018-09-04 13:37:31 +09:00
Jean-Baptiste Dominguez
05d73e3e14 init missing variables 2018-09-04 13:34:08 +09:00
Jean-Baptiste Dominguez
547b216edd migrate copayApp to bitcoincom. Clean up 2018-09-04 13:32:36 +09:00
Jean-Baptiste Dominguez
cf1dc66b59 renaming files 2018-09-04 11:56:13 +09:00
Jean-Baptiste Dominguez
23659b0cd4 Rename files reviewed 2018-09-04 11:35:01 +09:00
Jean-Baptiste Dominguez
8322453edf clean send flow state when transaction sent 2018-09-04 11:24:25 +09:00
Jean-Baptiste Dominguez
c715fdcb41 Rename incomingData to incomingDataService 2018-09-04 11:24:07 +09:00
Brendon Duncan
4315d16f73 The Enter Amount screen now correctly sets the amount when sendMax() is called when available funds exceed the max limit. 2018-09-04 12:52:54 +12:00
Brendon Duncan
4dc3e7c2e8 Enter Amount displaying ongoing progress indicator when contacting Shapeshift. Send max button now displays max limit amount when available funds are above the Shapeshift limit. 2018-09-04 12:21:57 +12:00
Brendon Duncan
b2178c84e3 When available funds are higher than Shapeshift max limit, the send max button changes to send max limit. 2018-09-04 11:02:52 +12:00
Brendon Duncan
52f18c3c9b Got the Enter Amount screen unit tests running. 2018-09-04 09:13:09 +12:00
Sebastiaan Pasma
383d811067
Multi-line buttons fix 2018-09-03 14:44:09 +02:00
Sebastiaan Pasma
274d221af0
Links changed, app store added and some logic added 2018-09-03 13:45:40 +02:00
Sebastiaan Pasma
b1bf269ca2
Review transaction screen: iPhone X fee summary display fix 2018-09-03 11:54:15 +02:00
Brendon Duncan
b7dda8b6ca Currency in send max button now updates with currency change. 2018-09-03 20:17:46 +12:00
Brendon Duncan
8908b5ef80 Send max button behaviour is now conditional based on min and max limits. 2018-09-03 20:12:20 +12:00
Brendon Duncan
1c2c381317 Can now scan good data after scanning bad data. 2018-09-03 16:56:30 +12:00
Jean-Baptiste Dominguez
6f28f6ba2b redir cb 2018-09-03 13:31:58 +09:00
Brendon Duncan
afa9fad9d2 Now parses wallet import data. 2018-09-03 14:12:12 +12:00
Jean-Baptiste Dominguez
e8b3476ea1
Merge pull request #318 from Bitcoin-com/wallet/task/500
Update bitcoin-uri-service.js
2018-09-03 10:37:25 +09:00
Brendon Duncan
f84b1e4f35 Changed name to amountInSatoshis. 2018-09-03 13:02:28 +12:00
Brendon Duncan
48b8bbf90a Added amountSatoshis. 2018-09-03 12:53:12 +12:00
Jean-Baptiste Dominguez
b4d42215d3 add copay invitation in incomingData 2018-09-03 09:08:12 +09:00
Jean-Baptiste Dominguez
6e52aaca2d 1st cleaning for incomingData 2018-09-03 08:28:22 +09:00
Jean-Baptiste Dominguez
1708eeef82 Fix address format 2018-08-31 18:48:16 +09:00
Jean-Baptiste Dominguez
ddd867092c Refactor incomingData 2018-08-31 18:37:04 +09:00
Jean-Baptiste Dominguez
fa15b26792
Update bitcoin-uri.service.js
Add the conversion to satoshi however a currency can be precised, in that case, the satoshi conversion should be not operated.
2018-08-31 18:36:40 +09:00
Jean-Baptiste Dominguez
2b8c2d1c61
Merge pull request #316 from Bitcoin-com/wallet/task/500
Changed testnet to isTestnet.
2018-08-31 16:45:40 +09:00
Jean-Baptiste Dominguez
7fa2ab7ff4 Merge 2018-08-31 16:11:58 +09:00
Jean-Baptiste Dominguez
dd59169d5f adapt for the request specific amount. Clean comments and code, and more. 2018-08-31 16:09:31 +09:00
Brendon Duncan
ef23746de6 Changed testnet to isTestnet. 2018-08-31 17:14:58 +12:00
Sebastiaan Pasma
d65e4401dd
Update popup 2018-08-30 14:10:46 +02:00
Brendon Duncan
c4d9b94a86 Merged latest changes for detecting addresses. 2018-08-30 20:49:03 +12:00
Brendon Duncan
421c4ca26a Bugfix for displaying error message. 2018-08-30 20:46:58 +12:00
Brendon Duncan
6a68d73e3a Now handles spaces after address prefix. 2018-08-30 20:20:51 +12:00
Brendon Duncan
918451f3da Scanning or pasting ordinary URL gives the option to open it in a browser. 2018-08-30 19:56:18 +12:00
Jean-Baptiste Dominguez
2c0432e292 3rd step enhancement send flow 2018-08-30 16:03:51 +09:00
Brendon Duncan
98f317dea7 Merged more permissive Bitcoin Cash URIs. 2018-08-30 18:16:26 +12:00
Jean-Baptiste Dominguez
480cfe43ca
Merge pull request #312 from Bitcoin-com/wallet/task/500
Upgrade the bitcoin uri service and its integration
2018-08-30 14:41:38 +09:00
Brendon Duncan
986f85e7aa The send tab paste button now recognises a wider variety of Bitcoin Cash prefixes. 2018-08-30 17:18:26 +12:00
Brendon Duncan
9877e13390 Corrected the addres for display in the Review screen cashAddr. 2018-08-30 16:34:21 +12:00
Brendon Duncan
5ad9c7bf49 "Testnet not supported" message when pasting. 2018-08-30 15:55:29 +12:00
Brendon Duncan
5747cbfb66 "Testnet not supported" message when scanning a testnet address. 2018-08-30 15:49:59 +12:00
Brendon Duncan
e6fba98af9 Not using data if it is for the testnet. 2018-08-30 09:04:01 +12:00
Jean-Baptiste Dominguez
162fd685e5 second step enhancement 2018-08-29 17:28:07 +09:00
Jean-Baptiste Dominguez
d864b35513 First enhancement in the send flow architecture 2018-08-29 15:38:23 +09:00
Brendon Duncan
529bdf3386 Alert and resume scanning if data is not recognised. 2018-08-29 18:28:37 +12:00
Brendon Duncan
6d48572f28 Handling all cash URI addresses formats at the same time. 2018-08-29 18:27:58 +12:00
Brendon Duncan
471a9ba4ae Treating BitPay address like cashAddr. 2018-08-29 17:39:04 +12:00
Jean-Baptiste Dominguez
b35ee316a8
Merge pull request #310 from Bitcoin-com/wallet/task/500
Upgrade bitcoin-uri.service.js
2018-08-29 14:27:23 +09:00
Brendon Duncan
8a1e3f2297 Bitcoin Cash URI in incoming data now more permissive with the prefix. 2018-08-29 15:55:49 +12:00
Brendon Duncan
89f4328f8e BIP70 in IncomingDataService uses new BitcoinUriService. 2018-08-29 15:42:43 +12:00
Brendon Duncan
5738bab13e Updated comments. 2018-08-29 15:41:13 +12:00
Brendon Duncan
fcfb039673 parse() now only returns the address in the format that was present in the data, to make it easier to find out about the data. 2018-08-29 15:21:43 +12:00
Brendon Duncan
3a3a525133 Bugfix for displaying payment amount. 2018-08-29 11:38:20 +12:00
Brendon Duncan
e6d438abf9 Test for a bare URL being invalid. 2018-08-29 11:18:09 +12:00
Brendon Duncan
32aa02a8c2 Fails gracefully when not passed a string. 2018-08-29 10:15:03 +12:00
Brendon Duncan
d30a076f4b Changed argument name to data, because it may not be a URI. 2018-08-29 10:05:23 +12:00
Brendon Duncan
217b02504a Added tests for single slash. Removed some unused code. 2018-08-29 10:04:02 +12:00
Brendon Duncan
3b74ab7d8c Tolerating extra dash and slashes. 2018-08-29 09:59:47 +12:00
Brendon Duncan
9bed4239da Grouped the output. 2018-08-29 09:54:04 +12:00
Brendon Duncan
6c85cffb20 Now handles encrypted private key. 2018-08-29 09:11:14 +12:00
Brendon Duncan
b95798d271 Tests for private keys on testnet. 2018-08-29 08:49:18 +12:00
Brendon Duncan
a9f2794d11 Testing uncompressed private keys on mainnet. 2018-08-28 20:56:10 +12:00
Brendon Duncan
61a29cf7ea Copay invitation and wifPrivateKey. 2018-08-28 18:42:03 +12:00
Brendon Duncan
c2cca3c080 Bitcoin cash uppercase. 2018-08-28 17:18:05 +12:00
Brendon Duncan
e8005c9ea6 Legacy addresses with bitcoincash: prefix. 2018-08-28 17:10:15 +12:00
Brendon Duncan
4d525c85d7 CashAddr on testnet and Bitpay format on mainnet. 2018-08-28 17:00:52 +12:00
Jean-Baptiste Dominguez
1d1fde21ea
Merge pull request #309 from Bitcoin-com/wallet/task/500
Get the interface for the sendFlowService
2018-08-28 11:22:39 +09:00
Brendon Duncan
a4ab20abba Tests for BIP72. 2018-08-28 14:17:43 +12:00
Jean-Baptiste Dominguez
4564040459 fixes for pkg mas 2018-08-28 10:50:53 +09:00
Sebastiaan Pasma
3cab114618
template.pot change 2018-08-27 14:09:06 +02:00
Sebastiaan Pasma
2c2c21bcdf
Update notifications now able to parse "rc"'s and also show release notes from GitHub. 2018-08-27 14:06:10 +02:00
Sebastiaan Pasma
8217351141
possible fix for selecting the right currency on new wallets 2018-08-27 10:59:14 +02:00
Brendon Duncan
1be9ce39c1 Starting to work on more comprehensive handling of cashAddr format. Basic handling of cashAddr on testnet. 2018-08-27 20:46:11 +12:00
Brendon Duncan
43592a1689
Fix package.json. 2018-08-27 18:04:55 +12:00
Jean-Baptiste Dominguez
d0bd3e1f61
Merge pull request #306 from Bitcoin-com/wallet/sprint/21
Wallet/sprint/21
2018-08-27 13:22:53 +09:00
Jean-Baptiste Dominguez
1c450418b8
Merge pull request #301 from Bitcoin-com/wallet/prod
5.0
2018-08-27 12:59:17 +09:00
Jean-Baptiste Dominguez
7718724958 pkg building script 2018-08-27 12:00:02 +09:00
Jean-Baptiste Dominguez
9a44a4b33b
Merge pull request #304 from Bitcoin-com/wallet/sprint/21
Wallet/sprint/21
2018-08-26 22:20:25 +09:00
Jean-Baptiste Dominguez
4deeb80a14
Merge pull request #303 from Bitcoin-com/wallet/dev
Wallet/dev
2018-08-26 22:16:46 +09:00
Jean-Baptiste Dominguez
0a4054707f
Merge pull request #302 from Bitcoin-com/wallet/prod
Wallet/prod
2018-08-26 22:07:20 +09:00
Jean-Baptiste Dominguez
1fa87fc9a0
Merge pull request #299 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-23 16:33:00 +09:00
Jean-Baptiste Dominguez
07ff264619
Merge pull request #297 from Bitcoin-com/wallet/dev
Wallet/dev
2018-08-23 14:40:54 +09:00
Jean-Baptiste Dominguez
dd4fcc9ed1
Update appConfig.json 2018-08-23 14:40:18 +09:00
Jean-Baptiste Dominguez
7e0998c919
Merge pull request #296 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-23 14:39:47 +09:00
Jean-Baptiste Dominguez
a2009a2f06
Merge pull request #295 from Bitcoin-com/wallet/task/503
Tweak strings to match translations.
2018-08-23 14:39:23 +09:00
Brendon Duncan
39bcb9daae Tweak strings to match translations. 2018-08-23 16:21:15 +12:00
Brendon Duncan
b9943c403f Testing addresses with Bitcore wallet client. 2018-08-23 14:37:02 +12:00
Brendon Duncan
1da9a79296 Parsing BTC testnet address. 2018-08-23 14:27:03 +12:00
Brendon Duncan
93d061c96a Returning addresses from cashAddr with bitcoincash: prefix. 2018-08-23 12:55:58 +12:00
Brendon Duncan
ab0b8b19b0 Returning legacy address for cashAddr. 2018-08-23 12:47:47 +12:00
Brendon Duncan
70f76baad0 bitcoinUriService passing first test. 2018-08-23 10:48:49 +12:00
Brendon Duncan
f16ef22436 amountController tests no longer fail. 2018-08-23 10:32:47 +12:00
Sebastiaan Pasma
ed998e9036
Make "Share the Wallet App" translatable 2018-08-22 16:27:30 +02:00
Sebastiaan Pasma
4cf268682b
removed comments 2018-08-22 16:21:57 +02:00
Brendon Duncan
feca8b5807 Checking every time we get earlier data, if all transactions have been fetched. 2018-08-22 20:01:30 +12:00
Brendon Duncan
e6beb6fed1 Displaying more cached data while waiting for first tx history fetch. 2018-08-22 19:51:10 +12:00
Brendon Duncan
745737ef73 Adding missing parameter. 2018-08-22 19:39:32 +12:00
Brendon Duncan
95de043d3d Merged. 2018-08-22 19:32:53 +12:00
Brendon Duncan
ad6a1fbe8d Adding latest transactions. 2018-08-22 19:28:24 +12:00
Brendon Duncan
ecb3b2391d Grunt task for signing. 2018-08-22 18:17:33 +12:00
Brendon Duncan
14f77cf03f Using generic *PACKAGENAME* in template. 2018-08-22 12:07:20 +12:00
Brendon Duncan
e5560bf63a Images with config file changes. 2018-08-22 11:48:19 +12:00
Sebastiaan Pasma
d5f01e9713
stop fetching the wallet history when everything is fetched 2018-08-21 21:36:55 +02:00
Jean-Baptiste Dominguez
66e643f903
Merge pull request #291 from Bitcoin-com/wallet/dev
Wallet/dev
2018-08-21 12:46:38 +09:00
Jean-Baptiste Dominguez
feb41adc58 Upgrade the version 2018-08-21 10:44:38 +07:00
Jean-Baptiste Dominguez
ef6b52c6e9 translation 2018-08-21 10:42:12 +07:00
Brendon Duncan
78f0ff28cd Getting earlier transactions with pagination. 2018-08-21 12:43:03 +12:00
Brendon Duncan
0bd94601ae Controlling when infinite scroll is available. 2018-08-21 09:17:56 +12:00
Brendon Duncan
72cb94d212 Using infinite scroll on cached data. 2018-08-21 08:58:19 +12:00
Brendon Duncan
ba98fbe187 Merge sprint/21. 2018-08-20 17:23:01 +12:00
Brendon Duncan
03fa87adbc Displaying transactions from cache when first entering wallet details. 2018-08-20 17:21:30 +12:00
Brendon Duncan
bbe2fb20c4 Updated package.json attempt 4. 2018-08-20 12:02:11 +12:00
Brendon Duncan
2a5a21f7d7 Updated package.json for real. 2018-08-20 11:48:48 +12:00
Brendon Duncan
09871c9eba Updated package.json. 2018-08-20 11:46:34 +12:00
Brendon Duncan
bb92f5ec1b Merged updated sprint/21. 2018-08-20 11:31:49 +12:00
Jean-Baptiste Dominguez
b0f9cb43d6
Merge pull request #289 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-18 02:03:55 +09:00
Jean-Baptiste Dominguez
d06e9f7088
Update package-template.json 2018-08-18 02:03:23 +09:00
Jean-Baptiste Dominguez
f4346fd921
Update bower.json 2018-08-18 02:02:50 +09:00
Jean-Baptiste Dominguez
1fcab222c5
Merge pull request #288 from Bitcoin-com/wallet/sprint/20
Update package.json
2018-08-18 01:29:46 +09:00
Jean-Baptiste Dominguez
154e495846
Update package.json 2018-08-18 01:29:04 +09:00
Jean-Baptiste Dominguez
8f356f8d75
Merge pull request #287 from Bitcoin-com/wallet/sprint/20
ionic resolution
2018-08-18 01:18:34 +09:00
Jean-Baptiste Dominguez
6dcc221ee1 ionic resolution 2018-08-18 01:17:04 +09:00
Jean-Baptiste Dominguez
1e2cfd3ae4
Merge pull request #286 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-18 00:53:18 +09:00
Jean-Baptiste Dominguez
3cef258912 Merge branch 'wallet/sprint/20' of https://github.com/Bitcoin-com/Wallet into wallet/sprint/20 2018-08-18 00:51:24 +09:00
Jean-Baptiste Dominguez
a67f9acbc6 Resolution package 2018-08-18 00:51:08 +09:00
Brendon Duncan
9ee9e8fbed Merged quick fix for asn1. 2018-08-17 16:58:10 +12:00
Brendon Duncan
26891f6e47 Cleaned up log message. 2018-08-17 16:54:04 +12:00
Brendon Duncan
b3e34483b6 Show my address button. 2018-08-17 11:59:27 +12:00
Brendon Duncan
aa75ba18d6 Removed old content. 2018-08-17 11:45:43 +12:00
Jean-Baptiste Dominguez
eee1a69d84
Update package.json 2018-08-16 17:54:51 +09:00
Jean-Baptiste Dominguez
e8f7126c89 package.json 2018-08-16 17:52:23 +09:00
Jean-Baptiste Dominguez
e6ae1c0520 Add the command in package.json 2018-08-16 17:51:59 +09:00
Jean-Baptiste Dominguez
56be096207 quick fix for asn1 2018-08-16 17:51:20 +09:00
Jean-Baptiste Dominguez
acee3024a9 Quick fix for asn1 2018-08-16 17:51:08 +09:00
Brendon Duncan
33d780f2e5 The spinner in wallet details now spins when the infinite scroll spinner spins. 2018-08-16 15:44:59 +12:00
Brendon Duncan
93b6c3f1be Spinner same size as refresh button. 2018-08-16 15:00:51 +12:00
Sebastiaan Pasma
0ae6f043ed
loading new txs using pagination 2018-08-15 17:23:00 +02:00
Jean-Baptiste Dominguez
c27bfcb800
Merge pull request #282 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-15 17:27:52 +09:00
Brendon Duncan
c280adbb06 Merged view for transaction sharing fix. 2018-08-15 12:33:10 +12:00
Brendon Duncan
8dd573624d View change for previous fix. 2018-08-15 12:31:03 +12:00
Sebastiaan Pasma
99d8de02da
Show pasted address instead of always cashaddr format on bch 2018-08-14 15:53:18 +02:00
Sebastiaan Pasma
448679d1a6
receive tab not showing fiat amount on receiving amount ("payment received" screen) 2018-08-14 14:05:22 +02:00
Jean-Baptiste Dominguez
8f2ce2ce12
Merge pull request #281 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-14 18:20:13 +09:00
Sebastiaan Pasma
abe71a8077
typo in template.pot 2018-08-14 10:27:27 +02:00
Jean-Baptiste Dominguez
f834f6783f
Merge pull request #280 from Bitcoin-com/wallet/task/541
Fix for building android release
2018-08-14 17:15:07 +09:00
Jean-Baptiste Dominguez
5a5d31d45d Fix for building android release 2018-08-14 17:13:44 +09:00
Jean-Baptiste Dominguez
a34520c2a9
Merge pull request #279 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-14 16:49:22 +09:00
Jean-Baptiste Dominguez
f18546b8d6
Update appConfig.json 2018-08-14 16:48:55 +09:00
Jean-Baptiste Dominguez
7541f65361
Merge pull request #278 from Bitcoin-com/wallet/dev
Wallet/dev
2018-08-14 16:41:53 +09:00
Jean-Baptiste Dominguez
4c93b26e54
Merge pull request #277 from Bitcoin-com/wallet/prod
Wallet/prod
2018-08-14 16:41:23 +09:00
Brendon Duncan
197ee9eeeb Fix for the Custom Amount screen now following the price display setting. 2018-08-14 17:24:17 +12:00
Brendon Duncan
05e204dec8 Changed the review controller to allow the transaction to be shared, once successful. 2018-08-14 16:58:13 +12:00
Brendon Duncan
9b5f4b3516 Merged latest changes.
# Conflicts:
#	src/js/controllers/review.controller.js
#	www/views/review.html
2018-08-14 16:15:05 +12:00
Brendon Duncan
cf6658c83a Removed $apply() inside $watch. 2018-08-14 14:48:07 +12:00
Brendon Duncan
058fc617bb Merged text changes. 2018-08-14 14:43:42 +12:00
Jean-Baptiste Dominguez
580912748a
Merge pull request #276 from Bitcoin-com/wallet/task/514
Upgrade text
2018-08-14 11:41:37 +09:00
Jean-Baptiste Dominguez
24033f4615
Merge branch 'wallet/sprint/20' into wallet/task/514 2018-08-14 11:41:31 +09:00
Jean-Baptiste Dominguez
947c2d324f Upgrade text 2018-08-14 11:38:24 +09:00
Brendon Duncan
4e2c06f69d Changed "Bitcoin" to "Bitcoin Core" on the Sweep Paper Wallet screen and made other strings translatable. 2018-08-14 12:24:10 +12:00
Sebastiaan Pasma
587971724e
template.pot change 2018-08-13 16:52:00 +02:00
Sebastiaan Pasma
5123ba9007
template.pot fix 2018-08-13 15:33:48 +02:00
Sebastiaan Pasma
f6a99f7f47
Merge branch 'wallet/sprint/20' into wallet/dev 2018-08-13 15:31:01 +02:00
Sebastiaan Pasma
14406f6bc4
template.pot fix 2018-08-13 15:28:22 +02:00
Sebastiaan Pasma
4591d4992e
Merge remote-tracking branch 'origin/wallet/dev' into wallet/prod 2018-08-13 14:34:33 +02:00
Sebastiaan Pasma
d2a1461a26
Merge remote-tracking branch 'origin/wallet/dev' into wallet/dev 2018-08-13 14:13:55 +02:00
Sebastiaan Pasma
f51542874b
small fix: minus before alternative currency 2018-08-13 14:12:36 +02:00
Sebastiaan Pasma
1dad3ab3fd
Many translation fixes. Missing translations in template.pot and added some in views 2018-08-13 13:48:41 +02:00
Jean-Baptiste Dominguez
a648b69297
Merge pull request #275 from Bitcoin-com/wallet/dev
Wallet/dev
2018-08-13 16:15:38 +09:00
Jean-Baptiste Dominguez
1c38298bbf
Merge pull request #274 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-13 16:15:03 +09:00
Jean-Baptiste Dominguez
a1abf54b4a
Merge pull request #273 from Bitcoin-com/wallet/task/428
Wallet/task/428
2018-08-13 16:14:32 +09:00
Jean-Baptiste Dominguez
30230304b6 Fix height header 2018-08-13 16:13:29 +09:00
Jean-Baptiste Dominguez
f93797efc0
Merge pull request #272 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-13 16:10:29 +09:00
Jean-Baptiste Dominguez
1d62da34d7
Merge pull request #271 from Bitcoin-com/wallet/dev
Wallet/dev
2018-08-13 15:37:50 +09:00
Jean-Baptiste Dominguez
15b161d55d
Merge pull request #269 from Bitcoin-com/wallet/dev
Wallet/dev
2018-08-13 15:36:06 +09:00
Jean-Baptiste Dominguez
9c999d0cd6
Update appConfig.json 2018-08-13 15:35:26 +09:00
Jean-Baptiste Dominguez
b25879b251
Merge pull request #268 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-13 15:33:24 +09:00
Jean-Baptiste Dominguez
e27aa9a612
Merge pull request #267 from Bitcoin-com/wallet/task/427
Custom amount crypto decimal
2018-08-13 14:45:18 +09:00
Jean-Baptiste Dominguez
c54cb55c51 Custom amount crypto decimal 2018-08-13 14:44:07 +09:00
Jean-Baptiste Dominguez
08ff6f2a6c
Merge pull request #266 from Bitcoin-com/wallet/task/427
Manage the currency state
2018-08-13 14:14:34 +09:00
Jean-Baptiste Dominguez
52e1b5e811 Manage the currency state 2018-08-13 14:13:49 +09:00
Brendon Duncan
b7d2c3e05c Merged fixes to Wallet Details. 2018-08-13 17:00:32 +12:00
Brendon Duncan
0b71daf04d Removed previous fix as it is superceded by a better one. 2018-08-13 16:51:38 +12:00
Brendon Duncan
6de4f2ecda Enlarged Wallet Details header to fit Receive and Send buttons without covering the unlocked balance. 2018-08-13 16:45:46 +12:00
Jean-Baptiste Dominguez
803653135f
Merge pull request #265 from Bitcoin-com/wallet/task/427
Fix formatted amount.
2018-08-13 13:37:28 +09:00
Jean-Baptiste Dominguez
430f4644eb Fix formatted amount. 2018-08-13 13:32:20 +09:00
Brendon Duncan
5da475f1ee Merged sprint/20. 2018-08-13 15:55:57 +12:00
Brendon Duncan
a29a41b647 Removed console.log(). 2018-08-13 15:48:20 +12:00
Brendon Duncan
098d454b8b Fixed formatting of numbers in the thousands. 2018-08-13 15:43:20 +12:00
Brendon Duncan
9d918a694c Merged fixes.
# Conflicts:
#	src/js/controllers/walletSelectorController.js
2018-08-13 14:36:59 +12:00
Brendon Duncan
80c9d682b5 Fix in formatted-amount of display of subcent fees in transactions details page. 2018-08-13 11:23:15 +12:00
Brendon Duncan
84fd483f19 Fix for removing dark portion of Review Transaction screen below personal note. 2018-08-13 10:47:00 +12:00
Brendon Duncan
5445ddbecd Fix for wallet selection header when in Shapeshift flow. Also fixed a coin already present bug that occurred in subsequent Shapeshift flows. 2018-08-13 10:00:39 +12:00
Sebastiaan Pasma
4dd1c6f40b
Merge remote-tracking branch 'origin/wallet/task/537' into wallet/sprint/20 2018-08-10 15:11:10 +02:00
Sebastiaan Pasma
d28ba24e1c
receive specific amount fix to use sendFlowService 2018-08-10 15:10:44 +02:00
Sebastiaan Pasma
f86ab3faec
revert code cleanup 2018-08-10 12:42:28 +02:00
Sebastiaan Pasma
f69b72b24f
Merge remote-tracking branch 'origin/wallet/sprint/20' into wallet/sprint/20 2018-08-10 12:12:45 +02:00
Sebastiaan Pasma
0339d6e85e
Merge remote-tracking branch 'origin/wallet/task/537' into wallet/sprint/20 2018-08-10 12:12:37 +02:00
Sebastiaan Pasma
335ef9defd
Merge remote-tracking branch 'origin/wallet/task/537' into wallet/task/537 2018-08-10 12:12:20 +02:00
Jean-Baptiste Dominguez
3cf577fcfb
Merge pull request #263 from Bitcoin-com/wallet/task/537
Cleaning code
2018-08-10 19:11:22 +09:00
Sebastiaan Pasma
e4c5da0d44
thirdParty fix 2018-08-10 12:07:24 +02:00
Jean-Baptiste Dominguez
949cbc7697 Cleaning code 2018-08-10 19:04:53 +09:00
Jean-Baptiste Dominguez
4cba8e1298
Merge pull request #262 from Bitcoin-com/wallet/task/537
Wallet/task/537
2018-08-10 18:44:51 +09:00
Jean-Baptiste Dominguez
daf9bb5356 Notify to reload home tab 2018-08-10 18:43:28 +09:00
Jean-Baptiste Dominguez
5185c6ee3c Fix amount 2018-08-10 18:41:47 +09:00
Jean-Baptiste Dominguez
81126a9d04 Merge branch 'wallet/task/537' of https://github.com/Bitcoin-com/Wallet into wallet/task/537 2018-08-10 17:47:32 +09:00
Jean-Baptiste Dominguez
3365a61d62 invalidate cache 2018-08-10 17:47:21 +09:00
Sebastiaan Pasma
dd75f581e7
move stateParams and fromWallet outside of the clipboar function 2018-08-10 10:47:16 +02:00
Jean-Baptiste Dominguez
b292f57b02
Merge pull request #261 from Bitcoin-com/wallet/task/537
Wallet/task/537
2018-08-10 17:21:13 +09:00
Jean-Baptiste Dominguez
9e28c4ec45 Fix bug send max with thirdparty (Shapeshift) 2018-08-10 17:20:04 +09:00
Jean-Baptiste Dominguez
3d3aa25d5b Merge branch 'wallet/task/537' of https://github.com/Bitcoin-com/Wallet into wallet/task/537 2018-08-10 17:13:29 +09:00
Brendon Duncan
9e11835000 Equal sized digits on Wallet Details alternative balance. 2018-08-10 19:45:43 +12:00
Brendon Duncan
c2bcae3537 Merged fixes for iPhone 5 / SE.
# Conflicts:
#	www/views/amount.html
2018-08-10 19:16:04 +12:00
Brendon Duncan
d88d3365ad Fix for long amounts on iPhone 5 / SE. Fix for buttons below amounts on iPhone 5 / SE. 2018-08-10 19:09:55 +12:00
Brendon Duncan
38d2c6a3c6 Merge fix for wallet-balance for non-stringifyable wallet. 2018-08-10 17:16:50 +12:00
Brendon Duncan
812ed5f1cd wallet-balance workaround for wallet not being stringify-able, and hence not being interpolatable, and hence not being able to pass it to the directive. 2018-08-10 17:13:24 +12:00
Jean-Baptiste Dominguez
ee84235d3a Top bar message 2018-08-10 14:05:46 +09:00
Brendon Duncan
38b2d84f2e Merged error handling for wallet-balance. 2018-08-10 16:23:39 +12:00
Brendon Duncan
e6105ef552 Merge. 2018-08-10 16:20:53 +12:00
Brendon Duncan
3ff0f50a7b Added quotes. 2018-08-10 16:20:26 +12:00
Brendon Duncan
8d404f1908 Handle null wallet. 2018-08-10 16:19:24 +12:00
Brendon Duncan
14724ea6f6 Merged formatting of some amounts. 2018-08-10 14:30:53 +12:00
Brendon Duncan
4dd334087b Removed formatted amount from the entry of the Amount screen as it was causing a bug. 2018-08-10 14:24:41 +12:00
Jean-Baptiste Dominguez
e0c4155ef1
Merge pull request #260 from Bitcoin-com/wallet/task/537
Add tracking shapeshift
2018-08-10 11:22:46 +09:00
Jean-Baptiste Dominguez
0410ad1491 Add tracking shapeshift 2018-08-10 11:21:29 +09:00
Brendon Duncan
18c8f4cf07 formatted-amount for transaction proposals and wallet activity. 2018-08-10 14:17:42 +12:00
Jean-Baptiste Dominguez
40676d8032
Merge pull request #259 from Bitcoin-com/wallet/task/537
Handle error in the review screen
2018-08-10 11:13:19 +09:00
Jean-Baptiste Dominguez
4c9ff1b28b Handle error in the review screen 2018-08-10 11:11:53 +09:00
Jean-Baptiste Dominguez
a34bd614fa
Merge pull request #258 from Bitcoin-com/wallet/task/427
crypto decimal
2018-08-10 10:57:20 +09:00
Brendon Duncan
cb9feb99ce Merge wallet-balance that includes formatted-amount 2018-08-10 13:56:48 +12:00
Jean-Baptiste Dominguez
b70bd804dc crypto decimal 2018-08-10 10:56:01 +09:00
Brendon Duncan
82c0746ff8 wallet-balance directive uses formatted-amount. 2018-08-10 13:48:59 +12:00
Jean-Baptiste Dominguez
1f07e8ec57
Merge pull request #257 from Bitcoin-com/wallet/task/427
Wallet/task/427
2018-08-10 10:44:49 +09:00
Jean-Baptiste Dominguez
82ede65363 New decimal on the review screen 2018-08-10 10:43:54 +09:00
Jean-Baptiste Dominguez
39e515d3c5
Merge pull request #256 from Bitcoin-com/wallet/sprint/20
Wallet/sprint/20
2018-08-10 10:39:42 +09:00
Jean-Baptiste Dominguez
bd32a7c08a
Merge pull request #255 from Bitcoin-com/wallet/task/537
Wallet/task/537
2018-08-10 10:26:14 +09:00
Brendon Duncan
d7285a72e4 wallet-balance directive retrieves alternative amount when needed. 2018-08-10 13:26:12 +12:00
Brendon Duncan
355ed27b87 wallet balance directive displaying fiat balance from wallet status. 2018-08-10 13:04:44 +12:00
Brendon Duncan
afb3a1d49f wallet-balance directive displaying basic crypto balance. 2018-08-10 12:46:00 +12:00
Brendon Duncan
678ad516ee Merge sprint/20. 2018-08-10 12:19:13 +12:00
Sebastiaan Pasma
577756fd44
button color + Time ago fix 2018-08-09 17:14:05 +02:00
Jean-Baptiste Dominguez
06a56cab4d
Merge pull request #254 from Bitcoin-com/wallet/task/427
Fix decimal
2018-08-09 23:30:23 +09:00
Jean-Baptiste Dominguez
bc9e1710c2
Merge branch 'wallet/sprint/20' into wallet/task/427 2018-08-09 23:30:12 +09:00
Jean-Baptiste Dominguez
2408753e91 Fix decimal 2018-08-09 23:28:59 +09:00
Sebastiaan Pasma
8b19f599b6
Merge remote-tracking branch 'origin/wallet/task/537' into wallet/sprint/20 2018-08-09 13:46:34 +02:00
Sebastiaan Pasma
ee0042b6e7
sendMax bugfix when returning to previous screen 2018-08-09 13:39:27 +02:00
Sebastiaan Pasma
25965f6268
shapeshift moved to default services and communities fix 2018-08-09 10:17:29 +02:00
Sebastiaan Pasma
420305cf01
shapeshift moved to default services and communities fix 2018-08-09 10:16:45 +02:00
Jean-Baptiste Dominguez
fb8d2efe12
Merge pull request #253 from Bitcoin-com/wallet/task/537
Wallet/task/537
2018-08-09 16:42:21 +09:00
Jean-Baptiste Dominguez
b46b01471a
Merge pull request #252 from Bitcoin-com/wallet/dev
Wallet/dev
2018-08-09 16:19:39 +09:00
Brendon Duncan
0ec0e5c945 Merged latest. 2018-08-09 18:59:46 +12:00
Brendon Duncan
ac8cdcf5be Android 4.4 fix for Amount screen, removal of  . 2018-08-09 18:59:03 +12:00
Brendon Duncan
de33fe5868 Refactored formattedAmount. 2018-08-09 18:58:21 +12:00
Jean-Baptiste Dominguez
c8d7e88f81
Merge branch 'wallet/sprint/20' into wallet/dev 2018-08-09 15:52:48 +09:00
Jean-Baptiste Dominguez
0c15a83782
Merge pull request #250 from Bitcoin-com/wallet/task/537
Wallet/task/537
2018-08-09 15:41:29 +09:00
Jean-Baptiste Dominguez
3bb446cdee
Merge branch 'wallet/sprint/20' into wallet/task/537 2018-08-09 15:41:17 +09:00
Jean-Baptiste Dominguez
4cf68076a0 remove comment on bitanalytics 2018-08-09 15:35:31 +09:00
Jean-Baptiste Dominguez
9076ad2098 add update wallet 2018-08-09 15:35:03 +09:00
Jean-Baptiste Dominguez
b742eadd4e clean and remove bug home 2018-08-09 15:13:29 +09:00
Jean-Baptiste Dominguez
9bdd44a483 Merge branch 'wallet/task/537' of https://github.com/Bitcoin-com/Wallet into wallet/task/537 2018-08-09 15:09:52 +09:00
Jean-Baptiste Dominguez
c68b1e77f6 clean controller and remove old firebase event 2018-08-09 15:09:43 +09:00
Brendon Duncan
cbf66a2176 Fix for formatting amounts on Android 4.4. 2018-08-09 17:54:20 +12:00
Jean-Baptiste Dominguez
a964b2d967 Merge branch 'wallet/task/537' of https://github.com/Bitcoin-com/Wallet into wallet/task/537 2018-08-09 13:15:29 +09:00
Jean-Baptiste Dominguez
77f6210076 Fix pop state on the send flow 2018-08-09 13:15:21 +09:00
Jean-Baptiste Dominguez
0ea97fc1c6 Fix state pop on the send flow 2018-08-09 13:14:44 +09:00
Brendon Duncan
7ce562ec64 Fix for Shapeshift now appearing again on Review Transaction screen. 2018-08-09 16:11:29 +12:00
Jean-Baptiste Dominguez
a490f0ce1f dead code 2018-08-09 13:06:52 +09:00
Jean-Baptiste Dominguez
647e126169 Fix style css for the from wallet & activate the from wallet in the send tab 2018-08-09 12:49:35 +09:00
Jean-Baptiste Dominguez
e183643298 Remove from the route the stateparams, adapt some controllers in the new sendflowservice 2018-08-09 12:35:39 +09:00
Brendon Duncan
188ddcba58 Review transation copying state at startup so it doesn't contaminate the sendFlowController. 2018-08-09 13:25:06 +12:00
Brendon Duncan
0410182d4f Incoming data working with sendFlowService. 2018-08-09 13:24:13 +12:00
Brendon Duncan
a2dff98c63 Back button on Review Transaction screen works with sendFlowService. 2018-08-09 13:12:44 +12:00
Brendon Duncan
b426209efb Fix for clearing current state only. 2018-08-09 13:06:50 +12:00
Brendon Duncan
bf9b467bfe Renamed sendFlowService functions to be more consistent. 2018-08-09 13:01:48 +12:00
Brendon Duncan
be0c18244e Review Transaction screen now displaying BCH addresses in cashaddr format. 2018-08-09 12:12:29 +12:00
Brendon Duncan
408d46e4d3 Hid the from wallet in the send screen for now, because it requires other layout changes to fit everything in, especially on small screens. 2018-08-09 11:43:20 +12:00
Brendon Duncan
1d025cbf35 Fixes for Android 4.4 2018-08-09 11:42:25 +12:00
Brendon Duncan
be2bc4cddb Showing From wallet in send tab. 2018-08-09 11:13:12 +12:00
Brendon Duncan
dff0d51ef3 Refactored sendFlowService and cleared its state before entering the send tab. 2018-08-09 11:10:26 +12:00
Brendon Duncan
e7ce86fb99 Merged fix for undefined currency. 2018-08-09 10:47:54 +12:00
Brendon Duncan
58d99231ae Handle undefined currency. 2018-08-09 10:46:07 +12:00
Brendon Duncan
eb500c0549 Updated decimal formatting. 2018-08-09 10:42:58 +12:00
Brendon Duncan
cb398a0f50 Merged cleanup for formated amount.
# Conflicts:
#	src/js/directives/formattedAmount.js
2018-08-09 07:58:24 +12:00
Brendon Duncan
1c3b113222 Removed unused config service. 2018-08-09 07:49:13 +12:00
Brendon Duncan
d81f194f87 Fix for when an amount changes from having a separate currency value, to the currency being one string with the amount. 2018-08-09 07:35:47 +12:00
Sebastiaan Pasma
02e8e0fbf0
clear send flow on home and wallet details 2018-08-08 17:29:28 +02:00
Sebastiaan Pasma
2206102715
sendflow service integrated into flow 2018-08-08 17:27:15 +02:00
Sebastiaan Pasma
f7ecdb2f2f
sendflow service integrated into flow 2018-08-08 17:10:47 +02:00
Sebastiaan Pasma
8229d51fdd
sendflow service 2018-08-08 16:35:49 +02:00
Jean-Baptiste Dominguez
73b18b16b6
Merge pull request #249 from Bitcoin-com/wallet/task/514
Wallet/task/514
2018-08-08 22:34:44 +09:00
Jean-Baptiste Dominguez
04f77c1daa Merge branch 'wallet/task/514' of https://github.com/Bitcoin-com/Wallet into wallet/task/514 2018-08-08 22:32:31 +09:00
Jean-Baptiste Dominguez
51921a1a1d Fix shapeshift flow go back available 2018-08-08 22:32:18 +09:00
Sebastiaan Pasma
753d2aea69
remove bottom menu on wallet selector + remove swipe back feature on review screen 2018-08-08 15:31:36 +02:00
Brendon Duncan
69e8c62f5c Fix for when an amount changes from having a separate currency value, to the currency being one string with the amount. 2018-08-08 22:00:07 +12:00
Brendon Duncan
b8de811fbe Merged fancy decimals.
# Conflicts:
#	www/views/walletDetails.html
2018-08-08 20:42:49 +12:00
Brendon Duncan
7e9cfa77c4 Now correctly derives currency from value. 2018-08-08 20:25:17 +12:00
Jean-Baptiste Dominguez
da964e5a9b
Merge pull request #248 from Bitcoin-com/wallet/task/514
Wallet/task/514
2018-08-08 17:17:51 +09:00
Jean-Baptiste Dominguez
b4e36e93cb Fix double loading in the review screen for shapeshift 2018-08-08 17:11:16 +09:00
Jean-Baptiste Dominguez
60028c44bb remove the header for shapeshift in the amount view 2018-08-08 16:59:00 +09:00
Jean-Baptiste Dominguez
5ee9d4d284
Merge pull request #247 from Bitcoin-com/wallet/task/514
height space in the bottom (wallet selection & review)
2018-08-08 16:25:31 +09:00
Jean-Baptiste Dominguez
644b3e6113 height space in the bottom (wallet selection & review) 2018-08-08 16:24:47 +09:00
Jean-Baptiste Dominguez
14c87892bc
Merge pull request #246 from Bitcoin-com/wallet/task/514
Wallet/task/514
2018-08-08 16:10:58 +09:00
Jean-Baptiste Dominguez
158c571ce1
Merge branch 'wallet/sprint/20' into wallet/task/514 2018-08-08 16:10:51 +09:00
Jean-Baptiste Dominguez
ab13478f79 Add shapeshift service item 2018-08-08 16:03:34 +09:00
Brendon Duncan
ae6dcea81a Fix for getting Shapeshift working. 2018-08-08 18:58:26 +12:00
Brendon Duncan
3d9b24575b In Review Transaction screen, the note is now visible above the fees. 2018-08-08 18:57:55 +12:00
Jean-Baptiste Dominguez
6981a5af9f show only when it is ready 2018-08-08 15:52:20 +09:00
Brendon Duncan
a5862bd6c4 Merge. 2018-08-08 18:23:46 +12:00
Brendon Duncan
fcb4d4b004 Text is now visible on Send and Receive buttons in Wallet Details screen when activated. 2018-08-08 18:22:43 +12:00
Jean-Baptiste Dominguez
198bb88140
Merge pull request #244 from Bitcoin-com/wallet/sprint/20
sprint 20
2018-08-08 14:09:34 +09:00
Brendon Duncan
86a9e9fe92 Merge for alignment and size of Receive and Send buttons. 2018-08-08 16:34:14 +12:00
Brendon Duncan
939263c385 Alignment and size of Receive and Send buttons on the Home tab matches the Wallet Details tab: equal spacing. 2018-08-08 16:30:57 +12:00
Brendon Duncan
5d3e11b7bb Fixed alignment of buttons in Wallet Details on wide screens.. 2018-08-08 16:10:58 +12:00
Brendon Duncan
da88ddbd40 ShapeshiftService fix for app startup. 2018-08-08 15:36:18 +12:00
Jean-Baptiste Dominguez
a1250be73d
Merge pull request #243 from Bitcoin-com/wallet/task/514
Wallet/task/514
2018-08-08 11:23:48 +09:00
Jean-Baptiste Dominguez
037c00ec9e
Merge branch 'wallet/sprint/20' into wallet/task/514 2018-08-08 11:23:35 +09:00
Jean-Baptiste Dominguez
1c71e961b9
Merge pull request #232 from Bitcoin-com/wallet/task/423
Small improvement - 423 - Only change button color if it contains an address, not on all content
2018-08-08 10:57:10 +09:00
Jean-Baptiste Dominguez
5048bc135b
Merge pull request #224 from Bitcoin-com/wallet/task/441
441 - Translatable strings for the "Home" tab
2018-08-08 10:56:35 +09:00
Jean-Baptiste Dominguez
7f0946b390
Merge branch 'wallet/sprint/20' into wallet/task/441 2018-08-08 10:56:26 +09:00
Jean-Baptiste Dominguez
06ffa4c233
Merge pull request #226 from Bitcoin-com/wallet/task/442
442 - Missing "Price Display" translation
2018-08-08 10:54:21 +09:00
Jean-Baptiste Dominguez
b4bf0c314f
Merge pull request #230 from Bitcoin-com/wallet/task/508
508 - Fix the QRCode scan.
2018-08-08 10:54:09 +09:00
Jean-Baptiste Dominguez
ecad91d328
Merge pull request #237 from Bitcoin-com/wallet/task/439
439 - Enter Amount screen modifications
2018-08-08 10:53:59 +09:00
Jean-Baptiste Dominguez
f20f5ae648
Merge pull request #236 from Bitcoin-com/wallet/task/428
Improvement - 428 - Send/Receive buttons
2018-08-08 10:53:48 +09:00
Jean-Baptiste Dominguez
75843c68ff
Merge pull request #231 from Bitcoin-com/wallet/task/505
505 - BitAnalytics 0.2.1 with GA
2018-08-08 10:53:01 +09:00
Jean-Baptiste Dominguez
699d1dddf2
Merge pull request #220 from Bitcoin-com/wallet/task/426
Improvement - 426 - New Payment Sent screen
2018-08-08 10:51:51 +09:00
Jean-Baptiste Dominguez
8ac6094c22
Merge pull request #227 from Bitcoin-com/wallet/task/414
Improvement - 414 - "Custom amount" QR screen to include the price in big letters
2018-08-08 10:51:39 +09:00
Jean-Baptiste Dominguez
e52fb462dd
Merge pull request #228 from Bitcoin-com/wallet/task/484
484 - Android: Remove permission for Microphone use
2018-08-08 10:51:01 +09:00
Brendon Duncan
43adcc3806 More selective display of balances Wallet Details screen when fiat balance isn't available. 2018-08-08 13:38:43 +12:00
Brendon Duncan
820c1a3933 Wallet details does not display any balance text if it does not have balance yet. 2018-08-08 13:31:02 +12:00
Brendon Duncan
12aa9a3b18 formatted-amount displays "-.--" when it does not have a value. 2018-08-08 13:28:44 +12:00
Brendon Duncan
29a5a37c02 Formatter displays blank amount when value is NaN. 2018-08-08 12:24:13 +12:00
Sebastiaan Pasma
b1a1f24d93
New format also on walletSelector component and receive tab (including payment received) 2018-08-07 16:21:51 +02:00
Sebastiaan Pasma
9f418583ab
formatted amount controller update + css + renames + included in views 2018-08-07 16:11:47 +02:00
Jean-Baptiste Dominguez
e127b81e7c
Merge pull request #242 from Bitcoin-com/wallet/prod
Wallet/prod
2018-08-07 23:01:10 +09:00
Jean-Baptiste Dominguez
ab8f856e2b
Merge branch 'master' into wallet/prod 2018-08-07 23:01:00 +09:00
Sebastiaan Pasma
01a7024b52
Merge remote-tracking branch 'origin/wallet/task/514' into wallet/task/427 2018-08-07 15:06:54 +02:00
Jean-Baptiste Dominguez
07ac4e7738 Show memo for shapeshift 2018-08-07 20:50:56 +09:00
Jean-Baptiste Dominguez
af90c53e50 Add memo expended 2018-08-07 20:14:48 +09:00
Jean-Baptiste Dominguez
9420b63728 Fix shapeshift, remove the cancelTx. Remove the timer with the getStatus 2018-08-07 20:11:21 +09:00
Jean-Baptiste Dominguez
a295c03b2e Merge branch 'wallet/task/514' of https://github.com/Bitcoin-com/Wallet into wallet/task/514 2018-08-07 17:37:32 +09:00
Jean-Baptiste Dominguez
485039223f egifter template 2018-08-07 17:37:23 +09:00
Sebastiaan Pasma
52ca7bafd7
Merge remote-tracking branch 'origin/wallet/task/514' into wallet/task/514 2018-08-07 09:54:43 +02:00
Sebastiaan Pasma
83b1977a6f
Shapeshift controller useless functions removed 2018-08-07 09:47:37 +02:00
Jean-Baptiste Dominguez
37614f0811 Change to svg for egifter 2018-08-07 16:45:58 +09:00
Jean-Baptiste Dominguez
1aa31b6935 egifter template, waiting the logo in svg. 2018-08-07 16:36:33 +09:00
Jean-Baptiste Dominguez
d26a96500b eGifter incomingData 2018-08-07 15:30:28 +09:00
Jean-Baptiste Dominguez
e6389567e0 Merge branch 'wallet/task/514' of https://github.com/Bitcoin-com/Wallet into wallet/task/514 2018-08-07 15:02:43 +09:00
Jean-Baptiste Dominguez
91487cf74c shapeshift add the toAddress in the tx. Sending works. 2018-08-07 15:02:29 +09:00
Brendon Duncan
9b4b3996ae Merge. Also invoice name from third party data. 2018-08-07 17:58:35 +12:00
Brendon Duncan
59d1704673 Fix for display of fee when not for a BIP70 invoice. 2018-08-07 17:34:28 +12:00
Jean-Baptiste Dominguez
886204d8b0 incomingData time for bch 2018-08-07 14:34:02 +09:00
Jean-Baptiste Dominguez
a9711c2575 Fix incomingData, expires different depending on btc or bch (bitpay...) 2018-08-07 14:02:53 +09:00
Jean-Baptiste Dominguez
37402e45af Merge branch 'wallet/task/514' of https://github.com/Bitcoin-com/Wallet into wallet/task/514 2018-08-07 13:57:06 +09:00
Jean-Baptiste Dominguez
c800e8efe5 incomingData, bip70 & bitpay 2018-08-07 13:56:56 +09:00
Brendon Duncan
db7eee984b Error handling for Shapeshift, and UI for destination wallet. 2018-08-07 14:48:43 +12:00
Brendon Duncan
6c46ec2bca Fix for some changes which broke Shapeshift flow. 2018-08-07 14:23:53 +12:00
Brendon Duncan
6dfbbb15d4 Added showSendMaxWarning(). 2018-08-07 12:16:59 +12:00
Brendon Duncan
38852d32d4 Sending BIP70 payments. 2018-08-07 11:59:36 +12:00
Brendon Duncan
7d1fff424a Streamlined display of memo. 2018-08-07 11:34:35 +12:00
Brendon Duncan
09f627ea51 Suggested by merchant. 2018-08-07 11:27:05 +12:00
Brendon Duncan
e29f97eddf Payment request expiration. 2018-08-07 11:07:19 +12:00
Brendon Duncan
d183077a20 Countdown timer for BIP70 invoices. 2018-08-07 09:39:48 +12:00
Sebastiaan Pasma
5b6f48e6a2
Check min max on shapeshift flow 2018-08-06 18:11:37 +02:00
Sebastiaan Pasma
caafec4625
shapeshift controller 2018-08-06 18:06:10 +02:00
Jean-Baptiste Dominguez
470868ade9 Review screen, cleaning in the same time 2018-08-06 23:19:46 +09:00
Jean-Baptiste Dominguez
3652419b0d Fix double id 2018-08-06 22:21:40 +09:00
Jean-Baptiste Dominguez
bb3b00ae8d Fix incomingData toAddress, mistake 2018-08-06 22:20:51 +09:00
Jean-Baptiste Dominguez
59b9167ff0 Merge 2018-08-06 22:17:15 +09:00
Jean-Baptiste Dominguez
cc213956d0 header bitpay on the wallet selector, incoming data fix, clean a bit 2018-08-06 22:12:33 +09:00
Brendon Duncan
9273fb6407 Merge. 2018-08-06 21:46:09 +12:00
Brendon Duncan
cea77e910f One step closer to getting send max working. 2018-08-06 21:46:03 +12:00
Sebastiaan Pasma
ec354bd340
header css 2018-08-06 11:25:29 +02:00
Brendon Duncan
731cfebc8a Fixed destination coin for Shapeshift. 2018-08-06 20:39:59 +12:00
Brendon Duncan
f1f8f6e0f5 Tidied up third party data from BIP70 Payment Protocol. 2018-08-06 20:31:06 +12:00
Brendon Duncan
b0e46f18a1 The Origin screen can now display payment requests properly. 2018-08-06 16:45:00 +12:00
Brendon Duncan
4203a449d9 Displaying requested amount in origin screen. 2018-08-06 13:39:03 +12:00
Brendon Duncan
fb4bc1563c Starting to integrate BIP70 payment protocol into new send flow. 2018-08-06 12:04:14 +12:00
Sebastiaan Pasma
d7fabc3642
header + default colors 2018-08-03 14:28:56 +02:00
Sebastiaan Pasma
cebe9507f1
Make the "to"-address field work in new style + BTC transactions fix 2018-08-03 13:13:29 +02:00
Brendon Duncan
8148ad66b4 Payments to contacts now work. 2018-08-03 20:11:14 +12:00
Brendon Duncan
2f62092fd8 Payment sent message is displayed. 2018-08-03 19:59:25 +12:00
Sam Cheng Hung
671b46da41 Changes address component name to address-frame 2018-08-03 15:33:25 +08:00
Brendon Duncan
5973b30551 Sends wallet to wallet transaction with sound. 2018-08-03 19:14:33 +12:00
Brendon Duncan
3ca95d6d40 Wallet to wallet transaction sent successfully. The UI for it is still incomplete. 2018-08-03 17:56:46 +12:00
Sam Cheng Hung
f96610a66b Removes border and background from Paste Address button for send tab page 2018-08-03 13:35:05 +08:00
Brendon Duncan
e649da69ef In WalletService, createAddress now terminated properly, preventing double callback. 2018-08-03 17:11:47 +12:00
Jean-Baptiste Dominguez
114cb5e1e9
Merge pull request #241 from Bitcoin-com/wallet/dev
Wallet/dev
2018-08-03 10:38:32 +09:00
Jean-Baptiste Dominguez
9e5bd663a7
Update appConfig.json 2018-08-03 10:37:49 +09:00
Jean-Baptiste Dominguez
a8b0d245c1
Merge pull request #240 from Bitcoin-com/wallet/sprint/19
Wallet/sprint/19
2018-08-03 10:37:10 +09:00
Jean-Baptiste Dominguez
96a9ab9c6e
Merge pull request #238 from Bitcoin-com/wallet/task/416
Fix - 416 - buttom button border-radius fix
2018-08-03 10:36:11 +09:00
Jean-Baptiste Dominguez
d03bc4cb23
Merge pull request #239 from Bitcoin-com/wallet/task/510
Wallet/task/510
2018-08-03 10:35:46 +09:00
Brendon Duncan
6626663a31 Displays error when transaction amount too low. Reinstated warning colour for transactions with high fees. 2018-08-03 10:41:21 +12:00
Brendon Duncan
f758668395 Title on wallet-to-wallet destination screen. 2018-08-03 08:48:24 +12:00
Sebastiaan Pasma
eef84b25f8
update to txp creation. merged and refactored many features from confirm.js 2018-08-02 18:30:35 +02:00
Jean-Baptiste Dominguez
9c8ec7d3a2 Fix tx history 2018-08-03 01:17:01 +09:00
Jean-Baptiste Dominguez
66c9cefb0c Fix the tx history 2018-08-03 01:15:54 +09:00
Sebastiaan Pasma
f49e8725e8
Translations additions + some (s)css + review transaction changes 2018-08-02 16:05:12 +02:00
Sebastiaan Pasma
aacc80ea21
shapeshift flow 2018-08-02 15:42:35 +02:00
Sebastiaan Pasma
01dd774fae
thirdParty updates + shapeshift screens + merged with review transaction 2018-08-02 15:15:23 +02:00
Sebastiaan Pasma
391201471d
Merge remote-tracking branch 'origin/wallet/task/440' into wallet/task/514
# Conflicts:
#	i18n/po/template.pot
#	src/js/controllers/amount.js
#	www/css/main.css
2018-08-02 15:12:40 +02:00
Brendon Duncan
85a74bbd0e UI for crypto fee warning. 2018-08-02 21:11:28 +12:00
Brendon Duncan
e21592dec8 UI for crypto fee. 2018-08-02 20:43:18 +12:00
Brendon Duncan
4a1fd498f5 UI for sending to address. 2018-08-02 20:05:52 +12:00
Brendon Duncan
aeb6efcdd0 UI for sending to contact. 2018-08-02 19:51:50 +12:00
Brendon Duncan
e525b2e8ad UI for destination as wallet. 2018-08-02 18:14:54 +12:00
Brendon Duncan
1590a295da Bugfix for ShapeShift warnings. 2018-08-02 17:10:58 +12:00
Brendon Duncan
dc41aa6044 Warning messages for ShapeShift amounts. 2018-08-02 16:40:00 +12:00
Brendon Duncan
927c1e9478 Request Specifc Amount integrated into new send flow. 2018-08-02 15:44:59 +12:00
Brendon Duncan
ff643bf479 Starting on destination UI. 2018-08-02 11:48:41 +12:00
Brendon Duncan
438ab94404 Strings for translation. 2018-08-02 10:20:03 +12:00
Brendon Duncan
e58c3bf438 From wallet currency colour. 2018-08-02 10:07:25 +12:00
Brendon Duncan
0caa3fb92a From wallet details. 2018-08-02 09:48:12 +12:00
Sebastiaan Pasma
31d33ba656
Shape shift track 2018-08-01 11:53:58 +02:00
Sebastiaan Pasma
5372ba3dac
Merge remote-tracking branch 'origin/wallet/task/439' into wallet/task/514
# Conflicts:
#	src/js/controllers/amount.js
2018-08-01 11:16:59 +02:00
Sam Cheng Hung
18e00e5fca Renames amount directive to formatted-amount, fixes formatting for crypto 2018-08-01 16:59:13 +08:00
Brendon Duncan
38c3f2fb70 Displaying the amount. 2018-08-01 17:17:34 +12:00
Brendon Duncan
65ac476aaa Updated amount directive. 2018-08-01 14:29:37 +12:00
Brendon Duncan
d6176e0f3e Getting crypto value. 2018-08-01 14:28:26 +12:00
Brendon Duncan
52f1e93e5b Header text. 2018-08-01 11:36:25 +12:00
Brendon Duncan
f3a350f664 Redirecting to new Review screen when sending max. 2018-08-01 11:33:24 +12:00
Sebastiaan Pasma
a952edfe69
border-radius fix 2018-07-31 17:40:58 +02:00
Sebastiaan Pasma
42d77903e1
Third Party Service integration (Shapeshift) (CSS + translations + wallet selector + routes) 2018-07-31 17:21:56 +02:00
Sebastiaan Pasma
281b969fc3
Shapeshift refactor / Empty case / CSS 2018-07-31 15:03:20 +02:00
Brendon Duncan
0cba978d65 Replaced old amount screen. 2018-07-31 20:25:21 +12:00
Sam Cheng Hung
1895e0dbeb Adds watcher for changes to value or currency scope variables 2018-07-31 16:23:45 +08:00
Brendon Duncan
02f7bcc281 Not using amount directive. Removed safety area below All Available Funds button. 2018-07-31 20:18:27 +12:00
Brendon Duncan
97aa7c415e Merged fix for amount directive. 2018-07-31 19:51:19 +12:00
Sam Cheng Hung
8dc1e06048 Removes dummy values on home tab 2018-07-31 15:46:12 +08:00
Sam Cheng Hung
5a0c1417d4 Prevents reassignment of bound attribute size-equal 2018-07-31 15:44:59 +08:00
Brendon Duncan
778cbfbab0 Should have been part of merge for amount directive. 2018-07-31 19:16:11 +12:00
Brendon Duncan
2353109adf Bugfix for font for insufficient funds warning. 2018-07-31 17:59:26 +12:00
Brendon Duncan
2987d17e11 Merged amount directive. 2018-07-31 13:28:16 +12:00
Brendon Duncan
71a31ce399 Available funds now accurately reflects the primary currency choice. 2018-07-31 13:25:56 +12:00
Brendon Duncan
0fdd478ae4 Fixed up bold fonts. 2018-07-31 12:47:03 +12:00
Sebastiaan Pasma
9b27cb50e2
Merge remote-tracking branch 'origin/wallet/task/466' into wallet/task/454 2018-07-30 22:17:56 +02:00
Sebastiaan Pasma
ed291b1ac5
removed currencySymbolService and it's references 2018-07-30 15:25:52 +02:00
Sebastiaan Pasma
734153ec5b
more fixes on the send/receive on Android & iOS / removed some unused code 2018-07-30 15:17:15 +02:00
Sam Cheng Hung
3a89b4e2eb Merge branch 'wallet/task/427' into wallet/task/440 2018-07-30 17:47:25 +08:00
Sam Cheng Hung
e0ef42b09a Removes dummy text 2018-07-30 17:47:05 +08:00
Sam Cheng Hung
51bd970121 Merges amount directive 2018-07-30 17:46:00 +08:00
Sam Cheng Hung
1eac545751 Merge branch 'wallet/task/427' into wallet/task/440 2018-07-30 17:45:46 +08:00
Sam Cheng Hung
da536a3f5b Fixes default value of size-equal 2018-07-30 17:45:26 +08:00
Sam Cheng Hung
343fde08f3 Merges amount directive 2018-07-30 17:35:15 +08:00
Sam Cheng Hung
5c4890fac4 Removes amount directive template 2018-07-30 17:34:20 +08:00
Sam Cheng Hung
f4b0b46067 Adds size-equal and capitalizes currency text 2018-07-30 17:33:38 +08:00
Sam Cheng Hung
7fb2792a1a Adds size-equal class to amount directive 2018-07-30 16:56:27 +08:00
Sam Cheng Hung
e1d65bc557 Adds amount directive 2018-07-30 16:49:57 +08:00
Sam Cheng Hung
2b96293c80 Move amount directive to a separate branch 2018-07-30 16:40:16 +08:00
Sebastiaan Pasma
3732d21728
send/receive iPhoneX fixes 2018-07-30 09:37:14 +02:00
Brendon Duncan
7669ab2479 Transitioning from the Shapeshift screen. 2018-07-30 19:28:30 +12:00
Brendon Duncan
f0ccee8a0a Refining the display of available funds. 2018-07-30 18:28:27 +12:00
Brendon Duncan
d5666c9d29 Ported changes from 459. 2018-07-28 20:24:29 -07:00
Brendon Duncan
b5a2e890a5 Merge wallet/task/459 into wallet/task/439. 2018-07-28 19:30:36 -07:00
Brendon Duncan
9781f90f2b Warning colour for insufficient funds. 2018-07-28 19:20:12 -07:00
Brendon Duncan
72a5b3cabd Primary ("Next") button. 2018-07-28 17:18:52 -07:00
Brendon Duncan
0ba1ea1f42 Use All Available Funds button. 2018-07-28 15:36:23 -07:00
Brendon Duncan
81e9f527ff Route for send amount. 2018-07-28 13:04:04 -07:00
Sam Cheng Hung
2b32fe9bdc Changes amount directive scope values to bind to parent scope property 2018-07-27 17:04:53 +08:00
Sam Cheng Hung
47de79cc64 Adds support for 0, 2, 3 and 8 decimal places and locale commas and decimals 2018-07-27 17:03:09 +08:00
Sam Cheng Hung
69b2fac8e5 Updates amount font size 2018-07-27 12:29:34 +08:00
Brendon Duncan
f65b632273 Available funds appearance in normal case. 2018-07-26 13:22:03 -07:00
Brendon Duncan
8fd0b76a44 Change Currency button appearance. 2018-07-26 13:09:16 -07:00
Sebastiaan Pasma
b2ed16bf21
mobile support for send/receive buttons and some refactors to fix the navigation flow. 2018-07-26 19:38:29 +02:00
Sebastiaan Pasma
d87c2e65f7
Wallet buttons max width + Receive in viewing wallet. 2018-07-26 15:04:42 +02:00
Sam Cheng Hung
2492a405a1 Adds fee-summary bar, adds amount directive, adds support for fee-summary overlapping with content on scrollable small screens 2018-07-26 14:29:53 +08:00
Brendon Duncan
507fb21862 Available funds. 2018-07-25 18:46:42 -07:00
Brendon Duncan
91daae9f7a Improved amount card layout. Darker background under card. 2018-07-25 18:19:21 -07:00
Brendon Duncan
e539f0e713 Space around amount, and added "Not Enough Funds" warning. 2018-07-25 17:32:07 -07:00
Brendon Duncan
decd0a123e Buttons on keypad have correct colour in new Enter Amount screen. 2018-07-25 16:43:45 -07:00
Sebastiaan Pasma
aff0dd3183
fixes for other cases, address to address + contacts + thirdParty stub 2018-07-25 17:25:38 +02:00
Sebastiaan Pasma
79d6b4d7ad
confirm screen: display address + back button logic in origin/destination screens 2018-07-25 16:05:07 +02:00
Sebastiaan Pasma
75edb62799
removed capitalized-class 2018-07-25 15:24:44 +02:00
Sebastiaan Pasma
d51ab2bf79
only change button color if it contains an address 2018-07-25 15:11:14 +02:00
Sebastiaan Pasma
b88329fbb3
removed unused vars + changes for wallet to wallet transfer 2018-07-25 15:07:15 +02:00
Sebastiaan Pasma
4093e2ba71
refactored the sendFlowController 2018-07-25 11:26:33 +02:00
Jean-Baptiste Dominguez
029ac7dd39 Fix the QRCode scan. 2018-07-25 16:26:06 +09:00
Jean-Baptiste Dominguez
bba85794ac BitAnalytics 0.2.1 with GA 2018-07-25 16:17:42 +09:00
Brendon Duncan
91dac0f54c Refactored Enter Amount controller to follow latest Angular 1 guidelines. 2018-07-24 12:37:51 -07:00
Sebastiaan Pasma
fd4adbfb57
wallet to wallet case worked out. Also fixed routes and some css 2018-07-24 14:24:22 +02:00
Sam Cheng Hung
4b18e4b1c3 Adds expand-content component, update various UI measurements 2018-07-24 15:27:21 +08:00
Sebastiaan Pasma
84ef395100
qr code added to request payment (and also working on smaller qrs, for iPhone 5/SE) 2018-07-24 07:36:03 +02:00
Brendon Duncan
7dd1d4048b Correction of typo in last commit. 2018-07-23 12:18:06 -07:00
Brendon Duncan
ac91282c13 Indicative change for view. 2018-07-23 12:02:04 -07:00
Sebastiaan Pasma
3604ee3c3c
routes, renames and flow 2018-07-23 16:58:32 +02:00
Sebastiaan Pasma
7aecd2306f
comments & show wallets 2018-07-23 14:48:25 +02:00
Sebastiaan Pasma
893dbe5c6f
"has no funds" case 2018-07-23 14:20:46 +02:00
Sebastiaan Pasma
1153830d05
custom amount screen 2018-07-20 10:41:09 +02:00
Sebastiaan Pasma
713bbf71ca
currency format service + remove bottom amount in request amount screen 2018-07-20 10:06:59 +02:00
Sam Cheng Hung
6efd338f87 Adds action-minor component 2018-07-20 15:56:39 +08:00
Brendon Duncan
da853bcbf6 Placeholders for buttons. 2018-07-20 18:15:25 +12:00
Sebastiaan Pasma
3952df6343
forked the cordova media plugin to remove unused permissions 2018-07-19 17:07:30 +02:00
Sebastiaan Pasma
c3cded5cb0
wallet to wallet (sub)title 2018-07-19 15:50:09 +02:00
Sebastiaan Pasma
a0b4f10ca9
reverted IDE spacings 2018-07-19 15:43:32 +02:00
Sebastiaan Pasma
00ca5cded6
uppercase pipes 2018-07-19 15:41:06 +02:00
Sebastiaan Pasma
95faffa769
remove bold font style 2018-07-19 15:30:29 +02:00
Sebastiaan Pasma
8ddfffd56b
amount on custom amount screen 2018-07-19 15:21:27 +02:00
Sam Cheng Hung
22e93b823c Adds address component 2018-07-19 20:21:58 +08:00
Sebastiaan Pasma
442f6ba4df
currency symbol 2018-07-19 13:20:38 +02:00
Sebastiaan Pasma
700d2c8a23
currency symbol 2018-07-19 13:19:56 +02:00
Sebastiaan Pasma
b1befb1e73
wallet Details buttons 2018-07-19 13:10:25 +02:00
Sam Cheng Hung
a2f6277e7e Added content-frame, item and ion-content components, added dummy wallet interfaces 2018-07-19 17:41:02 +08:00
Sebastiaan Pasma
54478a4848
translation + faster transition 2018-07-19 10:23:10 +02:00
Sebastiaan Pasma
4f4bee27f1
Options also translatable 2018-07-19 09:59:56 +02:00
Brendon Duncan
0a96ae0dbe Added $scope.isRequestingSpecifcAmount. 2018-07-19 17:06:53 +12:00
Brendon Duncan
0076ff26e6 Currency of available funds changes when the currency of the amount is changed. 2018-07-19 16:24:24 +12:00
Brendon Duncan
19bec8a09a Fixed update of available funds text. 2018-07-19 15:34:53 +12:00
Brendon Duncan
d2d1511e61 Added some additional validation checks on wallet status. 2018-07-19 13:03:29 +12:00
Brendon Duncan
9e7566b171 Removing log statements. 2018-07-19 12:58:17 +12:00
Brendon Duncan
61f1603bbf Added $scope.availableFunds. 2018-07-19 12:52:37 +12:00
Brendon Duncan
3cedfa5146 Added $scope.fundsAreInsufficient for triggering UI. 2018-07-19 12:19:08 +12:00
Sebastiaan Pasma
047171f38e
wallet selection stub 2018-07-18 16:48:57 +02:00
Sebastiaan Pasma
46906352e5
remove "add wallet" buttons 2018-07-18 16:47:15 +02:00
Sebastiaan Pasma
450b80b03f
send/receive buttons on walletDetails + currencySymbolService 2018-07-18 16:30:54 +02:00
Sebastiaan Pasma
b8bab036e6
wallet to wallet transfer views + css 2018-07-18 11:54:41 +02:00
Sebastiaan Pasma
8c124fba19
price display translation 2018-07-18 11:29:03 +02:00
Sam Cheng Hung
155ea281d8 Adds header component 2018-07-18 17:24:13 +08:00
Sam Cheng Hung
8a0575d238 Add empty view and controller for review transaction route 2018-07-18 16:41:52 +08:00
Brendon Duncan
3df2836081 Successful test with amountController, using beforeEnter. 2018-07-18 20:26:20 +12:00
Sebastiaan Pasma
8725adb959
sent-successful svg 2018-07-18 09:02:52 +02:00
Brendon Duncan
0db57f997a First successful test, instantiating an amountController. 2018-07-18 18:24:49 +12:00
Brendon Duncan
cc907251f7 Removing unused services, and making string translatable. 2018-07-18 17:20:59 +12:00
Brendon Duncan
afd560187e Merged translations.
# Conflicts:
#	i18n/po/template.pot
2018-07-18 11:01:31 +12:00
Brendon Duncan
19327f84f0 Merged wallet/sprint/20 into wallet/task/477. 2018-07-18 10:51:34 +12:00
Brendon Duncan
ef121f52fa Merged wallet/sprint20 into wallet/task/475.
# Conflicts:
#	src/js/services/bitcoincomService.js
2018-07-18 10:47:43 +12:00
Sebastiaan Pasma
a5a999958c
send/receive buttons on home page 2018-07-17 15:15:37 +02:00
Sebastiaan Pasma
6463d5df34
Merge branch 'wallet/sprint/20' into wallet/task/426 2018-07-17 13:41:09 +02:00
Sebastiaan Pasma
fb275d4b08
Merge branch 'wallet/sprint/19' into wallet/sprint/20 2018-07-17 13:39:58 +02:00
Brendon Duncan
30b847322a Added wallet ready message to template. 2018-07-17 12:33:52 +12:00
Brendon Duncan
ee09085343 Services get the new translations. 2018-07-17 11:17:20 +12:00
Brendon Duncan
63d0ed39ad Made strings in Home tab translatable for "Explore Bitcoin.com", "Services", and "Community". 2018-07-17 11:00:33 +12:00
Sebastiaan Pasma
1871992303
Use native navigator clipboard over element data clipboard function 2018-07-16 17:42:15 +02:00
Sebastiaan Pasma
236a93d69d
share transaction after sending on mobile + share explorer url on desktop. 2018-07-16 17:21:15 +02:00
Jean-Baptiste Dominguez
f9f8522119 Increment version 2018-06-06 17:56:50 +09:00
Jean-Baptiste Dominguez
d1b47bf020
Merge pull request #166 from Bitcoin-com/wallet/hotfix/372
Wallet/hotfix/372
2018-06-06 17:51:18 +09:00
176 changed files with 13361 additions and 4381 deletions

14
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/www/index.html"
}
]
}

View file

@ -8,26 +8,32 @@ module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
exec: {
get_nwjs_for_pkg: {
command: 'if [ ! -d ./cache/0.19.5-pkg/osx64/nwjs.app ]; then cd ./cache; curl https://dl.nwjs.io/v0.19.5-mas-beta/nwjs-mas-v0.19.5-osx-x64.zip --output nwjs.zip; unzip nwjs.zip; mkdir -p ./0.19.5-pkg/osx64; cp -R ./nwjs-mas-v0.19.5-osx-x64/nwjs.app ./0.19.5-pkg/osx64/; fi'
},
create_others_dist: {
command: 'sh webkitbuilds/create-others-dist.sh "<%= pkg.name %>" "<%= pkg.fullVersion %>" "<%= pkg.nameCaseNoSpace %>" "<%= pkg.title %>"'
},
create_dmg_dist: {
command: 'sh webkitbuilds/create-dmg-dist.sh "<%= pkg.name %>" "<%= pkg.fullVersion %>" "<%= pkg.nameCaseNoSpace %>" "<%= pkg.title %>"'
},
create_pkg_dist: {
command: 'sh webkitbuilds/create-pkg-dist.sh "<%= pkg.name %>" "<%= pkg.fullVersion %>" "<%= pkg.nameCaseNoSpace %>" "<%= pkg.title %>"'
},
sign_desktop_dist: {
command: 'sh webkitbuilds/sign-desktop-dist.sh "<%= pkg.name %>" "<%= pkg.fullVersion %>"'
},
appConfig: {
command: 'node ./util/buildAppConfig.js'
},
externalServices: {
command: 'node ./util/buildExternalServices.js'
android_studio: {
command: ' open -a open -a /Applications/Android\\ Studio.app platforms/android',
},
build_android_debug: {
command: 'cordova prepare android && cordova build android --debug',
},
build_android_release: {
command: 'cordova prepare android && cordova build android --release',
},
build_ios_debug: {
command: 'cordova prepare ios && cordova build ios --debug',
options: {
maxBuffer: 3200 * 1024
}
},
build_ios_release: {
command: 'cordova prepare ios && cordova build ios --release',
options: {
maxBuffer: 1600 * 1024
}
},
chrome: {
command: 'make -C chrome-app '
},
clean: {
command: 'rm -Rf bower_components node_modules'
@ -38,8 +44,38 @@ module.exports = function(grunt) {
coveralls: {
command: 'cat coverage/report-lcov/lcov.info |./node_modules/coveralls/bin/coveralls.js'
},
chrome: {
command: 'make -C chrome-app '
create_dmg_dist: {
command: 'sh webkitbuilds/create-dmg-dist.sh "<%= pkg.name %>" "<%= pkg.fullVersion %>" "<%= pkg.nameCaseNoSpace %>" "<%= pkg.title %>"'
},
create_others_dist: {
command: 'sh webkitbuilds/create-others-dist.sh "<%= pkg.name %>" "<%= pkg.fullVersion %>" "<%= pkg.nameCaseNoSpace %>" "<%= pkg.title %>"'
},
create_pkg_dist: {
command: 'sh webkitbuilds/create-pkg-dist.sh "<%= pkg.name %>" "<%= pkg.fullVersion %>" "<%= pkg.nameCaseNoSpace %>" "<%= pkg.title %>"'
},
externalServices: {
command: 'node ./util/buildExternalServices.js'
},
get_nwjs_for_pkg: {
command: 'if [ ! -d ./cache/0.19.5-pkg/osx64/nwjs.app ]; then cd ./cache; curl https://dl.nwjs.io/v0.19.5-mas-beta/nwjs-mas-v0.19.5-osx-x64.zip --output nwjs.zip; unzip nwjs.zip; mkdir -p ./0.19.5-pkg/osx64; cp -R ./nwjs-mas-v0.19.5-osx-x64/nwjs.app ./0.19.5-pkg/osx64/; fi'
},
log_android: {
command: 'adb logcat | grep chromium',
},
run_android: {
command: 'cordova run android --device',
},
run_android_emulator: {
command: 'cordova run android --emulator',
},
sign_android: {
// When the build log outputs "Built the following apk(s):", it seems to need the filename to start with "android-release".
// It looks like it simply lists all apk files starting with "android-release"
command: 'rm -f platforms/android/build/outputs/apk/android-release-signed-*.apk; jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ../bitcoin-com-release-key.jks -signedjar platforms/android/build/outputs/apk/android-release-signed.apk platforms/android/build/outputs/apk/android-release-unsigned.apk bitcoin-com && zipalign -v 4 platforms/android/build/outputs/apk/android-release-signed.apk platforms/android/build/outputs/apk/bitcoin-com-wallet-<%= pkg.fullVersion %>-android-signed-aligned.apk',
stdin: true,
},
sign_desktop_dist: {
command: 'sh webkitbuilds/sign-desktop-dist.sh "<%= pkg.name %>" "<%= pkg.fullVersion %>"'
},
wpinit: {
command: 'make -C cordova wp-init',
@ -47,40 +83,9 @@ module.exports = function(grunt) {
wpcopy: {
command: 'make -C cordova wp-copy',
},
iosdebug: {
command: 'npm run build:ios',
},
ios: {
command: 'npm run build:ios-release',
},
xcode: {
command: 'npm run open:ios',
},
androiddebug: {
command: 'npm run build:android',
},
android: {
command: 'npm run build:android-release',
},
androidrun: {
command: 'npm run run:android && npm run log:android',
},
androidbuild: {
command: 'cd cordova/project && cordova build android --release',
},
androidsign: {
command: 'rm -f cordova/project/platforms/android/build/outputs/apk/android-release-signed-aligned.apk; jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ../bitcoin-com-release-key.jks -signedjar cordova/project/platforms/android/build/outputs/apk/android-release-signed.apk cordova/project/platforms/android/build/outputs/apk/android-release-unsigned.apk bitcoin-com && ../android-sdk-macosx/build-tools/27.0.1/zipalign -v 4 cordova/project/platforms/android/build/outputs/apk/android-release-signed.apk cordova/project/platforms/android/build/outputs/apk/android-release-signed-aligned.apk ',
stdin: true,
},
desktopsign: {
cmd: 'gpg -u E0AE67E7 --output webkitbuilds/others/<%= pkg.title %>-linux.zip.sig --detach-sig webkitbuilds/others/<%= pkg.title %>-linux.zip ; gpg -u E0AE67E7 --output webkitbuilds/others/<%= pkg.title %>.exe.sig --detach-sig webkitbuilds/others/<%= pkg.title %>.exe'
},
desktopverify: {
cmd: 'gpg --verify webkitbuilds/<%= pkg.title %>-linux.zip.sig webkitbuilds/<%= pkg.title %>-linux.zip; gpg --verify webkitbuilds/<%= pkg.title %>.exe.sig webkitbuilds/<%= pkg.title %>.exe'
},
osxsign: {
cmd: 'gpg -u E0AE67E7 --output webkitbuilds/<%= pkg.title %>.dmg.sig --detach-sig webkitbuilds/<%= pkg.title %>.dmg'
},
command: 'open platforms/ios/*.xcodeproj',
}
},
watch: {
options: {
@ -163,7 +168,7 @@ module.exports = function(grunt) {
},
bitanalytics: {
src: [
'bitanalytics/bitanalytics-0.1.0.js'
'bitanalytics/bitanalytics.js'
],
dest: 'www/lib/bitanalytics.js'
},
@ -296,10 +301,10 @@ module.exports = function(grunt) {
},
pkg: {
options: {
appName: '<%= pkg.nameCaseNoSpace %>',
appName: '<%= pkg.title %>',
platforms: ['osx64'],
buildDir: './webkitbuilds/pkg',
version: '0.19.5',
version: '0.19.4',
macIcns: './resources/<%= pkg.name %>/mac/pkg/app.icns',
exeIco: './www/img/app/logo.ico',
macPlist: {
@ -348,30 +353,49 @@ module.exports = function(grunt) {
grunt.registerTask('wp', ['prod', 'exec:wp']);
grunt.registerTask('wp-copy', ['default', 'exec:wpcopy']);
grunt.registerTask('wp-init', ['default', 'exec:wpinit']);
grunt.registerTask('ios', ['exec:ios']);
grunt.registerTask('ios-debug', ['exec:iosdebug']);
grunt.registerTask('ios-run', ['exec:xcode']);
grunt.registerTask('cordovaclean', ['exec:cordovaclean']);
grunt.registerTask('android-debug', ['exec:androiddebug', 'exec:androidrun']);
grunt.registerTask('android', ['exec:android']);
grunt.registerTask('android-release', ['prod', 'exec:android', 'exec:androidsign']);
grunt.registerTask('desktopsign', ['exec:desktopsign', 'exec:desktopverify']);
// Build all
grunt.registerTask('build-app-release', ['build-mobile-release', 'build-desktop-release']);
/**
* Mobile app
*/
// Build mobile app
grunt.registerTask('build-mobile-release', ['build-ios-release', 'build-android-release']);
// Build ios
grunt.registerTask('start-ios', ['default', 'exec:build_ios_debug', 'exec:xcode']);
grunt.registerTask('build-ios-debug', ['default', 'exec:build_ios_debug']);
grunt.registerTask('build-ios-release', ['prod', 'exec:build_ios_release']);
// Build android
grunt.registerTask('start-android', ['build-android-debug', 'exec:run_android']);
grunt.registerTask('build-android-debug', ['default', 'exec:build_android_debug']);
grunt.registerTask('start-android-emulator', ['build-android-debug', 'exec:run_android_emulator']);
grunt.registerTask('build-android-release', ['prod', 'exec:build_android_release', 'sign-android']);
grunt.registerTask('sign-android', ['exec:sign_android']);
/**
* Desktop app
*/
// Build desktop
grunt.registerTask('desktop-build', ['desktop-others', 'desktop-osx-dmg', 'desktop-osx-pkg']);
grunt.registerTask('build-desktop', ['build-desktop-others', 'build-desktop-osx-dmg', 'build-desktop-osx-pkg']);
// Build desktop win64 & linux64
grunt.registerTask('desktop-others', ['prod', 'nwjs:others', 'copy:linux', 'exec:create_others_dist']);
grunt.registerTask('build-desktop-others', ['prod', 'nwjs:others', 'copy:linux', 'exec:create_others_dist']);
// Build desktop osx pkg
grunt.registerTask('desktop-osx-pkg', ['prod', 'exec:get_nwjs_for_pkg', 'nwjs:pkg', 'exec:create_pkg_dist']);
grunt.registerTask('build-desktop-osx-pkg', ['prod', 'exec:get_nwjs_for_pkg', 'nwjs:pkg', 'exec:create_pkg_dist']);
// Build desktop osx dmg
grunt.registerTask('desktop-osx-dmg', ['prod', 'nwjs:dmg', 'exec:create_dmg_dist']);
grunt.registerTask('build-desktop-osx-dmg', ['prod', 'nwjs:dmg', 'exec:create_dmg_dist']);
// Sign desktop
grunt.registerTask('desktop-sign', ['exec:sign_desktop_dist']);
grunt.registerTask('sign-desktop', ['exec:sign_desktop_dist']);
// Release desktop
grunt.registerTask('desktop-release', ['desktop-build', 'desktop-sign']);
grunt.registerTask('build-desktop-release', ['build-desktop', 'sign-desktop']);
};

View file

@ -1,3 +1,24 @@
This is a fork of the Bitcoin.com wallet to add additional features.
Features included:
- Zero fee transactions (only works for Bitcoin Cash). You will be asked for, if you want to send a transaction as zero fee on the confirmation page.
## Zero fee transactions:
Because most network nodes on the Bitcoin Cash network don't relay zero fee txs, you will experience some strange issues, but don't worry: for me personally the Bitcoin.com pool has included all my zero fee transactions, but please beware that the receiver probably won't see your tx before it has been confirmed and please do also keep in mind, that the transactions coming after it won't confirm or be seen before the zero fee one has been confirmed.
If you do already have a Bitcoin.com wallet, you need to create a new one to use this feature or change the wallet URL to: https://bws.freepages.dk/bws/api
## Disclaimer
Please beware this is my personal experimental project. You are more than welcome to play with it, but I don't take any responsibility of loss of funds due to errors in the code, so please make sure you made a backup before running this software.
## Builds
You can build the software yourself using the instructions below or use prebuilt binaries which can be found here (currently Windows and Linux only): https://ipfs.io/ipfs/QmR1DaS3QsDS48SzAWKUWFfmtMfJc4tgMtkSk3JFmuzewe
##
The Bitcoin.com wallet is a fork of the Copay Wallet (https://github.com/bitpay/copay).
The Bitcoin.com wallet is a secure bitcoin wallet platform for both desktop and mobile devices. It uses [Bitcore Wallet Service](https://github.com/Bitcoin-com/bitcore-wallet-service) (our fork of the [Bitpay Bitcore Wallet Service](https://github.com/bitpay/bitcore-wallet-service)) (BWS) for peer synchronization and network interfacing.
@ -113,14 +134,14 @@ npm run start:desktop
Before building the release version for a platform, run the `clean-all` command to delete any untracked files in your current working directory. (Be sure to stash any uncommited changes you've made.) This guarantees consistency across builds for the current state of this repository.
The `final` commands build the production version of the app, and bundle it with the release version of the platform being built.
The `build:*-release` commands build the production version of the app, and bundle it with the release version of the platform being built.
### Android
```sh
npm run clean-all
npm run apply:bitcoincom
npm run final:android
npm run build:android-release
```
### iOS
@ -128,7 +149,7 @@ npm run final:android
```sh
npm run clean-all
npm run apply:bitcoincom
npm run final:ios
npm run build:ios-release
```
### Desktop (Linux, macOS, and Windows)
@ -136,7 +157,7 @@ npm run final:ios
```sh
npm run clean-all
npm run apply:bitcoincom
npm run final:desktop
npm run build:desktop-release
```
## About The Bitcoin.com Wallet

View file

@ -24,9 +24,9 @@
"windowsAppId": "804636ee-b017-4cad-8719-e58ac97ffa5c",
"pushSenderId": "1036948132229",
"description": "A Secure Bitcoin Wallet",
"version": "4.13.1",
"fullVersion": "4.13-rc2",
"androidVersion": "413100",
"version": "5.1.3",
"fullVersion": "5.1-rc2",
"androidVersion": "501003",
"_extraCSS": "",
"_enabledExtensions": {
"coinbase": false,

View file

@ -268,5 +268,33 @@ div.onboarding-topic {
display: block;
float: left;
max-height: 100%;
max-width: 100%;
max-width: 100%;
}
.bitpay-banner {
background: #1A3A8B;
padding: 10px;
box-shadow: 0px 5px 10px 0px #cccccc;
height: 5em;
}
.bitpay-logo {
display: block;
max-height: 100%;
width: 100%;
height: 4em;
}
.egifter-banner {
background: #1A3A8B;
padding: 10px;
box-shadow: 0px 5px 10px 0px #cccccc;
height: 5em;
text-align: center;
}
.egifter-logo {
max-height: 100%;
max-width: 100%;
height: 4em;
}

View file

@ -72,7 +72,7 @@
<plugin name="cordova-plugin-queries-schemes" spec="~0.1.5" />
<plugin name="cordova-plugin-firebase" spec="https://github.com/arnesson/cordova-plugin-firebase.git" />
<plugin name="cordova-plugin-wkwebview-inputfocusfix" spec="https://github.com/onderceylan/cordova-plugin-wkwebview-inputfocusfix.git" />
<plugin name="cordova-plugin-media" spec="~5.0.2">
<plugin name="cordova-plugin-media-fork" spec="~5.0.3">
<variable name="KEEP_AVAUDIOSESSION_ALWAYS_ACTIVE" value="NO" />
</plugin>
<!-- Supported Platforms -->
@ -85,6 +85,12 @@
<config-file platform="ios" target="*-Info.plist" parent="UIStatusBarHidden"><true/></config-file>
<config-file platform="ios" target="*-Info.plist" parent="UIViewControllerBasedStatusBarAppearance"><false/></config-file>
<config-file target="*-Info.plist" parent="ITSAppUsesNonExemptEncryption"><false/></config-file>
<icon src="resources/*PACKAGENAME*/ios/icon/AppIcon24x24@2x.png" width="48" height="48" />
<icon src="resources/*PACKAGENAME*/ios/icon/AppIcon27.5x27.5@2x.png" width="55" height="55" />
<icon src="resources/*PACKAGENAME*/ios/icon/AppIcon44x44@2x.png" width="88" height="88" />
<icon src="resources/*PACKAGENAME*/ios/icon/AppIcon86x86@2x.png" width="172" height="172" />
<icon src="resources/*PACKAGENAME*/ios/icon/AppIcon98x98@2x.png" width="196" height="196" />
<icon src="resources/*PACKAGENAME*/ios/icon/icon-20.png" width="20" height="20" />
<icon src="resources/*PACKAGENAME*/ios/icon/icon-60@3x.png" width="180" height="180" />
<icon src="resources/*PACKAGENAME*/ios/icon/icon-60.png" width="60" height="60" />
<icon src="resources/*PACKAGENAME*/ios/icon/icon-60@2x.png" width="120" height="120" />
@ -102,6 +108,7 @@
<icon src="resources/*PACKAGENAME*/ios/icon/icon-small@3x.png" width="87" height="87" />
<icon src="resources/*PACKAGENAME*/ios/icon/icon-50.png" width="50" height="50" />
<icon src="resources/*PACKAGENAME*/ios/icon/icon-50@2x.png" width="100" height="100" />
<icon src="resources/*PACKAGENAME*/ios/icon/icon-1024.png" width="1024" height="1024" />
<splash src="resources/*PACKAGENAME*/ios/splash/Default~iphone.png" width="320" height="480"/>
<splash src="resources/*PACKAGENAME*/ios/splash/Default@2x~iphone.png" width="640" height="960"/>

View file

@ -24,8 +24,9 @@ ln -s ../resources/bitcoin.com/mac/pkg/build.cfg build.cfg
rm build_mas.py
ln -s ../resources/bitcoin.com/mac/pkg/build_mas.py build_mas.py
echo "Signing ${APP_NAME}"
export APP_PATH="pkg/${APP_NAME}/osx64/${APP_NAME}"
echo "Signing ${APP_FULLNAME}"
export CURRENT_PATH=`pwd`
export APP_PATH="pkg/${APP_FULLNAME}/osx64/${APP_FULLNAME}"
export TMP_PATH="tmp"
export DIST_PATH="dist"
@ -36,10 +37,16 @@ if [ ! -d $DIST_PATH ]; then
mkdir $DIST_PATH
fi
python build_mas.py -C build.cfg -O "${TMP_PATH}/${APP_NAME}.app" -I "${APP_PATH}.app" -P "$DIST_PATH/${APP_PACKAGE}-wallet-${APP_VERSION}-osx.pkg"
cd "${APP_PATH}.app/Contents/Versions"
ln -s "55.0.2883.87" "Current"
cd $CURRENT_PATH
chmod -vR 777 "${APP_PATH}.app/Contents"
python build_mas.py -C build.cfg -O "${TMP_PATH}/${APP_FULLNAME}.app" -I "${APP_PATH}.app" -P "$DIST_PATH/${APP_PACKAGE}-wallet-${APP_VERSION}-osx.pkg"
echo "Signing Done"
echo "Done."
exit
exit

View file

@ -87,46 +87,53 @@
"bitcoincashjs-fork": "^1.0.3"
},
"scripts": {
"postinstall": "bower install",
"start": "npm run build:www && ionic serve --nolivereload --nogulp -s --address 0.0.0.0",
"start:chrome": "npm run build:www && ionic serve --nolivereload --nogulp -s --address 0.0.0.0 --browser \"google chrome\"",
"start:ios": "npm run build:www && npm run build:ios && npm run open:ios",
"start:android": "npm run build:www && npm run build:android && npm run run:android",
"start:windows": "npm run build:www && npm run build:windows",
"start:desktop": "npm start",
"watch": "grunt watch",
"apply:bitcoincom": "npm i fs-extra && cd app-template && node apply.js bitcoincom && npm i && cordova prepare && cd ../ && ./fix-asn1.sh",
"build:app-release": "grunt build-app-release",
"build:mobile-release": "grunt build-mobile-release",
"build:desktop-release": "grunt build-desktop-release",
"build:android-debug": "grunt build-android-debug",
"build:android-release": "grunt build-android-release",
"build:ios-debug": "grunt build-ios-debug",
"build:ios-release": "grunt build-ios-release",
"build:desktop": "grunt build-desktop",
"build:osx-pkg": "grunt build-desktop-osx-pkg",
"build:osx-dmg": "grunt build-desktop-osx-dmg",
"build:others": "grunt build-desktop-others",
"build:windows": "cordova prepare windows && cordova build windows -- --arch=\"ARM\"",
"build:windows-release": "cordova prepare windows && cordova build windows --release --arch=\"ARM\"",
"build:www": "grunt",
"build:www-release": "grunt prod",
"build:ios": "cordova prepare ios && cordova build ios --debug",
"build:android": "cordova prepare android && cordova build android --debug",
"build:windows": "cordova prepare windows && cordova build windows -- --arch=\"ARM\"",
"build:ios-release": "cordova prepare ios && cordova build ios --release",
"build:android-release": "cordova prepare android && cordova build android --release",
"build:windows-release": "cordova prepare windows && cordova build windows --release --arch=\"ARM\"",
"build:desktop-release": "grunt desktop-release",
"build:desktop": "grunt desktop-build",
"build:osx-pkg": "grunt desktop-osx-pkg",
"build:osx-dmg": "grunt desktop-osx-dmg",
"build:others": "grunt desktop-others",
"sign:desktop": "grunt desktop-sign",
"open:ios": "open platforms/ios/*.xcodeproj",
"open:android": "open -a open -a /Applications/Android\\ Studio.app platforms/android",
"final:www": "npm run build:www-release",
"final:ios": "npm run final:www && npm run build:ios-release && npm run open:ios",
"final:android": "npm run final:www && npm run build:android-release && npm run sign:android && npm run run:android-release",
"final:windows": "npm run final:www && npm run build:windows-release",
"final:desktop": "npm run final:www && npm run build:desktop-release",
"run:android": "cordova run android --device",
"run:android-release": "cordova run android --device --release",
"log:android": "adb logcat | grep chromium",
"sign:android": "rm -f platforms/android/build/outputs/apk/android-release-signed-aligned.apk; jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ../bitcoin-com-release-key.jks -signedjar platforms/android/build/outputs/apk/android-release-signed.apk platforms/android/build/outputs/apk/android-release-unsigned.apk bitcoin-com && $ANDROID_HOME/build-tools/27.0.1/zipalign -v 4 platforms/android/build/outputs/apk/android-release-signed.apk platforms/android/build/outputs/apk/android-release-signed-aligned.apk",
"apply:copay": "npm i fs-extra && cd app-template && node apply.js copay && npm i && cordova prepare",
"apply:bitpay": "npm i fs-extra && cd app-template && node apply.js bitpay && npm i && cordova prepare",
"apply:bitcoincom": "npm i fs-extra && cd app-template && node apply.js bitcoincom && npm i && cordova prepare",
"test": "karma start test/karma.conf.js --single-run",
"clean": "trash platforms && trash plugins && cordova prepare",
"clean-all": "git clean -dfx",
"log:android": "adb logcat | grep chromium",
"open:android": "grunt exec:android_studio",
"open:ios": "grunt exec:xcode",
"postinstall": "bower install",
"sign:android": "grunt sign-android",
"sign:desktop": "grunt sign-desktop",
"start": "npm run build:www && ionic serve --nolivereload --nogulp -s --address 0.0.0.0",
"start:chrome": "npm run build:www && ionic serve --nolivereload --nogulp -s --address 0.0.0.0 --browser \"google chrome\"",
"start:android": "grunt start-android",
"start:android-emulator": "grunt start-android",
"start:android-log": "grunt start-android && npm run log:android",
"start:ios": "grunt start-ios",
"start:windows": "npm run build:www && npm run build:windows",
"test": "karma start test/karma.conf.js --single-run",
"unstage-package": "git reset package.json",
"clean-all": "git clean -dfx"
"watch": "grunt watch"
},
"devDependencies": {
"cordova": "^6.3.1",
@ -141,4 +148,4 @@
"pre-commit": "^1.1.3"
},
"pre-commit": "unstage-package"
}
}

View file

@ -6256,7 +6256,6 @@ var ClickAction = /** @class */ (function (_super) {
// Add event listener to all the elements found
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
console.log('init ' + this.name);
element.addEventListener('click', this.listener);
}
};
@ -6276,7 +6275,7 @@ var ClickAction = /** @class */ (function (_super) {
}(action_1.default));
exports.default = ClickAction;
},{"../action":4,"../log-event":15,"../log-event-handlers":14}],6:[function(require,module,exports){
},{"../action":4,"../log-event":16,"../log-event-handlers":15}],6:[function(require,module,exports){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
@ -6315,7 +6314,7 @@ var BitAnalytics = /** @class */ (function () {
exports.default = BitAnalytics;
BitAnalytics.main();
},{"./action-factory":2,"./action-handlers":3,"./channels/adjust-channel":9,"./channels/mixpanel-channel":12,"./log-event":15,"./log-event-handlers":14}],7:[function(require,module,exports){
},{"./action-factory":2,"./action-handlers":3,"./channels/adjust-channel":9,"./channels/mixpanel-channel":12,"./log-event":16,"./log-event-handlers":15}],7:[function(require,module,exports){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
@ -6413,7 +6412,6 @@ var AdjustChannel = /** @class */ (function (_super) {
_this.eventTypes = config.eventTypes;
var os = _this.adjustedOs(config.os);
_this.advertisingId = _this.getAdvertisingId(os);
console.log('Advertising ID for adjust: ' + _this.advertisingId);
// TODO: Different initialisation for Cordova.
var sessionParams = {
app_version: config.appVersion,
@ -6560,11 +6558,10 @@ var FirebaseChannel = /** @class */ (function (_super) {
var keys = Object.keys(params);
var keysLength = keys.length;
var sanitized = {};
for (var i = 0; i < keysLength; i++) {
var key = keys[i];
keys.map(function (key) {
var cleanKey = key.replace('-', '_').replace(/[\W]+/g, '');
sanitized[cleanKey] = params[key];
}
});
return sanitized;
};
return FirebaseChannel;
@ -6588,13 +6585,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
var channel_1 = __importDefault(require("../channel"));
var ga_1 = __importDefault(require("../external-libs/ga"));
var GoogleAnalyticsChannel = /** @class */ (function (_super) {
__extends(GoogleAnalyticsChannel, _super);
function GoogleAnalyticsChannel(name, config) {
var _this = _super.call(this, name) || this;
_this.dataLayer = null;
_this.gaInstance = null;
_this.trackingId = '';
_this.eventLabels = ['id'];
if (!config.trackingId) {
throw new Error('[BitAnalytics] Google Analytics config is missing tracking ID.');
@ -6602,8 +6598,12 @@ var GoogleAnalyticsChannel = /** @class */ (function (_super) {
if (config.eventLabels) {
_this.eventLabels = config.eventLabels;
}
_this.trackingId = config.trackingId;
_this.setUpGa();
_this.gaInstance = new ga_1.default({
trackID: config.trackingId,
appVersion: config.appVersion,
appName: config.appName || 'App'
});
_this.isReady = true;
return _this;
}
/**
@ -6612,49 +6612,26 @@ var GoogleAnalyticsChannel = /** @class */ (function (_super) {
*
*/
GoogleAnalyticsChannel.prototype.postEvent = function (name, params) {
// Default Google Analytics Events
// https://developers.google.com/analytics/devguides/collection/gtagjs/events
// Useful to convert to these, or start with these?
if (this.isReady) {
params.event_category = name;
var category = name;
var action = name;
var label = name;
var value = params['value'] || '';
for (var _i = 0, _a = this.eventLabels; _i < _a.length; _i++) {
var eventLabel = _a[_i];
if (params[eventLabel]) {
params.event_label = params[eventLabel];
label = params[eventLabel];
break;
}
}
this.gtag('event', name, params);
this.gaInstance.event(category, action, label, value);
}
};
/**
*
* Private methods
*
*/
/**
* Mimics function in the tracking snippet
*/
GoogleAnalyticsChannel.prototype.gtag = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
console.log(arguments);
window.dataLayer.push(arguments);
};
GoogleAnalyticsChannel.prototype.setUpGa = function () {
// From what GA recommends to insert into page
window.dataLayer = window.dataLayer || [];
this.gtag('js', new Date());
this.gtag('config', this.trackingId);
this.isReady = true;
};
return GoogleAnalyticsChannel;
}(channel_1.default));
exports.default = GoogleAnalyticsChannel;
},{"../channel":8}],12:[function(require,module,exports){
},{"../channel":8,"../external-libs/ga":14}],12:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
@ -6677,7 +6654,7 @@ var MixpanelChannel = /** @class */ (function (_super) {
function MixpanelChannel(name, config) {
var _this = _super.call(this, name) || this;
if (!config.token) {
throw new DOMException('[BitAnalytics] Config incorrect.');
throw new Error('[BitAnalytics] Config incorrect.');
}
_this.mixpanelInstance = mixpanel;
mixpanel.init(config.token, config.config);
@ -6746,6 +6723,207 @@ exports.default = MixpanelChannel;
},{}],14:[function(require,module,exports){
"use strict";
/*
* name: nwjs-analytics -Node-Webkit Google Analytics integration
* version: 1.0.2
* github: https://github.com/Daaru00/nwjs-analytics
*/
function GA(opt) {
this.apiVersion = opt.apiVersion || '1';
this.trackID = opt.trackID || 'UA-XXXXXXXX-X';
this.clientID = opt.clientID || null;
this.userID = opt.userID || null;
this.appName = opt.appName || 'App';
this.appVersion = opt.appVersion || '1.0.0';
this.debug = opt.debug || false;
this.performanceTracking = opt.performanceTracking || true;
this.errorTracking = opt.errorTracking || true;
this.userLanguage = opt.userLanguage || "en";
this.currency = opt.currency || "EUR";
this.lastScreenName = opt.lastScreenName || '';
}
GA.prototype.sendRequest = function (data, callback) {
var ga = this;
if (!this.clientID || this.clientID == null)
this.clientID = this.generateClientID();
if (!this.userID || this.userID == null)
this.userID = this.generateClientID();
var postData = "v=" + this.apiVersion
+ "&an=" + this.appName
+ "&av=" + this.appVersion
+ "&tid=" + this.trackID
+ "&cid=" + this.clientID
+ "&sr=" + this.getScreenResolution()
+ "&vp=" + this.getViewportSize();
Object.keys(data).forEach(function (key) {
var val = data[key];
if (typeof val != "undefined")
postData += "&" + key + "=" + val;
});
var http = new XMLHttpRequest();
var url = "https://www.google-analytics.com";
if (!this.debug)
url += "/collect";
else
url += "/debug/collect";
http.open("GET", url + "?" + postData, true);
http.onreadystatechange = function () {
if (ga.debug)
console.log(http.response);
if (http.readyState == 4 && http.status == 200) {
if (callback)
callback(true);
}
else {
if (callback)
callback(false);
}
};
http.send();
};
GA.prototype.generateClientID = function () {
var id = "";
var possibilities = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 5; i++)
id += possibilities.charAt(Math.floor(Math.random() * possibilities.length));
return id;
};
GA.prototype.getScreenResolution = function () {
return screen.width + "x" + screen.height;
};
GA.prototype.getColorDept = function () {
return screen.colorDepth + "-bits";
};
GA.prototype.getUserAgent = function () {
return navigator.userAgent;
};
GA.prototype.getViewportSize = function () {
return window.screen.availWidth + "x" + window.screen.availHeight;
};
/*
* Measurement Protocol
* [https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide]
*/
GA.prototype.screenView = function (screename) {
var data = {
't': 'screenview',
'cd': screename
};
this.sendRequest(data);
this.lastScreenName = screename;
};
GA.prototype.event = function (category, action, label, value) {
var data = {
't': 'event',
'ec': category,
'ea': action,
};
if (label) {
data['el'] = label;
}
if (value) {
data['ev'] = value;
}
if (this.lastScreenName) {
data['cd'] = this.lastScreenName;
}
this.sendRequest(data);
};
GA.prototype.exception = function (msg, fatal) {
var data = {
't': 'exception',
'exd': msg,
'exf': fatal || 0
};
this.sendRequest(data);
};
GA.prototype.timing = function (category, variable, time, label) {
var data = {
't': 'timing',
'utc': category,
'utv': variable,
'utt': time,
'utl': label,
};
this.sendRequest(data);
},
GA.prototype.ecommerce = {
transactionID: false,
generateTransactionID: function () {
var id = "";
var possibilities = "0123456789";
for (var i = 0; i < 5; i++)
id += possibilities.charAt(Math.floor(Math.random() * possibilities.length));
return id;
},
transaction: function (total, items) {
var t_id = "";
if (!this.ecommerce.transactionID)
t_id = this.ecommerce.generateTransactionID();
else
t_id = this.ecommerce.transactionID;
var data = {
't': 'transaction',
'ti': t_id,
'tr': total,
'cu': this.currency,
};
this.sendRequest(data);
items.forEach(function (item) {
var data = {
't': 'item',
'ti': t_id,
'in': item.name,
'ip': item.price,
'iq': item.qty,
'ic': item.id,
'cu': this.currency
};
this.sendRequest(data);
});
}
},
GA.prototype.custom = function (data) {
this.sendRequest(data);
};
module.exports = GA;
/*
* Performance Tracking
*/
/*window.addEventListener("load", function() {
if(ga.performanceTracking) {
setTimeout(function() {
var timing = window.performance.timing;
var userTime = timing.loadEventEnd - timing.navigationStart;
ga.timing("performance", "pageload", userTime);
}, 0);
}
}, false);*/
/*
* Error Reporting
*/
/*window.onerror = function (msg, url, lineNo, columnNo, error) {
var message = [
'Message: ' + msg,
'Line: ' + lineNo,
'Column: ' + columnNo,
'Error object: ' + JSON.stringify(error)
].join(' - ');
if(ga.errorTracking)
{
setTimeout(function() {
ga.exception(message.toString());
}, 0);
}
return false;
};*/
},{}],15:[function(require,module,exports){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
@ -6857,7 +7035,7 @@ var LogEventHandlers = /** @class */ (function () {
_this.channels.push(channel);
}
catch (error) {
console.log('[BitAnalytics] ' + error.name + ': ' + error.message);
console.log(error.message);
}
});
};
@ -6865,7 +7043,7 @@ var LogEventHandlers = /** @class */ (function () {
}());
exports.default = LogEventHandlers;
},{"./channel-factory":7}],15:[function(require,module,exports){
},{"./channel-factory":7}],16:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var LogEvent = /** @class */ (function () {

View file

@ -24,6 +24,6 @@
},
"resolutions": {
"angular": "1.5.3",
"ionic": "1b7414faba"
"ionic": "eefba1331b"
}
}

11
fix-asn1.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/bash
firstLine=`awk 'NR < 2 {print}' node_modules/asn1.js-rfc5280/index.js`
if [ "$firstLine" = "try {" ]; then
echo "var asn1 = require('asn1.js');" > node_modules/asn1.js-rfc5280/index.new.js
awk 'NR > 6 {print}' node_modules/asn1.js-rfc5280/index.js >> node_modules/asn1.js-rfc5280/index.new.js
rm node_modules/asn1.js-rfc5280/index.js
mv node_modules/asn1.js-rfc5280/index.new.js node_modules/asn1.js-rfc5280/index.js
echo "node_modules/asn1.js-rfc5280/index.js fixed"
fi

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Catalan\n"
"Language: ca\n"
"PO-Revision-Date: 2018-07-27 08:43\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "Número de compte"
msgid "Instant transactions with low fees"
msgstr "Transaccions instantànies amb comissions baixes"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Fons insuficients"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Canvia de moneda"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Fons disponibles"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Utilitza tots els fons disponibles"
#: www/views/amount.html:99
msgid "Next"
msgstr "Següent"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "Comptes"
@ -206,6 +226,20 @@ msgstr "Gairebé ja estem! Repassem-ho."
msgid "Alternative Currency"
msgstr "Moneda alternativa"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "Visualització del preu"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Fiat"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Criptomoneda"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com no està disponible en aquest moment. Torneu-ho a provar més tard."
@ -486,7 +520,7 @@ msgid "Cannot Create Wallet"
msgstr "No es pot crear la cartera"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr "No us podeu unir a la mateixa cartera més d'un cop"
#: www/views/includes/bitpayCardsCard.html:2
@ -662,6 +696,7 @@ msgstr "Copayer {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "Copiat al porta-retalls"
@ -1281,6 +1316,7 @@ msgstr "Amb finalitats d'auditoria"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "Des de"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "Rebeu notícies i actualitzacions de BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "Comença"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "Comença"
@ -2168,6 +2200,10 @@ msgstr "Pagament rebutjat"
msgid "Payment Sent"
msgstr "Pagament enviat"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "Comparteix aquesta transacció"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "Pagament acceptat, però encara no emès"
@ -2185,7 +2221,7 @@ msgid "Payment details"
msgstr "Dades de pagament"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr "Sol·licitud de pagament"
#: www/views/mercadoLibreCards.html:22
@ -2358,7 +2394,7 @@ msgstr "Rep"
#: www/views/customAmount.html:44
msgid "Receive in"
msgstr "Rep a"
msgstr "Rebre en"
#: www/views/includes/walletHistory.html:24
#: www/views/tx-details.html:18
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "Enganxa l'adreça"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Transferència de cartera a cartera"
msgid "Transfer between wallets"
msgstr "Transferència entre carteres"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,10 +2668,6 @@ msgstr "Escaneja el codi QR"
msgid "Send Bitcoin faster!"
msgstr "Envia bitcoins més ràpid!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Envia bitcoins més ràpid!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Deseu adreces utilitzades freqüentment i envieu-los bitcoins d'un sol toc"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "Podeu rebre bitcoins des de qualsevol cartera o servei."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Per començar, heu de crear una cartera bitcoin i obtenir uns quants bitcoins."
@ -2891,10 +2925,15 @@ msgid "Sweep"
msgstr "Escombratge"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Escombra la cartera de paper"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "Escombra la cartera de paper"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr "S'està escombrant la cartera..."
@ -3061,6 +3100,14 @@ msgstr "Aquesta aplicació emmagatzema els vostres bitcoins amb una seguretat de
msgid "This bitcoin payment request has expired."
msgstr "Aquesta sol·licitud de pagament bitcoin ha caducat."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "El pagament venç:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "La sol·licitud de pagament ha vençut"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "Per a"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "Per començar, compreu bitcoins o compartiu la vostra adreça. Podeu rebre bitcoins de qualsevol cartera o servei."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Per començar, heu de crear una cartera bitcoin i obtenir uns quants bitcoins."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "Per {{reason}} ja heu d'haver afegit el vostre compte BitPay - {{email}}"
@ -3118,6 +3161,26 @@ msgstr "Recàrrega en curs..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "Recàrrega de {{amountStr}} a la targeta de dèbit ({{cardLastNumber}})"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "Inicia ShapeShift"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "Canvieu de BTC a BCH en minuts."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "Per iniciar el procés heu d'afegir fons a la cartera."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "El procés és ràpid i rebreu l'import canviat a la vostra cartera."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "Aquest servei el presta un tercer, ShapeShift, que cobrarà una petita comissió pel servei. Veureu la comissió abans d'iniciar la transacció."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "Explora Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Jocs de Bitcoin Cash"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "Comparteix l'aplicació de la cartera"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Notícies"
@ -3758,3 +3825,119 @@ msgstr "Bitcoin Cash gratis"
msgid "Your Bitcoin Wallets are ready!"
msgstr "Les vostres carteres bitcoin ja estan a punt!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "L'adreça no conté informació sobre la moneda. Comproveu que envieu la moneda correcta."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "Reviseu la transacció"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "Esteu enviant"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "Esteu canviant"
#: www/views/review.html:36
msgid "To:"
msgstr "Per a:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "Afegiu nota personal"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "Suggerida pel comerciant:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "Introduïu el text aquí"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "Nota personal:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "Menys d'1 cèntim"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "Aquesta factura ja no accepta pagaments"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "Envia la quantitat màxima"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "Error desconegut."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "No hi ha cap cartera de Bitcoin Cash per transferir els fons trobats."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "No s'ha trobat cap Bitcoin Cash."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "S'ha trobat Bitcoin Core:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "No hi ha cap cartera de Bitcoin Core per transferir els fons trobats."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "No s'ha trobat cap Bitcoin Core."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "L'escaneig ha fallat"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "No s'han reconegut les dades."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "No compatible"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet no és compatible."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "Obre a l'explorador web"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "Adreça no vàlida"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "No s'ha definit l'import"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "L'import és inferior al mínim"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "L'import supera el límit"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Resposta no vàlida de Shapeshift"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Czech\n"
"Language: cs\n"
"PO-Revision-Date: 2018-07-27 08:43\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -79,7 +79,27 @@ msgstr "Číslo účtu"
#: www/views/tab-home.html:61
msgid "Instant transactions with low fees"
msgstr "Okamžité transakce s nízkou platbou"
msgstr "Okamžité transakce s nízkými poplatky"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Nedostatek prostředků"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Změnit měnu"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Dostupné prostředky"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Použít všechny dostupné prostředky"
#: www/views/amount.html:99
msgid "Next"
msgstr "Další"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
@ -206,6 +226,20 @@ msgstr "Téměř hotovo! Podívejme se."
msgid "Alternative Currency"
msgstr "Alternativní měna"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "Zobrazení cen"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Nucený oběh"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Kryptoměna"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com není v této chvíli k dispozici. Zkuste to prosím později."
@ -486,8 +520,8 @@ msgid "Cannot Create Wallet"
msgstr "Není možné vytvořit peněženku"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgstr "Není možné několikrát sloučit stejnou peněženku"
msgid "Cannot join the same wallet more than once"
msgstr "Nelze se připojit vícekrát ke stejné peněžence"
#: www/views/includes/bitpayCardsCard.html:2
msgid "Cards"
@ -662,6 +696,7 @@ msgstr "Spoluplátce {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "Zkopírováno do schránky"
@ -903,7 +938,7 @@ msgstr "Mazání peněženky..."
#: src/js/services/onGoingProcess.js:28
msgid "Deleting payment proposal"
msgstr "Mázání návrhu platby"
msgstr "Mazání návrhu platby"
#: www/views/join.html:141
#: www/views/tab-create-personal.html:111
@ -957,7 +992,7 @@ msgstr "Duplikování peněženky..."
#: www/views/addresses.html:19
msgid "Each bitcoin wallet can generate billions of addresses from your 12-word backup. A new address is automatically generated and shown each time you receive a payment."
msgstr "Každá Bitcoin peněženka může z 12-ti slov zálohovací fráze vygenerovat miliardy adres. Vždy, když přijímáté platbu, je automaticky vygenerována nová adresa."
msgstr "Každá Bitcoin peněženka může z 12-ti slov zálohovací fráze vygenerovat miliardy adres. Vždy, když přijímáte platbu, je automaticky vygenerována nová adresa."
#: src/js/services/feeService.js:13
msgid "Economy"
@ -1262,7 +1297,7 @@ msgstr "Nastavení filtru"
#: src/js/services/fingerprintService.js:43
#: src/js/services/fingerprintService.js:48
msgid "Finger Scan Failed"
msgstr "Scan otisku prstu se nezdařil"
msgstr "Sken otisku prstu se nezdařil"
#: src/js/controllers/feedback/send.js:34
#: www/views/feedback/complete.html:7
@ -1281,6 +1316,7 @@ msgstr "Pro účely auditu"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "Od"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "Získávejte novinky a aktualizace z BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "Začněte"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "Začněte"
@ -1515,7 +1547,7 @@ msgstr "Je-li povoleno, budou chráněny veškeré citlivé informace (privátn
#: www/views/advancedSettings.html:23
msgid "If enabled, the Recent Transactions card - a list of transactions occuring across all wallets - will appear in the Home tab."
msgstr "Je-li povoleno, zobrazí se na kartě Domů karta Nadávné transakce - seznam posledních transakcí napříč všemi peněženkami."
msgstr "Je-li povoleno, zobrazí se na kartě Domů karta Nedávné transakce - seznam posledních transakcí napříč všemi peněženkami."
#: www/views/advancedSettings.html:14
msgid "If enabled, wallets will also try to spend unconfirmed funds. This option may cause transaction delays."
@ -1635,7 +1667,7 @@ msgstr "Neplatná odvozovací cesta"
#: src/js/controllers/copayers.js:90
msgid "Invitation to share a {{appName}} Wallet"
msgstr "Pozvání ke sdílení {{appName}} peněženky"
msgstr "Pozvánka ke sdílení {{appName}} peněženky"
#: www/views/mercadoLibreCards.html:20
#: www/views/modals/mercadolibre-card-details.html:48
@ -1660,7 +1692,7 @@ msgstr "Je vhodné vyvarovat se opakovanému použití adres - chrání to jak V
#: src/js/controllers/backup.js:76
msgid "It's important that you write your backup phrase down correctly. If something happens to your wallet, you'll need this backup to recover your money. Please review your backup and try again."
msgstr "Je důležité si správně napsat zálohovací frázi. Stane-li se něco Vaší peněžence, budete tuto zálohu potřebovat ke znovuzprístupnění peněz. Zkontrolujte prosím Vaši zálohu a zkuste to znovu."
msgstr "Je důležité si správně napsat zálohovací frázi. Stane-li se něco Vaší peněžence, budete tuto zálohu potřebovat ke zístupnění peněz. Zkontrolujte prosím Vaši zálohu a zkuste to znovu."
#: www/views/join.html:151
msgid "Join"
@ -1928,7 +1960,7 @@ msgstr "Žádné peněženky k příjmu peněz"
#: www/views/cashScan.html:15
msgid "No wallets eligible for Bitcoin Cash support"
msgstr "Žádné peněženky poporující Bitcoin Cash"
msgstr "Žádné peněženky podporující Bitcoin Cash"
#: src/js/controllers/cashScan.js:58
msgid "Non BIP44 wallet"
@ -1936,7 +1968,7 @@ msgstr "Jiná než BIP44 peněženka"
#: www/views/cashScan.html:46
msgid "Non eligible BTC wallets"
msgstr "Peněženky nezpůsobilé k BTC"
msgstr "Peněženky nezpůsobilé pro BTC"
#: src/js/services/feeService.js:12
msgid "Normal"
@ -2168,6 +2200,10 @@ msgstr "Platba odmítnuta"
msgid "Payment Sent"
msgstr "Platba odeslána"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "Sdílet tuto transakci"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "Platba přijata, ale zatím nerozeslána"
@ -2185,7 +2221,7 @@ msgid "Payment details"
msgstr "Detaily platby"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr "Žádost o platbu"
#: www/views/mercadoLibreCards.html:22
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "Vložit adresu"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Převod mezi peněženkami"
msgid "Transfer between wallets"
msgstr "Přenos mezi peněženkami"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,10 +2668,6 @@ msgstr "Skenovat QR kód"
msgid "Send Bitcoin faster!"
msgstr "Odesílejte Bitcoin rychleji!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Odesílejte Bitcoin rychleji!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Uložte si často používané adresy a posílejte jim Bitcoin jedním kliknutím"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "Můžete přijímat Bitcoin z jakékoliv peněženky nebo služby."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Chcete-li začít, budete muset vytvořit Bitcoin peněženku a Bitcoin získat."
@ -2891,10 +2925,15 @@ msgid "Sweep"
msgstr "Sweep"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Sweep papírové peněženky"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "Sweep papírové peněženky"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr "Probíhá sweep peněženky..."
@ -3061,6 +3100,14 @@ msgstr "Tato aplikace k držení Vašich Bitcoinů používá nejmodernější z
msgid "This bitcoin payment request has expired."
msgstr "Tato platba vypršela."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "Platba vyprší:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "Platnost žádosti o platbu vypršela"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "Na"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "Chcete-li začít, nakupte Bitcoin nebo sdílejte svou adresu. Můžete přijímat Bitcoin z jakékoliv jiné peněženky nebo služby."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Chcete-li začít, budete potřebovat vytvořit Bitcoin peněženku a získat Bitcoin."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "Pro {{reason}} musíte nejprve přidat Váš účet BitPay - {{email}}"
@ -3118,6 +3161,26 @@ msgstr "Navyšování v průběhu..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "Navýšit debetní kartu ({{cardLastNumber}}) o {{amountStr}}"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "Spustit ShapeShift"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "Vyměňte BTC za BCH za několik minut."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "Ke spuštění procesu musíte do peněženky přidat prostředky."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "Tento proces je rychlý a vyměněnou částku dostanete do peněženky."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "Tuto službu poskytuje nezávislý poskytovatel ShapeShift, který za službu účtuje malý poplatek. Poplatek se zobrazí před spuštěním transakce."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3302,7 +3365,7 @@ msgstr "Upozornění: Soukromý klíč této peněženky není k dispozici. Expo
#: www/views/modals/paypro.html:42
msgid "WARNING: UNTRUSTED CERTIFICATE"
msgstr "Upozornění: Nedůveryhodný certifikát"
msgstr "Upozornění: Nedůvěryhodný certifikát"
#: src/js/services/onGoingProcess.js:15
msgid "Waiting for Ledger..."
@ -3550,7 +3613,7 @@ msgstr "Zálohu můžete vytvořit později v nastavení peněženky."
#: src/js/controllers/preferencesLanguage.js:12
msgid "You can make contributions by signing up on our Crowdin community translation website. Were looking forward to hearing from you!"
msgstr "Můžete přispívat příhlášením k webovým stránkám Crowdin komunity pro překlady. Těšíme se na Váše příspěvky!"
msgstr "Můžete přispívat přihlášením k webovým stránkám Crowdin komunity pro překlady. Těšíme se na Vaše příspěvky!"
#: www/views/tab-scan.html:16
msgid "You can scan bitcoin addresses, payment requests, paper wallets, and more."
@ -3734,6 +3797,10 @@ msgstr "Prohlédnout Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash hry"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "Sdílet aplikaci peněženky"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Novinky"
@ -3758,3 +3825,119 @@ msgstr "Bitcoin Cash zdarma"
msgid "Your Bitcoin Wallets are ready!"
msgstr "Vaše Bitcoin peněženka je připravena!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "Adresa neobsahuje žádné údaje o měně. Zkontrolujte, zda posíláte správnou měnu."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "Zkontrolovat transakci"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "Posíláte"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "Vyměňujete"
#: www/views/review.html:36
msgid "To:"
msgstr "Příjemce:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "Přidat osobní poznámku"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "Doporučeno obchodníkem:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "Sem zadejte text"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "Osobní poznámka:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "Méně než 1 koruna"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "Tato faktura již nepřijímá platby"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "Odeslat maximální částku"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "Neznámá chyba."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "Žádná Bitcoin Cash peněženka pro transfer nalezených prostředků."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "Žádný Bitcoin Cash nenalezen."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Nalezen Bitcoin Core:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "Žádná Bitcoin Core peněženka pro transfer nalezených prostředků."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "Žádný Bitcoin Core nenalezen."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "Sken selhal"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "Data nebyla rozpoznána."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "Nepodporováno"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet není podporován."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "Otevřít ve webovém prohlížeči"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "Neplatná adresa"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "Částka nedefinována"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "Nižší než minimální částka"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "Nadlimitní částka"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Neplatná odpověď z Shapeshift"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: German\n"
"Language: de\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "Kontonummer"
msgid "Instant transactions with low fees"
msgstr "Sofortige Transaktionen mit niedrigen Gebühren"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Unzureichende Geldmittel"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Währung ändern"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Verfügbare Mittel"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Alle zur Verfügung stehenden Mittel verwenden"
#: www/views/amount.html:99
msgid "Next"
msgstr "Weiter"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "Konten"
@ -206,6 +226,20 @@ msgstr "Fast fertig! Fassen wir zusammen."
msgid "Alternative Currency"
msgstr "Alternative Währung"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "Preisanzeige"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Fiat"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Kryptowährung"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com ist zurzeit nicht verfügbar. Bitte versuchen Sie es später nochmal."
@ -486,7 +520,7 @@ msgid "Cannot Create Wallet"
msgstr "Wallet kann nicht erstellt werden"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr "An einem Wallet kann nicht mehrfach teilgenommen werden"
#: www/views/includes/bitpayCardsCard.html:2
@ -662,6 +696,7 @@ msgstr "Copayer {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "In die Zwischenablage kopiert"
@ -1281,6 +1316,7 @@ msgstr "Zur Kontrolle"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "Von"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "Erhalten Sie Neuigkeiten und Aktualisierungen von BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "Loslegen"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "Los gehts"
@ -1597,7 +1629,7 @@ msgstr "Unzureichende bestätigte Mittel"
#: src/js/controllers/topup.js:177
#: src/js/services/bwcError.js:71
msgid "Insufficient funds for fee"
msgstr "Nicht ausreichendes Guthaben für die Gebühr"
msgstr "Unzureichendes Guthaben für die Gebühr"
#: www/views/tab-settings.html:123
msgid "Integrations"
@ -2168,6 +2200,10 @@ msgstr "Zahlung abgelehnt"
msgid "Payment Sent"
msgstr "Zahlung gesendet"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "Diese Transaktion teilen"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "Zahlung akzeptiert, aber noch nicht übermittelt"
@ -2185,7 +2221,7 @@ msgid "Payment details"
msgstr "Zahlungsdetails"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr "Zahlungsanforderung"
#: www/views/mercadoLibreCards.html:22
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "Adresse einfügen"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Wallet-zu-Wallet-Überweisung"
msgid "Transfer between wallets"
msgstr "Transfer zwischen Wallets"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,10 +2668,6 @@ msgstr "QR-Code scannen"
msgid "Send Bitcoin faster!"
msgstr "Versenden Sie Bitcoin schneller!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Versenden Sie Bitcoin schneller!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Speichern Sie häufig verwendete Adressen und senden Sie ihnen Bitcoin mit nur einem Tippen"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "Sie können Bitcoin von jeder Wallet oder jedem Dienst erhalten."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Um loszulegen müssen Sie eine Bitcoin-Wallet erstellen und einige Bitcoins erhalten."
@ -2891,10 +2925,15 @@ msgid "Sweep"
msgstr "Leeren"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Paperwallet löschen"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "Paperwallet löschen"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr "Leere Wallet..."
@ -3061,6 +3100,14 @@ msgstr "Diese App speichert Ihre Bitcoins mit modernster Sicherheit."
msgid "This bitcoin payment request has expired."
msgstr "Diese Bitcoin Zahlungsaufforderung ist abgelaufen."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "Zahlung läuft ab:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "Zahlungsaufforderung ist abgelaufen"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "An"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "Um loszulegen kaufe Bitcoins oder teilen Sie ihre Adresse. Sie können Bitcoins von jeder beliebigen Wallet oder von einem Dienstleister/Broker empfangen."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Um loszulegen müssen Sie eine Bitcoin-Wallet erstellen und einige Bitcoins erhalten."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "Zum {{reason}} müssen Sie erst Ihr BitPay-Konto hinzufügen - {{email}}"
@ -3118,6 +3161,26 @@ msgstr "Aufladung in Bearbeitung..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "Laden sie {{amountStr}} auf die Debitkarte ({{cardLastNumber}}) auf"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "ShapeShift starten"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "Tauschen Sie ihre BTC in Minuten zu BCH um."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "Sie müssen Mittel in Ihre Wallet hinzufügen, um den Vorgang zu starten."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "Der Vorgang ist kurz und Sie werden den getauschten Betrag in Ihre Wallet erhalten."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "Diese Dienstleistung wird von dem Drittanbieter Shapeshift angeboten, welcher eine kleine Dienstgebühr berechnet. Diese Gebühr wird angezeigt, bevor Sie die Transaktion starten."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "Erkunden Sie Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash Spiele"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "Die Wallet-App teilen"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Neuigkeiten"
@ -3758,3 +3825,119 @@ msgstr "Kostenloses Bitcoin Cash"
msgid "Your Bitcoin Wallets are ready!"
msgstr "Ihre Bitcoin-Wallet ist fertig!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "Die Adresse enthält keine Währungsinformationen, stellen Sie bitte sicher, dass Sie die richtige Währung senden."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "Transaktion überprüfen"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "Sie senden"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "Sie tauschen"
#: www/views/review.html:36
msgid "To:"
msgstr "An:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "Persönliche Anmerkung hinzufügen"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "Vom Händler vorgeschlagen:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "Hier Text eingeben"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "Persönliche Anmerkung:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "Weniger als 1 Cent"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "Diese Rechnung akzeptiert keine Zahlungen mehr"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "Maximalen Betrag senden"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "Unbekannter Fehler."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "Keine Bitcoin Cash Wallet, zu welchem Geld verschickt werden kann, gefunden."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "Kein Bitcoin Cash gefunden."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Bitcoin Core gefunden:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "Keine Bitcoin Core Wallet, zu welchem Geld verschickt werden kann, gefunden."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "Kein Bitcoin Core gefunden."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "Scan ist fehlgeschlagen"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "Daten nicht erkannt."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "Nicht unterstützt"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet wird nicht unterstützt."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "Im Webbrowser öffnen"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "Ungültige Adresse"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "Betrag ist nicht definiert"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "Menge liegt unter dem Minimum"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "Betrag ist über dem Grenzwert"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Ungültige Antwort von Shapeshift"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Spanish\n"
"Language: es\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "Número de cuenta"
msgid "Instant transactions with low fees"
msgstr "Transacciones instantáneas con comisiones bajas"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Sin fondos suficientes"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Cambiar moneda"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Fondos disponibles"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Usar todos los fondos"
#: www/views/amount.html:99
msgid "Next"
msgstr "Siguiente"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "Cuentas"
@ -206,6 +226,20 @@ msgstr "¡Casi listo! Vamos a revisar."
msgid "Alternative Currency"
msgstr "Moneda Alternativa"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "Muestra de precio"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Fiat"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Criptomoneda"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com no está disponible en este momento. Inténtalo de nuevo más tarde."
@ -486,7 +520,7 @@ msgid "Cannot Create Wallet"
msgstr "No se pudo crear la billetera"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr "No puede unirse a la misma billetera más de una vez"
#: www/views/includes/bitpayCardsCard.html:2
@ -662,6 +696,7 @@ msgstr "Co-pagador {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "Copiado al portapapeles"
@ -1281,6 +1316,7 @@ msgstr "Para propósitos de auditoría"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "Desde"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "Recibir noticias y actualizaciones de BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "Comenzar"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "Empezar"
@ -2168,6 +2200,10 @@ msgstr "Pago Rechazado"
msgid "Payment Sent"
msgstr "Pago Enviado"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "Comparte esta transacción"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "Pago aceptado, pero aún no fue enviado"
@ -2185,8 +2221,8 @@ msgid "Payment details"
msgstr "Detalles del pago"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgstr "Solicitud de pago"
msgid "Payment Request"
msgstr "Solicitar pago"
#: www/views/mercadoLibreCards.html:22
#: www/views/modals/mercadolibre-card-details.html:39
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "Pegar dirección"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Billetera a billetera"
msgid "Transfer between wallets"
msgstr "Transferir entre billeteras"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,17 +2668,13 @@ msgstr "Escanear código QR"
msgid "Send Bitcoin faster!"
msgstr "¡Envía Bitcoin más rápido!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "¡Envía Bitcoin más rápido!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Guardar las direcciones que usas frecuentemente y envía Bitcoin en un click"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Añadie tu primer contacto"
msgstr "Añade tu primer contacto"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "Puedes recibir bitcoin desde cualquier billetera o servicio."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Para empezar, necesitarás crear una billetera y obtener bitcoins."
@ -2891,9 +2925,14 @@ msgid "Sweep"
msgstr "Importar"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Importar billetera en papel"
msgstr "Importar billetera de papel"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "Importar billetera de papel"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
@ -3061,6 +3100,14 @@ msgstr "Esta aplicación almacena tus bitcoins con seguridad avanzada."
msgid "This bitcoin payment request has expired."
msgstr "Esta solicitud de pago ha caducado."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "El pago expira en:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "El pago ha expirado"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "Para"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "Para empezar, compra bitcoin o comparte tu dirección. Puedes recibir bitcoin desde cualquier billetera o servicio."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Para empezar, necesitarás crear una billetera y obtener Bitcoins."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "Para {{reason}} primero debes agregar tu cuenta de BitPay - {{email}}"
@ -3118,6 +3161,26 @@ msgstr "Recarda en progreso..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "Recargar {{amountStr}} a la tarjeta de débito ({{cardLastNumber}})"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "Empezar ShapeShift"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "Intercambia tus BTC a BCH en minutos."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "Para iniciar el cambio necesitas añadir fondos a tu billetera."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "El proceso es rápido y recibirás la cantidad intercambiada en tu cartera."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "Este servicio es proporcionado por el tercero ShapeShift, quien cobrará una pequeña tarifa por el servicio. La tarifa se mostrará antes de empezar la transacción."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "Explora Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Juegos de Bitcoin Cash"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "Comparte esta app"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Noticias"
@ -3758,3 +3825,119 @@ msgstr "Bitcoin Cash gratis"
msgid "Your Bitcoin Wallets are ready!"
msgstr "¡Tus billeteras Bitcoin están listas!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "La dirección no contiene información sobre la criptomoneda. Por favor asegúrese de estar enviando la criptomoneda correcta."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "Revisar transacción"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "Estás enviando"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "Estás cambiando"
#: www/views/review.html:36
msgid "To:"
msgstr "Para:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "Añadir nota personal"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "Sugerido por el comerciante:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "Introduce el texto aquí"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "Nota personal:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "Menos de 1 centavo"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "Esta factura ya no está aceptando pagos"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "Enviar cantidad máxima"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "Error desconocido."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "No se encontró billetera BCH para transferir estos fondos."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "No se encontró Bitcoin Cash."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Bitcoin Core encontrado:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "No se encontró billetera BTC para transferir estos fondos."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "No se encontró Bitcoin Core."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "Falló el escaneado"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "Datos no reconocidos."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "No compatible"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet no es compatible."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "Abrir en navegador web"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "Dirección inválida"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "Cantidad no definida"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "Cantidad por debajo del mínimo"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "Cantidad por encima del límite"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Respuesta inválida de Shapeshift"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Persian\n"
"Language: fa\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "شماره حساب"
msgid "Instant transactions with low fees"
msgstr "معاملات فوری با پرداخت کم"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "موجودی ناکافی"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "تغییر ارز"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "موجودی قابل استفاده"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "استفاده از تمام موجودی در دسترس"
#: www/views/amount.html:99
msgid "Next"
msgstr "بعدی"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "حساب ها"
@ -206,6 +226,20 @@ msgstr "تقریبا به پایان رسیدیم! بیا مروری کنیم."
msgid "Alternative Currency"
msgstr "ارز دوم"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "نمایش قیمت"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "پول اعتباری"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "ارز رمزنگاری شده"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com در حال حاضر در دسترس نمی باشد، خواهشمند است در زمان دیگری امتحان کنید."
@ -486,7 +520,7 @@ msgid "Cannot Create Wallet"
msgstr "قادر به ایجاد کیف پول نیست"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr "امکان بیش از یک بار پیوستن به یک کیف پول نیست"
#: www/views/includes/bitpayCardsCard.html:2
@ -662,6 +696,7 @@ msgstr "Copayer {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "در کلیپ بورد کپی شد"
@ -1281,6 +1316,7 @@ msgstr "برای اهداف حسابرسی"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "از"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "دریافت اخبار و به روز رسانی از BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "شروع کنید"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "شروع کنید"
@ -2168,6 +2200,10 @@ msgstr "پرداخت رد شد"
msgid "Payment Sent"
msgstr "پرداخت ارسال شد"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "به اشتراک گذاشتن این معامله"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "پرداخت پذیرفته شده اما هنوز پخش نشده"
@ -2185,7 +2221,7 @@ msgid "Payment details"
msgstr "جزئیات پرداخت"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr "درخواست پرداخت"
#: www/views/mercadoLibreCards.html:22
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "جای گذاری آدرس"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "انتقال پول از کیف پول به کیف پول"
msgid "Transfer between wallets"
msgstr "انتقال بین کیف پول ها"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,10 +2668,6 @@ msgstr "اسکن کد QR"
msgid "Send Bitcoin faster!"
msgstr "ارسال سریع تر بیت کوین!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "ارسال سریع تر بیت کوین!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "ذخیره آدرس های اغلب استفاده شده و ارسال بیت کوین به آنها تنها با یک ضربه"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "شما می توانید از هر کیف پول و یا خدمات بیت کوین دریافت کنید."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "برای شروع، شما نیاز دارید که یک کیف پول ایجاد کنید و مقداری بیتکوین تهیه کنید."
@ -2891,9 +2925,14 @@ msgid "Sweep"
msgstr "وارد کردن و تغییر آدرس به جدید(sweep)"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "وارد کردن والت کاغذی و تغییر آدرس به جدید(sweep)"
msgstr "جاروب کردن کیف پول کاغذی"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "جاروب کردن کیف پول کاغذی"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
@ -3061,6 +3100,14 @@ msgstr "این نرم افزار بیتکوین های شما را با بالا
msgid "This bitcoin payment request has expired."
msgstr "این درخواست پرداخت بیتکوین منقضی شده است."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "زمان انقضای پرداخت:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "درخواست پرداخت منقضی شده است"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "به"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "برای شروع، بیتکوین بخرید و یا آدرس خود را به اشتراک بگذارید. شما می توانید از هر کیف پول یا سرویسی بیتکوین دریافت کنید."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "برای شروع، شما نیاز دارید که یک کیف پول بیت کوین ایجاد کرده و مقداری بیت کوین تهیه کنید."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "برای انجام {{reason}} شما ابتدا باید حساب - {{email}} BitPay خود را اضافه کنید"
@ -3118,6 +3161,26 @@ msgstr "در حال پردازش انتقال به صورت Top Up..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "در حال انتقال {{amountStr}} به صورت Top Up به کارت اعتباری {{cardLastNumber}}"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "راه اندازی ShapeShift"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "تبدیل BTC به BCH خود طرف چند دقیقه."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "برای شروع فرایند باید به موجودی کیف پول خود اضافه کنید."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "فرایند سریع است و شما مقدار ارز تبدیل شده را در کیف پول خود دریافت خواهید کرد."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "این سرویس توسط همکار ما ShapeShift به عنوان یک طرف سوم انجام می شود و هزینه ای اندک برای آن دریافت می کند. قبل از شروع تراکنش هزینه نشان داده می شود."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "کاوش Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash Games"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "اشتراک گذاری نرم افزار کیف پول"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "اخبار"
@ -3758,3 +3825,119 @@ msgstr "رایگان Bitcoin Cash"
msgid "Your Bitcoin Wallets are ready!"
msgstr "کیف پول بیت کوین شما آماده است!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "آدرس شامل اطلاعات ارز نیست. از ارسال ارز صحیح اطمینان حاصل کنید."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "بررسی تراکنش"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "مبلغ ارسالی به وسیله شما"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "مبلغ تبدیل شده"
#: www/views/review.html:36
msgid "To:"
msgstr "به:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "اضافه کردن یادداشت شخصی"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "پیشنهاد شده توسط تاجر:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "متن را اینجا وارد کنید"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "یادداشت شخصی:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "کمتر از 1 سنت"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "این صورت حساب دیگر پرداخت ها را نمی پذیرد"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "ارسال حداکثر مقدار"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "خطای ناشناخته."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "هیچ کیف پولی از نوع Bitcoin Cash برای انتقال وجه یافت نشد."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "Bitcoin Cash یافت نشد."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Bitcoin Core یافت شده:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "هیچ کیف پولی از نوع Bitcoin Core برای انتقال وجه یافت نشد."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "Bitcoin Core یافت نشد."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "اسکن انجام نشد"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "داده ها شناسایی نشد."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "پشتیبانی نشده"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet پشتیبانی نمی شود."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "آدرس"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "باز کردن در مرورگر"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "آدرس نامعتبر"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "مبلغ تعریف نشده است"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "مقدار زیر مقدار حداقل است"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "مقدار بالاتر از حد است"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "پاسخ نامعتبر از Shapeshift"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: French\n"
"Language: fr\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "Numéro de compte"
msgid "Instant transactions with low fees"
msgstr "Instant transactions with low fees"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Fonds insuffisants"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Changer de devise"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Fonds disponibles"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Utiliser tous les fonds disponibles"
#: www/views/amount.html:99
msgid "Next"
msgstr "Suivant"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "Comptes"
@ -206,6 +226,20 @@ msgstr "C'est presque terminé ! Vérifions."
msgid "Alternative Currency"
msgstr "Devise alternative"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "Affichage des prix"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Fiat"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Cryptocurrency"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com nest pas disponible pour le moment. Veuillez réessayer plus tard."
@ -486,8 +520,8 @@ msgid "Cannot Create Wallet"
msgstr "Impossible de créer le portefeuille"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgstr "Impossible de rejoindre le même portefeuille plus d'une fois"
msgid "Cannot join the same wallet more than once"
msgstr "Impossible de joindre le même portefeuille plus d'une fois"
#: www/views/includes/bitpayCardsCard.html:2
msgid "Cards"
@ -662,6 +696,7 @@ msgstr "Copayeur {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "Copié(e) dans le presse-papier"
@ -1281,6 +1316,7 @@ msgstr "À des fins de vérification"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "De"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "Obtenir les actualités et mises à jour de BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "Commencer"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "Commencez"
@ -2168,6 +2200,10 @@ msgstr "Paiement rejeté"
msgid "Payment Sent"
msgstr "Paiement envoyé"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "Partager cette transaction"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "Paiement accepté, mais pas encore diffusé"
@ -2185,7 +2221,7 @@ msgid "Payment details"
msgstr "Détails du paiement"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr "Demande de paiement"
#: www/views/mercadoLibreCards.html:22
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "Coller l'adresse"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Transfert de portefeuille à portefeuille"
msgid "Transfer between wallets"
msgstr "Transfert entre les portefeuilles"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,10 +2668,6 @@ msgstr "Numérisez le code QR"
msgid "Send Bitcoin faster!"
msgstr "Envoyez des Bitcoin plus vite !"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Envoyez des Bitcoin plus vite !"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Enregistrez les adresses fréquemment utilisées et envoyez-leurs des Bitcoins en un seul geste"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "Vous pouvez recevoir des Bitcoins de n'importe quel portefeuille ou service."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Pour commencer, vous aurez besoin de créer un portefeuille bitcoin et d'obtenir quelques bitcoins."
@ -2891,9 +2925,14 @@ msgid "Sweep"
msgstr "Balayer"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Balayer un portefeuille de papier"
msgstr "Balayer un portefeuille papier"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "Balayer un portefeuille papier"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
@ -3061,6 +3100,14 @@ msgstr "Cette appli conserve vos bitcoins avec une sécurité de pointe."
msgid "This bitcoin payment request has expired."
msgstr "Cette demande de paiement bitcoin a expiré."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "Expiration du paiement:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "La demande de paiement a expiré"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "À"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "Pour commencer, achetez des bitcoins ou partagez votre adresse. Vous pouvez recevoir des bitcoins de n'importe quel portefeuille ou service."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Pour commencer, vous aurez besoin de créer un portefeuille Bitcoin et d'obtenir quelques bitcoins."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "Pour {{reason}} vous devez d'abord ajouter votre compte BitPay - {{email}}"
@ -3118,6 +3161,26 @@ msgstr "Rechargement en cours..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "Rechargement de {{amountStr}} vers la carte de débit ({{cardLastNumber}})"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "Démarrer ShapeShift"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "Changez vos BTC en BCH en quelques minutes."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "Pour démarrer, vous devez ajouter des fonds à votre portefeuille."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "Le processus est rapide et vous recevrez le montant changé dans votre portefeuille."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "Ce service est fourni par le tiers ShapeShift, qui facturera une somme modique pour le service. Le montant sera affiché avant de démarrer la transaction."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "Explorez Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Jeux Bitcoin Cash"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "Partager lapplication Wallet"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Nouvelles"
@ -3758,3 +3825,119 @@ msgstr "Bitcoin Cash Gratuit"
msgid "Your Bitcoin Wallets are ready!"
msgstr "Vos portefeuilles bitcoin sont prêts !"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "L'adresse ne contient pas dinformations de devise, assurez-vous que vous envoyez la bonne devise."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "Vérifier la transaction"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "Vous envoyez"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "Vous changez"
#: www/views/review.html:36
msgid "To:"
msgstr "À :"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "Ajouter une note personnelle"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "Suggéré par le marchand :"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "Entrez le texte ici"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "Note personnelle :"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "Moins de 1 centime"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "Cette facture naccepte plus les paiements"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "Envoi du montant maximal"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "Erreur inconnue."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "Aucun portefeuille Bitcoin Cash auquel transférer des fonds trouvé."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "Pas de Bitcoin Cash trouvé."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Bitcoin Core trouvé :"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "Aucun portefeuille Bitcoin Core auquel transférer des fonds trouvé."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "Pas de Bitcoin Core trouvé."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "Échec de l'analyse"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "Données non reconnues."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "Non pris en charge"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet nest pas pris en charge."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "Ouvrir dans le navigateur web"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "Adresse invalide"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "Le montant nest pas défini"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "Le montant est inférieur au minimum"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "Le montant est supérieur à la limite"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Réponse de Shapeshift invalide"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Italian\n"
"Language: it\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "Numero del Conto"
msgid "Instant transactions with low fees"
msgstr "Transazioni istantanee con commissioni basse"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Fondi insufficienti"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Cambia valuta"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Fondi disponibili"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Usa tutti i fondi disponibili"
#: www/views/amount.html:99
msgid "Next"
msgstr "Avanti"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "Account"
@ -206,6 +226,20 @@ msgstr "Quasi finito! Ripassiamo."
msgid "Alternative Currency"
msgstr "Valuta alternativa"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "Visualizzazione prezzi"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Fiat"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Criptovaluta"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Ia tabella dei guadagni di Amazon.com non è disponibile al momento. Per favore riprova piu tardi."
@ -486,7 +520,7 @@ msgid "Cannot Create Wallet"
msgstr "Impossibile creare portafoglio"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr "Non è possibile aggiungere un portafoglio più di una volta"
#: www/views/includes/bitpayCardsCard.html:2
@ -662,6 +696,7 @@ msgstr "Pagatore {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "Copiato negli appunti"
@ -1281,6 +1316,7 @@ msgstr "Per finalità di controllo"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "Da"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "Ricevi notizie e aggiornamenti da BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "Per iniziare"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "Inizia"
@ -2168,6 +2200,10 @@ msgstr "Pagamento Rifiutato"
msgid "Payment Sent"
msgstr "Pagamento Inviato"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "Condividi questa transazione"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "Pagamento accettato, ma non ancora inviata alla rete"
@ -2185,7 +2221,7 @@ msgid "Payment details"
msgstr "Dettagli pagamento"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr "Richiesta di pagamento"
#: www/views/mercadoLibreCards.html:22
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "Incolla indirizzo"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Trasferimento da portafoglio a portafoglio"
msgid "Transfer between wallets"
msgstr "Trasferisci tra portafogli"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,10 +2668,6 @@ msgstr "Scansiona codice QR"
msgid "Send Bitcoin faster!"
msgstr "Invia Bitcoin più velocemente!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Invia Bitcoin più velocemente!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Salva gli indirizzi più utilizzati e invia Bitcoin con un solo tocco"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "Puoi ricevere Bitcoin da qualsiasi portafoglio o servizio."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Per iniziare, è necessario che tu crei un portafoglio bitcoin e ottenerne qualcuno."
@ -2891,10 +2925,15 @@ msgid "Sweep"
msgstr "Spazzola"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Spazzare il portafoglio di carta"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "Spazzare il portafoglio di carta"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr "Spazzolamento Portafoglio..."
@ -3061,6 +3100,14 @@ msgstr "Questa app memorizza i tuoi bitcoin con sicurezza all'avanguardia."
msgid "This bitcoin payment request has expired."
msgstr "Questa richiesta di pagamento in bitcoin è scaduta."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "Scadenza del pagamento:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "La richiesta di pagamento è scaduta"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "A"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "Per iniziare, acquista bitcoin o condividi il tuo indirizzo. È possibile ricevere bitcoin da qualsiasi servizio o portafoglio."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Per iniziare, devi creare un portafoglio bitcoin e ottenere qualche bitcoin."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "Per {{reason}} è necessario innanzitutto aggiungere il tuo account BitPay - {{email}}"
@ -3118,6 +3161,26 @@ msgstr "Ricarica in corso..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "Ricaricare di {{amountStr}} sulla carta di debito ({{cardLastNumber}})"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "Avvia ShapeShift"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "Cambia i tuoi BTC in BCH in pochi minuti."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "Per avviare il processo devi aggiungere fondi al tuo portafoglio."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "Il processo è veloce e riceverai l'importo cambiato nel tuo portafoglio."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "Questo servizio è fornito dalla terza parte ShapeShift, che addebiterà una piccola commissione per lo stesso. La commissione sarà mostrata prima di iniziare la transazione."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "Esplora Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Giochi Bitcoin Cash"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "Condividere l'app Portafoglio"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "News"
@ -3758,3 +3825,119 @@ msgstr "Bitcoin Cash gratis"
msgid "Your Bitcoin Wallets are ready!"
msgstr "I tuoi portafogli Bitcoin sono pronti!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "L'indirizzo non contiene informazioni sulla valuta. Verifica di inviare la valuta corretta."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "Rivedi transazione"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "Stai inviando"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "Stai spostando"
#: www/views/review.html:36
msgid "To:"
msgstr "A:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "Aggiungi nota personale"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "Suggerito dal commerciante:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "Inserisci il testo qui"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "Nota personale:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "Meno di 1 centesimo"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "Questa fattura non accetta più pagamenti"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "Inviare importo massimo"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "Errore sconosciuto."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "Nessun portafoglio Bitcoin Cash trovato per il trasferimento di fondi."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "Nessun Bitcoin Cash trovato."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Bitcoin Core trovato:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "Nessun portafoglio Bitcoin Core trovato per il trasferimento di fondi."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "Nessun Bitcoin Core trovato."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "Scansione non riuscita"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "Dati non riconosciuti."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "Non supportato"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet non supportato."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "Aprire nel browser web"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "Indirizzo non valido"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "Importo non definito"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "Importo inferiore al minimo"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "Importo sopra il limite"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Risposta non valida da Shapeshift"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Japanese\n"
"Language: ja\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "ポケット番号"
msgid "Instant transactions with low fees"
msgstr "僅かな手数料で即時決済"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "残高不足"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "通貨を変更"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "利用可能な残高"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "利用可能な資金をすべて使用"
#: www/views/amount.html:99
msgid "Next"
msgstr "次"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "アカウント一覧"
@ -206,6 +226,20 @@ msgstr "ほぼ完了!確認してみましょう。"
msgid "Alternative Currency"
msgstr "表示通貨"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "価格表示"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "法定通貨"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "仮想通貨"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com は現在ご利用できません、また後でお試しください"
@ -488,8 +522,8 @@ msgid "Cannot Create Wallet"
msgstr "ウォレットを作成できません。"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgstr "同じ端末で同じウォレットに複数回参加することできません。"
msgid "Cannot join the same wallet more than once"
msgstr "同じ端末で同じウォレットに複数回参加することできません。"
#: www/views/includes/bitpayCardsCard.html:2
msgid "Cards"
@ -664,6 +698,7 @@ msgstr "ウォレット参加者 {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "クリップボードにコピーしました"
@ -1283,6 +1318,7 @@ msgstr "監査用機能"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "送信者"
@ -1343,10 +1379,6 @@ msgid "Get news and updates from BitPay"
msgstr "BitPay からのニュースや更新情報を受け取ります。"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "始めよう"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "始めよう"
@ -2170,6 +2202,10 @@ msgstr "送金が却下されました"
msgid "Payment Sent"
msgstr "送金が完了しました"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "このトランザクションを共有"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "取引が承認されましたが、まだ送信していません。"
@ -2187,8 +2223,8 @@ msgid "Payment details"
msgstr "支払いの詳細"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgstr "支払い請求"
msgid "Payment Request"
msgstr "支払いを要求する"
#: www/views/mercadoLibreCards.html:22
#: www/views/modals/mercadolibre-card-details.html:39
@ -2623,7 +2659,7 @@ msgid "Paste Address"
msgstr "アドレスをペースト"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgid "Transfer between wallets"
msgstr "ウォレット間送金"
#: www/views/tab-send.html:35
@ -2634,10 +2670,6 @@ msgstr "QRコードを読み取る"
msgid "Send Bitcoin faster!"
msgstr "ビットコイン送金をより高速に!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "ビットコイン送金をより高速に!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "よく使うアドレスを保存すればワンタップでビットコインを送金できます"
@ -2659,6 +2691,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "どのウォレットやサービスからでもビットコインを受け取ることができます。"
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "はじめに、ビットコインウォレットを作成し、ビットコインを入手する必要があります。"
@ -2895,10 +2929,15 @@ msgid "Sweep"
msgstr "全残高インポート"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "ペーパーウォレットの全残高インポート"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "ペーパーウォレットの全残高インポート"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr "ビットコイン回収中…"
@ -3067,6 +3106,14 @@ msgstr "このアプリは、最先端のセキュリティであなたのビッ
msgid "This bitcoin payment request has expired."
msgstr "ビットコインペイメントの請求期限が切れています。"
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "支払い請求の有効期限:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "支払い要求の期限が切れています"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3108,10 +3155,6 @@ msgstr "宛先"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "はじめるには、ビットコインを購入したり、アドレスを他の人に共有したりしましょう。どのビットコインウォレットやサービスから受け取れます。"
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "はじめに、ビットコインウォレットを作成し、ビットコインを入手する必要があります。"
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "{{reason}}その前にBitPayアカウントを追加する必要があります - {{email}}"
@ -3124,6 +3167,26 @@ msgstr "残高補充処理中..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "デビットカード ({{cardLastNumber}}) に {{amountStr}} の入金を行う"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "ShapeShiftを開始"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "数分でBTCをBCHに変換できます。"
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "処理を開始するには、資金をウォレットに追加する必要があります。"
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "処理は高速で、交換した金額がウォレットに届きます。"
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "このサービスは、少額のサービス手数料を請求する第三者組織である ShapeShift によって提供されています。手数料は取引を開始する前に表示されます。"
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3740,6 +3803,10 @@ msgstr "Bitcoin.com を参照"
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash ゲーム"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "ウォレットアプリを共有"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "ニュース"
@ -3764,3 +3831,119 @@ msgstr "無料 Bitcoin Cash"
msgid "Your Bitcoin Wallets are ready!"
msgstr "ビットコインウォレットが完成しました!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "アドレスに通貨情報が含まれていません。正しい通貨を送金していることを確認してください。"
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "トランザクションの確認"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "送金中: "
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "取引中: "
#: www/views/review.html:36
msgid "To:"
msgstr "宛先:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "個人用メモを追加"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "お店からのおすすめ:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "ここにテキストを入力してください"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "個人用メモ:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "1セント以下"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "この請求書はもう支払を受け付けていません"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "全残高を送金"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "不明なエラーです。"
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "資金を送金できるビットコインキャッシュウォレットが見つかりません。"
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "ビットコインキャッシュが見つかりません。"
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "ビットコインが見つかりました:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "資金を送金できるビットコインウォレットが見つかりません。"
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "ビットコインが見つかりません。"
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "スキャンできませんでした"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "データが認識されていません。"
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "未対応"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet には対応していません。"
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "ウェブブラウザで開く"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "無効なアドレス"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "金額が定義されていません"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "金額が最少額を下回っています"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "金額が上限を超えています"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Shapeshift から無効な応答がありました"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Korean\n"
"Language: ko\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "계정 번호"
msgid "Instant transactions with low fees"
msgstr "낮은 수수료로 빠른 송금을"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "펀드 부족"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "통화 변경"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "보유 펀드"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "전체 펀드 사용"
#: www/views/amount.html:99
msgid "Next"
msgstr "다음"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "계정들"
@ -206,6 +226,20 @@ msgstr "거의 끝났습니다! 복습해보도록 하겠습니다."
msgid "Alternative Currency"
msgstr "알트 코인"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "가격 표시"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "법정 화폐"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "가상 화폐"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "아마존에 접속할 수 없습니다. 다시 시도해주세요."
@ -486,7 +520,7 @@ msgid "Cannot Create Wallet"
msgstr "지갑을 생성할 수 없습니다"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr "같은 지갑에 한 번 이상 접속할 수 없습니다"
#: www/views/includes/bitpayCardsCard.html:2
@ -662,6 +696,7 @@ msgstr "공동지불인 {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "클립보드에 복사 완료"
@ -1281,6 +1316,7 @@ msgstr "계좌 검토 용도"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "출처"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "BitPay에서 최신 소식을 받아보세요"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "시작하기"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "시작하기"
@ -2168,6 +2200,10 @@ msgstr "송금 거부"
msgid "Payment Sent"
msgstr "송금 완료"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "거래 공유"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "송금을 수락했으나 아직 브로드캐스트되지 않았습니다"
@ -2185,7 +2221,7 @@ msgid "Payment details"
msgstr "결제 디테일"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr "결제 요구"
#: www/views/mercadoLibreCards.html:22
@ -2621,7 +2657,7 @@ msgid "Paste Address"
msgstr "주소 붙여넣기"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgid "Transfer between wallets"
msgstr "지갑 간 전송"
#: www/views/tab-send.html:35
@ -2632,10 +2668,6 @@ msgstr "QR 코드 스캔"
msgid "Send Bitcoin faster!"
msgstr "비트코인 속성 전송!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "비트코인 속성 전송!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "자주 사용하는 주소를 저장하고 한 번의 탭으로 저장된 주소에 비트코인 전송"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "지갑 또는 서비스에서 비트코인을 받을 수 있습니다."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "시작하시기 위해선 비트코인 지갑을 생성하시거나 비트코인을 구매하세요."
@ -2891,10 +2925,15 @@ msgid "Sweep"
msgstr "스윕하기"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "종이 지갑 스윕하기"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "종이 지갑 스윕하기"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr "지갑 스윕 중..."
@ -3061,6 +3100,14 @@ msgstr "이 앱은 귀하의 비트코인을 최첨단 보안 서비스로 보
msgid "This bitcoin payment request has expired."
msgstr "비트코인 결제 요구가 만료되었습니다."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "송금 만료:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "결제 요청 만료"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "보내는 대상"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "시작하시려면 비트코인을 구매하시거나 주소를 등록해주세요. 어디에서든 비트코인을 받을 수 있습니다."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "시작하려면 비트코인 지갑을 만들고 비트코인을 구매하십시오."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "{{reason}}하기 위해선 BitPay 계정 - {{email}}을 먼저 추가하셔야 합니다."
@ -3118,6 +3161,26 @@ msgstr "추가 지불(Top up) 진행 중..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "체크 카드 ({{cardLastNumber}})에 {{amountStr}} 추가 지불(Top up)하기"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "ShapeShift 시작"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "BTC를 몇 분 내에 BCH로 교환"
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "과정을 시작하려면 월릿에 펀드를 적립해야 합니다."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "과정은 빠르며 월릿에 교환 금액이 전송됩니다."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "제3자 회사 Shapeshift는 소액의 수수료를 받고 서비스를 제공합니다. 수수료 금액은 거래 시작 전에 표시됩니다."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "Bitcoin.com 탐색"
msgid "Bitcoin Cash Games"
msgstr "BCH 게임"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "지갑 응용 프로그램 공유"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "소식"
@ -3758,3 +3825,119 @@ msgstr "무료 BCH"
msgid "Your Bitcoin Wallets are ready!"
msgstr "비트코인 지갑이 완료되었습니다!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "주소는 통화 정보를 포함하지 않으므로, 전송 금액을 확인해야 합니다."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "거래 확인"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "전송"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "전환"
#: www/views/review.html:36
msgid "To:"
msgstr "대상:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "개인 메모 작성"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "회사/업소 제안:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "텍스트 입력"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "개인 메모:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "1센트 미만"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "이 청구서는 더 이상 결제를 수락하지 않습니다"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "최대 수량 보내는 중"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "알 수 없는 오류가 발생 했습니다."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "자금 찾을 없습니다 Bitcoin Cash 현금 지갑."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "찾을 수 없습니다 Bitcoin Cash 현금."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Bitcoin Core 코어 발견:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "자금 찾을 없습니다 Bitcoin Core 현금 지갑."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "찾을 수 없습니다 Bitcoin Core 현금."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "검색 실패"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "데이터 인식 되지입니다."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "지원 되지 않는"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet는 지원 되지 않습니다."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "웹 브라우저에서 열기"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "주소 오류"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "금액은 정의 되지 않은"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "Minimun 아래 금액은"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "제한 위에 금액은"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "변신에서 잘못 된 응답"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Dutch\n"
"Language: nl\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -79,7 +79,27 @@ msgstr "Account Nummer"
#: www/views/tab-home.html:61
msgid "Instant transactions with low fees"
msgstr "Directe transacties tegen lage kosten"
msgstr "Onmiddellijke transacties met lage kosten"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Onvoldoende saldo"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Verander valuta"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Beschikbaar saldo"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Alle beschikbare saldo gebruiken"
#: www/views/amount.html:99
msgid "Next"
msgstr "Volgende"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
@ -159,7 +179,7 @@ msgstr "Adresboek"
#: www/views/preferencesInformation.html:41
msgid "Address Type"
msgstr "Adres Type"
msgstr "Adrestype"
#: www/views/addresses.html:64
msgid "Addresses With Balance"
@ -183,11 +203,11 @@ msgstr "Alle Adressen"
#: www/views/modals/wallet-balance.html:18
msgid "All of your bitcoin wallet balance may not be available for immediate spending."
msgstr "Mogelijk is niet het volledige saldo van uw bitcoin portemonnee direct beschikbaar voor uitgaven."
msgstr "Mogelijk is niet het volledige saldo van je Bitcoin portemonnee direct beschikbaar voor uitgaven."
#: www/views/tab-receive.html:25
msgid "All signing devices must be added to this multisig wallet before bitcoin addresses can be created."
msgstr "Alle ondertekenende apparaten moeten worden toegevoegd aan deze meervoudige-ondertekening portemonnee voordat bitcoin adressen kunnen worden aangemaakt."
msgstr "Alle ondertekenende apparaten moeten worden toegevoegd aan deze portemonnee met meervoudige ondertekening, alvorens Bitcoin adressen kunnen worden aangemaakt."
#: www/views/tab-scan.html:21
msgid "Allow Camera Access"
@ -199,16 +219,30 @@ msgstr "Meldingen toestaan"
#: www/views/onboarding/disclaimer.html:14
msgid "Almost done! Let's review."
msgstr "Bijna klaar! Nog eens nakijken."
msgstr "Bijna klaar! Kijk alles nog eens na."
#: www/views/preferencesAltCurrency.html:4
#: www/views/tab-settings.html:79
msgid "Alternative Currency"
msgstr "Alternatieve Valuta"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "Prijsaanduiding"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Fiat"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Cryptovaluta"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com is niet beschikbaar op dit moment. Probeer het later nog eens."
msgstr "Amazon.com is op dit moment niet beschikbaar. Probeer het later nog eens."
#: www/views/amount.html:44
#: www/views/customAmount.html:34
@ -230,15 +264,15 @@ msgstr "Bedrag te laag om te besteden"
#: src/js/controllers/tab-home.js:147
msgid "An update to this app is available. For your security, please update to the latest version."
msgstr "Er is een update voor deze app beschikbaar. Update a.u.b. naar de nieuwste versie voor uw veiligheid."
msgstr "Er is een update voor deze app beschikbaar. Update naar de nieuwste versie voor je eigen veiligheid."
#: www/views/backupWarning.html:14
msgid "Anyone with your backup phrase can access or spend your bitcoin."
msgstr "Iemand die uw herstel zin weet heeft toegang tot uw bitcoin en kan deze uitgeven."
msgstr "Iedereen die je herstelzin weet, heeft toegang tot je Bitcoin en kan deze uitgeven."
#: www/views/addresses.html:94
msgid "Approximate Bitcoin network fee to transfer wallet's balance (with normal priority)"
msgstr "Geschatte Bitcoin netwerk transactiekosten voor overdracht van volledige saldo van portemonnee (met normale prioriteit)"
msgstr "Geschatte transactiekosten van het Bitcoin netwerk, voor het overmaken van het saldo van je portemonnee. (met normale prioriteit)"
#: www/views/backupWarning.html:10
msgid "Are you being watched?"
@ -246,40 +280,40 @@ msgstr "Kijkt er iemand mee?"
#: src/js/controllers/preferencesExternal.js:15
msgid "Are you being watched? Anyone with your recovery phrase can access or spend your bitcoin."
msgstr "Kijkt er iemand mee? Iedereen die uw herstel zin weet heeft toegang tot uw bitcoin en kan het uitgeven."
msgstr "Kijkt er iemand mee? Iedereen die je herstelzin weet, heeft toegang tot je Bitcoin en kan deze uitgeven."
#: src/js/controllers/copayers.js:56
msgid "Are you sure you want to cancel and delete this wallet?"
msgstr "Weet u zeker dat u wilt annuleren en deze portemonnee verwijderen?"
msgstr "Weet je zeker dat je wilt annuleren en deze portemonnee verwijderen?"
#: src/js/controllers/addressbookView.js:37
msgid "Are you sure you want to delete this contact?"
msgstr "Weet u zeker dat u deze contactpersoon wilt verwijderen?"
msgstr "Weet je zeker dat je deze contactpersoon wilt verwijderen?"
#: src/js/controllers/preferencesDelete.js:25
msgid "Are you sure you want to delete this wallet?"
msgstr "Weet u zeker dat u deze portemonnee wilt verwijderen?"
msgstr "Weet je zeker dat je deze portemonnee wilt verwijderen?"
#: src/js/controllers/modals/txpDetails.js:154
msgid "Are you sure you want to reject this transaction?"
msgstr "Weet u zeker dat u deze transactie wilt afwijzen?"
msgstr "Weet je zeker dat je deze transactie wilt afwijzen?"
#: src/js/controllers/modals/txpDetails.js:171
msgid "Are you sure you want to remove this transaction?"
msgstr "Weet u zeker dat u deze transactie wilt verwijderen?"
msgstr "Weet je zeker dat je deze transactie wil verwijderen?"
#: src/js/controllers/onboarding/backupRequest.js:23
msgid "Are you sure you want to skip it?"
msgstr "Weet u zeker dat u dit wilt overslaan?"
msgstr "Weet je zeker dat je dit wil overslaan?"
#: www/views/modals/bitpay-card-confirmation.html:4
msgid "Are you sure you would like to log out of your BitPay Card account?"
msgstr "Weet u zeker dat u wilt uitloggen uit uw BitPay Kaart account?"
msgstr "Weet je zeker dat je wilt uitloggen uit je BitPay Kaart account?"
#: src/js/controllers/preferencesBitpayCard.js:7
#: src/js/controllers/preferencesBitpayServices.js:20
msgid "Are you sure you would like to remove your BitPay Card ({{lastFourDigits}}) from this device?"
msgstr "Weet u zeker dat u de BitPay Kaart ({{lastFourDigits}}) van dit apparaat wilt verwijderen?"
msgstr "Weet je zeker dat je de BitPay Kaart ({{lastFourDigits}}) van dit apparaat wilt verwijderen?"
#: www/views/includes/walletInfo.html:10
msgid "Auditable"
@ -315,11 +349,11 @@ msgstr "Back-up"
#: www/views/includes/backupNeededPopup.html:7
msgid "Backup Needed"
msgstr "Backup Nodig"
msgstr "Back-up Nodig"
#: src/js/controllers/lockSetup.js:87
msgid "Backup all livenet wallets before using this function"
msgstr "Maak een backup van alle livenet portemonnees voordat u deze functie gebruikt"
msgstr "Maak een back-up van alle livenet portemonnees voordat je deze functie gebruikt"
#: src/js/controllers/cashScan.js:64
#: www/views/includes/walletListSettings.html:12
@ -329,16 +363,16 @@ msgstr "Backup nodig"
#: www/views/includes/backupNeededPopup.html:9
msgid "Backup now"
msgstr "Backup maken"
msgstr "Back-up maken"
#: www/views/onboarding/backupRequest.html:11
#: www/views/tab-export-file.html:89
msgid "Backup wallet"
msgstr "Backup van portemonnee maken"
msgstr "Back-up van portemonnee maken"
#: src/js/controllers/lockSetup.js:84
msgid "Backup your wallet before using this function"
msgstr "Maak een backup van uw portemonnee voordat u deze functie gebruikt"
msgstr "Maak een back-up van je portemonnee alvorens je deze functie gebruikt"
#: src/js/services/profileService.js:446
msgid "Bad wallet invitation"
@ -350,7 +384,7 @@ msgstr "Saldo Per Adres"
#: www/views/includes/confirmBackupPopup.html:7
msgid "Be sure to store your recovery phrase in a secure place. If this app is deleted, your money cannot be recovered without it."
msgstr "Zorg dat u de herstel zin op een veilige plek bewaard. Als deze app verwijderd is, kan uw saldo niet meer worden hersteld zonder de herstel zin."
msgstr "Zorg dat je de herstelzin op een veilige plek bewaard. Als je deze app verwijderd, kan je saldo niet meer hersteld worden zonder deze herstelzin."
#: www/views/preferencesBitpayServices.html:9
msgid "BitPay Visa&reg; Cards"
@ -486,8 +520,8 @@ msgid "Cannot Create Wallet"
msgstr "Kan Portemonnee Niet Aanmaken"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgstr "Kan niet meerdere keren tegelijk deelnemen aan een portemonnee"
msgid "Cannot join the same wallet more than once"
msgstr "Je kan niet meerdere keren tegelijk aan een portemonnee deelnemen"
#: www/views/includes/bitpayCardsCard.html:2
msgid "Cards"
@ -503,11 +537,11 @@ msgstr "Controleer de installatie en probeer het opnieuw."
#: www/views/tab-import-file.html:4
msgid "Choose a backup file from your computer"
msgstr "Kies een backup bestand op uw computer"
msgstr "Kies een backup bestand op je computer"
#: www/views/modals/wallets.html:9
msgid "Choose your destination wallet"
msgstr "Kies uw doel portemonnee"
msgstr "Kies je bestemming portemonnee"
#: www/views/modals/wallets.html:10
msgid "Choose your source wallet"
@ -589,11 +623,11 @@ msgstr "Bevestig aankoop"
#: www/views/modals/pin.html:10
msgid "Confirm your PIN"
msgstr "Bevestig uw PIN"
msgstr "Bevestig je PIN"
#: src/js/services/walletService.js:1033
msgid "Confirm your new spending password"
msgstr "Bevestig uw nieuwe bestedingswachtwoord"
msgstr "Bevestig je nieuwe wachtwoord om te spenderen"
#: www/views/tx-details.html:98
msgid "Confirmations"
@ -626,7 +660,7 @@ msgstr "Contactpersonen"
#: www/views/tab-send.html:86
msgid "Saved frequently used addresses"
msgstr "Opgeslagen veelgebruikte adressen"
msgstr "Veelgebruikte adressen"
#: www/views/onboarding/notifications.html:9
msgid "Continue"
@ -662,6 +696,7 @@ msgstr "Copayer {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "Gekopieerd naar klembord"
@ -734,7 +769,7 @@ msgstr "Kon niet worden gemaakt: Ongeldige portemonnee herstel zin"
#: src/js/controllers/import.js:114
msgid "Could not decrypt file, check your password"
msgstr "Kon bestand niet ontsleutelen, check uw wachtwoord"
msgstr "Het bestand kon niet worden ontsleutelt, controleer je wachtwoord"
#: src/js/controllers/modals/txpDetails.js:181
msgid "Could not delete payment proposal"
@ -940,7 +975,7 @@ msgstr "Privé sleutel niet bijvoegen"
#: www/views/preferencesLanguage.html:21
msgid "Don't see your language on Crowdin? Contact the Owner on Crowdin! We'd love to support your language."
msgstr "Ziet u uw taal niet op Crowdin? Neem contact op met de Eigenaar op Crowdin! We willen graag uw taal ondersteunen."
msgstr "Zie je je eigen taal niet op Crowdin? Neem contact op met de Eigenaar op Crowdin! We willen graag jouw taal ondersteunen."
#: www/views/tab-export-file.html:59
#: www/views/tab-home.html:22
@ -957,7 +992,7 @@ msgstr "Portemonnee dupliceren..."
#: www/views/addresses.html:19
msgid "Each bitcoin wallet can generate billions of addresses from your 12-word backup. A new address is automatically generated and shown each time you receive a payment."
msgstr "Elke bitcoin portemonnee kan miljarden adressen genereren vanuit uw backup bestaand uit 12 woorden. Elke keer dat u een betaling ontvangt wordt automatisch een nieuw adres gegenereerd en getoond."
msgstr "Elke Bitcoin portemonnee kan miljarden adressen genereren vanuit je back-up bestaande uit 12 woorden. Elke keer dat je een betaling ontvangt wordt automatisch een nieuw adres gegenereerd en getoond."
#: src/js/services/feeService.js:13
msgid "Economy"
@ -986,7 +1021,7 @@ msgstr "Aanmaken en gebruiken van Bitcoin Cash portemonnees inschakelen binnen d
#: www/views/tab-scan.html:19
msgid "Enable camera access in your device settings to get started."
msgstr "Schakel camera toegang in vanuit uw apparaat instellingen om aan de slag te gaan."
msgstr "Schakel camera toegang in vanuit je apparaatinstellingen om aan de slag te gaan."
#: www/views/preferencesNotifications.html:29
msgid "Enable email notifications"
@ -1037,11 +1072,11 @@ msgstr "Vul de herstel zin in (BIP39)"
#: www/views/onboarding/collectEmail.html:13
msgid "Enter your email"
msgstr "Vul uw email in"
msgstr "Vul je e-mailadres in"
#: www/views/backup.html:69
msgid "Enter your password"
msgstr "Voer uw wachtwoord in"
msgstr "Voer je wachtwoord in"
#. Trying to import a malformed wallet export QR code
#: src/js/controllers/activity.js:45
@ -1281,6 +1316,7 @@ msgstr "Voor audit doeleinden"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "Van"
@ -1341,17 +1377,13 @@ msgid "Get news and updates from BitPay"
msgstr "Ontvang nieuws en updates van BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "Aan de slag"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "Aan de slag"
#: www/views/addressbook.html:20
msgid "Get started by adding your first one."
msgstr "Ga aan de slag door uw eerste toe te voegen."
msgstr "Ga aan de slag door je eerste contact toe te voegen."
#: src/js/services/onGoingProcess.js:23
msgid "Getting fee levels..."
@ -1460,7 +1492,7 @@ msgstr "Start"
#: src/js/controllers/feedback/send.js:65
#: src/js/controllers/feedback/send.js:69
msgid "How could we improve your experience?"
msgstr "Hoe zouden wij uw ervaring kunnen verbeteren?"
msgstr "Hoe zouden wij jouw ervaring kunnen verbeteren?"
#: www/views/feedback/rateCard.html:3
msgid "How do you like {{appName}}?"
@ -1523,7 +1555,7 @@ msgstr "Indien ingeschakeld, zullen portemonnees ook onbevestigd saldo proberen
#: src/js/controllers/onboarding/backupRequest.js:18
msgid "If this device is replaced or this app is deleted, neither you nor BitPay can recover your funds without a backup."
msgstr "Als dit apparaat wordt vervangen of deze app wordt verwijderd, kunnen u noch BitPay uw saldo herstellen zonder backup."
msgstr "Als dit apparaat wordt vervangen of deze app wordt verwijderd, kunnen jij of BitPay je saldo niet herstellen zonder back-up."
#: www/views/feedback/complete.html:23
msgid "If you have additional feedback, please let us know by tapping the \"Send feedback\" option in the Settings tab."
@ -1531,7 +1563,7 @@ msgstr "Als u meer feedback heeft, laat het ons dan weten via de \"Geef feedback
#: www/views/includes/screenshotWarningModal.html:8
msgid "If you take a screenshot, your backup may be viewed by other apps. You can make a safe backup with physical paper and a pen."
msgstr "Als u een screenshot neemt kunnen andere apps uw backup zien. U kunt een veilige backup maken met fysieke pen en papier."
msgstr "Als je een screenshot neemt kunnen andere apps jouw back-up zien. Je kunt het beste een veilige back-up maken op pen en papier."
#: www/views/tab-import-hardware.html:42
#: www/views/tab-import-phrase.html:80
@ -1556,7 +1588,7 @@ msgstr "Portemonnee importeren..."
#: www/views/backup.html:72
msgid "In order to verify your wallet backup, please type your password."
msgstr "Vul uw wachtwoord in om de backup van uw portemonnee te verifiëren."
msgstr "Vul je wachtwoord in om de back-up van je portemonnee te verifiëren."
#: www/views/mercadoLibreCards.html:24
#: www/views/modals/mercadolibre-card-details.html:29
@ -1660,7 +1692,7 @@ msgstr "Het is aan te raden adressen niet te hergebruiken - dit beschermt uw pri
#: src/js/controllers/backup.js:76
msgid "It's important that you write your backup phrase down correctly. If something happens to your wallet, you'll need this backup to recover your money. Please review your backup and try again."
msgstr "Het is van belang uw backup zin correct op te schrijven. Als er iets gebeurt met uw portemonnee, heeft u deze backup nodig om toegang tot uw geld te herstellen. Controleer uw backup en probeer het nogmaals."
msgstr "Het is van belang je back-up zin correct op te schrijven. Als er iets gebeurt met je portemonnee, heeft u deze back-up zin nodig om toegang tot uw geld te herstellen. Controleer je back-up zin en probeer het nogmaals."
#: www/views/join.html:151
msgid "Join"
@ -1668,7 +1700,7 @@ msgstr "Deelnemen"
#: src/js/controllers/copayers.js:85
msgid "Join my {{appName}} Wallet. Here is the invitation code: {{secret}} You can download {{appName}} for your phone or desktop at {{appUrl}}"
msgstr "Neem deel aan mijn {{appName}} Portemonnee. Hier is de uitnodigingscode: {{secret}} U kunt {{appName}} voor uw telefoon of desktop hier downloaden {{appUrl}}"
msgstr "Neem deel aan mijn {{appName}} Portemonnee. Hier is de uitnodigingscode: {{secret}} Je kunt {{appName}} voor je telefoon of desktop hier downloaden {{appUrl}}"
#: www/views/add.html:30
#: www/views/join.html:5
@ -1705,7 +1737,7 @@ msgstr "Meer informatie"
#: www/views/backup.html:43
msgid "Let's verify your backup phrase."
msgstr "Laten we de backup zin verifiëren."
msgstr "Laten we uw back-up zin verifiëren."
#: www/views/addresses.html:45
#: www/views/allAddresses.html:14
@ -1994,11 +2026,11 @@ msgstr "Geef mij een melding wanneer transacties zijn bevestigd"
#: www/views/includes/backupNeededPopup.html:8
msgid "Now is a good time to backup your wallet. If this device is lost, it is impossible to access your funds without a backup."
msgstr "Dit is een goed moment om een backup van de portemonnee te maken. Als dit apparaat kwijt raakt is het onmogelijk om toegang tot uw saldo te krijgen zonder een backup."
msgstr "Dit is een goed moment om een back-up van de portemonnee te maken. Als dit apparaat kwijt raakt is het onmogelijk om toegang tot je saldo te krijgen zonder een back-up."
#: www/views/backupWarning.html:11
msgid "Now is a perfect time to assess your surroundings. Nearby windows? Hidden cameras? Shoulder-spies?"
msgstr "Dit is het juiste moment om uw omgeving te bekijken. Ramen in de buurt? Verborgen camera's? Kijkt er iemand mee over uw schouder?"
msgstr "Dit is het juiste moment om je omgeving te bekijken. Ramen in de buurt? Verborgen camera's? Kijkt er iemand met je mee over je schouder?"
#: src/js/controllers/buyAmazon.js:312
#: src/js/controllers/topup.js:286
@ -2032,7 +2064,7 @@ msgstr "OK"
#: www/views/tab-home.html:39
msgid "On this screen you can see all your wallets, accounts, and assets."
msgstr "Op dit scherm ziet u al uw portemonnees, accounts en eigendommen."
msgstr "Op dit scherm zie je al je portemonnees, accounts en eigendommen."
#: src/js/controllers/bitpayCard.js:113
#: src/js/controllers/cashScan.js:19
@ -2105,7 +2137,7 @@ msgstr "Wachtwoord"
#: src/js/controllers/import.js:98
msgid "Password required. Make sure to enter your password in advanced options"
msgstr "Wachtwoord vereist. Vul uw wachtwoord in bij de geavanceerde opties"
msgstr "Wachtwoord vereist. Vul je wachtwoord in bij de geavanceerde opties"
#: www/views/join.html:33
msgid "Paste invitation here"
@ -2168,6 +2200,10 @@ msgstr "Betaling Afgewezen"
msgid "Payment Sent"
msgstr "Betaling Verzonden"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "Deel deze transactie"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "Betaling geaccepteerd, maar nog niet verzonden"
@ -2185,8 +2221,8 @@ msgid "Payment details"
msgstr "Details Betaling"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgstr "Betalingsverzoek"
msgid "Payment Request"
msgstr "Betaalverzoek"
#: www/views/mercadoLibreCards.html:22
#: www/views/modals/mercadolibre-card-details.html:39
@ -2224,7 +2260,7 @@ msgstr "Vul de herstel zin van de portemonnee in"
#: www/views/modals/pin.html:9
msgid "Please enter your PIN"
msgstr "Vul uw PIN in"
msgstr "Vul je PIN in"
#: www/views/backup.html:53
msgid "Please tap each word in the correct order."
@ -2241,7 +2277,7 @@ msgstr "Een moment geduld a.u.b."
#: src/js/controllers/import.js:238
msgid "Please, select your backup file"
msgstr "Selecteer uw backup bestand"
msgstr "Selecteer je back-upbestand"
#: www/views/bitpayCard.html:81
msgid "Pre-Auth Holds"
@ -2437,7 +2473,7 @@ msgstr "BitPay Kaart verwijderen?"
#: src/js/controllers/preferencesBitpayServices.js:8
msgid "Removing your BitPay account will remove all associated BitPay account data from this device. Are you sure you would like to remove your BitPay Account ({{email}}) from this device?"
msgstr "Het verwijderen van uw BitPay account zal alle geassocieerde BitPay accountgegevens van dit apparaat verwijderen. Weet u zeker dat u de BitPay Account ({{email}}) van dit apparaat wilt verwijderen?"
msgstr "Het verwijderen van je BitPay account zal alle geassocieerde BitPay accountgegevens van dit apparaat verwijderen. Weet je zeker dat u de BitPay Account ({{email}}) van dit apparaat wil verwijderen?"
#: www/views/join.html:116
#: www/views/join.html:124
@ -2512,11 +2548,11 @@ msgstr "Scan nogmaals"
#: src/js/services/fingerprintService.js:56
msgid "Scan your fingerprint please"
msgstr "Scan uw vingerafdruk"
msgstr "Scan je vingerafdruk a.u.b."
#: www/views/preferencesCash.html:23
msgid "Scan your wallets for Bitcoin Cash"
msgstr "Scannen naar Bitcoin Cash in uw portemonnees"
msgstr "Scan je portemonnees voor Bitcoin Cash"
#: src/js/services/onGoingProcess.js:30
msgid "Scanning Wallet funds..."
@ -2544,7 +2580,7 @@ msgstr "Klembord"
#: src/js/controllers/tab-send.js:29
msgid "Your Clipboard is empty"
msgstr "Uw klembord is leeg"
msgstr "Je klembord is leeg"
#: www/views/modals/search.html:16
msgid "Search transactions"
@ -2552,7 +2588,7 @@ msgstr "Doorzoek transacties"
#: www/views/preferencesAltCurrency.html:14
msgid "Search your currency"
msgstr "Zoek uw valuta"
msgstr "Zoek je valuta"
#: www/views/preferences.html:30
msgid "Security"
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "Adres plakken"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Portemonnee overdracht"
msgid "Transfer between wallets"
msgstr "Overdracht tussen portemonnees"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,21 +2668,17 @@ msgstr "Scan QR-code"
msgid "Send Bitcoin faster!"
msgstr "Stuur Bitcoin sneller!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Stuur Bitcoin sneller!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Sla veelgebruikte adressen op en verstuur ze Bitcoin met een druk op de knop"
#: www/views/tab-send.html:55
msgid "Add your first contact"
msgstr "Uw eerste contact toevoegen"
msgstr "Je eerste contact toevoegen"
#: www/views/tab-send.html:65
msgid "Your Bitcoin wallet is empty"
msgstr "Uw Bitcoin portemonnee is leeg"
msgstr "Je Bitcoin portemonnee is leeg"
#: www/views/tab-send.html:69
msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address."
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "U kunt Bitcoin ontvangen van elke portemonnee of dienst."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Om aan de slag te gaan zult u een bitcoin portemonnee moeten aanmaken en wat bitcoin moeten verkrijgen."
@ -2705,7 +2739,7 @@ msgstr "Transactie verzenden"
#: src/js/controllers/confirm.js:545
msgid "Sending {{amountStr}} from your {{name}} wallet"
msgstr "Verzenden van {{amountStr}} vanuit uw {{name}} portemonnee"
msgstr "Verzenden van {{amountStr}} vanuit je portemonnee '{{name}}'"
#: www/views/includes/walletHistory.html:42
#: www/views/modals/tx-status.html:9
@ -2745,7 +2779,7 @@ msgstr "Stel wachtwoord in"
#: src/js/controllers/preferencesFee.js:85
msgid "Set your own fee in satoshis/byte"
msgstr "Kies uw eigen transactiekosten in satoshi/byte"
msgstr "Kies je eigen transactiekosten in satoshi/byte"
#: www/views/tab-settings.html:3
#: www/views/tabs.html:19
@ -2891,9 +2925,14 @@ msgid "Sweep"
msgstr "Saldo opnemen"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Saldo papieren portemonnee opnemen"
msgstr "Paper wallet leeghalen"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "Paper wallet leeghalen"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
@ -2905,7 +2944,7 @@ msgstr "DEZE ACTIE IS ONOMKEERBAAR"
#: www/views/onboarding/welcome.html:5
msgid "Take control of your money,<br>get started with bitcoin."
msgstr "Neem controle over uw geld,<br>aan de slag met bitcoin."
msgstr "Neem de controle over je geld,<br>aan de slag met Bitcoin."
#: www/views/walletDetails.html:132
#: www/views/walletDetails.html:52
@ -2953,7 +2992,7 @@ msgstr "Bedankt!"
#: src/js/controllers/feedback/send.js:73
msgid "That's exciting to hear. We'd love to earn that fifth star from you how could we improve your experience?"
msgstr "Dat is goed om te horen. Wij zouden graag die vijfde ster verdienen - hoe kunnen wij uw ervaring verbeteren?"
msgstr "Dat is goed om te horen. Wij zouden graag die vijfde ster verdienen - hoe kunnen wij jouw ervaring verbeteren?"
#: src/js/services/ledger.js:152
msgid "The Ledger Chrome application is not installed"
@ -2965,7 +3004,7 @@ msgstr "De hoeveelheid bitcoin die direct te besteden is vanuit deze portemonnee
#: www/views/modals/wallet-balance.html:93
msgid "The amount of bitcoin stored in this wallet that is allocated as inputs to your pending transaction proposals. The amount is determined using unspent transaction outputs associated with this wallet and may be more than the actual amounts associated with your pending transaction proposals."
msgstr "De hoeveelheid bitcoin opgeslagen in deze portemonnee die is toegewezen als invoer voor uw wachtende betalingsvoorstellen. De hoeveelheid is bepaald door te kijken naar ongebruikte transactie uitvoer geassocieerd met deze portemonnee en kan meer zijn dan de daadwerkelijke hoeveelheid geassocieerd met de wachtende betalingsvoorstellen."
msgstr "De hoeveelheid Bitcoin opgeslagen in deze portemonnee, die is toegewezen als invoer voor uw wachtende betalingsvoorstellen. De hoeveelheid is bepaald, door te kijken naar ongebruikte transactie uitvoer geassocieerd met deze portemonnee en kan meer zijn dan de daadwerkelijke hoeveelheid geassocieerd met de wachtende betalingsvoorstellen."
#: www/views/modals/wallet-balance.html:74
msgid "The amount of bitcoin stored in this wallet with less than 1 blockchain confirmation."
@ -2985,7 +3024,7 @@ msgstr "Des te hoger de betaalde transactiekosten, des te meer reden een miner h
#: www/views/addresses.html:51
msgid "The maximum number of consecutive unused addresses (20) has been reached. When one of your unused addresses receives a payment, a new address will be generated and shown in your Receive tab."
msgstr "Het maximum aantal opeenvolgende ongebruikte adressen (20) is bereikt. Wanneer een van uw ongebruikte adressen een betaling ontvangt zal een nieuw adres worden gegenereerd en worden getoond in het tabblad Ontvangen."
msgstr "Het maximum aantal opeenvolgende ongebruikte adressen (20) is bereikt. Wanneer een van je ongebruikte adressen een betaling ontvangt zal een nieuw adres gegenereerd en weergegeven worden in het tabblad Ontvangen."
#: src/js/controllers/onboarding/terms.js:21
msgid "The official English Terms of Service are available on the BitPay website."
@ -3055,17 +3094,25 @@ msgstr "Deze app is fantastisch!"
#: www/views/onboarding/tour.html:47
msgid "This app stores your bitcoin with cutting-edge security."
msgstr "Deze app bewaart uw bitcoin met de nieuwste beveiliging."
msgstr "Deze app bewaart uw Bitcoin met de nieuwste beveiliging."
#: src/js/controllers/confirm.js:523
msgid "This bitcoin payment request has expired."
msgstr "Dit bitcoin betalingsverzoek is verlopen."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "Betaling verloopt:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "Betalingsverzoek is verlopen"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
msgid "This password cannot be recovered. If the password is lost, there is no way you could recover your funds."
msgstr "Dit wachtwoord kan niet worden achterhaald. Als het wachtwoord verloren gaat is er geen mogelijkheid om toegang tot uw saldo te herstellen."
msgstr "Dit wachtwoord kan niet worden achterhaald. Als het wachtwoord verloren gaat, dan is er geen mogelijkheid om toegang tot jouw saldo te herstellen."
#: www/views/backup.html:31
msgid "This recovery phrase was created with a password. To recover this wallet both the recovery phrase and password are needed."
@ -3100,15 +3147,11 @@ msgstr "Naar"
#: www/views/tab-send.html:32
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "Om aan de slag te gaan, koop bitcoin of deel uw adres. U kunt bitcoin ontvangen van elke portemonnee of dienst."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Om aan de slag te gaan, zult u een Bitcoin-portemonnee aan moeten maken en wat Bitcoin moeten verkrijgen."
msgstr "Om aan de slag te gaan, koop je Bitcoin of deel je je adres. Je kunt Bitcoin ontvangen van elke portemonnee of dienst."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "Om {{reason}} zult u eerst uw BitPay account moeten toevoegen - {{email}}"
msgstr "Om {{reason}} zult je eerst uw BitPay account moeten toevoegen - {{email}}"
#: src/js/services/onGoingProcess.js:48
msgid "Top up in progress..."
@ -3118,6 +3161,26 @@ msgstr "Bezig met opladen..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "Vul debet kaart ({{cardLastNumber}}) aan met {{amountStr}}"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "ShapeShift starten"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "Binnen enkele minuten je BTC omwisselen naar BCH."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "Om het proces te starten moet je eerst bitcoin in je portemonnee hebben staan."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "Het proces is snel en je ontvangt het uitgewisselde bedrag direct in je portemonnee."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "Deze dienst wordt aangeboden door de partij ShapeShift, die zal een kleine vergoeding voor de service rekenen. Deze vergoeding wordt getoond voordat je de transactie start."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3252,7 +3315,7 @@ msgstr "Herstel zin valideren..."
#: www/views/modals/fingerprintCheck.html:4
msgid "Verify your identity"
msgstr "Verifieer uw identiteit"
msgstr "Verifieër je identiteit"
#: www/views/preferencesAbout.html:14
#: www/views/preferencesExternal.html:25
@ -3449,7 +3512,7 @@ msgstr "Portemonnee niet geregistreerd"
#: src/js/services/bwcError.js:29
msgid "Wallet not registered at the wallet service. Recreate it from \"Create Wallet\" using \"Advanced Options\" to set your recovery phrase"
msgstr "Portemonnee niet geregistreerd bij de wallet service. Maak deze opnieuw aan vanuit \"Portemonnee Aanmaken\" en maak gebruik van \"Geavanceerde Opties\" om uw herstel zin in te voeren"
msgstr "Portemonnee niet geregistreerd bij de wallet service. Maak deze opnieuw aan vanuit \"Portemonnee Aanmaken\" en maak gebruik van \"Geavanceerde Opties\" om je herstelzin in te voeren"
#: www/views/backup.html:12
msgid "Wallet recovery phrase not available"
@ -3494,7 +3557,7 @@ msgstr "Wij zoeken altijd naar manieren om {{appName}} te verbeteren."
#: src/js/controllers/feedback/send.js:83
msgid "We're always looking for ways to improve {{appName}}. How could we improve your experience?"
msgstr "Wij zoeken altijd naar manieren om {{appName}} te verbeteren. Hoe kunnen wij uw ervaring verbeteren?"
msgstr "Wij zoeken altijd naar manieren om {{appName}} te verbeteren. Hoe kunnen wij jouw ervaring verbeteren?"
#: www/views/includes/incomingDataMenu.html:6
msgid "Website"
@ -3546,7 +3609,7 @@ msgstr "Ja, overslaan"
#: src/js/controllers/onboarding/backupRequest.js:24
msgid "You can create a backup later from your wallet settings."
msgstr "U kunt later een backup maken vanuit uw portemonnee instellingen."
msgstr "Je kunt later een back-up maken vanuit uw portemonnee instellingen."
#: src/js/controllers/preferencesLanguage.js:12
msgid "You can make contributions by signing up on our Crowdin community translation website. Were looking forward to hearing from you!"
@ -3574,7 +3637,7 @@ msgstr "U kunt het inwisselen voor valuta's zoals de Amerikaanse Dollar, de Euro
#: www/views/onboarding/tour.html:46
msgid "You control your bitcoin."
msgstr "U heeft de controle over uw bitcoin."
msgstr "Jij hebt de controle over jouw Bitcoin."
#: www/views/modals/chooseFeeLevel.html:64
msgid "You should not set a fee higher than {{maxFeeRecommended}} satoshis/byte."
@ -3582,65 +3645,65 @@ msgstr "Het is af te raden transactiekosten te kiezen hoger dan {{maxFeeRecommen
#: www/views/modals/bitpay-card-confirmation.html:5
msgid "You will need to log back for fill in your BitPay Card."
msgstr "U zult opnieuw moeten inloggen om uw BitPay Kaart op te laden."
msgstr "Je zult opnieuw moeten inloggen om je BitPay Kaart op te laden."
#: www/views/preferencesNotifications.html:34
msgid "You'll receive email notifications about payments sent and received from your wallets."
msgstr "U zult email meldingen ontvangen over verzonden en ontvangen betalingen van uw portemonnee."
msgstr "U zult e-mail meldingen ontvangen over verzonden en ontvangen betalingen van jouw portemonnee."
#: www/views/bitpayCard.html:50
msgid "Your BitPay Card is ready. Add funds to your card to start using it at stores and ATMs worldwide."
msgstr "Uw BitPay Kaart is gereed. Voeg saldo toe aan uw kaart om deze te kunnen gebruiken in winkels en pinautomaten over de hele wereld."
msgstr "Je BitPay Kaart is gereed. Voeg saldo toe aan je kaart om deze te kunnen gebruiken in winkels en pinautomaten over de hele wereld."
#: www/views/mercadoLibre.html:57
#: www/views/mercadoLibreCards.html:6
msgid "Your Gift Cards"
msgstr "Uw Cadeaubonnen"
msgstr "Je Cadeaubonnen"
#: www/views/includes/confirmBackupPopup.html:6
msgid "Your bitcoin wallet is backed up!"
msgstr "Er is een backup gemaakt van uw bitcoin portemonnee!"
msgstr "Er is een backup gemaakt van je Bitcoin portemonnee!"
#: www/views/tab-home.html:36
msgid "Your bitcoin wallet is ready!"
msgstr "Uw bitcoin portemonnee is gereed!"
msgstr "Je Bitcoin portemonnee is gereed!"
#: www/views/modals/chooseFeeLevel.html:61
msgid "Your fee is lower than recommended."
msgstr "Uw gekozen transactiekosten zijn lager dan aangeraden."
msgstr "Je gekozen transactiekosten zijn lager dan aangeraden."
#: www/views/feedback/send.html:42
msgid "Your ideas, feedback, or comments"
msgstr "Uw ideeën, feedback of opmerkingen"
msgstr "Je ideeën, feedback of opmerkingen"
#: www/views/tab-create-shared.html:22
msgid "Your name"
msgstr "Uw naam"
msgstr "Je naam"
#: www/views/join.html:16
msgid "Your nickname"
msgstr "Uw bijnaam"
msgstr "Je bijnaam"
#: www/views/tab-export-file.html:11
#: www/views/tab-import-file.html:20
msgid "Your password"
msgstr "Uw wachtwoord"
msgstr "Je wachtwoord"
#: www/views/buyAmazon.html:102
msgid "Your purchase could not be completed"
msgstr "Uw aankoop kon niet worden voltooid"
msgstr "Je aankoop kon niet worden voltooid"
#: www/views/buyAmazon.html:105
msgid "Your purchase was added to the list of pending"
msgstr "Uw aankoop is op de in-behandeling lijst gezet"
msgstr "Je aankoop is op de in-behandeling lijst gezet"
#: www/views/onboarding/backupRequest.html:10
msgid "Your wallet is never saved to cloud storage or standard device backups."
msgstr "Uw portemonnee wordt nooit opgeslagen in de cloud of in standaard apparaat backups."
msgstr "Je portemonnee wordt nooit opgeslagen in de cloud of in standaard apparaat back-ups."
#: src/js/services/walletService.js:1030
msgid "Your wallet key will be encrypted. The Spending Password cannot be recovered. Be sure to write it down."
msgstr "Uw privé sleutel wordt versleuteld. Het Bestedingswachtwoord kan niet worden achterhaald, schrijf deze zorgvuldig op."
msgstr "Je privésleutel wordt versleuteld. Het wachtwoord voor besteden kan niet worden achterhaald, schrijf deze zorgvuldig op."
#: www/views/includes/walletList.html:13
#: www/views/includes/walletSelector.html:21
@ -3658,7 +3721,7 @@ msgstr "[Saldo Scannen]"
#: src/js/controllers/bitpayCardIntro.js:11
msgid "add your BitPay Visa card(s)"
msgstr "voeg uw BitPay Visa kaart(en) toe"
msgstr "voeg je BitPay Visa kaart(en) toe"
#: www/views/includes/available-balance.html:8
msgid "locked by pending payments"
@ -3716,7 +3779,7 @@ msgstr "Shapeshift"
#: www/views/includes/community.html:3
msgid "Community"
msgstr "Community"
msgstr "Gemeenschap"
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
@ -3734,6 +3797,10 @@ msgstr "Bitcoin.com verkennen"
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash spellen"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "Wallet app delen"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Nieuws"
@ -3756,5 +3823,121 @@ msgstr "Gratis Bitcoin Cash"
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr "Uw bitcoin portemonnee is gereed!"
msgstr "Je Bitcoin portemonnee is gereed!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "Adres bevat geen valutagegevens, zorg ervoor dat je de correcte valuta verzendt."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "Controleer transactie"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "Je verzendt"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "Je shift"
#: www/views/review.html:36
msgid "To:"
msgstr "Naar:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "Persoonlijke opmerking toevoegen"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "Voorgesteld door derde partij:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "Voer hier tekst in"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "Persoonlijke opmerking:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "Minder dan 1 cent"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "Deze factuur accepteert geen betalingen meer"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "Alles versturen"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "Onbekende fout."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "Geen Bitcoin Cash portemonnee gevonden om bedrag naartoe over te maken."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "Geen Bitcoin Cash gevonden."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Bitcoin Core gevonden:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "Geen Bitcoin Core portemonnee gevonden om waarde naartoe te versturen."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "Geen Bitcoin Core gevonden."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "Scannen mislukt"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "Gegevens niet herkend."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "Niet ondersteund"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet wordt niet ondersteund."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "Open in webbrowser"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "Ongeldig adres"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "Bedrag is niet gespecificeerd"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "Bedrag lager is dan het minimum"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "Bedrag is boven het limiet"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Ongeldig respons van Shapeshift"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Polish\n"
"Language: pl\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "Numer konta"
msgid "Instant transactions with low fees"
msgstr "Natychmiastowe transakcje z niskimi prowizjami"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Niewystarczające środki"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Zmień walutę"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Dostępne środki"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Użyj wszystkich dostępnych środków"
#: www/views/amount.html:99
msgid "Next"
msgstr "Dalej"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "Konta"
@ -206,6 +226,20 @@ msgstr "Prawie gotowe! Dokonajmy przeglądu."
msgid "Alternative Currency"
msgstr "Alternatywna waluta"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "Wyświetlanie ceny"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Fiat"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Kryptowaluta"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com jest aktualnie niedostępny. Spróbuj później."
@ -486,7 +520,7 @@ msgid "Cannot Create Wallet"
msgstr "Nie można utworzyć portfela"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr "Nie można dołączyć tego samego portfela więcej niż raz"
#: www/views/includes/bitpayCardsCard.html:2
@ -662,6 +696,7 @@ msgstr "Współwłaściciele {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "Skopiowano do schowka"
@ -1281,6 +1316,7 @@ msgstr "Do celów audytu"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "Z"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "Otrzymywanie wiadomości i aktualizacji z BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "Pierwsze kroki"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "Zacznij"
@ -2168,6 +2200,10 @@ msgstr "Wypłata odrzucona"
msgid "Payment Sent"
msgstr "Płatność wysłana"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "Udostępnij tę transakcję"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "Wypłata zaakceptowana, ale jeszcze nie nadana"
@ -2185,7 +2221,7 @@ msgid "Payment details"
msgstr "Szczegóły wypłaty"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr "Wniosek o płatność"
#: www/views/mercadoLibreCards.html:22
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "Wklej adres"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Transfer z portfela do portfela"
msgid "Transfer between wallets"
msgstr "Transfer między portfelami"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,10 +2668,6 @@ msgstr "Zeskanuj kod QR"
msgid "Send Bitcoin faster!"
msgstr "Przesyłaj Bitcoiny szybciej!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Przesyłaj Bitcoiny szybciej!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Zapisz często używane adresy i wyślij im Bitcoin za pomocą jednego dotknięcia"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "Bitcoiny można odbierać z dowolnego portfela lub usługi."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Aby rozpocząć należy utworzyć portfel i dostać trochę bitcoinów."
@ -2891,10 +2925,15 @@ msgid "Sweep"
msgstr "Opróżnij"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Wyczyść papierowy portfel"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "Wyczyść papierowy portfel"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr "Sczytywanie portfela..."
@ -3061,6 +3100,14 @@ msgstr "Ta aplikacja przechowuje Twoje bitcoiny z zaawansowanymi zabezpieczeniam
msgid "This bitcoin payment request has expired."
msgstr "Ten wniosek płatności wygasł."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "Płatność wygasa:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "Wniosek o płatność wygasł"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "Do"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "Aby zacząć, kup bitcoiny lub udostępnij swój adres. Możesz otrzymać bitcoiny z dowolnego portfela lub usługi."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Aby rozpocząć należy utworzyć portfel i dostać trochę bitcoinów."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "Aby móc wykonać czynność {{reason}}, musisz przedtem dodać swoje konto BitPay {{email}}"
@ -3118,6 +3161,26 @@ msgstr "Doładowanie w trakcie..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "Doładuj o {{amountStr}} kartę debetową ({{cardLastNumber}})"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "Rozpocznij ShapeShift"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "Wymień BTC na BCH w ciągu paru chwil."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "Aby zacząć, dodaj środki do portfela."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "Proces jest szybki, a użytkownik otrzyma wymienione środki do portfela."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "Ta usługa jest świadczona przez podmiot zewnętrzny ShapeShift, który naliczy za nią niewielką opłatę. Będzie ona widoczna przed rozpoczęciem transakcji."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "Poznaj Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Gry Bitcoin Cash"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "Udostępnij aplikację Portfel"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Aktualności"
@ -3758,3 +3825,119 @@ msgstr "Darmowa Bitcoin Cash"
msgid "Your Bitcoin Wallets are ready!"
msgstr "Twoje portfele Bitcoin są gotowe!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "Adres nie zawiera informacji o walucie; upewnij się, że przesyłasz odpowiednią walutę."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "Potwierdzenie transakcji"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "Przesyłasz"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "Przelewasz"
#: www/views/review.html:36
msgid "To:"
msgstr "Do:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "Dodaj notatkę osobistą"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "Sugestia handlowca:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "Wprowadź tekst tutaj"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "Notatka osobista:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "Mniej niż 1 cent"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "Nie można już opłacić tej faktury"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "Wyślij maksymalną kwotę"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "Nieznany błąd."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "Nie znaleziono portfela Bitcoin Cash do przekazania środków."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "Nie znaleziono Bitcoin Cash."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Znaleziono Bitcoin Core:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "Nie znaleziono portfela Bitcoin Core do przekazania środków."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "Nie znaleziono Bitcoin Core."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "Skanowanie nie powiodło się"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "Nie rozpoznano danych."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "Nieobsługiwane"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Sieć testowa nie jest obsługiwana."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "Adres URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "Otwórz w przeglądarce internetowej"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "Nieprawidłowy adres"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "Kwota nie jest określona"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "Kwota niższa od minimalnej"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "Kwota przekracza limit"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Nieprawidłowa odpowiedź z Shapeshift"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Portuguese, Brazilian\n"
"Language: pt\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "Número de conta"
msgid "Instant transactions with low fees"
msgstr "Transações instantâneas com taxas baixas"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Fundos insuficientes"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Alterar moeda"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Fundos disponíveis"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Usar todos os fundos disponíveis"
#: www/views/amount.html:99
msgid "Next"
msgstr "Próximo"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "Contas"
@ -206,6 +226,20 @@ msgstr "Quase pronto! Vamos rever."
msgid "Alternative Currency"
msgstr "Moeda Alternativa"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "Exibição de preço"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Fiat"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Criptomoeda"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com não está disponível neste momento. Por favor, tente mais tarde."
@ -486,8 +520,8 @@ msgid "Cannot Create Wallet"
msgstr "Não é possível criar a carteira"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgstr "Não pode juntar-se a mesma carteira mais que uma vez"
msgid "Cannot join the same wallet more than once"
msgstr "Não pode juntar-se à mesma carteira mais que uma vez"
#: www/views/includes/bitpayCardsCard.html:2
msgid "Cards"
@ -662,6 +696,7 @@ msgstr "Copayer {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "Copiado para a área de transferência"
@ -1281,6 +1316,7 @@ msgstr "Para fins de auditoria"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "De"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "Receba notícias e atualizações da BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "Começar"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "Começar"
@ -1591,7 +1623,7 @@ msgstr "Endereço de rede incorreto"
#: src/js/controllers/confirm.js:306
#: src/js/services/bwcError.js:44
msgid "Insufficient confirmed funds"
msgstr "Insuficiência de fundos confirmados"
msgstr "Insuficiência de fundos confirmada"
#: src/js/controllers/topup.js:165
#: src/js/controllers/topup.js:177
@ -2058,7 +2090,7 @@ msgstr "Abrir Projeto no GitHub"
#: src/js/controllers/bitpayCard.js:123
#: src/js/controllers/tx-details.js:192
msgid "Open Explorer"
msgstr "Abra o Explorer"
msgstr "Abrir o Explorer"
#: www/views/tab-scan.html:22
msgid "Open Settings"
@ -2168,6 +2200,10 @@ msgstr "Pagamento Rejeitado"
msgid "Payment Sent"
msgstr "Pagamento Enviado"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "Compartilhar esta transação"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "Pagamento aceito, mas ainda não publicado"
@ -2185,8 +2221,8 @@ msgid "Payment details"
msgstr "Detalhes do pagamento"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgstr "Pedido de pagamento"
msgid "Payment Request"
msgstr "Solicitação de pagamento"
#: www/views/mercadoLibreCards.html:22
#: www/views/modals/mercadolibre-card-details.html:39
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "Colar endereço"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Transferência de carteira para carteira"
msgid "Transfer between wallets"
msgstr "Transferência entre carteiras"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,10 +2668,6 @@ msgstr "Digitalizar o código QR"
msgid "Send Bitcoin faster!"
msgstr "Envie Bitcoin mais rápido!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Envie Bitcoin mais rápido!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Salvar endereços usados com frequência e enviar Bitcoin com apenas um toque"
@ -2657,12 +2689,14 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "Você pode receber bitcoin de qualquer carteira ou serviço."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Para começar, você precisa criar uma carteira de bitcoins e obter alguns bitcoins."
#: www/views/tab-send.html:74
msgid "Buy Bitcoin now"
msgstr "Compre Bitcoin agora"
msgstr "Comprar Bitcoin agora"
#: www/views/tab-send.html:76
msgid "Show my address"
@ -2891,10 +2925,15 @@ msgid "Sweep"
msgstr "Limpar"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Varrer a carteira de papel"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "Varrer a carteira de papel"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr "Carteira de varredura..."
@ -3061,6 +3100,14 @@ msgstr "Este aplicativo armazena seu bitcoin com segurança de ponta."
msgid "This bitcoin payment request has expired."
msgstr "Este bitcoin pagamento pedido expirou."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "Pagamento expira em:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "Pedido de pagamento expirou"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "Para"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "Para começar, compre bitcoins ou compartilhe seu endereço. Você pode receber bitcoins de qualquer carteira ou serviço."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Para começar, você precisará criar uma carteira e obter algum bitcoin."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "Para {{reason}} você deve primeiro adicionar sua conta BitPay - {{email}}"
@ -3118,6 +3161,26 @@ msgstr "Recarga em andamento..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "Recarga de {{amountStr}} para cartão de débito ({{cardLastNumber}})"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "Iniciar ShapeShift"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "Troque seu BTC para BCH em minutos."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "Para iniciar o processo, você precisa adicionar fundos à sua carteira."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "O processo é rápido e você receberá a quantia convertida na sua carteira."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "Este serviço é fornecido pela terceira ShapeShift, que cobrará uma pequena taxa pelo serviço. A taxa será exibida antes de você iniciar a transação."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "Explore Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Jogos Bitcoin Cash"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "Compartilhar o app de carteira"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Notícias"
@ -3758,3 +3825,119 @@ msgstr "Bitcoin Cash grátis"
msgid "Your Bitcoin Wallets are ready!"
msgstr "As suas carteiras de Bitcoin estão prontas!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "O endereço não contém informações de moeda. Certifique-se de que está enviando a moeda correta."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "Revisar transação"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "Você está enviando"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "Você está trocando"
#: www/views/review.html:36
msgid "To:"
msgstr "Para:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "Adicionar nota pessoal"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "Sugerido pelo comerciante:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "Insira o texto aqui"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "Nota pessoal:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "Menos de 1 centavo"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "Essa fatura não aceita mais pagamentos"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "Enviar montante máximo"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "Erro desconhecido."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "Nenhuma carteira de Bitcoin Cash para transferir fundos encontrada."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "Bitcoin Cash não encontrado."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Bitcoin Core encontrado:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "Nenhuma carteira de Bitcoin Core para transferir fundos encontrada."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "Nenhum Bitcoin Core encontrado."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "Falha de verificação"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "Dados não reconhecidos."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "Não suportado"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet não suportado."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "Abrir no navegador da Web"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "Endereço inválido"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "Montante não definido"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "Montante abaixo do mínimo"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "Montante acima do limite"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Resposta inválida do Shapeshift"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Russian\n"
"Language: ru\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "Номер учётной записи"
msgid "Instant transactions with low fees"
msgstr "Мгновенные транзакции с низкой комиссией"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Недостаточно средств"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Изменить валюту"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Доступные средства"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Использовать все доступные средства"
#: www/views/amount.html:99
msgid "Next"
msgstr "Далее"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "Аккаунты"
@ -206,6 +226,20 @@ msgstr "Почти готово! Давайте проверим."
msgid "Alternative Currency"
msgstr "Альтернативная валюта"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "Отображение цен"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Фиатная валюта"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Криптовалюта"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Сайт Amazon.com сейчас недоступен. Попробуйте позже."
@ -486,7 +520,7 @@ msgid "Cannot Create Wallet"
msgstr "Не удаётся создать кошелёк"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr "Нельзя присоединиться к одному и тому же кошельку более одного раза"
#: www/views/includes/bitpayCardsCard.html:2
@ -662,6 +696,7 @@ msgstr "Совладелец {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "Скопировано в буфер обмена"
@ -1281,6 +1316,7 @@ msgstr "Для целей ревизии"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "От"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "Получать письма с новостями от BitPay"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "Начать"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "Начать"
@ -2168,6 +2200,10 @@ msgstr "Платёж отклонён"
msgid "Payment Sent"
msgstr "Платёж отправлен"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "Поделиться транзакцией"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "Платёж принят, но пока не отправлен"
@ -2185,7 +2221,7 @@ msgid "Payment details"
msgstr "Детали платежа"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr "Запрос платежа"
#: www/views/mercadoLibreCards.html:22
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "Вставить адрес"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "Перевод с кошелька на кошелек"
msgid "Transfer between wallets"
msgstr "Перевод между кошельками"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,10 +2668,6 @@ msgstr "Сканировать QR код"
msgid "Send Bitcoin faster!"
msgstr "Отправляйте биткойны еще быстрее!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "Отправляйте биткойны еще быстрее!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "Сохраняйте часто используемые адреса кошельков и отправляйте на них биткойны одним нажатием"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "Вы можете получать биткойны с любого кошелька или сервиса."
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Чтобы начать работу, вам нужно создать кошелёк и получить биткойн."
@ -2891,10 +2925,15 @@ msgid "Sweep"
msgstr "Считать"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Пополнить с бумажного кошелька"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "Пополнить с бумажного кошелька"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr "Считывание кошелька..."
@ -3061,6 +3100,14 @@ msgstr "Это приложение хранит биткойны с высоч
msgid "This bitcoin payment request has expired."
msgstr "Срок этого запроса платежа истёк."
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "Срок платежа:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "Срок запроса на платеж истёк"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "Кому"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "Чтобы начать работу, купите биткойн или поделитесь вашим адресом. Вы можете получать биткойны из любого кошелька или сервиса."
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "Чтобы начать работу, вам нужно создать кошелёк и получить биткойн."
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "{{reason}}: сначала нужно добавить учетную запись BitPay — {{email}}"
@ -3118,6 +3161,26 @@ msgstr "Выполняется пополнение..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "Пополнить дебетовую карту ({{cardLastNumber}}) на {{amountStr}}"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "Начать обмен ShapeShift"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "Обмен BTC на BCH за пару минут."
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "Для начала нужно добавить средства в кошелёк."
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "Обмен происходит быстро. Итоговая сумма поступит вам в кошелёк."
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "Услуга предоставляется сторонней компанией ShapeShift, которая взимает небольшую комиссию. Комиссия будет показана перед началом транзакции."
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "Обзор Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Игры Bitcoin Cash"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "Поделиться программой «Кошелёк»"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "Новости"
@ -3758,3 +3825,119 @@ msgstr "Bitcoin Cash бесплатно"
msgid "Your Bitcoin Wallets are ready!"
msgstr "Ваши кошельки готовы!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "Адрес не содержит сведений о валюте. Проверьте, правильную ли валюту вы отправляете."
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "Проверка транзакции"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "Вы отправляете"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "Вы меняете"
#: www/views/review.html:36
msgid "To:"
msgstr "Куда:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "Добавить личное сообщение"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "Предложено продавцом:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "Вводите текст сюда"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "Личное сообщение:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "менее 1 копейки"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "По этому инвойсу платежи больше не принимаются"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "Отправить максимальную сумму"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "Неизвестная ошибка."
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "Не найден кошелек Bitcoin Cash для перевода средств."
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "Не найден Bitcoin Cash."
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "Найден Bitcoin Core:"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "Не найден кошелек Bitcoin Core для перевода средств."
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "Не найден Bitcoin Core."
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "Ошибка сканирования"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "Данные не распознаны."
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "Не поддерживается"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "Testnet не поддерживается."
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "URL-адрес"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "Открыть в веб-браузере"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "Неверный адрес"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "Сумма не задана"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "Сумма ниже минимума"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "Сумма больше ограничения"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Неправильный ответ от Shapeshift"

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Swedish\n"
"Language: sv\n"
"PO-Revision-Date: 2018-07-27 08:44\n"
"PO-Revision-Date: 2018-09-06 16:45\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -41,7 +41,7 @@ msgstr "Fem stjärnor hjälper oss att göra {{appName}} bättre och mer åtkoml
#: www/views/mercadoLibre.html:18
#: www/views/mercadoLibre.html:40
msgid "<b>Only</b> redeemable on Mercado Livre (Brazil)"
msgstr ""
msgstr "<b>Only</b> redeemable on Mercado Livre (Brazil)"
#: src/js/controllers/feedback/send.js:27
#: www/views/feedback/complete.html:21
@ -79,7 +79,27 @@ msgstr "Kontonummer"
#: www/views/tab-home.html:61
msgid "Instant transactions with low fees"
msgstr ""
msgstr "Direkta transaktioner med låga avgifter"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "Otillräckliga medel"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "Ändra valuta"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "Tillgängliga medel"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "Använd alla tillgängliga medel"
#: www/views/amount.html:99
msgid "Next"
msgstr "Nästa"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
@ -199,13 +219,27 @@ msgstr "Tillåt notificationer"
#: www/views/onboarding/disclaimer.html:14
msgid "Almost done! Let's review."
msgstr ""
msgstr "Nästan klart! Låt oss granska."
#: www/views/preferencesAltCurrency.html:4
#: www/views/tab-settings.html:79
msgid "Alternative Currency"
msgstr "Alternativ Valuta"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr ""
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "Fiat"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "Kryptovaluta"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "Amazon.com är inte tillgängligt för tillfället. Försök igen senare."
@ -359,7 +393,7 @@ msgstr ""
#: www/views/addressbook.add.html:38
#: www/views/includes/incomingDataMenu.html:29
msgid "Bitcoin Address"
msgstr ""
msgstr "Bitcoin-adress"
#: www/views/cashScan.html:4
msgid "Bitcoin Cash (BCH) Balances"
@ -392,7 +426,7 @@ msgstr ""
#: www/views/onboarding/tour.html:31
msgid "Bitcoin is a currency."
msgstr ""
msgstr "Bitcoin är en valuta."
#: www/views/onboarding/disclaimer.html:15
msgid "Bitcoin is different &ndash; it cannot be safely held with a bank or web service."
@ -412,7 +446,7 @@ msgstr ""
#: www/views/modals/txp-details.html:36
msgid "Broadcast Payment"
msgstr ""
msgstr "Sänd betalning"
#: src/js/controllers/modals/txpDetails.js:64
#: src/js/controllers/tx-details.js:81
@ -421,16 +455,16 @@ msgstr ""
#: src/js/services/onGoingProcess.js:11
msgid "Broadcasting transaction"
msgstr ""
msgstr "Sänder transaktion"
#: www/views/unsupported.html:6
msgid "Browser unsupported"
msgstr ""
msgstr "Webbläsaren stöds inte"
#: www/views/buyAmazon.html:5
#: www/views/buyMercadoLibre.html:6
msgid "Buy"
msgstr ""
msgstr "Köp"
#: www/views/includes/buyAndSellCard.html:3
msgid "Buy &amp; Sell Bitcoin"
@ -439,16 +473,16 @@ msgstr ""
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr ""
msgstr "Köp Bitcoin"
#: www/views/mercadoLibre.html:22
#: www/views/mercadoLibre.html:50
msgid "Buy a Gift Card"
msgstr ""
msgstr "Köp ett presentkort"
#: src/js/controllers/buyAmazon.js:334
msgid "Buy from"
msgstr ""
msgstr "Köp från"
#: src/js/services/onGoingProcess.js:40
msgid "Buying Bitcoin..."
@ -456,7 +490,7 @@ msgstr ""
#: src/js/services/onGoingProcess.js:12
msgid "Calculating fee"
msgstr ""
msgstr "Beräknar avgift"
#: src/js/controllers/buyAmazon.js:313
#: src/js/controllers/buyMercadoLibre.js:307
@ -475,35 +509,35 @@ msgstr ""
#: www/views/modals/bitpay-card-confirmation.html:8
#: www/views/modals/confirmation.html:13
msgid "Cancel"
msgstr ""
msgstr "Avbryt"
#: www/views/copayers.html:36
msgid "Cancel invitation"
msgstr ""
msgstr "Avbryt inbjudan"
#: src/js/controllers/onboarding/tour.js:52
msgid "Cannot Create Wallet"
msgstr ""
msgstr "Kan inte skapa plånbok"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr ""
#: www/views/includes/bitpayCardsCard.html:2
msgid "Cards"
msgstr ""
msgstr "Kort"
#: www/views/modals/paypro.html:30
msgid "Certified by"
msgstr ""
msgstr "Certifierad av"
#: www/views/preferencesExternal.html:19
msgid "Check installation and retry."
msgstr ""
msgstr "Kontrollera installationen och försök igen."
#: www/views/tab-import-file.html:4
msgid "Choose a backup file from your computer"
msgstr ""
msgstr "Välj en backup-fil från din dator"
#: www/views/modals/wallets.html:9
msgid "Choose your destination wallet"
@ -662,6 +696,7 @@ msgstr ""
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr ""
@ -1281,6 +1316,7 @@ msgstr ""
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr ""
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr ""
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr ""
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr ""
@ -2168,6 +2200,10 @@ msgstr ""
msgid "Payment Sent"
msgstr ""
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr ""
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr ""
@ -2185,7 +2221,7 @@ msgid "Payment details"
msgstr ""
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr ""
#: www/views/mercadoLibreCards.html:22
@ -2621,7 +2657,7 @@ msgid "Paste Address"
msgstr ""
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgid "Transfer between wallets"
msgstr ""
#: www/views/tab-send.html:35
@ -2632,10 +2668,6 @@ msgstr ""
msgid "Send Bitcoin faster!"
msgstr ""
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr ""
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr ""
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr ""
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr ""
@ -2891,10 +2925,15 @@ msgid "Sweep"
msgstr ""
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr ""
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr ""
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr ""
@ -3061,6 +3100,14 @@ msgstr ""
msgid "This bitcoin payment request has expired."
msgstr ""
#: www/views/review.html:55
msgid "Payment expires:"
msgstr ""
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr ""
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr ""
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr ""
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr ""
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr ""
@ -3118,6 +3161,26 @@ msgstr ""
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr ""
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr ""
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr ""
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr ""
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr ""
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr ""
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr ""
msgid "Bitcoin Cash Games"
msgstr ""
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr ""
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr ""
@ -3758,3 +3825,119 @@ msgstr ""
msgid "Your Bitcoin Wallets are ready!"
msgstr ""
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr ""
#: www/views/review.html:4
msgid "Review Transaction"
msgstr ""
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr ""
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr ""
#: www/views/review.html:36
msgid "To:"
msgstr ""
#: www/views/review.html:53
msgid "Add personal note"
msgstr ""
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr ""
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr ""
#: www/views/review.html:57
msgid "Personal note:"
msgstr ""
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr ""
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr ""
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr ""
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr ""
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr ""
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr ""
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr ""
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr ""
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr ""
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr ""
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr ""
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr ""
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr ""
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr ""
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr ""
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr ""
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr ""
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr ""
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr ""
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr ""

View file

@ -72,6 +72,26 @@ msgstr ""
msgid "Instant transactions with low fees"
msgstr ""
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr ""
#: www/views/amount.html:42
msgid "Change Currency"
msgstr ""
#: www/views/amount.html:49
msgid "Available Funds"
msgstr ""
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr ""
#: www/views/amount.html:99
msgid "Next"
msgstr ""
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr ""
@ -197,6 +217,20 @@ msgstr ""
msgid "Alternative Currency"
msgstr ""
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr ""
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr ""
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr ""
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr ""
@ -428,6 +462,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr ""
#: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr ""
@ -476,7 +511,7 @@ msgid "Cannot Create Wallet"
msgstr ""
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr ""
#: www/views/includes/bitpayCardsCard.html:2
@ -652,6 +687,7 @@ msgstr ""
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr ""
@ -1271,6 +1307,7 @@ msgstr ""
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr ""
@ -1331,10 +1368,6 @@ msgid "Get news and updates from BitPay"
msgstr ""
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr ""
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr ""
@ -2158,6 +2191,10 @@ msgstr ""
msgid "Payment Sent"
msgstr ""
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr ""
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr ""
@ -2175,7 +2212,7 @@ msgid "Payment details"
msgstr ""
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgid "Payment Request"
msgstr ""
#: www/views/mercadoLibreCards.html:22
@ -2611,7 +2648,7 @@ msgid "Paste Address"
msgstr ""
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgid "Transfer between wallets"
msgstr ""
#: www/views/tab-send.html:35
@ -2622,10 +2659,6 @@ msgstr ""
msgid "Send Bitcoin faster!"
msgstr ""
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr ""
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr ""
@ -2647,6 +2680,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr ""
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr ""
@ -2881,10 +2916,15 @@ msgid "Sweep"
msgstr ""
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr ""
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr ""
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
msgstr ""
@ -3051,6 +3091,14 @@ msgstr ""
msgid "This bitcoin payment request has expired."
msgstr ""
#: www/views/review.html:55
msgid "Payment expires:"
msgstr ""
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr ""
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3092,10 +3140,6 @@ msgstr ""
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr ""
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr ""
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr ""
@ -3108,6 +3152,26 @@ msgstr ""
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr ""
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr ""
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr ""
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr ""
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr ""
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr ""
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3699,3 +3763,171 @@ msgstr ""
#: www/views/includes/walletInfo.html:18
msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr ""
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr ""
#: www/views/includes/community.html:3
msgid "Community"
msgstr ""
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr ""
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr ""
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr ""
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr ""
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr ""
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr ""
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr ""
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr ""
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr ""
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr ""
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr ""
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr ""
#: www/views/review.html:4
msgid "Review Transaction"
msgstr ""
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr ""
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr ""
#: www/views/review.html:36
msgid "To:"
msgstr ""
#: www/views/review.html:53
msgid "Add personal note"
msgstr ""
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr ""
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr ""
#: www/views/review.html:57
msgid "Personal note:"
msgstr ""
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr ""
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr ""
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr ""
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr ""
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr ""
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr ""
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr ""
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr ""
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr ""
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr ""
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr ""
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr ""
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr ""
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr ""
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr ""
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr ""
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr ""
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr ""
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr ""
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr ""

File diff suppressed because it is too large Load diff

View file

@ -11,7 +11,7 @@ msgstr ""
"Last-Translator: emilold\n"
"Language-Team: Chinese Simplified\n"
"Language: zh\n"
"PO-Revision-Date: 2018-07-27 08:43\n"
"PO-Revision-Date: 2018-09-15 05:56\n"
#: www/views/modals/paypro.html:34
msgid "(Trusted)"
@ -81,6 +81,26 @@ msgstr "帐号"
msgid "Instant transactions with low fees"
msgstr "以较低费用进行即时交易"
#: www/views/walletSelector.html:49
msgid "Insufficient funds"
msgstr "资金不足"
#: www/views/amount.html:42
msgid "Change Currency"
msgstr "更改货币"
#: www/views/amount.html:49
msgid "Available Funds"
msgstr "可用资金"
#: www/views/amount.html:59
msgid "Use All Available Funds"
msgstr "使用所有可用资金"
#: www/views/amount.html:99
msgid "Next"
msgstr "下一步"
#: www/views/preferencesBitpayServices.html:23
msgid "Accounts"
msgstr "帐户"
@ -206,6 +226,20 @@ msgstr "差不多完成了 !让我们回顾一下。"
msgid "Alternative Currency"
msgstr "替代货币"
#: www/views/tab-settings.html:75
msgid "Price Display"
msgstr "价格显示"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr "法币"
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr "加密货币"
#: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "亚马逊服务器暂时无法访问,请稍候再试。"
@ -486,7 +520,7 @@ msgid "Cannot Create Wallet"
msgstr "不能创建钱包"
#: src/js/services/profileService.js:442
msgid "Cannot join the same wallet more that once"
msgid "Cannot join the same wallet more than once"
msgstr "无法重复加入同一个钱包"
#: www/views/includes/bitpayCardsCard.html:2
@ -662,6 +696,7 @@ msgstr "Copayer {{$index}}"
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr "已复制到剪贴板"
@ -1281,6 +1316,7 @@ msgstr "供审计目的"
#: www/views/modals/txp-details.html:74
#: www/views/topup.html:34
#: www/views/tx-details.html:52
#: www/views/review.html:22
msgid "From"
msgstr "来自"
@ -1341,10 +1377,6 @@ msgid "Get news and updates from BitPay"
msgstr "从 BitPay 获取新闻和更新"
#: www/views/onboarding/welcome.html:8
msgctxt "button"
msgid "Get started"
msgstr "开始使用"
#: www/views/bitpayCard.html:49
msgid "Get started"
msgstr "马上体验"
@ -2168,6 +2200,10 @@ msgstr "支付被拒绝"
msgid "Payment Sent"
msgstr "支付已发送"
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr "分享此交易"
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr "支付已被接受,但尚未广播"
@ -2185,8 +2221,8 @@ msgid "Payment details"
msgstr "支付明细"
#: www/views/modals/paypro.html:6
msgid "Payment request"
msgstr "付请求"
msgid "Payment Request"
msgstr "付请求"
#: www/views/mercadoLibreCards.html:22
#: www/views/modals/mercadolibre-card-details.html:39
@ -2621,8 +2657,8 @@ msgid "Paste Address"
msgstr "粘贴地址"
#: www/views/tab-send.html:27
msgid "Wallet to Wallet Transfer"
msgstr "钱包转账"
msgid "Transfer between wallets"
msgstr "钱包之间转账"
#: www/views/tab-send.html:35
msgid "Scan QR Code"
@ -2632,10 +2668,6 @@ msgstr "扫描二维码"
msgid "Send Bitcoin faster!"
msgstr "更快地发送比特币!"
#: www/views/tab-send.html:46
msgid "Send Bitcoin faster!"
msgstr "更快地发送比特币!"
#: www/views/tab-send.html:50
msgid "Save frequently used addresses and send them Bitcoin in just one tap"
msgstr "保存常用地址,只需点击一下即可将比特币发送到这些地址"
@ -2657,6 +2689,8 @@ msgid "You can receive bitcoin from any wallet or service."
msgstr "您可以从任何钱包或服务接收比特币。"
#: www/views/tab-send.html:72
#: www/views/shapeshift.html:23
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "若要开始,您将需要创建一个比特币的钱包,并获得一些比特币。"
@ -2891,9 +2925,14 @@ msgid "Sweep"
msgstr "扫描"
#: www/views/includes/incomingDataMenu.html:89
#: www/views/paperWallet.html:3
msgctxt "List item"
msgid "Sweep paper wallet"
msgstr "Sweep 纸钱包"
msgstr "清空纸钱包"
#: www/views/paperWallet.html:3
msgctxt "Page title"
msgid "Sweep Paper Wallet"
msgstr "清空纸钱包"
#: src/js/services/onGoingProcess.js:33
msgid "Sweeping Wallet..."
@ -3061,6 +3100,14 @@ msgstr "此应用程序商店你比特币与尖端的安全。"
msgid "This bitcoin payment request has expired."
msgstr "这比特币付款请求已过期。"
#: www/views/review.html:55
msgid "Payment expires:"
msgstr "付款到期:"
#: www/views/review.html:56
msgid "Payment request has expired"
msgstr "付款请求已过期"
#: www/views/join.html:133
#: www/views/tab-create-personal.html:103
#: www/views/tab-create-shared.html:132
@ -3102,10 +3149,6 @@ msgstr "发送到"
msgid "To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service."
msgstr "若要开始,请买比特币或共享您的地址。你可以从任何钱包或服务接收比特币。"
#: www/views/tab-send.html:33
msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin."
msgstr "首先,您需要创建一个比特币钱包,并获得一些比特币。"
#: src/js/services/bitpayAccountService.js:73
msgid "To {{reason}} you must first add your BitPay account - {{email}}"
msgstr "到 {{reason}},您必须首先添加您的 BitPay 帐户-{{email}}"
@ -3118,6 +3161,26 @@ msgstr "在进展充值..."
msgid "Top up {{amountStr}} to debit card ({{cardLastNumber}})"
msgstr "充值 {{amountStr}},记入借方卡 ({{cardLastNumber}})"
#: www/views/shapeshift.html:30
msgid "Start ShapeShift"
msgstr "开始 ShapeShift"
#: www/views/shapeshift.html:30
msgid "Exchange your BTC to BCH in minutes."
msgstr "在数分钟内将您的 BTC 兑换为 BCH。"
#: www/views/shapeshift.html:30
msgid "To start the process you need to add funds to your wallet."
msgstr "要开始兑换,您需要先向钱包中充入资金。"
#: www/views/shapeshift.html:30
msgid "The process is fast and you will receive the exchanged amount in your wallet."
msgstr "兑换操作非常快,您将在自己的钱包中收到兑换后的金额。"
#: www/views/shapeshift.html:34
msgid "This service is provided by the third-party ShapeShift, who will charge a small fee for the service. The fee will be shown before you start the transaction."
msgstr "此服务由第三方 ShapeShift 提供,他们将收取少量服务费。所需费用将在您开始交易之前显示。"
#: www/views/buyAmazon.html:61
#: www/views/buyMercadoLibre.html:60
#: www/views/modals/wallet-balance.html:23
@ -3734,6 +3797,10 @@ msgstr "探索 Bitcoin.com"
msgid "Bitcoin Cash Games"
msgstr "Bitcoin Cash 游戏"
#: www/views/includes/community.html:29
msgid "Share the Wallet App"
msgstr "分享钱包应用"
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr "新闻"
@ -3758,3 +3825,119 @@ msgstr "免费的 Bitcoin Cash"
msgid "Your Bitcoin Wallets are ready!"
msgstr "您的比特币钱包已就绪!"
#: src/js/controllers/amount.js:49
msgid "Address does not contain currency information, please make sure you are sending the correct currency."
msgstr "地址未包含货币信息,请确保您发送的货币正确。"
#: www/views/review.html:4
msgid "Review Transaction"
msgstr "检查交易"
#: src/js/controllers/review.controller.js:36
msgid "You are sending"
msgstr "您将发送"
#: src/js/controllers/review.controller.js:66
msgid "You are shifting"
msgstr "您将兑换"
#: www/views/review.html:36
msgid "To:"
msgstr "到:"
#: www/views/review.html:53
msgid "Add personal note"
msgstr "添加个人注释"
#: www/views/review.html:87
msgid "Suggested by merchant:"
msgstr "商户建议:"
#: src/js/controllers/review.controller.js:37
msgid "Enter text here"
msgstr "在此处输入文本"
#: www/views/review.html:57
msgid "Personal note:"
msgstr "个人注释:"
#: www/views/review.html:69
msgid "Less than 1 cent"
msgstr "少于 1 美分"
#: src/js/services/incomingData.js:129
msgid "This invoice is no longer accepting payments"
msgstr "此发票不再接受付款"
#: www/views/amount.html.js:60
msgid "Send Maximum Amount"
msgstr "发送最大金额"
#: src/js/controllers/amount.controller.js:239
msgid "Unknown error."
msgstr "未知错误。"
#: www/views/paperWallet.html:48
msgid "No Bitcoin Cash wallet to transfer funds to found."
msgstr "未找到可以转入资金的 Bitcoin Cash 钱包。"
#: www/views/paperWallet.html:54
msgid "No Bitcoin Cash found."
msgstr "未找到 Bitcoin Cash。"
#: www/views/paperWallet.html:60
msgid "Bitcoin Core found:"
msgstr "已找到 Bitcoin Core"
#: www/views/paperWallet.html:98
msgid "No Bitcoin Core wallet to transfer funds to found."
msgstr "未找到可以转入资金的 Bitcoin Core 钱包。"
#: www/views/paperWallet.html:104
msgid "No Bitcoin Core found."
msgstr "未找到 Bitcoin Core。"
#: src/js/controllers/tab-scan.js:120
msgid "Scan Failed"
msgstr "扫描失败"
#: src/js/controllers/tab-scan.js:121
msgid "Data not recognised."
msgstr "数据未被识别。"
#: src/js/controllers/tab-scan.js:121
msgid "Unsupported"
msgstr "不受支持"
#: src/js/controllers/tab-scan.js:121
msgid "Testnet is not supported."
msgstr "不支持测试网。"
#: www/views/includes/incomingDataMenu.html:81
msgid "URL"
msgstr "网址"
#: www/views/includes/incomingDataMenu.html:90
msgid "Open in web browser"
msgstr "在网络浏览器中打开"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid address"
msgstr "地址无效"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is not defined"
msgstr "未定义金额"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is below the minimun"
msgstr "金额低于最低金额"
#: src/js/services/shapeshift.service.js.html:90
msgid "Amount is above the limit"
msgstr "金额高于限额"
#: src/js/services/shapeshift.service.js.html:90
msgid "Invalid response from Shapeshift"
msgstr "Shapeshift 的响应无效"

View file

@ -8,7 +8,7 @@
"postinstall": "npm run apply:copay && echo && echo \"Repo configured for standard Copay distribution. To switch to the BitPay distribution, run 'npm run apply:bitpay'.\" && echo",
"start": "echo && echo \"Choose a distribution by running 'npm run apply:copay' or 'npm run apply:bitpay'.\" && echo",
"apply:copay": "npm i fs-extra@0.30 && cd app-template && node apply.js copay && cd .. && npm i",
"apply:bitcoincom": "npm i fs-extra && cd app-template && node apply.js bitcoincom && npm i && cordova prepare",
"apply:bitcoincom": "npm i fs-extra && cd app-template && node apply.js bitcoincom && npm i && cordova prepare && cd ../ && ./fix-asn1.sh",
"apply:bitpay": "npm i fs-extra@0.30 && cd app-template && node apply.js bitpay && cd .. && npm i",
"unstage-package": "git reset package.json",
"clean-all": "git clean -dfx"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

View file

@ -178,11 +178,17 @@ def codesign_app(config, args):
plistlib.writePlist(child_entitlements, tmp_child_entitlements)
info('Child entitlements: %s' % tmp_child_entitlements)
framework = glob(args.output, 'nwjs Framework.framework', returnOnFound=True)
system('codesign -f --verbose -s "%s" --entitlements %s --deep "%s"' % (identity, tmp_child_entitlements, framework))
helperApp = glob(args.output, 'nwjs Helper.app', returnOnFound=True)
system('codesign -f --verbose -s "%s" --entitlements %s --deep "%s"' % (identity, tmp_child_entitlements, helperApp))
libffmpeg = glob(os.path.join(args.output, 'Contents/Versions/55.0.2883.87/nwjs Framework.framework/Versions/A'), 'libffmpeg.dylib', returnOnFound=True)
system('codesign --deep --force --verbose --verify --sign "%s" --entitlements %s --deep "%s"' % (identity, tmp_child_entitlements, libffmpeg))
libnode = glob(os.path.join(args.output, 'Contents/Versions/55.0.2883.87/nwjs Framework.framework/Versions/A'), 'libnode.dylib', returnOnFound=True)
system('codesign --deep --force --verbose --verify --sign "%s" --entitlements %s --deep "%s"' % (identity, tmp_child_entitlements, libnode))
helperApp = glob(args.output, 'nwjs Helper.app', returnOnFound=True)
system('codesign --deep --force --verbose --verify --sign "%s" --entitlements %s --deep "%s"' % (identity, tmp_child_entitlements, helperApp))
framework = glob(args.output, 'nwjs Framework.framework', returnOnFound=True)
system('codesign --deep --force --verbose --verify --sign "%s" --entitlements %s --deep "%s"' % (identity, tmp_child_entitlements, framework))
## sign parent app
(_, tmp_parent_entitlements) = tempfile.mkstemp()
if config.has_option('Sign', 'ParentEntitlements'):

View file

@ -5,7 +5,9 @@
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<string>$GROUPID</string>
<array>
<string>299HJ3G3BP.com.bitcoin.mwallet.mac</string>
</array>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.network.client</key>

View file

@ -1,21 +1,25 @@
ext {
ANDROID_SUPPORT_V4_VERSION = '26.1.0'
}
configurations.all {
resolutionStrategy {
force "com.android.support:support-v4:26.1.0"
force "com.google.android.gms:play-services-auth:11.8.0"
force "com.google.android.gms:play-services-identity:11.8.0"
force "com.google.android.gms:play-services-ads:11.8.0"
force "com.google.android.gms:play-services-base:11.8.0"
force "com.google.android.gms:play-services-gcm:11.8.0"
force "com.google.android.gms:play-services-analytics:11.8.0"
force "com.google.android.gms:play-services-location:11.8.0"
force "com.google.android.gms:play-services-basement:11.8.0"
force "com.google.android.gms:play-services-tagmanager:11.8.0"
force 'com.google.firebase:firebase-core:11.8.0'
force 'com.google.firebase:firebase-crash:11.8.0'
force 'com.google.firebase:firebase-auth:11.8.0'
force 'com.google.firebase:firebase-common:11.8.0'
force 'com.google.firebase:firebase-config:11.8.0'
force 'com.google.firebase:firebase-perf:11.8.0'
force 'com.google.firebase:firebase-messaging:11.8.0'
}
resolutionStrategy {
force "com.android.support:support-v4:26.1.0"
force "com.google.android.gms:play-services-auth:11.8.0"
force "com.google.android.gms:play-services-identity:11.8.0"
force "com.google.android.gms:play-services-ads:11.8.0"
force "com.google.android.gms:play-services-base:11.8.0"
force "com.google.android.gms:play-services-gcm:11.8.0"
force "com.google.android.gms:play-services-analytics:11.8.0"
force "com.google.android.gms:play-services-location:11.8.0"
force "com.google.android.gms:play-services-basement:11.8.0"
force "com.google.android.gms:play-services-tagmanager:11.8.0"
force 'com.google.firebase:firebase-core:11.8.0'
force 'com.google.firebase:firebase-crash:11.8.0'
force 'com.google.firebase:firebase-auth:11.8.0'
force 'com.google.firebase:firebase-common:11.8.0'
force 'com.google.firebase:firebase-config:11.8.0'
force 'com.google.firebase:firebase-perf:11.8.0'
force 'com.google.firebase:firebase-messaging:11.8.0'
}
}

View file

@ -19,7 +19,9 @@ var modules = [
'copayApp.controllers',
'copayApp.directives',
'copayApp.addons',
'bitcoincom.directives'
'bitcoincom.controllers',
'bitcoincom.directives',
'bitcoincom.services'
];
var copayApp = window.copayApp = angular.module('copayApp', modules);
@ -29,4 +31,6 @@ angular.module('copayApp.services', []);
angular.module('copayApp.controllers', []);
angular.module('copayApp.directives', []);
angular.module('copayApp.addons', []);
angular.module('bitcoincom.controllers', []);
angular.module('bitcoincom.directives', []);
angular.module('bitcoincom.services', []);

View file

@ -21,6 +21,9 @@ angular.module('copayApp.controllers').controller('addressbookAddController', fu
$timeout(function() {
var form = addressbookForm;
if (data && form) {
if (data.result) {
data = data.result;
}
data = data.replace(/^bitcoin(cash)?:/, '');
form.address.$setViewValue(data);
form.address.$isValid = true;
@ -36,9 +39,9 @@ angular.module('copayApp.controllers').controller('addressbookAddController', fu
addressbook.address = translated.legacy;
}
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("contact_created", [{
"coin": $scope.addressbookEntry.coin

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('addressbookViewController', function($scope, $state, $timeout, lodash, addressbookService, popupService, $ionicHistory, platformInfo, gettextCatalog, configService, bitcoinCashJsService) {
angular.module('copayApp.controllers').controller('addressbookViewController', function($scope, sendFlowService, $state, $timeout, lodash, addressbookService, popupService, $ionicHistory, platformInfo, gettextCatalog, configService, bitcoinCashJsService) {
var config = configService.getSync();
var defaults = configService.getDefaults();
@ -21,23 +21,14 @@ angular.module('copayApp.controllers').controller('addressbookViewController', f
});
$scope.sendTo = function() {
$ionicHistory.removeBackView();
$state.go('tabs.send');
$timeout(function() {
var to = '';
if ($scope.addressbookEntry.coin == 'bch') {
var a = 'bitcoincash:' + $scope.addressbookEntry.address;
to = bitcoinCashJsService.readAddress(a).legacy;
} else {
to = $scope.addressbookEntry.address;
}
$state.transitionTo('tabs.send.amount', {
toAddress: to,
toName: $scope.addressbookEntry.name,
toEmail: $scope.addressbookEntry.email,
coin: $scope.addressbookEntry.coin
});
}, 100);
var stateParams = {
data: $scope.addressbookEntry.address,
toName: $scope.addressbookEntry.name,
toEmail: $scope.addressbookEntry.email,
coin: $scope.addressbookEntry.coin
};
sendFlowService.start(stateParams);
};
$scope.remove = function(addressbookEntry) {

View file

@ -0,0 +1,774 @@
'use strict';
(function(){
angular
.module('bitcoincom.controllers')
.controller('amountController', amountController);
function amountController(configService, $filter, gettextCatalog, $ionicHistory, $ionicModal, $ionicScrollDelegate, lodash, $log, nodeWebkitService, rateService, $scope, $state, $timeout, sendFlowService, shapeshiftService, txFormatService, platformInfo, ongoingProcess, popupService, profileService, walletService, $window) {
var vm = this;
// Variables
vm.allowSend = false;
vm.altCurrencyList = [];
vm.alternativeAmount = '';
vm.alternativeUnit = '';
vm.amount = '0';
vm.availableFunds = '';
vm.canSendAllAvailableFunds = true;
vm.errorMessage = '';
// Use insufficient for logic, as when the amount is invalid, funds being
// either sufficent or insufficient doesn't make sense.
vm.fundsAreInsufficient = false;
vm.globalResult = '';
vm.isRequestingSpecificAmount = false;
vm.listComplete = false;
vm.lastUsedPopularList = [];
vm.maxAmount = 0;
vm.minAmount = 0;
vm.sendableFunds = '';
vm.showSendMaxButton = false;
vm.showSendLimitMaxButton = false;
vm.thirdParty = false;
vm.unit = '';
// Functions
vm.changeUnit = changeUnit;
vm.close = close;
vm.findCurrency = findCurrency;
vm.finish = finish;
vm.goBack = goBack;
vm.loadMore = loadMore;
vm.next = next;
vm.openPopup = openPopup;
vm.pushDigit = pushDigit;
vm.removeDigit = removeDigit;
vm.save = save;
vm.sendMax = sendMax;
$scope.$on('$ionicView.beforeEnter', onBeforeEnter);
$scope.$on('$ionicView.leave', onLeave);
var LENGTH_EXPRESSION_LIMIT = 19;
var LENGTH_BEFORE_COMMA_EXPRESSION_LIMIT = 8;
var LENGTH_AFTER_COMMA_EXPRESSION_LIMIT = 8;
var altCurrencyModal = null;
var altUnitIndex = 0;
var availableUnits = [];
var canSendMax = true;
var fiatCode;
var isNW = platformInfo.isNW;
var isAndroid = platformInfo.isAndroid;
var isIos = platformInfo.isIOS;
var lastUsedAltCurrencyList = [];
var passthroughParams = {};
var satToUnit;
var transactionSendableAmount = {
crypto: '',
satoshis: null
};
var unitDecimals;
var unitIndex = 0;
var unitToSatoshi;
var useSendMax = false;
var walletSpendableAmount = {
crypto: '',
satoshis: null
};
function onLeave() {
angular.element($window).off('keydown');
}
function onBeforeEnter(event, data) {
if (data.direction == "back") {
sendFlowService.state.pop();
}
initCurrencies();
passthroughParams = sendFlowService.state.getClone();
console.log('amount onBeforeEnter after back sendflow ', passthroughParams);
vm.fromWalletId = passthroughParams.fromWalletId;
vm.toWalletId = passthroughParams.toWalletId;
vm.minAmount = parseFloat(passthroughParams.minAmount);
vm.maxAmount = parseFloat(passthroughParams.maxAmount);
vm.isRequestingSpecificAmount = !passthroughParams.fromWalletId;
vm.showSendMaxButton = !vm.isRequestingSpecificAmount;
var config = configService.getSync().wallet.settings;
unitToSatoshi = config.unitToSatoshi;
satToUnit = 1 / unitToSatoshi;
unitDecimals = config.unitDecimals;
setAvailableUnits();
updateUnitUI();
var reNr = /^[1234567890\.]$/;
var reOp = /^[\*\+\-\/]$/;
if (!isAndroid && !isIos) {
angular.element($window).on('keydown', function(e) {
if (!e.key) return;
if (e.which === 8) { // you can add others here inside brackets.
if (!altCurrencyModal) {
e.preventDefault();
vm.removeDigit();
}
}
if (e.key.match(reNr)) {
vm.pushDigit(e.key);
} else if (e.key.match(reOp)) {
pushOperator(e.key);
} else if (e.keyCode === 86) {
if (e.ctrlKey || e.metaKey) processClipboard();
} else if (e.keyCode === 13) vm.finish();
$timeout(function() {
$scope.$apply();
});
});
}
resetAmount();
processAmount();
$timeout(function() {
$ionicScrollDelegate.resize();
}, 10);
function setAvailableUnits() {
var defaults = configService.getDefaults();
var configCache = configService.getSync();
availableUnits = [];
var coinFromWallet = '';
if (passthroughParams.fromWalletId) {
var fromWallet = profileService.getWallet(passthroughParams.fromWalletId);
coinFromWallet = fromWallet.coin;
} else {
var toWallet = profileService.getWallet(passthroughParams.toWalletId);
coinFromWallet = toWallet.coin;
}
if (coinFromWallet === 'bch') {
availableUnits.push({
name: 'Bitcoin Cash',
id: 'bch',
shortName: (configCache.bitcoinCashAlias || defaults.bitcoinCashAlias).toUpperCase(),
});
};
if (coinFromWallet === 'btc') {
availableUnits.push({
name: 'Bitcoin',
id: 'btc',
shortName: (configCache.bitcoinAlias || defaults.bitcoinAlias).toUpperCase(),
});
}
unitIndex = 0;
// currency have preference
var fiatName;
if (passthroughParams.currency) {
fiatCode = passthroughParams.currency;
altUnitIndex = unitIndex
unitIndex = availableUnits.length;
} else {
fiatCode = config.alternativeIsoCode || 'USD';
fiatName = config.alternanativeName || fiatCode;
altUnitIndex = availableUnits.length;
}
availableUnits.push({
name: fiatName || fiatCode,
// TODO
id: fiatCode,
shortName: fiatCode,
isFiat: true,
});
unitIndex = lodash.findIndex(availableUnits, {
isFiat: true
});
altUnitIndex = 0;
if (passthroughParams.fromWalletId) {
var fromWallet = profileService.getWallet(passthroughParams.fromWalletId);
updateAvailableFundsFromWallet(fromWallet);
}
if (passthroughParams.thirdParty) {
vm.thirdParty = passthroughParams.thirdParty; // Parse stringified JSON-object
if (vm.thirdParty) {
initShapeshift();
}
}
}
}
function goBack() {
sendFlowService.router.goBack();
}
function initShapeshift() {
if (vm.thirdParty.id === 'shapeshift') {
vm.thirdParty.data = vm.thirdParty.data || {};
vm.fromWallet = profileService.getWallet(vm.fromWalletId);
vm.toWallet = profileService.getWallet(vm.toWalletId);
vm.showSendMaxButton = false;
vm.showSendLimitMaxButton = false;
vm.canSendAllAvailableFunds = false;
ongoingProcess.set('connectingShapeshift', true);
shapeshiftService.getMarketData(vm.fromWallet.coin, vm.toWallet.coin, function onMarketData(err, data) {
ongoingProcess.set('connectingShapeshift', false);
if (err) {
// Error stop here
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.message, function () {
goBack();
});
} else {
vm.thirdParty.data.minAmount = vm.minAmount = parseFloat(data.minimum);
vm.thirdParty.data.maxAmount = vm.maxAmount = parseFloat(data.maxLimit);
setMaximumButtonFromWallet(vm.fromWallet);
}
});
}
}
function paste(value) {
vm.amount = value;
processAmount();
$timeout(function() {
$scope.$apply();
});
}
function processClipboard() {
if (!isNW) return;
var value = nodeWebkitService.readFromClipboard();
if (value && evaluate(value) > 0) paste(evaluate(value));
}
function sendMax() {
if (canSendMax) {
useSendMax = true;
finish();
} else {
var transactionSendableAmountInUnits = transactionSendableAmount.satoshis * satToUnit;
if (vm.minAmount && transactionSendableAmountInUnits < vm.minAmount) {
popupService.showAlert(
gettextCatalog.getString('Insufficient funds'),
gettextCatalog.getString('Amount below minimum allowed')
);
} else {
// Need to be precise, so use crypto directly rather than fiat with exchange rate
if (availableUnits[unitIndex].isFiat) {
var tempIndex = altUnitIndex;
altUnitIndex = unitIndex;
unitIndex = tempIndex;
}
vm.amount = transactionSendableAmountInUnits.toFixed(LENGTH_AFTER_COMMA_EXPRESSION_LIMIT);
useSendMax = true;
finish();
}
}
}
function updateUnitUI() {
vm.unit = availableUnits[unitIndex].shortName;
vm.alternativeUnit = availableUnits[altUnitIndex].shortName;
processAmount();
$log.debug('Update unit coin @amount unit:' + vm.unit + " alternativeUnit:" + vm.alternativeUnit);
}
function changeUnit() {
vm.amount = '0';
if (!(availableUnits[unitIndex].isFiat && availableUnits.length > 2 && altUnitIndex == 0)) {
unitIndex++;
if (unitIndex >= availableUnits.length) unitIndex = 0;
}
if (availableUnits[unitIndex].isFiat) {
altUnitIndex = altUnitIndex == 0 && availableUnits.length > 2 ? 1 : 0;
} else {
altUnitIndex = lodash.findIndex(availableUnits, {
isFiat: true
});
}
updateAvailableFundsStringIfNeeded();
updateUnitUI();
}
function pushDigit(digit) {
if (vm.amount && digit != '.') {
var amountSplitByComma = vm.amount.split('.');
if (amountSplitByComma.length > 1 && amountSplitByComma[1].length >= LENGTH_AFTER_COMMA_EXPRESSION_LIMIT) return;
if (amountSplitByComma.length == 1 && amountSplitByComma[0].length >= LENGTH_BEFORE_COMMA_EXPRESSION_LIMIT) return;
}
if (vm.amount && vm.amount.length >= LENGTH_EXPRESSION_LIMIT) return;
if (vm.amount.indexOf('.') > -1 && digit == '.') return;
if (vm.amount == '0' && digit == '0') return;
if (availableUnits[unitIndex].isFiat && vm.amount.indexOf('.') > -1 && vm.amount[vm.amount.indexOf('.') + 2]) return;
if (vm.amount == '0' && digit != '.') {
vm.amount = '';
}
if (vm.amount == '' && digit == '.') {
vm.amount = '0';
}
vm.amount = (vm.amount + digit).replace('..', '.');
processAmount();
}
function pushOperator(operator) {
if (!vm.amount || vm.amount.length == 0) return;
vm.amount = pushOperator(vm.amount);
function pushOperator(val) {
if (!isOperator(lodash.last(val))) {
return val + operator;
} else {
return val.slice(0, -1) + operator;
}
}
}
function isOperator(val) {
var regex = /[\/\-\+\x\*]/;
return regex.test(val);
}
function isExpression(val) {
var regex = /^\.?\d+(\.?\d+)?([\/\-\+\*x]\d?\.?\d+)+$/;
return regex.test(val);
}
function removeDigit() {
vm.amount = (vm.amount).toString().slice(0, -1);
processAmount();
}
function resetAmount() {
vm.amount = vm.alternativeAmount = vm.globalResult = '0';
vm.allowSend = false;
}
function openPopup() {
$ionicModal.fromTemplateUrl('views/modals/altCurrency.html', {
scope: $scope
}).then(function(modal) {
altCurrencyModal = modal;
altCurrencyModal.show();
});
}
function close() {
altCurrencyModal.remove();
altCurrencyModal = null;
}
function processAmount() {
var formatedValue = format(vm.amount);
var result = evaluate(formatedValue);
var amountInCrypto = 0;
if (lodash.isNumber(result)) {
vm.globalResult = isExpression(vm.amount) ? '= ' + processResult(result) : '';
if (availableUnits[unitIndex].isFiat) {
var a = fromFiat(result);
if (a) {
amountInCrypto = a;
var amountInSatoshis = a * unitToSatoshi;
vm.fundsAreInsufficient = !!passthroughParams.fromWalletId
&& walletSpendableAmount.satoshis !== null
&& walletSpendableAmount.satoshis < amountInSatoshis;
vm.alternativeAmount = txFormatService.formatAmount(amountInSatoshis, true);
vm.allowSend = lodash.isNumber(a)
&& a > 0
&& (!vm.minAmount || a >= vm.minAmount)
&& (!vm.maxAmount || a <= vm.maxAmount)
&& !vm.fundsAreInsufficient;
} else {
if (result) {
vm.alternativeAmount = 'N/A';
} else {
vm.alternativeAmount = null;
}
vm.fundsAreInsufficient = false;
vm.allowSend = false;
}
} else {
amountInCrypto = result;
vm.fundsAreInsufficient = passthroughParams.fromWalletId
&& walletSpendableAmount.satoshis !== null
&& walletSpendableAmount.satoshis < result * unitToSatoshi;
vm.alternativeAmount = $filter('formatFiatAmount')(toFiat(result));
vm.allowSend = lodash.isNumber(result)
&& result > 0
&& (!vm.minAmount || result >= vm.minAmount)
&& (!vm.maxAmount || result <= vm.maxAmount)
&& !vm.fundsAreInsufficient;
}
} else {
vm.fundsAreInsufficient = false;
}
if (vm.fundsAreInsufficient) {
vm.errorMessage = gettextCatalog.getString('Not enough available funds');
} else if (amountInCrypto && vm.thirdParty && vm.thirdParty.id === 'shapeshift') {
if (amountInCrypto < vm.minAmount) {
vm.errorMessage = gettextCatalog.getString('Amount is below minimum');
} else if (amountInCrypto > vm.maxAmount) {
vm.errorMessage = gettextCatalog.getString('Amount is above maximum');
} else {
vm.errorMessage = '';
}
} else {
vm.errorMessage = '';
}
}
function processResult(val) {
if (availableUnits[unitIndex].isFiat) return $filter('formatFiatAmount')(val);
else return txFormatService.formatAmount(val.toFixed(unitDecimals) * unitToSatoshi, true);
}
function fromFiat(val) {
return parseFloat((rateService.fromFiat(val, fiatCode, availableUnits[altUnitIndex].id) * satToUnit).toFixed(unitDecimals));
}
function toFiat(val) {
if (!rateService.getRate(fiatCode)) return;
return parseFloat((rateService.toFiat(val * unitToSatoshi, fiatCode, availableUnits[unitIndex].id)).toFixed(2));
}
function evaluate(val) {
var result;
try {
result = $scope.$eval(val);
} catch (e) {
return 0;
}
if (!lodash.isFinite(result)) return 0;
return result;
}
function format(val) {
if (!val) return;
var result = val.toString();
if (isOperator(lodash.last(val))) result = result.slice(0, -1);
return result.replace('x', '*');
}
function finish() {
var unit = availableUnits[unitIndex];
var uiAmount = evaluate(format(vm.amount));
var satoshis = 0;
if (unit.isFiat) {
satoshis = Math.floor(fromFiat(uiAmount) * unitToSatoshi);
} else {
satoshis = Math.floor(uiAmount * unitToSatoshi);
}
var confirmData = {
amount: (useSendMax && canSendMax) ? undefined : satoshis,
displayAddress: passthroughParams.displayAddress,
fromWalletId: passthroughParams.fromWalletId,
sendMax: useSendMax,
toAddress: passthroughParams.toAddress,
toWalletId: passthroughParams.toWalletId
};
if (vm.thirdParty) {
confirmData.thirdParty = vm.thirdParty;
}
if (!confirmData.fromWalletId) {
$state.transitionTo('tabs.paymentRequest.confirm', confirmData);
} else {
sendFlowService.goNext(confirmData);
useSendMax = false;
}
}
// Currency
var nextCurrencies = 10;
var completeAlternativeList = [];
var popularCurrencyList = [
{isoCode: 'USD', order: 0},
{isoCode: 'EUR', order: 1},
{isoCode: 'JPY', order: 2},
{isoCode: 'GBP', order: 3},
{isoCode: 'AUD', order: 4},
{isoCode: 'CAD', order: 5},
{isoCode: 'CHF', order: 6},
{isoCode: 'CNY', order: 7},
{isoCode: 'KRW', order: 8},
{isoCode: 'HKD', order: 9},
];
function initCurrencies() {
var unusedCurrencyList = [{
isoCode: 'LTL'
}, {
isoCode: 'BTC'
}, {
isoCode: 'BCC'
}, {
isoCode: 'BCH_BTC'
}, {
isoCode: 'BCH'
}];
rateService.whenAvailable(function() {
vm.listComplete = false;
var idx = lodash.indexBy(unusedCurrencyList, 'isoCode');
var idx2 = lodash.indexBy(lastUsedAltCurrencyList, 'isoCode');
var idx3 = lodash.indexBy(popularCurrencyList, 'isoCode');
var alternatives = rateService.listAlternatives(true);
lodash.each(alternatives, function(c) {
if (idx3[c.isoCode]) {
idx3[c.isoCode].name = c.name;
}
if (!idx[c.isoCode] && !idx2[c.isoCode] && !idx3[c.isoCode]) {
completeAlternativeList.push(c);
}
});
vm.altCurrencyList = completeAlternativeList.slice(0, 10);
vm.lastUsedPopularList = lodash.unique(lodash.union(lastUsedAltCurrencyList, popularCurrencyList), 'isoCode');
rateService.updateRates();
$timeout(function() {
$scope.$apply();
});
});
}
function loadMore() {
$timeout(function() {
vm.altCurrencyList = completeAlternativeList.slice(0, nextCurrencies);
nextCurrencies += 10;
vm.listComplete = vm.altCurrencyList.length >= completeAlternativeList.length;
$scope.$broadcast('scroll.infiniteScrollComplete');
}, 100);
}
function next() {
useSendMax = false;
vm.finish();
}
function findCurrency(search) {
if (!search) initCurrencies();
var list = lodash.unique(lodash.union(completeAlternativeList, lodash.union(lastUsedAltCurrencyList, popularCurrencyList)), 'isoCode');
vm.altCurrencyList = lodash.filter(list, function(item) {
var val = item.name
var val2 = item.isoCode;
return lodash.includes(val.toLowerCase(), search.toLowerCase()) || lodash.includes(val2.toLowerCase(), search.toLowerCase());
});
$timeout(function() {
$scope.$apply();
});
}
function save(newAltCurrency) {
var opts = {
wallet: {
settings: {
alternativeName: newAltCurrency.name,
alternativeIsoCode: newAltCurrency.isoCode,
}
}
};
configService.set(opts, function(err) {
if (err) $log.warn(err);
walletService.updateRemotePreferences(profileService.getWallets());
var altUnitIndex = lodash.findIndex(availableUnits, {
isFiat: true
});
availableUnits[altUnitIndex].id = newAltCurrency.isoCode;
availableUnits[altUnitIndex].name = newAltCurrency.isoCode;
availableUnits[altUnitIndex].shortName = newAltCurrency.isoCode;
fiatCode = newAltCurrency.isoCode;
updateAvailableFundsStringIfNeeded();
updateUnitUI();
close();
});
}
function updateAvailableFundsStringIfNeeded() {
if (passthroughParams.fromWalletId && walletSpendableAmount.satoshis !== null) {
vm.availableFunds = walletSpendableAmount.crypto;
if (availableUnits[unitIndex].isFiat) {
var coin = availableUnits[altUnitIndex].id;
txFormatService.formatAlternativeStr(coin, walletSpendableAmount.satoshis, function formatCallback(formatted){
if (formatted) {
$scope.$apply(function() {
vm.availableFunds = formatted;
});
}
});
}
updateMaximumButtonIfNeeded();
}
}
function updateAvailableFundsFromWallet(wallet) {
console.log('amount updateAvailableFundsFromWallet()');
var availableFundsInFiat = '';
if (wallet.status && wallet.status.isValid) {
walletSpendableAmount.crypto = wallet.status.spendableBalanceStr;
walletSpendableAmount.satoshis = wallet.status.spendableAmount;
if (wallet.status.alternativeBalanceAvailable) {
availableFundsInFiat = wallet.status.spendableBalanceAlternative + ' ' + wallet.status.alternativeIsoCode;
} else {
availableFundsInFiat = '';
}
} else if (wallet.cachedStatus && wallet.cachedStatus.isValid) {
if (wallet.cachedStatus.alternativeBalanceAvailable) {
availableFundsInFiat = wallet.cachedStatus.spendableBalanceAlternative + ' ' + wallet.cachedStatus.alternativeIsoCode;
} else {
availableFundsInFiat = '';
}
walletSpendableAmount.crypto = wallet.cachedStatus.spendableBalanceStr;
walletSpendableAmount.satoshis = wallet.cachedStatus.spendableAmount;
} else {
walletSpendableAmount.crypto = '';
walletSpendableAmount.satoshis = null;
}
if (availableUnits[unitIndex].isFiat) {
vm.availableFunds = availableFundsInFiat || walletSpendableAmount.crypto;
} else {
vm.availableFunds = walletSpendableAmount.crypto;
}
setMaximumButtonFromWallet(wallet);
}
function updateMaximumButtonIfNeeded() {
console.log('sendmax updateMaximumButtonIfNeeded()');
if (vm.showSendMaxButton || vm.showSendLimitMaxButton) {
transactionSendableAmount.fiat = '';
vm.sendableFunds = transactionSendableAmount.crypto;
if (availableUnits[unitIndex].isFiat) {
var coin = availableUnits[altUnitIndex].id;
txFormatService.formatAlternativeStr(coin, transactionSendableAmount.satoshis, function formatCallback(formatted){
if (formatted) {
$scope.$apply(function onApply() {
vm.sendableFunds = formatted;
});
}
});
}
}
}
function setMaximumButtonFromWallet(wallet) {
console.log('sendmax setMaximumButtonFromWallet()');
var minSatoshis = vm.minAmount * unitToSatoshi;
var maxSatoshis = vm.maxAmount * unitToSatoshi;
if (minSatoshis > walletSpendableAmount.satoshis) {
console.log('sendmax Hiding max buttons as minimum is too high.');
canSendMax = false;
vm.showSendMaxButton = true;
vm.showSendLimitMaxButton = false;
transactionSendableAmount.satoshis = walletSpendableAmount.satoshis;
} else if (maxSatoshis) {
if (walletSpendableAmount.satoshis > maxSatoshis) {
console.log('sendmax Showing max limit button as available is greater than max limit.');
canSendMax = false;
vm.showSendMaxButton = false;
vm.showSendLimitMaxButton = true;
transactionSendableAmount.satoshis = maxSatoshis;
} else {
console.log('sendmax Showing sendmax as all available as less than max limit.');
// Enabling send max here is a little dangerous, if they receive funds between pressing
// this and the calculation in the Review screen.
canSendMax = false;
vm.showSendMaxButton = true;
vm.showSendLimitMaxButton = false;
transactionSendableAmount.satoshis = walletSpendableAmount.satoshis;
}
} else {
console.log('sendmax Showing sendmax as all available because no limits.');
canSendMax = true;
vm.showSendMaxButton = true;
vm.showSendLimitMaxButton = false;
transactionSendableAmount.satoshis = walletSpendableAmount.satoshis;
}
if (vm.showSendMaxButton || vm.showSendLimitMaxButton) {
console.log('sendmax Setting max button text');
transactionSendableAmount.crypto = txFormatService.formatAmountStr(wallet.coin, transactionSendableAmount.satoshis);
vm.sendableFunds = transactionSendableAmount.crypto;
if (availableUnits[unitIndex].isFiat) {
txFormatService.formatAlternativeStr(wallet.coin, transactionSendableAmount.satoshis, function onFormat(formatted){
if (formatted) {
$scope.$apply(function onApply() {
vm.sendableFunds = formatted;
});
}
});
}
}
}
}
})();

View file

@ -1,636 +0,0 @@
'use strict';
angular.module('copayApp.controllers').controller('amountController', function($scope, $filter, $timeout, $ionicModal, $ionicScrollDelegate, $ionicHistory, storageService, walletService, gettextCatalog, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, txFormatService, ongoingProcess, popupService, bwcError, payproService, profileService, bitcore, amazonService, nodeWebkitService) {
var _id;
var unitToSatoshi;
var satToUnit;
var unitDecimals;
var satToBtc;
var SMALL_FONT_SIZE_LIMIT = 10;
var LENGTH_EXPRESSION_LIMIT = 19;
var LENGTH_BEFORE_COMMA_EXPRESSION_LIMIT = 8;
var LENGTH_AFTER_COMMA_EXPRESSION_LIMIT = 8;
var isNW = platformInfo.isNW;
var unitIndex = 0;
var altUnitIndex = 0;
var availableUnits = [];
var fiatCode;
var fixedUnit;
$scope.amountModel = { amount: 0 };
$scope.isChromeApp = platformInfo.isChromeApp;
$scope.isAndroid = platformInfo.isAndroid;
$scope.isIos = platformInfo.isIOS;
$scope.$on('$ionicView.leave', function() {
angular.element($window).off('keydown');
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
initCurrencies();
if (data.stateParams.shapeshiftOrderId && data.stateParams.shapeshiftOrderId.length > 0) {
$scope.minShapeshiftAmount = parseFloat(data.stateParams.minShapeshiftAmount);
$scope.maxShapeshiftAmount = parseFloat(data.stateParams.maxShapeshiftAmount);
$scope.shapeshiftOrderId = data.stateParams.shapeshiftOrderId;
}
// To get the wallet from with the new flow
$scope.fromWalletId = data.stateParams.fromWalletId;
if (data.stateParams.noPrefix) {
$scope.showWarningMessage = data.stateParams.noPrefix != 0;
if ($scope.showWarningMessage) {
var message = 'Address doesn\'t contain currency information, please make sure you are sending the correct currency.';
popupService.showAlert('', message, function() {}, 'Ok');
}
}
var config = configService.getSync().wallet.settings;
function setAvailableUnits() {
var defaults = configService.getDefaults();
var configCache = configService.getSync();
availableUnits = [];
var hasBCHWallets = profileService.getWallets({
coin: 'bch'
}).length;
if (hasBCHWallets) {
availableUnits.push({
name: 'Bitcoin Cash',
id: 'bch',
shortName: (configCache.bitcoinCashAlias || defaults.bitcoinCashAlias).toUpperCase(),
});
};
var hasBTCWallets = profileService.getWallets({
coin: 'btc'
}).length;
if (hasBTCWallets) {
availableUnits.push({
name: 'Bitcoin',
id: 'btc',
shortName: (configCache.bitcoinAlias || defaults.bitcoinAlias).toUpperCase(),
});
}
unitIndex = 0;
if (data.stateParams.coin) {
var coins = data.stateParams.coin.split(',');
var newAvailableUnits = [];
lodash.each(coins, function(c) {
var coin = lodash.find(availableUnits, {
id: c
});
if (!coin) {
$log.warn('Could not find desired coin:' + data.stateParams.coin)
} else {
newAvailableUnits.push(coin);
}
});
if (newAvailableUnits.length > 0) {
availableUnits = newAvailableUnits;
}
}
// currency have preference
var fiatName;
if (data.stateParams.currency) {
fiatCode = data.stateParams.currency;
altUnitIndex = unitIndex
unitIndex = availableUnits.length;
} else {
fiatCode = config.alternativeIsoCode || 'USD';
fiatName = config.alternanativeName || fiatCode;
altUnitIndex = availableUnits.length;
}
availableUnits.push({
name: fiatName || fiatCode,
// TODO
id: fiatCode,
shortName: fiatCode,
isFiat: true,
});
if (data.stateParams.fixedUnit) {
fixedUnit = true;
}
unitIndex = lodash.findIndex(availableUnits, {
isFiat: true
});
altUnitIndex = 0;
};
// Go to...
_id = data.stateParams.id; // Optional (BitPay Card ID or Wallet ID)
$scope.nextStep = data.stateParams.nextStep;
setAvailableUnits();
updateUnitUI();
$scope.hasMaxAmount = true;
if ($ionicHistory.backView().stateName == 'tabs.receive') {
$scope.hasMaxAmount = false;
}
$scope.showMenu = $ionicHistory.backView() && ($ionicHistory.backView().stateName == 'tabs.send' || $ionicHistory.backView().stateName == 'tabs.bitpayCard');
$scope.recipientType = data.stateParams.recipientType || null;
$scope.toAddress = data.stateParams.toAddress;
$scope.displayAddress = data.stateParams.displayAddress;
$scope.toName = data.stateParams.toName;
$scope.toEmail = data.stateParams.toEmail;
$scope.toColor = data.stateParams.toColor;
if (!$scope.nextStep && !data.stateParams.toAddress) {
$log.error('Bad params at amount')
throw ('bad params');
}
var reNr = /^[1234567890\.]$/;
var reOp = /^[\*\+\-\/]$/;
if (!$scope.isAndroid && !$scope.isIos) {
var disableKeys = angular.element($window).on('keydown', function(e) {
if (!e.key) return;
if (e.which === 8) { // you can add others here inside brackets.
if (!$scope.altCurrencyModal) {
e.preventDefault();
$scope.removeDigit();
}
}
if (e.key.match(reNr)) {
$scope.pushDigit(e.key);
} else if (e.key.match(reOp)) {
$scope.pushOperator(e.key);
} else if (e.keyCode === 86) {
if (e.ctrlKey || e.metaKey) processClipboard();
} else if (e.keyCode === 13) $scope.finish();
$timeout(function() {
$scope.$apply();
});
});
}
$scope.specificAmount = $scope.specificAlternativeAmount = '';
$scope.isCordova = platformInfo.isCordova;
unitToSatoshi = config.unitToSatoshi;
satToUnit = 1 / unitToSatoshi;
satToBtc = 1 / 100000000;
unitDecimals = config.unitDecimals;
$scope.resetAmount();
// in SAT ALWAYS
if ($stateParams.toAmount) {
$scope.amountModel.amount = (($stateParams.toAmount) * satToUnit).toFixed(unitDecimals);
}
$scope.processAmount();
$timeout(function() {
$ionicScrollDelegate.resize();
}, 10);
});
$scope.goBack = function() {
if ($scope.shapeshiftOrderId) {
$state.go('tabs.send').then(function() {
$ionicHistory.clearHistory();
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.shapeshift');
});
});
} else {
$ionicHistory.goBack();
}
}
function paste(value) {
$scope.amountModel.amount = value;
$scope.processAmount();
$timeout(function() {
$scope.$apply();
});
};
function processClipboard() {
if (!isNW) return;
var value = nodeWebkitService.readFromClipboard();
if (value && evaluate(value) > 0) paste(evaluate(value));
};
$scope.sendMax = function() {
$scope.useSendMax = true;
$scope.finish();
};
$scope.toggleAlternative = function() {
if ($scope.amountModel.amount && isExpression($scope.amountModel.amount)) {
var amount = evaluate(format($scope.amountModel.amount));
$scope.globalResult = '= ' + processResult(amount);
}
};
function updateUnitUI() {
$scope.unit = availableUnits[unitIndex].shortName;
$scope.alternativeUnit = availableUnits[altUnitIndex].shortName;
$scope.processAmount();
$log.debug('Update unit coin @amount unit:' + $scope.unit + " alternativeUnit:" + $scope.alternativeUnit);
};
$scope.changeUnit = function() {
$scope.amountModel.amount = '0';
if (fixedUnit) return;
if (!(availableUnits[unitIndex].isFiat && availableUnits.length > 2 && altUnitIndex == 0)) {
unitIndex++;
if (unitIndex >= availableUnits.length) unitIndex = 0;
}
if (availableUnits[unitIndex].isFiat) {
altUnitIndex = altUnitIndex == 0 && availableUnits.length > 2 ? 1 : 0;
} else {
altUnitIndex = lodash.findIndex(availableUnits, {
isFiat: true
});
}
updateUnitUI();
};
$scope.changeAlternativeUnit = function() {
// Do nothing is fiat is not main unit
if (!availableUnits[unitIndex].isFiat) return;
var nextCoin = lodash.findIndex(availableUnits, function(x) {
if (x.isFiat) return false;
if (x.id == availableUnits[altUnitIndex].id) return false;
return true;
});
if (nextCoin >= 0) {
altUnitIndex = nextCoin;
updateUnitUI();
}
};
function checkFontSize() {
if ($scope.amountModel.amount && $scope.amountModel.amount.length >= SMALL_FONT_SIZE_LIMIT) $scope.smallFont = true;
else $scope.smallFont = false;
};
$scope.pushDigit = function(digit) {
if ($scope.amountModel.amount && digit != '.') {
var amountSplitByComma = $scope.amountModel.amount.split('.');
if (amountSplitByComma.length > 1 && amountSplitByComma[1].length >= LENGTH_AFTER_COMMA_EXPRESSION_LIMIT) return;
if (amountSplitByComma.length == 1 && amountSplitByComma[0].length >= LENGTH_BEFORE_COMMA_EXPRESSION_LIMIT) return;
}
if ($scope.amountModel.amount && $scope.amountModel.amount.length >= LENGTH_EXPRESSION_LIMIT) return;
if ($scope.amountModel.amount.indexOf('.') > -1 && digit == '.') return;
if ($scope.amountModel.amount == '0' && digit == '0') return;
if (availableUnits[unitIndex].isFiat && $scope.amountModel.amount.indexOf('.') > -1 && $scope.amountModel.amount[$scope.amountModel.amount.indexOf('.') + 2]) return;
if ($scope.amountModel.amount == '0' && digit != '.') {
$scope.amountModel.amount = '';
}
if ($scope.amountModel.amount == '' && digit == '.') {
$scope.amountModel.amount = '0';
}
$scope.amountModel.amount = ($scope.amountModel.amount + digit).replace('..', '.');
checkFontSize();
$scope.processAmount();
};
$scope.pushOperator = function(operator) {
if (!$scope.amountModel.amount || $scope.amountModel.amount.length == 0) return;
$scope.amountModel.amount = _pushOperator($scope.amountModel.amount);
function _pushOperator(val) {
if (!isOperator(lodash.last(val))) {
return val + operator;
} else {
return val.slice(0, -1) + operator;
}
};
};
function isOperator(val) {
var regex = /[\/\-\+\x\*]/;
return regex.test(val);
};
function isExpression(val) {
var regex = /^\.?\d+(\.?\d+)?([\/\-\+\*x]\d?\.?\d+)+$/;
return regex.test(val);
};
$scope.removeDigit = function() {
$scope.amountModel.amount = ($scope.amountModel.amount).toString().slice(0, -1);
$scope.processAmount();
checkFontSize();
};
$scope.resetAmount = function() {
$scope.amountModel.amount = $scope.alternativeAmount = $scope.globalResult = '';
$scope.allowSend = false;
checkFontSize();
};
$scope.openPopup = function() {
$ionicModal.fromTemplateUrl('views/modals/altCurrency.html', {
scope: $scope
}).then(function(modal) {
$scope.altCurrencyModal = modal;
$scope.altCurrencyModal.show();
});
};
$scope.close = function() {
$scope.altCurrencyModal.remove();
$scope.altCurrencyModal = false;
};
$scope.processAmount = function() {
var formatedValue = format($scope.amountModel.amount);
var result = evaluate(formatedValue);
if (lodash.isNumber(result)) {
$scope.globalResult = isExpression($scope.amountModel.amount) ? '= ' + processResult(result) : '';
if (availableUnits[unitIndex].isFiat) {
var a = fromFiat(result);
if (a) {
$scope.alternativeAmount = txFormatService.formatAmount(a * unitToSatoshi, true);
$scope.allowSend = lodash.isNumber(a) && a > 0
&& (!$scope.shapeshiftOrderId
|| (a >= $scope.minShapeshiftAmount && a <= $scope.maxShapeshiftAmount));
} else {
if (result) {
$scope.alternativeAmount = 'N/A';
} else {
$scope.alternativeAmount = null;
}
$scope.allowSend = false;
}
} else {
$scope.alternativeAmount = $filter('formatFiatAmount')(toFiat(result));
$scope.allowSend = lodash.isNumber(result) && result > 0
&& (!$scope.shapeshiftOrderId
|| (result >= $scope.minShapeshiftAmount && result <= $scope.maxShapeshiftAmount));
}
}
};
function processResult(val) {
if (availableUnits[unitIndex].isFiat) return $filter('formatFiatAmount')(val);
else return txFormatService.formatAmount(val.toFixed(unitDecimals) * unitToSatoshi, true);
};
function fromFiat(val) {
return parseFloat((rateService.fromFiat(val, fiatCode, availableUnits[altUnitIndex].id) * satToUnit).toFixed(unitDecimals));
};
function toFiat(val) {
if (!rateService.getRate(fiatCode)) return;
return parseFloat((rateService.toFiat(val * unitToSatoshi, fiatCode, availableUnits[unitIndex].id)).toFixed(2));
};
function evaluate(val) {
var result;
try {
result = $scope.$eval(val);
} catch (e) {
return 0;
}
if (!lodash.isFinite(result)) return 0;
return result;
};
function format(val) {
if (!val) return;
var result = val.toString();
if (isOperator(lodash.last(val))) result = result.slice(0, -1);
return result.replace('x', '*');
};
$scope.finish = function() {
function finish() {
var unit = availableUnits[unitIndex];
var _amount = evaluate(format($scope.amountModel.amount));
var coin = unit.id;
if (unit.isFiat) {
coin = availableUnits[altUnitIndex].id;
}
if ($scope.nextStep) {
$state.transitionTo($scope.nextStep, {
id: _id,
amount: $scope.useSendMax ? null : _amount,
currency: unit.id.toUpperCase(),
coin: coin,
useSendMax: $scope.useSendMax,
fromWalletId: $scope.fromWalletId
});
} else {
var amount = _amount;
if (unit.isFiat) {
amount = (fromFiat(amount) * unitToSatoshi).toFixed(0);
} else {
amount = (amount * unitToSatoshi).toFixed(0);
}
var confirmData = {
recipientType: $scope.recipientType,
toAmount: amount,
toAddress: $scope.toAddress,
displayAddress: $scope.displayAddress || $scope.toAddress,
toName: $scope.toName,
toEmail: $scope.toEmail,
toColor: $scope.toColor,
coin: coin,
useSendMax: $scope.useSendMax,
fromWalletId: $scope.fromWalletId
};
if ($scope.shapeshiftOrderId) {
var shapeshiftOrderUrl = 'https://www.shapeshift.io/#/status/';
shapeshiftOrderUrl += $scope.shapeshiftOrderId;
confirmData.description = shapeshiftOrderUrl;
confirmData.fromWalletId = $scope.fromWalletId;
if (confirmData.useSendMax) {
var wallet = lodash.find(profileService.getWallets({ coin: coin }),
function(w) {
return w.id == $scope.fromWalletId;
});
var balance = parseFloat(wallet.cachedBalance.substring(0, wallet.cachedBalance.length-4));
if (balance < $scope.minShapeshiftAmount * 1.04) {
confirmData.useSendMax = false;
confirmData.toAmount = $scope.minShapeshiftAmount * unitToSatoshi;
} else if (balance > $scope.maxShapeshiftAmount) {
confirmData.useSendMax = false;
confirmData.toAmount = $scope.maxShapeshiftAmount * unitToSatoshi * 0.99;
}
}
}
$state.transitionTo('tabs.send.confirm', confirmData);
}
$scope.useSendMax = null;
}
if ($scope.showWarningMessage) {
var u = $scope.unit == 'BCH' || $scope.unit == 'BTC' ? $scope.unit : $scope.alternativeUnit;
var message = 'Are you sure you want to send ' + u.toUpperCase() + '?';
popupService.showConfirm(message, '', 'Yes', 'No', function(res) {
if (!res) {
$scope.useSendMax = null;
return;
};
finish();
});
} else {
finish();
}
};
// Currency
var next = 10;
var completeAlternativeList = [];
var popularCurrencyList = [
{isoCode: 'USD', order: 0},
{isoCode: 'EUR', order: 1},
{isoCode: 'JPY', order: 2},
{isoCode: 'GBP', order: 3},
{isoCode: 'AUD', order: 4},
{isoCode: 'CAD', order: 5},
{isoCode: 'CHF', order: 6},
{isoCode: 'CNY', order: 7},
{isoCode: 'KRW', order: 8},
{isoCode: 'HKD', order: 9},
]
function initCurrencies() {
var unusedCurrencyList = [{
isoCode: 'LTL'
}, {
isoCode: 'BTC'
}, {
isoCode: 'BCC'
}, {
isoCode: 'BCH_BTC'
}, {
isoCode: 'BCH'
}];
rateService.whenAvailable(function() {
$scope.listComplete = false;
var idx = lodash.indexBy(unusedCurrencyList, 'isoCode');
var idx2 = lodash.indexBy($scope.lastUsedAltCurrencyList, 'isoCode');
var idx3 = lodash.indexBy(popularCurrencyList, 'isoCode');
var alternatives = rateService.listAlternatives(true);
lodash.each(alternatives, function(c) {
if (idx3[c.isoCode]) {
idx3[c.isoCode].name = c.name;
}
if (!idx[c.isoCode] && !idx2[c.isoCode] && !idx3[c.isoCode]) {
completeAlternativeList.push(c);
}
});
$scope.altCurrencyList = completeAlternativeList.slice(0, 10);
$scope.lastUsedPopularList = lodash.unique(lodash.union($scope.lastUsedAltCurrencyList, popularCurrencyList), 'isoCode');
$timeout(function() {
$scope.$apply();
});
});
}
$scope.loadMore = function() {
$timeout(function() {
$scope.altCurrencyList = completeAlternativeList.slice(0, next);
next += 10;
$scope.listComplete = $scope.altCurrencyList.length >= completeAlternativeList.length;
$scope.$broadcast('scroll.infiniteScrollComplete');
}, 100);
};
$scope.findCurrency = function(search) {
if (!search) initCurrencies();
var list = lodash.unique(lodash.union(completeAlternativeList, lodash.union($scope.lastUsedAltCurrencyList, popularCurrencyList)), 'isoCode');
$scope.altCurrencyList = lodash.filter(list, function(item) {
var val = item.name
var val2 = item.isoCode;
return lodash.includes(val.toLowerCase(), search.toLowerCase()) || lodash.includes(val2.toLowerCase(), search.toLowerCase());
});
$timeout(function() {
$scope.$apply();
});
};
$scope.save = function(newAltCurrency) {
var opts = {
wallet: {
settings: {
alternativeName: newAltCurrency.name,
alternativeIsoCode: newAltCurrency.isoCode,
}
}
};
configService.set(opts, function(err) {
if (err) $log.warn(err);
walletService.updateRemotePreferences(profileService.getWallets());
var altUnitIndex = lodash.findIndex(availableUnits, {
isFiat: true
});
availableUnits[altUnitIndex].id = newAltCurrency.isoCode;
availableUnits[altUnitIndex].name = newAltCurrency.isoCode;
availableUnits[altUnitIndex].shortName = newAltCurrency.isoCode;
fiatCode = newAltCurrency.isoCode;
updateUnitUI();
$scope.close();
});
};
});

View file

@ -0,0 +1,604 @@
describe('amountController', function(){
var configCache,
configService,
gettextCatalog,
$controller,
$ionicHistory,
$rootScope,
ongoingProcess,
platformInfo,
popupService,
profileService,
rateService,
sendFlowService,
shapeshiftService,
txFormatService,
$scope,
$state,
$stateParams;
beforeEach(function(){
module('ngLodash');
module('copayApp.controllers');
configCache = {
wallet: {
settings: {
unitToSatoshi: 100000000
}
}
};
configService = jasmine.createSpyObj(['getDefaults','getSync']);
configService.getDefaults.and.returnValue({
bitcoinCashAlias: 'bch',
bitcoinAlias: 'btc'
});
configService.getSync.and.returnValue(configCache);
gettextCatalog = jasmine.createSpyObj(['getString']);
gettextCatalog.getString.and.callFake(function(str){ return str; });
$ionicHistory = jasmine.createSpyObj(['backView']);
ongoingProcess = jasmine.createSpyObj(['set']);
platformInfo = {
isChromeApp: false,
isAndroid: false,
isIos: true
};
popupService = jasmine.createSpyObj(['showAlert']);
profileService = jasmine.createSpyObj(['getWallet', 'getWallets']);
rateService = jasmine.createSpyObj(['fromFiat', 'listAlternatives', 'updateRates', 'whenAvailable']);
sendFlowService = jasmine.createSpyObj(['getStateClone', 'pushState']);
shapeshiftService = jasmine.createSpyObj(['getMarketData']);
txFormatService = jasmine.createSpyObj(['formatAlternativeStr', 'formatAmountStr']);
txFormatService.formatAlternativeStr.and.callFake(function(coin, satoshis, cb) {
if (typeof satoshis !== "number") {
throw "satoshis in formatAlternativeStr() is not a number."
}
var units = satoshis / 100000000;
var formatted = (units * 10000).toFixed(2) + ' USD';
cb(formatted);
});
txFormatService.formatAmountStr.and.callFake(function(coin, satoshis) {
if (typeof satoshis !== "number") {
throw "satoshis in formatAmountStr() is not a number."
}
return (satoshis * 100000000).toFixed(8) + ' ' + (coin || 'bch').toUpperCase();
});
$state = jasmine.createSpyObj(['transitionTo']);
$stateParams = {};
inject(function(_$controller_, _$rootScope_){
// The injector unwraps the underscores (_) from around the parameter names when matching
$controller = _$controller_;
$rootScope = _$rootScope_;
});
});
it('receives fromWalletId and toAddress.', function() {
var backView = {
stateName: 'ignoreme'
};
$ionicHistory.backView.and.returnValue(backView);
var wallet = {
status: {
isValid: true,
spendableAmount: 123456
}
};
profileService.getWallet.and.returnValue(wallet);
profileService.getWallets.and.returnValue([{}]);
rateService.fromFiat.and.returnValue(12); // satoshis or coins?
var $scope = $rootScope.$new();
var amountController = $controller('amountController', {
configService: configService,
gettextCatalog: gettextCatalog,
$ionicHistory: $ionicHistory,
$ionicModal: {},
$ionicScrollDelegate: {},
nodeWebkitService: {},
ongoingProcess: ongoingProcess,
platformInfo: platformInfo,
profileService: profileService,
popupService: popupService,
rateService: rateService,
$scope: $scope,
sendFlowService: sendFlowService,
shapeshiftService: shapeshiftService,
$state: {},
$stateParams: $stateParams,
txFormatService: txFormatService,
walletService: {}
});
var sendFlowState = {
fromWalletId: 'fd56c1e7-e3ac-4fd9-8afc-27b9c1b3718b',
toAddress: 'qrup46avn8t466xxwlzs4qelht7cnwvesv2e29wf7s'
};
sendFlowService.getStateClone.and.returnValue(sendFlowState);
$scope.$emit('$ionicView.beforeEnter', {});
//expect($scope.fromWalletId).toBe('fd56c1e7-e3ac-4fd9-8afc-27b9c1b3718b');
//expect($scope.toAddress).toBe('qrup46avn8t466xxwlzs4qelht7cnwvesv2e29wf7s');
});
describe('Shapeshift', function() {
var walletFrom;
var walletTo;
beforeEach(function(){
walletFrom = {};
walletTo = {};
profileService.getWallet.and.callFake(function(walletId){
if (walletId === '4cd7673e-7320-4dfa-86e5-d4edb51d460a') {
return walletFrom;
} else if (walletId === 'bf00af8f-0788-4b57-b30a-0390747407e9') {
return walletTo;
} else {
return null;
}
});
rateService.listAlternatives.and.returnValue([
{name: "Australian Dollar", isoCode: "AUD"},
{name: "United States Dollar", isoCode: "USD"}
]);
});
it ('with available balance below limit, shows sendMax for triggering alert', function() {
walletFrom.coin = 'btc';
walletFrom.status = {
isValid: true,
spendableAmount: 789
};
walletTo.coin = 'bch';
profileService.getWallets.and.returnValue([{}]);
rateService.fromFiat.and.returnValue(12);
var $scope = $rootScope.$new();
var amountController = $controller('amountController', {
configService: configService,
gettextCatalog: gettextCatalog,
$ionicHistory: $ionicHistory,
$ionicModal: {},
$ionicScrollDelegate: {},
nodeWebkitService: {},
ongoingProcess: ongoingProcess,
platformInfo: platformInfo,
profileService: profileService,
popupService: popupService,
rateService: rateService,
$scope: $scope,
sendFlowService: sendFlowService,
shapeshiftService: shapeshiftService,
$state: $state,
$stateParams: $stateParams,
txFormatService: txFormatService,
walletService: {}
});
rateService.whenAvailable.and.callFake(function(cb){
cb();
});
var sendFlowState = {
amount: '',
displayAddress: null,
fromWalletId: '4cd7673e-7320-4dfa-86e5-d4edb51d460a',
sendMax: false,
thirdParty: {
id: 'shapeshift',
data: {},
},
toAddress: '',
toWalletId: 'bf00af8f-0788-4b57-b30a-0390747407e9'
};
sendFlowService.getStateClone.and.returnValue(sendFlowState);
var reqCoinIn = '';
var reqCoinOut = '';
shapeshiftService.getMarketData.and.callFake(function(coinIn, coinOut, cb){
reqCoinIn = coinIn;
reqCoinOut = coinOut;
cb({
maxLimit: '0.6846239',
minimum: '0.00013692'
});
});
$scope.$emit('$ionicView.beforeEnter', {});
expect(rateService.updateRates.calls.any()).toEqual(true);
expect(reqCoinIn).toBe('btc');
expect(reqCoinOut).toBe('bch');
expect(amountController.maxAmount).toBe(0.68462390);
expect(amountController.minAmount).toBe(0.00013692);
expect(amountController.showSendMaxButton).toEqual(true);
expect(amountController.showSendLimitMaxButton).toEqual(false);
expect(amountController.sendableFunds).toEqual('0.08 USD');
// Now hit the Send Max button
amountController.sendMax();
expect(popupService.showAlert.calls.argsFor(0)[0]).toEqual('Insufficient funds');
expect(popupService.showAlert.calls.argsFor(0)[1]).toEqual('Amount below minimum allowed');
expect(sendFlowService.pushState.calls.any()).toEqual(false);
expect($state.transitionTo.calls.any()).toEqual(false);
});
it ('with available balance between limits, uses sendMax', function() {
walletFrom.coin = 'btc';
walletFrom.status = {
isValid: true,
spendableAmount: 456789
};
walletTo.coin = 'bch';
profileService.getWallets.and.returnValue([{}]);
rateService.fromFiat.and.returnValue(12);
var $scope = $rootScope.$new();
var amountController = $controller('amountController', {
configService: configService,
gettextCatalog: {},
$ionicHistory: $ionicHistory,
$ionicModal: {},
$ionicScrollDelegate: {},
nodeWebkitService: {},
ongoingProcess: ongoingProcess,
platformInfo: platformInfo,
profileService: profileService,
popupService: {},
rateService: rateService,
$scope: $scope,
sendFlowService: sendFlowService,
shapeshiftService: shapeshiftService,
$state: $state,
$stateParams: $stateParams,
txFormatService: txFormatService,
walletService: {}
});
rateService.whenAvailable.and.callFake(function(cb){
cb();
});
var sendFlowState = {
amount: '',
displayAddress: null,
fromWalletId: '4cd7673e-7320-4dfa-86e5-d4edb51d460a',
sendMax: false,
thirdParty: {
id: 'shapeshift',
data: {},
},
toAddress: '',
toWalletId: 'bf00af8f-0788-4b57-b30a-0390747407e9'
};
sendFlowService.getStateClone.and.returnValue(sendFlowState);
var reqCoinIn = '';
var reqCoinOut = '';
shapeshiftService.getMarketData.and.callFake(function(coinIn, coinOut, cb){
reqCoinIn = coinIn;
reqCoinOut = coinOut;
cb({
maxLimit: '0.6846239',
minimum: '0.00013692'
});
});
$scope.$emit('$ionicView.beforeEnter', {});
expect(rateService.updateRates.calls.any()).toEqual(true);
expect(reqCoinIn).toBe('btc');
expect(reqCoinOut).toBe('bch');
expect(amountController.maxAmount).toBe(0.68462390);
expect(amountController.minAmount).toBe(0.00013692);
expect(amountController.showSendMaxButton).toEqual(true);
expect(amountController.showSendLimitMaxButton).toEqual(false);
// Now hit the Send Max button
var pushedState = null;
sendFlowService.pushState.and.callFake(function (sendFlowState){
pushedState = sendFlowState;
});
amountController.sendMax();
expect(pushedState.amount).toBeUndefined();
expect(pushedState.fromWalletId).toEqual('4cd7673e-7320-4dfa-86e5-d4edb51d460a');
expect(pushedState.sendMax).toEqual(true);
expect(pushedState.toWalletId).toEqual('bf00af8f-0788-4b57-b30a-0390747407e9');
expect(pushedState.thirdParty.id).toEqual('shapeshift');
expect(pushedState.thirdParty.data.maxAmount).toEqual(0.6846239);
expect(pushedState.thirdParty.data.minAmount).toEqual(0.00013692);
expect($state.transitionTo.calls.count()).toEqual(1);
expect($state.transitionTo.calls.argsFor(0)[0]).toEqual('tabs.send.review');
});
it ('with available balance higher than max, uses send limit max instead of sendMax', function() {
walletFrom.coin = 'btc';
walletFrom.status = {
isValid: true,
spendableAmount: 123456789
};
walletTo.coin = 'bch';
profileService.getWallets.and.returnValue([{}]);
rateService.fromFiat.and.returnValue(12); // satoshis or coins?
var $scope = $rootScope.$new();
var amountController = $controller('amountController', {
configService: configService,
gettextCatalog: {},
$ionicHistory: $ionicHistory,
$ionicModal: {},
$ionicScrollDelegate: {},
nodeWebkitService: {},
ongoingProcess: ongoingProcess,
platformInfo: platformInfo,
profileService: profileService,
popupService: {},
rateService: rateService,
$scope: $scope,
sendFlowService: sendFlowService,
shapeshiftService: shapeshiftService,
$state: $state,
$stateParams: $stateParams,
txFormatService: txFormatService,
walletService: {}
});
rateService.whenAvailable.and.callFake(function(cb){
cb();
});
var sendFlowState = {
amount: '',
displayAddress: null,
fromWalletId: '4cd7673e-7320-4dfa-86e5-d4edb51d460a',
sendMax: false,
thirdParty: {
id: 'shapeshift',
data: {},
},
toAddress: '',
toWalletId: 'bf00af8f-0788-4b57-b30a-0390747407e9'
};
sendFlowService.getStateClone.and.returnValue(sendFlowState);
var reqCoinIn = '';
var reqCoinOut = '';
shapeshiftService.getMarketData.and.callFake(function(coinIn, coinOut, cb){
reqCoinIn = coinIn;
reqCoinOut = coinOut;
cb({
maxLimit: '0.6846239',
minimum: '0.00013692'
});
});
$scope.$emit('$ionicView.beforeEnter', {});
expect(rateService.updateRates.calls.any()).toEqual(true);
expect(reqCoinIn).toBe('btc');
expect(reqCoinOut).toBe('bch');
expect(amountController.maxAmount).toBe(0.6846239);
expect(amountController.minAmount).toBe(0.00013692);
expect(amountController.showSendMaxButton).toEqual(false);
expect(amountController.showSendLimitMaxButton).toEqual(true);
// Now hit the Send Max button
var pushedState = null;
sendFlowService.pushState.and.callFake(function (sendFlowState){
pushedState = sendFlowState;
});
amountController.sendMax();
expect(pushedState.amount).toEqual(68462390);
expect(pushedState.fromWalletId).toEqual('4cd7673e-7320-4dfa-86e5-d4edb51d460a');
expect(pushedState.sendMax).toEqual(false);
expect(pushedState.toWalletId).toEqual('bf00af8f-0788-4b57-b30a-0390747407e9');
expect(pushedState.thirdParty.id).toEqual('shapeshift');
expect(pushedState.thirdParty.data.maxAmount).toEqual(0.6846239);
expect(pushedState.thirdParty.data.minAmount).toEqual(0.00013692);
expect($state.transitionTo.calls.count()).toEqual(1);
expect($state.transitionTo.calls.argsFor(0)[0]).toEqual('tabs.send.review');
});
});
describe('Wallet transfer', function() {
var walletFrom;
var walletTo;
beforeEach(function(){
walletFrom = {};
walletTo = {};
profileService.getWallet.and.callFake(function(walletId){
if (walletId === '4cd7673e-7320-4dfa-86e5-d4edb51d460a') {
return walletFrom;
} else if (walletId === 'bf00af8f-0788-4b57-b30a-0390747407e9') {
return walletTo;
} else {
return null;
}
});
rateService.listAlternatives.and.returnValue([
{name: "Australian Dollar", isoCode: "AUD"},
{name: "United States Dollar", isoCode: "USD"}
]);
});
it('wallet transfer send max.', function() {
walletFrom.coin = 'btc';
walletFrom.status = {
isValid: true,
spendableAmount: 123456789
};
profileService.getWallets.and.returnValue([{}]);
var $scope = $rootScope.$new();
var amountController = $controller('amountController', {
configService: configService,
gettextCatalog: gettextCatalog,
$ionicHistory: $ionicHistory,
$ionicModal: {},
$ionicScrollDelegate: {},
nodeWebkitService: {},
ongoingProcess: ongoingProcess,
platformInfo: platformInfo,
profileService: profileService,
popupService: popupService,
rateService: rateService,
$scope: $scope,
sendFlowService: sendFlowService,
shapeshiftService: shapeshiftService,
$state: $state,
$stateParams: $stateParams,
txFormatService: txFormatService,
walletService: {}
});
var sendFlowState = {
fromWalletId: '4cd7673e-7320-4dfa-86e5-d4edb51d460a',
toWalletId: 'bf00af8f-0788-4b57-b30a-0390747407e9'
};
sendFlowService.getStateClone.and.returnValue(sendFlowState);
$scope.$emit('$ionicView.beforeEnter', {});
expect(amountController.showSendMaxButton).toEqual(true);
expect(amountController.showSendLimitMaxButton).toEqual(false);
expect(amountController.sendableFunds).toEqual('12345.68 USD');
// Now hit the Send Max button
var pushedState = null;
sendFlowService.pushState.and.callFake(function (sendFlowState){
pushedState = sendFlowState;
});
amountController.sendMax();
expect(pushedState.amount).toBeUndefined();
expect(pushedState.fromWalletId).toEqual('4cd7673e-7320-4dfa-86e5-d4edb51d460a');
expect(pushedState.sendMax).toEqual(true);
expect(pushedState.toWalletId).toEqual('bf00af8f-0788-4b57-b30a-0390747407e9');
expect($state.transitionTo.calls.count()).toEqual(1);
expect($state.transitionTo.calls.argsFor(0)[0]).toEqual('tabs.send.review');
});
// This situation was seen in real life
it('wallet transfer with valid cached status only.', function() {
walletFrom.coin = 'btc';
walletFrom.status = {
isValid: false,
};
walletFrom.cachedStatus = {
isValid: true,
spendableAmount: 5678
};
profileService.getWallets.and.returnValue([{}]);
var $scope = $rootScope.$new();
var amountController = $controller('amountController', {
configService: configService,
gettextCatalog: gettextCatalog,
$ionicHistory: $ionicHistory,
$ionicModal: {},
$ionicScrollDelegate: {},
nodeWebkitService: {},
ongoingProcess: ongoingProcess,
platformInfo: platformInfo,
profileService: profileService,
popupService: popupService,
rateService: rateService,
$scope: $scope,
sendFlowService: sendFlowService,
shapeshiftService: shapeshiftService,
$state: $state,
$stateParams: $stateParams,
txFormatService: txFormatService,
walletService: {}
});
var sendFlowState = {
fromWalletId: '4cd7673e-7320-4dfa-86e5-d4edb51d460a',
toWalletId: 'bf00af8f-0788-4b57-b30a-0390747407e9'
};
sendFlowService.getStateClone.and.returnValue(sendFlowState);
$scope.$emit('$ionicView.beforeEnter', {});
expect(amountController.showSendMaxButton).toEqual(true);
expect(amountController.showSendLimitMaxButton).toEqual(false);
expect(amountController.sendableFunds).toEqual('0.57 USD');
});
});
});

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('backupController',
function($scope, $timeout, $log, $state, $stateParams, $ionicHistory, lodash, profileService, bwcService, walletService, ongoingProcess, popupService, gettextCatalog, $ionicModal, firebaseEventsService) {
function($scope, $timeout, $log, $state, $stateParams, $ionicHistory, lodash, profileService, bwcService, walletService, ongoingProcess, popupService, gettextCatalog, $ionicModal) {
if ($state.current.name == 'onboarding.backup') {
$scope.onboarding = true;
@ -89,7 +89,8 @@ angular.module('copayApp.controllers').controller('backupController',
$scope.setFlow(2);
})
} else {
firebaseEventsService.logEvent('backed_up_wallet');
//firebaseEventsService.logEvent('backed_up_wallet');
openConfirmBackupModal();
}
};

View file

@ -1,25 +1,20 @@
'use strict';
angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $filter, $timeout, $ionicScrollDelegate, gettextCatalog, walletService, platformInfo, lodash, configService, $stateParams, $window, $state, $log, profileService, bitcore, bitcoreCash, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, payproService, feeService, bwcError, txConfirmNotification, externalLinkService, firebaseEventsService, soundService) {
angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $timeout, $ionicScrollDelegate, $ionicLoading, ionicToast, addressbookService, gettextCatalog, walletService, platformInfo, lodash, configService, $state, $log, profileService, bitcore, bitcoreCash, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, feeService, bitcoinCashJsService, bwcError, txConfirmNotification, soundService, clipboardService) {
var countDown = null;
var FEE_TOO_HIGH_LIMIT_PER = 15;
var tx = {};
var lastTxId = "";
// Config Related values
var config = configService.getSync();
var walletConfig = config.wallet;
var unitToSatoshi = walletConfig.settings.unitToSatoshi;
var unitDecimals = walletConfig.settings.unitDecimals;
var satToUnit = 1 / unitToSatoshi;
var configFeeLevel = walletConfig.settings.feeLevel ? walletConfig.settings.feeLevel : 'normal';
// Platform info
var isChromeApp = platformInfo.isChromeApp;
var isCordova = platformInfo.isCordova;
var isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
//custom fee flag
var usingCustomFee = false;
@ -31,6 +26,16 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}, 10);
}
$scope.shareTransaction = function() {
var explorerTxUrl = 'https://explorer.bitcoin.com/'+tx.coin+'/tx/'+lastTxId;
if (platformInfo.isCordova) {
var text = 'Take a look at this Bitcoin transaction here: '+explorerTxUrl;
window.plugins.socialsharing.share(text, null, null, null);
} else {
ionicToast.show(gettextCatalog.getString('Copied to clipboard'), 'bottom', false, 3000);
clipboardService.copyToClipboard(explorerTxUrl);
}
};
$scope.showWalletSelector = function() {
$scope.walletSelector = true;
@ -45,7 +50,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$ionicConfig.views.swipeBackEnabled(false);
});
function exitWithError(err) {
$log.info('Error setting wallet selector:' + err);
popupService.showAlert(gettextCatalog.getString(), bwcError.msg(err), function() {
@ -68,112 +72,108 @@ angular.module('copayApp.controllers').controller('confirmController', function(
});
};
$scope.$on("$ionicView.beforeEnter", function(event, data) {
var setWalletSelector = function(coin, network, minAmount, cb) {
function setWalletSelector(coin, network, minAmount, cb) {
// no min amount? (sendMax) => look for no empty wallets
minAmount = minAmount || 1;
// no min amount? (sendMax) => look for no empty wallets
minAmount = minAmount || 1;
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: network,
coin: coin
});
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: network,
coin: coin
if (tx.fromWalletId) {
$scope.wallets = lodash.filter($scope.wallets, function (w) {
return w.id == tx.fromWalletId;
});
if (tx.fromWalletId) {
$scope.wallets = lodash.filter($scope.wallets, function(w) {
return w.id == tx.fromWalletId;
});
}
if (!$scope.wallets || !$scope.wallets.length) {
setNoWallet(gettextCatalog.getString('No wallets available'), true);
return cb();
}
var filteredWallets = [];
var index = 0;
var walletsUpdated = 0;
lodash.each($scope.wallets, function(w) {
walletService.getStatus(w, {}, function(err, status) {
if (err || !status) {
$log.error(err);
} else {
walletsUpdated++;
w.status = status;
if (!status.availableBalanceSat)
$log.debug('No balance available in: ' + w.name);
if (status.availableBalanceSat > minAmount) {
filteredWallets.push(w);
}
}
if (++index == $scope.wallets.length) {
if (!walletsUpdated)
return cb('Could not update any wallet');
if (lodash.isEmpty(filteredWallets)) {
setNoWallet(gettextCatalog.getString('Insufficient confirmed funds'), true);
}
$scope.wallets = lodash.clone(filteredWallets);
return cb();
}
});
});
};
// Setup $scope
var B = data.stateParams.coin == 'bch' ? bitcoreCash : bitcore;
var networkName;
try {
networkName = (new B.Address(data.stateParams.toAddress)).network.name;
} catch(e) {
var message = gettextCatalog.getString('Invalid address');
var backText = gettextCatalog.getString('Go back');
var learnText = gettextCatalog.getString('Learn more');
popupService.showConfirm(null, message, backText, learnText, function(back) {
$ionicHistory.nextViewOptions({
disableAnimate: true,
historyRoot: true
});
$state.go('tabs.send').then(function() {
$ionicHistory.clearHistory();
if (!back) {
var url = 'https://support.bitpay.com/hc/en-us/articles/115004671663';
externalLinkService.open(url);
}
});
});
return;
}
if (!$scope.wallets || !$scope.wallets.length) {
setNoWallet(gettextCatalog.getString('No wallets available'), true);
return cb();
}
var filteredWallets = [];
var index = 0;
var walletsUpdated = 0;
lodash.each($scope.wallets, function (w) {
walletService.getStatus(w, {}, function (err, status) {
if (err || !status) {
$log.error(err);
} else {
walletsUpdated++;
w.status = status;
if (!status.availableBalanceSat)
$log.debug('No balance available in: ' + w.name);
if (status.availableBalanceSat > minAmount) {
filteredWallets.push(w);
}
}
if (++index == $scope.wallets.length) {
if (!walletsUpdated)
return cb('Could not update any wallet');
if (lodash.isEmpty(filteredWallets)) {
setNoWallet(gettextCatalog.getString('Insufficient confirmed funds'), true);
}
$scope.wallets = lodash.clone(filteredWallets);
return cb();
}
});
});
};
$scope.getContacts = function(addr) {
addressbookService.list(function(err, ab) {
if (err) $log.error(err);
$scope.hasContacts = lodash.isEmpty(ab) ? false : true;
if (!$scope.hasContacts) return cb();
var completeContacts = [];
lodash.each(ab, function(v, k) {
completeContacts.push({
name: lodash.isObject(v) ? v.name : v,
address: k,
email: lodash.isObject(v) ? v.email : null,
recipientType: 'contact',
coin: v.coin,
displayCoin: (v.coin == 'bch'
? (config.bitcoinCashAlias || defaults.bitcoinCashAlias)
: (config.bitcoinAlias || defaults.bitcoinAlias)).toUpperCase()
});
});
return cb();
});
};
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.fromWallet = profileService.getWallet(data.stateParams.fromWalletId); // Wallet to send from
// Grab stateParams
tx = {
toAmount: parseInt(data.stateParams.toAmount),
amount: parseInt(data.stateParams.amount),
sendMax: data.stateParams.useSendMax == 'true' ? true : false,
fromWalletId: data.stateParams.fromWalletId,
toAddress: data.stateParams.toAddress,
displayAddress: data.stateParams.displayAddress,
description: data.stateParams.description,
paypro: data.stateParams.paypro,
feeLevel: configFeeLevel,
spendUnconfirmed: walletConfig.spendUnconfirmed,
// Vanity tx info (not in the real tx)
recipientType: data.stateParams.recipientType || null,
toName: data.stateParams.toName,
toEmail: data.stateParams.toEmail,
toColor: data.stateParams.toColor,
network: networkName,
coin: data.stateParams.coin,
recipientType: $scope.recipientType || null,
toName: null,
toEmail: null,
toColor: null,
network: false,
coin: $scope.fromWallet.coin,
txp: {},
};
@ -182,18 +182,71 @@ angular.module('copayApp.controllers').controller('confirmController', function(
tx.feeRate = parseInt(data.stateParams.requiredFeeRate);
}
if (tx.coin && tx.coin == 'bch') {
if (tx.coin && tx.coin === 'bch') {
tx.feeLevel = 'normal';
}
var B = data.stateParams.coin === 'bch' ? bitcoreCash : bitcore;
var networkName;
$scope.recipientType = null;
try {
if (data.stateParams.toWalletId) { // There is a toWalletId, so we presume this is a wallet-to-wallet transfer
$scope.recipientType = 'wallet'; // set transaction type to wallet-to-wallet
$ionicLoading.show();
var toWallet = profileService.getWallet(data.stateParams.toWalletId);
tx.toColor = toWallet.color;
tx.toName = toWallet.name;
// We need an address to send to, so we ask the walletService to create a new address for the toWallet.
walletService.getAddress(toWallet, true, function (err, addr) {
$ionicLoading.hide();
tx.toAddress = addr;
networkName = (new B.Address(tx.toAddress)).network.name;
tx.network = networkName;
setupTx(tx);
});
} else { // This is a Wallet-to-address transfer
networkName = (new B.Address(tx.toAddress)).network.name;
tx.network = networkName;
setupTx(tx);
}
} catch (e) {
var message = gettextCatalog.getString('Invalid address');
popupService.showAlert(null, message, function () {
$ionicHistory.nextViewOptions({
disableAnimate: true,
historyRoot: true
});
$state.go('tabs.send').then(function () {
$ionicHistory.clearHistory();
});
});
return;
}
});
var setupTx = function(tx) {
if (tx.coin === 'bch') {
tx.displayAddress = bitcoinCashJsService.readAddress(tx.toAddress).cashaddr;
} else {
tx.displayAddress = entry.address;
}
addressbookService.get(tx.coin+tx.toAddress, function(err, addr) { // Check if the recipient is a contact
if (!err && addr) {
tx.toName = addr.name;
tx.toEmail = addr.email;
tx.recipientType = 'contact';
}
});
// Other Scope vars
$scope.isCordova = isCordova;
$scope.isWindowsPhoneApp = isWindowsPhoneApp;
$scope.showAddress = false;
$scope.walletSelectorTitle = gettextCatalog.getString('Send from');
setWalletSelector(tx.coin, tx.network, tx.toAmount, function(err) {
setWalletSelector(tx.coin, tx.network, tx.amount, function(err) {
if (err) {
return exitWithError('Could not update wallets');
}
@ -207,7 +260,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.displayBalanceAsFiat = walletConfig.settings.priceDisplay === 'fiat';
});
};
function getSendMaxInfo(tx, wallet, cb) {
@ -231,7 +284,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
return setSendError(msg);
}
if (tx.toAmount > Number.MAX_SAFE_INTEGER) {
if (tx.amount > Number.MAX_SAFE_INTEGER) {
var msg = gettextCatalog.getString('Amount too big');
$log.warn(msg);
return setSendError(msg);
@ -241,7 +294,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
txp.outputs = [{
'toAddress': tx.toAddress,
'amount': tx.toAmount,
'amount': tx.amount,
'message': tx.description
}];
@ -280,13 +333,13 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.tx = tx;
function updateAmount() {
if (!tx.toAmount) return;
if (!tx.amount) return;
// Amount
tx.amountStr = txFormatService.formatAmountStr(wallet.coin, tx.toAmount);
tx.amountStr = txFormatService.formatAmountStr(wallet.coin, tx.amount);
tx.amountValueStr = tx.amountStr.split(' ')[0];
tx.amountUnitStr = tx.amountStr.split(' ')[1];
txFormatService.formatAlternativeStr(wallet.coin, tx.toAmount, function(v) {
txFormatService.formatAlternativeStr(wallet.coin, tx.amount, function(v) {
var parts = v.split(' ');
tx.alternativeAmountStr = v;
tx.alternativeAmountValueStr = parts[0];
@ -342,7 +395,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}
tx.sendMaxInfo = sendMaxInfo;
tx.toAmount = tx.sendMaxInfo.amount;
tx.amount = tx.sendMaxInfo.amount;
updateAmount();
ongoingProcess.set('calculatingFee', false);
$timeout(function() {
@ -393,7 +446,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
function useSelectedWallet() {
if (!$scope.useSendMax) {
showAmount(tx.toAmount);
showAmount(tx.amount);
}
$scope.onWalletSelect($scope.wallet);
@ -402,19 +455,19 @@ angular.module('copayApp.controllers').controller('confirmController', function(
function setButtonText(isMultisig, isPayPro) {
if (isPayPro) {
if (isCordova && !isWindowsPhoneApp) {
if (isCordova) {
$scope.buttonText = gettextCatalog.getString('Slide to pay');
} else {
$scope.buttonText = gettextCatalog.getString('Click to pay');
}
} else if (isMultisig) {
if (isCordova && !isWindowsPhoneApp) {
if (isCordova) {
$scope.buttonText = gettextCatalog.getString('Slide to accept');
} else {
$scope.buttonText = gettextCatalog.getString('Click to accept');
}
} else {
if (isCordova && !isWindowsPhoneApp) {
if (isCordova) {
$scope.buttonText = gettextCatalog.getString('Slide to send');
} else {
$scope.buttonText = gettextCatalog.getString('Click to send');
@ -422,7 +475,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}
};
$scope.toggleAddress = function() {
$scope.showAddress = !$scope.showAddress;
};
@ -465,7 +517,8 @@ angular.module('copayApp.controllers').controller('confirmController', function(
if (!lodash.isEmpty(warningMsg))
msg += '\n' + warningMsg;
popupService.showAlert(null, msg, function() {});
popupService.showAlert(null, msg, function() {});
};
$scope.onWalletSelect = function(wallet) {
@ -612,6 +665,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
txConfirmNotification.subscribe(wallet, {
txid: txp.txid
});
lastTxId = txp.txid;
}
}, onSendStatusChange);
};
@ -643,9 +697,9 @@ angular.module('copayApp.controllers').controller('confirmController', function(
soundService.play('misc/payment_sent.mp3');
}
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": $scope.wallet.coin,
@ -655,8 +709,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}], [channel, "adjust"]);
window.BitAnalytics.LogEventHandlers.postEvent(log);
// Should be removed
firebaseEventsService.logEvent('sent_bitcoin', { coin: $scope.wallet.coin });
$timeout(function() {
$scope.$digest();
}, 100);

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('createController',
function($scope, $rootScope, $timeout, $log, lodash, $state, $ionicScrollDelegate, $ionicHistory, profileService, configService, gettextCatalog, ledger, trezor, intelTEE, derivationPathHelper, ongoingProcess, walletService, storageService, popupService, appConfigService, pushNotificationsService, firebaseEventsService, $ionicNavBarDelegate) {
function($scope, $timeout, $log, lodash, $state, $ionicScrollDelegate, $ionicHistory, profileService, configService, gettextCatalog, ledger, trezor, intelTEE, derivationPathHelper, ongoingProcess, walletService, popupService, appConfigService, pushNotificationsService, $ionicNavBarDelegate) {
/* For compressed keys, m*73 + n*34 <= 496 */
var COPAYER_PAIR_LIMITS = {
@ -268,7 +268,7 @@ angular.module('copayApp.controllers').controller('createController',
}, 100);
}
else {
firebaseEventsService.logEvent('wallet_created', { coin: opts.coin });
//firebaseEventsService.logEvent('wallet_created', { coin: opts.coin });
$state.go('tabs.home');
}
}

View file

@ -17,7 +17,7 @@ angular.module('copayApp.controllers').controller('customAmountController', func
}
$scope.$on("$ionicView.beforeEnter", function(event, data) {
var walletId = data.stateParams.id;
var walletId = data.stateParams.toWalletId;
if (!walletId) {
showErrorAndBack('Error', 'No wallet selected');
@ -53,17 +53,26 @@ angular.module('copayApp.controllers').controller('customAmountController', func
$scope.address = bchAddresses[$scope.bchAddressType];
}
$scope.coin = data.stateParams.coin;
$scope.coin = $scope.wallet.coin;
var satoshis = parseInt(data.stateParams.amount, 10);
var parsedAmount = txFormatService.parseAmount(
$scope.wallet.coin,
data.stateParams.amount,
data.stateParams.currency);
satoshis,
'sat');
// Amount in USD or BTC
var amount = parsedAmount.amount;
var currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
configService.whenAvailable(function (config) {
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
$timeout(function () {
$scope.$apply();
});
});
if (currency != 'BTC' && currency != 'BCH') {
// Convert to BTC or BCH
var config = configService.getSync().wallet.settings;

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('tourController',
function($scope, $state, $log, $timeout, $filter, ongoingProcess, profileService, rateService, popupService, gettextCatalog, startupService, storageService, walletService, $q) {
function ($scope, $state, $log, $timeout, $filter, ongoingProcess, configService, profileService, rateService, popupService, gettextCatalog, lodash, startupService, storageService, uxLanguage, walletService, $q) {
$scope.data = {
index: 0
@ -46,62 +46,90 @@ angular.module('copayApp.controllers').controller('tourController',
creatingWallet = true;
ongoingProcess.set('creatingWallet', true);
$timeout(function() {
profileService.createDefaultWallet(function(err, walletClients) {
if (err) {
$log.warn(err);
uxLanguage.init(function(lang) {
var rateCode = uxLanguage.getRateCode(lang);
console.log("When Available: rateService");
rateService.whenAvailable(function() {
var alternatives = rateService.listAlternatives(true);
return $timeout(function() {
$log.warn('Retrying to create default wallet.....:' + ++retryCount);
if (retryCount > 3) {
ongoingProcess.set('creatingWallet', false);
popupService.showAlert(
gettextCatalog.getString('Cannot Create Wallet'), err,
function() {
retryCount = 0;
return $scope.createDefaultWallet();
}, gettextCatalog.getString('Retry'));
} else {
return $scope.createDefaultWallet();
}
}, 2000);
};
ongoingProcess.set('creatingWallet', false);
var bchWallet = walletClients[0];
var btcWallet = walletClients[1];
var bchWalletId = bchWallet.credentials.walletId;
var btcWalletId = btcWallet.credentials.walletId;
function createAddressPromise(wallet) {
return $q(function(resolve, reject) {
walletService.getAddress(wallet, true, function(e, addr) {
if (e) reject(e);
resolve(addr);
var newAltCurrency = lodash.find(alternatives, {
'isoCode': rateCode
});
configService.whenAvailable(function(config) {
var opts = {
wallet: {
settings: {
alternativeName: newAltCurrency.name,
alternativeIsoCode: newAltCurrency.isoCode,
}
}
};
configService.set(opts, function(err) {
if (err) $log.warn(err);
profileService.createDefaultWallet(function(err, walletClients) {
if (err) {
$log.warn(err);
return $timeout(function() {
$log.warn('Retrying to create default wallet.....:' + ++retryCount);
if (retryCount > 3) {
ongoingProcess.set('creatingWallet', false);
popupService.showAlert(
gettextCatalog.getString('Cannot Create Wallet'), err,
function() {
retryCount = 0;
return $scope.createDefaultWallet();
}, gettextCatalog.getString('Retry'));
} else {
return $scope.createDefaultWallet();
}
}, 2000);
}
;
ongoingProcess.set('creatingWallet', false);
var bchWallet = walletClients[0];
var btcWallet = walletClients[1];
var bchWalletId = bchWallet.credentials.walletId;
var btcWalletId = btcWallet.credentials.walletId;
function createAddressPromise(wallet) {
return $q(function (resolve, reject) {
walletService.getAddress(wallet, true, function (e, addr) {
if (e) reject(e);
resolve(addr);
});
});
}
function goToCollectEmail() {
$state.go('onboarding.collectEmail', {
bchWalletId: bchWalletId,
btcWalletId: btcWalletId
});
}
var bchAddressPromise = createAddressPromise(bchWallet);
var btcAddressPromise = createAddressPromise(btcWallet);
ongoingProcess.set('generatingNewAddress', true);
$q.all([bchAddressPromise, btcAddressPromise]).then(function (addresses) {
ongoingProcess.set('generatingNewAddress', false);
$state.go('tabs.home');
}, function (e) {
ongoingProcess.set('generatingNewAddress', false);
$log.warn(e);
popupService.showAlert(gettextCatalog.getString('Error'), e);
$state.go('tabs.home');
});
});
});
});
$log.debug('Setting default currency : ' + newAltCurrency);
});
}
function goToCollectEmail() {
$state.go('onboarding.collectEmail', {
bchWalletId: bchWalletId,
btcWalletId: btcWalletId
});
}
var bchAddressPromise = createAddressPromise(bchWallet);
var btcAddressPromise = createAddressPromise(btcWallet);
ongoingProcess.set('generatingNewAddress', true);
$q.all([bchAddressPromise, btcAddressPromise]).then(function(addresses) {
ongoingProcess.set('generatingNewAddress', false);
$state.go('tabs.home');
}, function(e) {
ongoingProcess.set('generatingNewAddress', false);
$log.warn(e);
popupService.showAlert(gettextCatalog.getString('Error'), e);
$state.go('tabs.home');
});
});
}, 300);
};
});
})
}, 300);
};
});

View file

@ -76,9 +76,9 @@ angular.module('copayApp.controllers').controller('preferencesNotificationsContr
emailService.updateEmail(opts);
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("settings_email_notification_toggle", [{
"toggle": $scope.emailNotifications.value

View file

@ -0,0 +1,974 @@
'use strict';
(function () {
angular
.module('copayApp.controllers')
.controller('reviewController', reviewController);
function reviewController(addressbookService, bitcoinCashJsService, bitcore, bitcoreCash, bwcError, clipboardService, configService, feeService, gettextCatalog, $interval, $ionicHistory, $ionicModal, ionicToast, lodash, $log, ongoingProcess, platformInfo, popupService, profileService, $scope, sendFlowService, shapeshiftService, soundService, $state, $timeout, txConfirmNotification, txFormatService, walletService) {
var vm = this;
vm.buttonText = '';
vm.destination = {
address: '',
balanceAmount: '',
balanceCurrency: '',
coin: '',
color: '',
currency: '',
currencyColor: '',
kind: '', // 'address', 'contact', 'wallet'
name: ''
};
vm.displayAddress = '';
vm.feeCrypto = '';
vm.feeFiat = '';
vm.fiatCurrency = '';
vm.feeIsHigh = false;
vm.feeLessThanACent = false;
vm.isCordova = platformInfo.isCordova;
vm.memo = '';
vm.notReadyMessage = '';
vm.origin = {
balanceAmount: '',
balanceCurrency: '',
currency: '',
currencyColor: '',
};
vm.originWallet = null;
vm.paymentExpired = false;
vm.personalNotePlaceholder = gettextCatalog.getString('Enter text here');
vm.primaryAmount = '';
vm.primaryCurrency = '';
vm.usingMerchantFee = false;
vm.readyToSend = false;
vm.remainingTimeStr = '';
vm.secondaryAmount = '';
vm.secondaryCurrency = '';
vm.sendingTitle = gettextCatalog.getString('You are sending');
vm.sendStatus = '';
vm.showAddress = true;
vm.thirdParty = false;
vm.wallet = null;
vm.memoExpanded = false;
// Functions
vm.goBack = goBack;
vm.onSuccessConfirm = onSuccessConfirm;
vm.onShareTransaction = onShareTransaction;
var sendFlowData;
var config = null;
var coin = '';
var countDown = null;
var defaults = {};
var usingCustomFee = false;
var usingMerchantFee = false;
var destinationWalletId = '';
var lastTxId = '';
var originWalletId = '';
var priceDisplayIsFiat = true;
var satoshis = null;
var toAddress = '';
var tx = {};
var txPayproData = null;
var unitFromSat = 0;
var FEE_TOO_HIGH_LIMIT_PERCENTAGE = 15;
$scope.$on("$ionicView.beforeEnter", onBeforeEnter);
function onBeforeEnter(event, data) {
console.log('review onBeforeEnter sendflow ', sendFlowService.state);
// Reset from last time
vm.memo = '';
defaults = configService.getDefaults();
sendFlowData = sendFlowService.state.getClone();
originWalletId = sendFlowData.fromWalletId;
if (typeof sendFlowData.amount === 'string') {
satoshis = parseInt(sendFlowData.amount, 10);
} else {
satoshis = sendFlowData.amount;
}
toAddress = sendFlowData.toAddress;
destinationWalletId = sendFlowData.toWalletId;
vm.displayAddress = sendFlowData.displayAddress;
vm.originWallet = profileService.getWallet(originWalletId);
vm.origin.currency = vm.originWallet.coin.toUpperCase();
coin = vm.originWallet.coin;
if (sendFlowData.thirdParty) {
vm.thirdParty = sendFlowData.thirdParty;
switch (vm.thirdParty.id) {
case 'shapeshift':
initShapeshift(function (err) {
if (err) {
// Error stop here
ongoingProcess.set('connectingShapeshift', false);
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString(), function () {
$ionicHistory.goBack();
});
} else {
_next(data);
}
});
break;
case 'bip70':
initBip70();
default:
_next(data);
break;
}
} else {
_next(data);
}
function _next() {
configService.get(function onConfig(err, configCache) {
if (err) {
$log.err('Error getting config.', err);
} else {
config = configCache;
priceDisplayIsFiat = config.wallet.settings.priceDisplay === 'fiat';
vm.origin.currencyColor = (vm.originWallet.coin === 'btc' ? defaults.bitcoinWalletColor : defaults.bitcoinCashWalletColor);
console.log("coin", vm.originWallet.coin, vm.origin.currencyColor, config.bitcoinWalletColor, vm.originWallet.coin === 'btc');
unitFromSat = 1 / config.wallet.settings.unitToSatoshi;
}
updateSendAmounts();
getOriginWalletBalance(vm.originWallet);
handleDestinationAsAddress(toAddress, coin);
handleDestinationAsWallet(sendFlowData.toWalletId);
createVanityTransaction(data);
});
}
}
vm.approve = function() {
if (!tx || !vm.originWallet) return;
if (vm.paymentExpired) {
popupService.showAlert(null, gettextCatalog.getString('This bitcoin payment request has expired.', function () {
$ionicHistory.goBack();
}));
vm.sendStatus = '';
$timeout(function() {
$scope.$apply();
});
return;
}
ongoingProcess.set('creatingTx', true, statusChangeHandler);
getTxp(lodash.clone(tx), vm.originWallet, false, function(err, txp) {
ongoingProcess.set('creatingTx', false, statusChangeHandler);
if (err) return;
// confirm txs for more that 20usd, if not spending/touchid is enabled
function confirmTx(cb) {
if (walletService.isEncrypted(vm.originWallet))
return cb();
var amountUsd = parseFloat(txFormatService.formatToUSD(vm.originWallet.coin, txp.amount));
return cb();
};
function publishAndSign() {
if (!vm.originWallet.canSign() && !vm.originWallet.isPrivKeyExternal()) {
$log.info('No signing proposal: No private key');
return walletService.onlyPublish(vm.originWallet, txp, function(err) {
if (err) setSendError(err);
}, statusChangeHandler);
}
walletService.publishAndSign(vm.originWallet, txp, function(err, txp) {
if (err) return setSendError(err);
if (config.confirmedTxsNotifications && config.confirmedTxsNotifications.enabled) {
txConfirmNotification.subscribe(vm.originWallet, {
txid: txp.txid
});
lastTxId = txp.txid;
}
}, statusChangeHandler);
};
confirmTx(function(nok) {
if (nok) {
vm.sendStatus = '';
$timeout(function() {
$scope.$apply();
});
return;
}
publishAndSign();
});
});
};
vm.chooseFeeLevel = function(tx, wallet) {
if (wallet.coin == 'bch') return;
if (usingMerchantFee) return;
var scope = $rootScope.$new(true);
scope.network = tx.network;
scope.feeLevel = tx.feeLevel;
scope.noSave = true;
scope.coin = vm.originWallet.coin;
if (usingCustomFee) {
scope.customFeePerKB = tx.feeRate;
scope.feePerSatByte = tx.feeRate / 1000;
}
$ionicModal.fromTemplateUrl('views/modals/chooseFeeLevel.html', {
scope: scope,
backdropClickToClose: false,
hardwareBackButtonClose: false
}).then(function(modal) {
scope.chooseFeeLevelModal = modal;
scope.openModal();
});
scope.openModal = function() {
scope.chooseFeeLevelModal.show();
};
scope.hideModal = function(newFeeLevel, customFeePerKB) {
scope.chooseFeeLevelModal.hide();
$log.debug('New fee level choosen:' + newFeeLevel + ' was:' + tx.feeLevel);
usingCustomFee = newFeeLevel == 'custom' ? true : false;
if (tx.feeLevel == newFeeLevel && !usingCustomFee) return;
tx.feeLevel = newFeeLevel;
if (usingCustomFee) tx.feeRate = parseInt(customFeePerKB);
updateTx(tx, vm.originWallet, {
clearCache: true,
dryRun: true
}, function() {});
};
};
function createVanityTransaction(data) {
console.log('createVanityTransaction()');
var configFeeLevel = config.wallet.settings.feeLevel ? config.wallet.settings.feeLevel : 'normal';
// Grab stateParams
tx = {
amount: parseInt(sendFlowData.amount),
sendMax: sendFlowData.sendMax,
fromWalletId: sendFlowData.fromWalletId,
toAddress: sendFlowData.toAddress,
paypro: txPayproData,
feeLevel: configFeeLevel,
spendUnconfirmed: config.wallet.spendUnconfirmed,
// Vanity tx info (not in the real tx)
recipientType: vm.destination.kind || null,
toName: vm.destination.name || null,
toEmail: vm.destination.email || null,
toColor: vm.destination.color || null,
network: false,
coin: vm.originWallet.coin,
txp: {},
};
if (data.stateParams.requiredFeeRate) {
vm.usingMerchantFee = true;
tx.feeRate = parseInt(data.stateParams.requiredFeeRate);
}
if (tx.coin && tx.coin === 'bch') {
tx.feeLevel = 'normal';
}
var B = tx.coin === 'bch' ? bitcoreCash : bitcore;
var networkName;
try {
if (vm.destination.kind === 'wallet') { // This is a wallet-to-wallet transfer
ongoingProcess.set('generatingNewAddress', true);
var toWallet = profileService.getWallet(destinationWalletId);
// We need an address to send to, so we ask the walletService to create a new address for the toWallet.
console.log('Getting address for wallet...');
walletService.getAddress(toWallet, true, function onWalletAddress(err, addr) {
console.log('getAddress cb called', err);
ongoingProcess.set('generatingNewAddress', false);
tx.toAddress = addr;
networkName = (new B.Address(tx.toAddress)).network.name;
tx.network = networkName;
console.log('calling setupTx() for wallet.');
setupTx(tx);
});
} else { // This is a Wallet-to-address transfer
networkName = (new B.Address(tx.toAddress)).network.name;
tx.network = networkName;
console.log('calling setupTx() for address.');
setupTx(tx);
}
} catch (e) {
console.error('Error setting up tx', e);
var message = gettextCatalog.getString('Invalid address');
popupService.showAlert(null, message, function () {
$ionicHistory.nextViewOptions({
disableAnimate: true,
historyRoot: true
});
$state.go('tabs.send').then(function () {
$ionicHistory.clearHistory();
});
});
return;
}
}
function getOriginWalletBalance(originWallet) {
var balanceText = getWalletBalanceDisplayText(vm.originWallet);
vm.origin.balanceAmount = balanceText.amount;
vm.origin.balanceCurrency = balanceText.currency;
}
function getSendMaxInfo(tx, wallet, cb) {
if (!tx.sendMax) return cb();
//ongoingProcess.set('retrievingInputs', true);
walletService.getSendMaxInfo(wallet, {
feePerKb: tx.feeRate,
excludeUnconfirmedUtxos: !tx.spendUnconfirmed,
returnInputs: true,
}, cb);
};
function getTxp(tx, wallet, dryRun, cb) {
// ToDo: use a credential's (or fc's) function for this
if (tx.description && !wallet.credentials.sharedEncryptingKey) {
var msg = gettextCatalog.getString('Could not add message to imported wallet without shared encrypting key');
$log.warn(msg);
return setSendError(msg);
}
if (tx.amount > Number.MAX_SAFE_INTEGER) {
var msg = gettextCatalog.getString('Amount too big');
$log.warn(msg);
return setSendError(msg);
}
var txp = {};
txp.outputs = [{
'toAddress': tx.toAddress,
'amount': tx.amount,
'message': vm.memo
}];
if (tx.sendMaxInfo) {
txp.inputs = tx.sendMaxInfo.inputs;
txp.fee = tx.sendMaxInfo.fee;
} else {
if (usingCustomFee || usingMerchantFee) {
txp.feePerKb = tx.feeRate;
} else txp.feeLevel = tx.feeLevel;
}
txp.message = vm.memo;
if (tx.paypro) {
txp.payProUrl = tx.paypro.url;
}
txp.excludeUnconfirmedUtxos = !tx.spendUnconfirmed;
txp.dryRun = dryRun;
walletService.createTx(wallet, txp, function(err, ctxp) {
if (err) {
setSendError(err);
return cb(err);
}
return cb(null, ctxp);
});
};
function getWalletBalanceDisplayText(wallet) {
var balanceCryptoAmount = '';
var balanceCryptoCurrencyCode = '';
var balanceFiatAmount = '';
var balanceFiatCurrency = '';
var displayAmount = '';
var displayCurrency = '';
var walletStatus = null;
if (wallet.status && wallet.status.isValid) {
walletStatus = wallet.status;
} else if (wallet.cachedStatus.isValid) {
walletStatus = wallet.cachedStatus;
}
if (walletStatus) {
var cryptoBalanceParts = walletStatus.spendableBalanceStr.split(' ');
balanceCryptoAmount = cryptoBalanceParts[0];
balanceCryptoCurrencyCode = cryptoBalanceParts.length > 1 ? cryptoBalanceParts[1] : '';
if (walletStatus.alternativeBalanceAvailable) {
balanceFiatAmount = walletStatus.spendableBalanceAlternative;
balanceFiatCurrency = walletStatus.alternativeIsoCode;
}
}
if (priceDisplayIsFiat) {
displayAmount = balanceFiatAmount ? balanceFiatAmount : balanceCryptoAmount;
displayCurrency = balanceFiatAmount ? balanceFiatCurrency : balanceCryptoCurrencyCode;
} else {
displayAmount = balanceCryptoAmount;
displayCurrency = balanceCryptoCurrencyCode;
}
return {
amount: displayAmount,
currency: displayCurrency
};
}
function goBack() {
sendFlowService.router.goBack();
}
function handleDestinationAsAddress(address, originCoin) {
if (!address) {
return;
}
// Check if the recipient is a contact
addressbookService.get(originCoin + address, function(err, contact) {
if (!err && contact) {
handleDestinationAsAddressOfContact(contact);
} else {
if (originCoin === 'bch') {
vm.destination.address = bitcoinCashJsService.readAddress(address).cashaddr;
} else {
vm.destination.address = address;
}
vm.destination.kind = 'address';
}
});
}
function handleDestinationAsAddressOfContact(contact) {
vm.destination.kind = 'contact';
vm.destination.name = contact.name;
vm.destination.email = contact.email;
vm.destination.color = contact.coin === 'btc' ? defaults.bitcoinWalletColor : defaults.bitcoinCashWalletColor;
vm.destination.currency = contact.coin.toUpperCase();
vm.destination.currencyColor = vm.destination.color;
}
function handleDestinationAsWallet(walletId) {
destinationWalletId = walletId;
if (!destinationWalletId) {
return;
}
var destinationWallet = profileService.getWallet(destinationWalletId);
vm.destination.coin = destinationWallet.coin;
vm.destination.color = destinationWallet.color;
vm.destination.currency = destinationWallet.coin.toUpperCase();
vm.destination.kind = 'wallet';
vm.destination.name = destinationWallet.name;
if (defaults) {
vm.destination.currencyColor = vm.destination.coin === 'btc' ? defaults.bitcoinWalletColor : defaults.bitcoinCashWalletColor;
}
var balanceText = getWalletBalanceDisplayText(destinationWallet);
vm.destination.balanceAmount = balanceText.amount;
vm.destination.balanceCurrency = balanceText.currency;
}
function initBip70() {
vm.sendingTitle = gettextCatalog.getString('You are paying');
vm.memo = vm.thirdParty.memo;
vm.memoExpanded = !!vm.memo;
vm.destination.name = vm.thirdParty.name;
txPayproData = {
caTrusted: vm.thirdParty.caTrusted,
domain: vm.thirdParty.domain,
expires: vm.thirdParty.expires,
toAddress: toAddress,
url: vm.thirdParty.url,
verified: vm.thirdParty.verified,
};
}
function initShapeshift(cb) {
vm.sendingTitle = gettextCatalog.getString('You are shifting');
if (!vm.thirdParty.data) {
vm.thirdParty.data = {};
}
var toWallet = profileService.getWallet(destinationWalletId);
vm.destination.name = toWallet.name;
vm.destination.color = toWallet.color;
vm.destination.currency = toWallet.coin.toUpperCase();
ongoingProcess.set('connectingShapeshift', true);
walletService.getAddress(vm.originWallet, false, function onReturnWalletAddress(err, returnAddr) {
if (err) {
return cb(err);
}
walletService.getAddress(toWallet, false, function onWithdrawalWalletAddress(err, withdrawalAddr) {
if (err) {
return cb(err);
}
// Need to use the correct service to do it.
var amount = parseFloat(satoshis / 100000000);
shapeshiftService.shiftIt(vm.originWallet.coin, toWallet.coin, withdrawalAddr, returnAddr, amount, function onShiftIt(err, shapeshiftData) {
if (err) {
return cb(err);
} else {
vm.destination.kind = 'shapeshift';
vm.destination.address = toAddress;
tx.toAddress = shapeshiftData.toAddress;
vm.memo = 'ShapeShift Order:\nhttps://www.shapeshift.io/#/status/' + shapeshiftData.orderId;
vm.memoExpanded = !!vm.memo;
ongoingProcess.set('connectingShapeshift', false);
cb();
}
});
});
});
}
function onShareTransaction() {
var explorerTxUrl = 'https://explorer.bitcoin.com/' + tx.coin + '/tx/' + lastTxId;
if (platformInfo.isCordova) {
var text = gettextCatalog.getString('Take a look at this Bitcoin Cash transaction here: ') + explorerTxUrl;
if (coin === 'btc') {
text = gettextCatalog.getString('Take a look at this Bitcoin transaction here: ') + explorerTxUrl;
}
window.plugins.socialsharing.share(text, null, null, null);
} else {
ionicToast.show(gettextCatalog.getString('Copied to clipboard'), 'bottom', false, 3000);
clipboardService.copyToClipboard(explorerTxUrl);
}
}
function startExpirationTimer(expirationTime) {
vm.paymentExpired = false;
setExpirationTime();
countDown = $interval(function() {
setExpirationTime();
}, 1000);
function setExpirationTime() {
console.log('setExpirationTime()');
var now = Math.floor(Date.now() / 1000);
if (now > expirationTime) {
setExpiredValues();
return;
}
var totalSecs = expirationTime - now;
var m = Math.floor(totalSecs / 60);
var s = totalSecs % 60;
vm.remainingTimeStr = m + ":" + ('0' + s).slice(-2);
};
function setExpiredValues() {
vm.paymentExpired = true;
vm.remainingTimeStr = gettextCatalog.getString('Expired');
vm.readyToSend = false;
if (countDown) $interval.cancel(countDown);
$timeout(function() {
$scope.$apply();
});
};
};
function updateSendAmounts() {
if (typeof satoshis !== 'number') {
return;
}
var cryptoAmount = '';
var cryptoCurrencyCode = '';
var amountStr = txFormatService.formatAmountStr(coin, satoshis);
if (amountStr) {
var amountParts = amountStr.split(' ');
cryptoAmount = amountParts[0];
cryptoCurrencyCode = amountParts.length > 1 ? amountParts[1] : '';
}
// Want to avoid flashing of amount strings so do all formatting after this has returned.
txFormatService.formatAlternativeStr(coin, satoshis, function(v) {
if (!v) {
vm.primaryAmount = cryptoAmount;
vm.primaryCurrency = cryptoCurrencyCode;
vm.secondaryAmount = '';
vm.secondaryCurrency = '';
return;
}
vm.secondaryAmount = vm.primaryAmount;
vm.secondaryCurrency = vm.primaryCurrency;
var fiatParts = v.split(' ');
var fiatAmount = fiatParts[0];
var fiatCurrency = fiatParts.length > 1 ? fiatParts[1] : '';
if (priceDisplayIsFiat) {
vm.primaryAmount = fiatAmount;
vm.primaryCurrency = fiatCurrency;
vm.secondaryAmount = cryptoAmount;
vm.secondaryCurrency = cryptoCurrencyCode;
} else {
vm.primaryAmount = cryptoAmount;
vm.primaryCurrency = cryptoCurrencyCode;
vm.secondaryAmount = fiatAmount;
vm.secondaryCurrency = fiatCurrency;
}
});
}
function onSuccessConfirm() {
vm.sendStatus = '';
$ionicHistory.nextViewOptions({
disableAnimate: true,
historyRoot: true
});
$state.go('tabs.send').then(function() {
$ionicHistory.clearHistory();
$state.transitionTo('tabs.home');
});
};
function setButtonText(isMultisig, isPayPro) {
if (isPayPro) {
if (vm.isCordova) {
vm.buttonText = gettextCatalog.getString('Slide to pay');
} else {
vm.buttonText = gettextCatalog.getString('Click to pay');
}
} else if (isMultisig) {
if (vm.isCordova) {
vm.buttonText = gettextCatalog.getString('Slide to accept');
} else {
vm.buttonText = gettextCatalog.getString('Click to accept');
}
} else {
if (vm.isCordova) {
vm.buttonText = gettextCatalog.getString('Slide to send');
} else {
vm.buttonText = gettextCatalog.getString('Click to send');
}
}
}
function setNotReady(msg, criticalError) {
vn.readyToSend = false;
vm.notReadyMessage = msg;
$scope.criticalError = criticalError;
$log.warn('Not ready to make the payment:' + msg);
$timeout(function() {
$scope.$apply();
});
};
function setSendError(msg) {
$scope.sendStatus = '';
vm.readyToSend = false;
$timeout(function() {
$scope.$apply();
});
popupService.showAlert(gettextCatalog.getString('Error at confirm'), bwcError.msg(msg), function () {
$ionicHistory.goBack();
});
};
function setupTx(tx) {
if (tx.coin === 'bch') {
tx.displayAddress = bitcoinCashJsService.readAddress(tx.toAddress).cashaddr;
} else {
tx.displayAddress = tx.toAddress;
}
addressbookService.get(tx.coin+tx.toAddress, function(err, addr) { // Check if the recipient is a contact
if (!err && addr) {
tx.toName = addr.name;
tx.toEmail = addr.email;
tx.recipientType = 'contact';
}
});
vm.showAddress = false;
setButtonText(vm.originWallet.credentials.m > 1, !!tx.paypro);
if (tx.paypro)
startExpirationTimer(tx.paypro.expires);
popupService.showConfirm(null, 'Do you want this transaction to be sent without a fee?', 'Yes', 'No', function(ok) {
if(ok){
tx.feeRate = 0;
// tx.feeLevel = 'free';
usingCustomFee = true;
}
updateTx(tx, vm.originWallet, {
dryRun: true
}, function(err) {
$timeout(function() {
$scope.$apply();
}, 10);
});
});
// setWalletSelector(tx.coin, tx.network, tx.amount, function(err) {
// if (err) {
// return exitWithError('Could not update wallets');
// }
//
// if (vm.wallets.length > 1) {
// vm.showWalletSelector();
// } else if (vm.wallets.length) {
// setWallet(vm.wallets[0], tx);
// }
// });
}
function showSendMaxWarning(wallet, sendMaxInfo) {
var feeAlternative = '',
msg = '';
function verifyExcludedUtxos() {
var warningMsg = [];
if (sendMaxInfo.utxosBelowFee > 0) {
warningMsg.push(gettextCatalog.getString("A total of {{amountBelowFeeStr}} were excluded. These funds come from UTXOs smaller than the network fee provided.", {
amountBelowFeeStr: txFormatService.formatAmountStr(wallet.coin, sendMaxInfo.amountBelowFee)
}));
}
if (sendMaxInfo.utxosAboveMaxSize > 0) {
warningMsg.push(gettextCatalog.getString("A total of {{amountAboveMaxSizeStr}} were excluded. The maximum size allowed for a transaction was exceeded.", {
amountAboveMaxSizeStr: txFormatService.formatAmountStr(vm.originWallet.coin, sendMaxInfo.amountAboveMaxSize)
}));
}
return warningMsg.join('\n');
};
feeAlternative = txFormatService.formatAlternativeStr(vm.originWallet.coin, sendMaxInfo.fee);
if (feeAlternative) {
msg = gettextCatalog.getString("{{feeAlternative}} will be deducted for bitcoin networking fees ({{fee}}).", {
fee: txFormatService.formatAmountStr(vm.originWallet.coin, sendMaxInfo.fee),
feeAlternative: feeAlternative
});
} else {
msg = gettextCatalog.getString("{{fee}} will be deducted for bitcoin networking fees).", {
fee: txFormatService.formatAmountStr(vm.originWallet.coin, sendMaxInfo.fee)
});
}
var warningMsg = verifyExcludedUtxos();
if (!lodash.isEmpty(warningMsg))
msg += '\n' + warningMsg;
popupService.showAlert(null, msg, function() {});
//popupService.showConfirm(null, msg, null, null, function() {});
};
function statusChangeHandler(processName, showName, isOn) {
$log.debug('statusChangeHandler: ', processName, showName, isOn);
if (
(
processName === 'broadcastingTx' ||
((processName === 'signingTx') && vm.originWallet.m > 1) ||
(processName == 'sendingTx' && !vm.originWallet.canSign() && !vm.originWallet.isPrivKeyExternal())
) && !isOn) {
// Show the popup
vm.sendStatus = 'success';
// Clear the send flow service state
sendFlowService.state.clear();
if ($state.current.name === "tabs.send.review") { // XX SP: Otherwise all open wallets on other devices play this sound if you have been in a send flow before on that device.
soundService.play('misc/payment_sent.mp3');
}
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
}
// When displaying Fiat, if the formatting fails, the crypto will be the primary amount.
var amount = unitFromSat * satoshis;
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": vm.originWallet.coin,
"type": "outgoing",
"amount": amount,
"fees": vm.feeCrypto
}], [channel, "adjust"]);
window.BitAnalytics.LogEventHandlers.postEvent(log);
$timeout(function() {
$scope.$digest();
}, 100);
} else if (showName) {
vm.sendStatus = showName;
}
};
function updateTx(tx, wallet, opts, cb) {
ongoingProcess.set('calculatingFee', true);
if (opts.clearCache) {
tx.txp = {};
}
// $scope.tx = tx;
// function updateAmount() {
// if (!tx.amount) return;
//
// // Amount
// tx.amountStr = txFormatService.formatAmountStr(originWallet.coin, tx.amount);
// tx.amountValueStr = tx.amountStr.split(' ')[0];
// tx.amountUnitStr = tx.amountStr.split(' ')[1];
// txFormatService.formatAlternativeStr(wallet.coin, tx.amount, function(v) {
// var parts = v.split(' ');
// tx.alternativeAmountStr = v;
// tx.alternativeAmountValueStr = parts[0];
// tx.alternativeAmountUnitStr = (parts.length > 0) ? parts[1] : '';
// });
// }
//
// updateAmount();
// refresh();
var feeServiceLevel = usingMerchantFee && vm.originWallet.coin == 'btc' ? 'urgent' : tx.feeLevel;
feeService.getFeeRate(vm.originWallet.coin, tx.network, feeServiceLevel, function(err, feeRate) {
if (err) {
ongoingProcess.set('calculatingFee', false);
return cb(err);
}
var msg;
// if (tx.feeLevel == 'free'){
// tx.feeRate = 0;
// }
// else
if (usingCustomFee) {
msg = gettextCatalog.getString('Custom');
tx.feeLevelName = msg;
} else if (usingMerchantFee) {
$log.info('Using Merchant Fee:' + tx.feeRate + ' vs. Urgent level:' + feeRate);
msg = gettextCatalog.getString('Suggested by Merchant');
tx.feeLevelName = msg;
} else {
tx.feeLevelName = feeService.feeOpts[tx.feeLevel];
tx.feeRate = feeRate;
}
getSendMaxInfo(lodash.clone(tx), wallet, function(err, sendMaxInfo) {
if (err) {
ongoingProcess.set('calculatingFee', false);
var msg = gettextCatalog.getString('Error getting SendMax information');
return setSendError(msg);
}
if (sendMaxInfo) {
$log.debug('Send max info', sendMaxInfo);
if (tx.sendMax && sendMaxInfo.amount == 0) {
ongoingProcess.set('calculatingFee', false);
setNotReady(gettextCatalog.getString('Insufficient confirmed funds'));
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Not enough funds for fee'), function () {
$ionicHistory.goBack();
});
return cb('no_funds');
}
tx.sendMaxInfo = sendMaxInfo;
tx.amount = tx.sendMaxInfo.amount;
satoshis = tx.amount;
updateSendAmounts();
ongoingProcess.set('calculatingFee', false);
$timeout(function() {
showSendMaxWarning(wallet, sendMaxInfo);
}, 200);
}
// txp already generated for this wallet?
if (tx.txp[wallet.id]) {
ongoingProcess.set('calculatingFee', false);
vm.readyToSend = true;
updateSendAmounts();
$scope.$apply();
return cb();
}
console.log('calling getTxp() from getSendMaxInfo cb.');
getTxp(lodash.clone(tx), wallet, opts.dryRun, function(err, txp) {
ongoingProcess.set('calculatingFee', false);
if (err) {
if (err.message == 'Insufficient funds') {
setNotReady(gettextCatalog.getString('Insufficient funds'));
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Not enough funds for fee'));
return cb('no_funds');
} else
return cb(err);
}
txp.feeStr = txFormatService.formatAmountStr(wallet.coin, txp.fee);
txFormatService.formatAlternativeStr(wallet.coin, txp.fee, function(v) {
// txp.alternativeFeeStr = v;
// if (txp.alternativeFeeStr.substring(0, 4) == '0.00')
// txp.alternativeFeeStr = '< ' + txp.alternativeFeeStr;
vm.feeFiat = v;
vm.fiatCurrency = config.wallet.settings.alternativeIsoCode;
if (v.substring(0, 1) === "<") {
vm.feeLessThanACent = true;
}
console.log("fiat", vm.feeFiat);
});
var per = (txp.fee / (txp.amount + txp.fee) * 100);
var perString = per.toFixed(2);
txp.feeRatePerStr = (perString == '0.00' ? '< ' : '') + perString + '%';
txp.feeToHigh = per > FEE_TOO_HIGH_LIMIT_PERCENTAGE;
vm.feeCrypto = (unitFromSat * txp.fee).toFixed(8);
vm.feeIsHigh = txp.feeToHigh;
console.log("crypto", vm.feeCrypto);
tx.txp[wallet.id] = txp;
$log.debug('Confirm. TX Fully Updated for wallet:' + wallet.id, tx);
vm.readyToSend = true;
updateSendAmounts();
console.log('readyToSend:', vm.readyToSend);
$scope.$apply();
return cb();
});
});
});
}
}
})();

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('servicesController', function($scope, $ionicScrollDelegate, $timeout, servicesService, configService) {
angular.module('copayApp.controllers').controller('servicesController', function(externalLinkService, $scope, $ionicScrollDelegate, $timeout, servicesService, configService) {
$scope.hide = false;
configService.whenAvailable(function(config) {
@ -20,4 +20,8 @@ angular.module('copayApp.controllers').controller('servicesController', function
}, 10);
};
$scope.open = function(url) {
externalLinkService.open(url, false);
}
});

View file

@ -1,67 +1,58 @@
'use strict';
angular.module('copayApp.controllers').controller('shapeshiftController', function($scope, $interval, profileService, walletService, popupService, lodash, $ionicNavBarDelegate) {
angular.module('copayApp.controllers').controller('shapeshiftController', function($scope, sendFlowService, $state, $timeout, $ionicHistory, profileService, walletService, popupService, lodash, $ionicNavBarDelegate) {
var walletsBtc = [];
var walletsBch = [];
function generateAddress(wallet, cb) {
if (!wallet) return;
walletService.getAddress(wallet, false, function(err, addr) {
if (err) {
popupService.showAlert(err);
}
return cb(addr);
});
}
function showToWallets() {
$scope.toWallets = $scope.fromWallet.coin == 'btc' ? walletsBch : walletsBtc;
$scope.onToWalletSelect($scope.toWallets[0]);
$scope.singleToWallet = $scope.toWallets.length == 1;
}
$scope.onFromWalletSelect = function(wallet) {
$scope.fromWallet = wallet;
showToWallets();
generateAddress(wallet, function(addr) {
$scope.fromWalletAddress = addr;
});
};
$scope.onToWalletSelect = function(wallet) {
$scope.toWallet = wallet;
generateAddress(wallet, function(addr) {
$scope.toWalletAddress = addr;
});
}
$scope.showMyAddress = showMyAddress;
$scope.$on("$ionicView.beforeEnter", function(event, data) {
walletsBtc = profileService.getWallets({coin: 'btc'});
walletsBch = profileService.getWallets({coin: 'bch'});
$scope.fromWallets = lodash.filter(walletsBtc.concat(walletsBch), function(w) {
return w.status.balance.availableAmount > 0;
return (w.status && w.status.balance && w.status.balance.availableAmount > 0);
});
if ($scope.fromWallets.length == 0) return;
$scope.onFromWalletSelect($scope.fromWallets[0]);
$scope.onToWalletSelect($scope.toWallets[0]);
$scope.singleFromWallet = $scope.fromWallets.length == 1;
$scope.singleToWallet = $scope.toWallets.length == 1;
$scope.singleFromWallet = $scope.fromWallets.length === 1;
$scope.fromWalletSelectorTitle = 'From';
$scope.toWalletSelectorTitle = 'To';
$scope.showFromWallets = false;
$scope.showToWallets = false;
$scope.walletsWithFunds = profileService.getWallets({onlyComplete: true, hasFunds: true});
$scope.wallets = profileService.getWallets({onlyComplete: true});
$scope.hasWallets = !lodash.isEmpty($scope.wallets);
});
$scope.$on("$ionicView.enter", function(event, data) {
$ionicNavBarDelegate.showBar(true);
});
$scope.showFromWalletSelector = function() {
$scope.showFromWallets = true;
// This could probably be enhanced refactoring the routes abstract states
$scope.createWallet = function() {
$state.go('tabs.home').then(function() {
$state.go('tabs.add.create-personal');
});
};
$scope.buyBitcoin = function() {
$state.go('tabs.home').then(function() {
$state.go('tabs.buyandsell');
});
};
$scope.shapeshift = function() {
var stateParams = {
thirdParty: {
id: 'shapeshift'
}
};
sendFlowService.start(stateParams);
}
$scope.showToWalletSelector = function() {
$scope.showToWallets = true;
function showMyAddress() {
$state.go('tabs.home').then(function() {
$state.go('tabs.receive');
});
}
});

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('tabHomeController',
function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, bannerService, externalLinkService, latestReleaseService, profileService, walletService, configService, $log, platformInfo, storageService, txpModalService, appConfigService, startupService, addressbookService, bwcError, nextStepsService, buyAndSellService, homeIntegrationsService, bitpayCardService, pushNotificationsService, timeService, bitcoincomService, pricechartService, firebaseEventsService, servicesService, shapeshiftService, $ionicNavBarDelegate, signVerifyMessageService) {
function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, bannerService, communityService, externalLinkService, latestReleaseService, profileService, walletService, configService, $log, platformInfo, sendFlowService, storageService, txpModalService, appConfigService, startupService, addressbookService, bwcError, nextStepsService, buyAndSellService, homeIntegrationsService, bitpayCardService, pushNotificationsService, timeService, bitcoincomService, pricechartService, firebaseEventsService, servicesService, shapeshiftService, $ionicNavBarDelegate, signVerifyMessageService) {
var wallet;
var listeners = [];
var notifications = [];
@ -20,7 +20,12 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.bannerUrl = '';
$scope.$on("$ionicView.afterEnter", function() {
$scope.$on("$ionicView.beforeEnter", onBeforeEnter);
$scope.$on("$ionicView.enter", onEnter);
$scope.$on("$ionicView.afterEnter", onAfterEnter);
$scope.$on("$ionicView.leave", onLeave);
function onAfterEnter () {
startupService.ready();
bannerService.getBanner(function (banner) {
@ -28,32 +33,32 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.bannerUrl = banner.url;
$scope.bannerIsLoading = false;
});
});
};
function onBeforeEnter (event, data) {
$scope.$on("$ionicView.beforeEnter", function(event, data) {
if (!$scope.homeTip) {
storageService.getHomeTipAccepted(function(error, value) {
$scope.homeTip = (value == 'accepted') ? false : true;
});
}
if ($scope.isNW) {
latestReleaseService.checkLatestRelease(function(err, newRelease) {
if (err) {
$log.warn(err);
return;
}
if (newRelease) {
$scope.newRelease = true;
$scope.updateText = gettextCatalog.getString('There is a new version of {{appName}} available', {
appName: $scope.name
});
}
});
}
});
latestReleaseService.checkLatestRelease(function(err, newReleaseData) {
if (err) {
$log.warn(err);
return;
}
if (newReleaseData) {
$scope.newRelease = true;
$scope.newReleaseText = gettextCatalog.getString('There is a new version of {{appName}} available', {
appName: $scope.name
});
$scope.newReleaseNotes = newReleaseData.releaseNotes;
}
});
}
$scope.$on("$ionicView.enter", function(event, data) {
function onEnter(event, data) {
$ionicNavBarDelegate.showBar(true);
updateAllWallets();
@ -97,34 +102,30 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}
$scope.showServices = true;
pushNotificationsService.init();
firebaseEventsService.init();
$timeout(function() {
$ionicScrollDelegate.resize();
$scope.$apply();
}, 10);
});
});
}
$scope.$on("$ionicView.leave", function(event, data) {
function onLeave (event, data) {
lodash.each(listeners, function(x) {
x();
});
});
}
$scope.createdWithinPastDay = function(time) {
return timeService.withinPastDay(time);
};
$scope.openExternalLink = function() {
var url = 'https://github.com/Bitcoin-com/Wallet/releases/latest';
var optIn = true;
var title = gettextCatalog.getString('Update Available');
var message = gettextCatalog.getString('An update to this app is available. For your security, please update to the latest version.');
var okText = gettextCatalog.getString('View Update');
var cancelText = gettextCatalog.getString('Go Back');
externalLinkService.open(url, optIn, title, message, okText, cancelText);
$scope.startFreshSend = function() {
sendFlowService.start();
}
$scope.showUpdatePopup = function() {
latestReleaseService.showUpdatePopup();
};
$scope.openBannerUrl = function() {
@ -205,6 +206,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
var j = 0;
lodash.each(wallets, function(wallet) {
walletService.invalidateCache(wallet); // Temporary solution, to have the good balance, when we ask to reload the wallets.
walletService.getStatus(wallet, {}, function(err, status) {
if (err) {
@ -224,6 +226,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
cb();
}
}
$scope.walletsWithFunds = profileService.getWallets({hasFunds: true});
});
});
};

View file

@ -1,7 +1,8 @@
'use strict';
angular.module('copayApp.controllers').controller('tabReceiveController', function($rootScope, $scope, $timeout, $log, $ionicModal, $state, $ionicHistory, $ionicPopover, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService, bwcError, bitcoinCashJsService, $ionicNavBarDelegate, txFormatService, soundService, clipboardService) {
angular.module('copayApp.controllers').controller('tabReceiveController', function($rootScope, $scope, $timeout, $log, $ionicModal, $state, $ionicHistory, $ionicPopover, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService, bwcError, bitcoinCashJsService, $ionicNavBarDelegate, sendFlowService, txFormatService, soundService, clipboardService) {
var CLOSE_NORMAL = 1000;
var listeners = [];
$scope.bchAddressType = { type: 'cashaddr' };
var bchAddresses = {};
@ -10,20 +11,63 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
$scope.isCordova = platformInfo.isCordova;
$scope.isNW = platformInfo.isNW;
var currentAddressSocket = {};
var paymentSubscriptionObj = { op:"addr_sub" }
var config;
var currentAddressSocket = null;
var paymentSubscriptionObj = { op:'addr_sub' };
$scope.displayBalanceAsFiat = true;
$scope.$on('$ionicView.beforeLeave', onBeforeLeave);
$scope.requestSpecificAmount = function() {
$state.go('tabs.paymentRequest.amount', {
id: $scope.wallet.credentials.walletId,
coin: $scope.wallet.coin
sendFlowService.start({
toWalletId: $scope.wallet.credentials.walletId,
isRequestAmount: true
});
};
function connectSocket() {
// Close existing socket if not connected with current address
if (currentAddressSocket) {
currentAddressSocket.close([CLOSE_NORMAL]);
}
if ($scope.wallet.coin === 'bch') {
// listen to bch address
currentAddressSocket = new WebSocket('wss://ws.blockchain.info/bch/inv');
paymentSubscriptionObj.addr = $scope.addrBchLegacy;
} else {
// listen to btc address
currentAddressSocket = new WebSocket('wss://ws.blockchain.info/inv');
paymentSubscriptionObj.addr = $scope.addr;
}
// create subscription to address
var msg = JSON.stringify(paymentSubscriptionObj);
currentAddressSocket.onopen = function (event) {
currentAddressSocket.send(msg);
};
// listen for response
currentAddressSocket.onmessage = function (event) {
//console.log("message received:" + event.data);
receivedPayment(event.data);
};
currentAddressSocket.onclose = function(event) {
if (event.code !== CLOSE_NORMAL) {
$log.debug('Socket was closed abnormally. Reconnect will be attempted in 1 second.');
$timeout(function() {
connectSocket();
}, 1000);
}
};
currentAddressSocket.onerror = function(err) {
console.error('Socket encountered error: ', err, 'Closing socket');
currentAddressSocket.close();
};
}
$scope.setAddress = function(newAddr, copyAddress) {
$scope.addr = null;
if (!$scope.wallet || $scope.generatingAddress || !$scope.wallet.isComplete()) return;
@ -36,49 +80,24 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
popupService.showAlert(err);
}
//close existing socket
if (currentAddressSocket.close === 'function') {
currentAddressSocket.close();
}
if ($scope.wallet.coin == 'bch') {
bchAddresses = bitcoinCashJsService.translateAddresses(addr);
$scope.addr = bchAddresses[$scope.bchAddressType.type];
$scope.addrBchLegacy = bchAddresses['legacy'];
// listen to bch address
currentAddressSocket = new WebSocket("wss://ws.blockchain.info/bch/inv");
paymentSubscriptionObj.addr = bchAddresses['legacy'];
if ($scope.wallet.coin === 'bch') {
bchAddresses = bitcoinCashJsService.translateAddresses(addr);
$scope.addr = bchAddresses[$scope.bchAddressType.type];
$scope.addrBchLegacy = bchAddresses['legacy'];
} else {
$scope.addr = addr;
// listen to btc address
currentAddressSocket = new WebSocket("wss://ws.blockchain.info/inv");
paymentSubscriptionObj.addr = $scope.addr
$scope.addr = addr;
}
connectSocket();
if (copyAddress === true) {
try {
clipboardService.copyToClipboard($scope.wallet.coin == 'bch' && $scope.bchAddressType.type == 'cashaddr' ? 'bitcoincash:' + $scope.addr : $scope.addr);
} catch (error) {
$log.debug("Error copying to clipboard:");
$log.debug('Error copying to clipboard:');
$log.debug(error);
}
}
// create subscription
var msg = JSON.stringify(paymentSubscriptionObj);
currentAddressSocket.onopen = function (event) {
//console.log("message sent: " + msg);
currentAddressSocket.send(msg);
}
// listen for response
currentAddressSocket.onmessage = function (event) {
//console.log("message received:" + event.data);
receivedPayment(event.data);
}
$timeout(function() {
$scope.$apply();
@ -138,16 +157,18 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
$scope.paymentReceivedAlternativeAmount = ''; // For when a subsequent payment is received.
txFormatService.formatAlternativeStr($scope.wallet.coin, data.x.out[i].value, function(alternativeStr){
if (alternativeStr) {
$scope.paymentReceivedAlternativeAmount = alternativeStr;
$scope.$apply(function () {
$scope.paymentReceivedAlternativeAmount = alternativeStr;
});
}
});
}
}
$scope.paymentReceivedCoin = $scope.wallet.coin;
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": $scope.wallet.coin,
@ -159,6 +180,9 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
soundService.play('misc/payment_received.mp3');
}
// Notify new tx
$scope.$emit('bwsEvent', $scope.wallet.id);
$scope.$apply(function () {
$scope.showingPaymentReceived = true;
});
@ -227,16 +251,24 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
}
};
function onBeforeLeave() {
currentAddressSocket.close([CLOSE_NORMAL]);
}
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.wallets = profileService.getWallets();
$scope.singleWallet = $scope.wallets.length == 1;
if (!$scope.wallets[0]) return;
// select first wallet if no wallet selected previously
var selectedWallet = checkSelectedWallet($scope.wallet, $scope.wallets);
var selectedWallet = null;
if (data.stateParams.walletId) { // from walletDetails
selectedWallet = checkSelectedWallet(profileService.getWallet(data.stateParams.walletId), $scope.wallets);
} else {
// select first wallet if no wallet selected previously
selectedWallet = checkSelectedWallet($scope.wallet, $scope.wallets);
}
$scope.onWalletSelect(selectedWallet);
$scope.showShareButton = platformInfo.isCordova ? (platformInfo.isIOS ? 'iOS' : 'Android') : null;
listeners = [
@ -248,7 +280,6 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
configService.whenAvailable(function(_config) {
$scope.displayBalanceAsFiat = _config.wallet.settings.priceDisplay === 'fiat';
config = _config;
});
});

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('tabScanController', function($scope, $log, $timeout, scannerService, incomingData, $state, $ionicHistory, $rootScope, $ionicNavBarDelegate) {
angular.module('copayApp.controllers').controller('tabScanController', function(gettextCatalog, popupService, $scope, $log, $timeout, scannerService, incomingDataService, $state, $ionicHistory, $rootScope, $ionicNavBarDelegate) {
var scannerStates = {
unauthorized: 'unauthorized',
@ -111,7 +111,18 @@ angular.module('copayApp.controllers').controller('tabScanController', function(
// Sometimes (testing in Chrome, when reading QR Code) data is an object
// that has a string data.result.
contents = contents.result || contents;
incomingData.redir(contents);
incomingDataService.redir(contents, function onError(err) {
if (err) {
var title = gettextCatalog.getString('Scan Failed');
popupService.showAlert(title, err.message, function onAlertShown() {
// Enable another scan since we won't receive incomingDataMenu.menuHidden
activate();
});
} else {
scannerService.resumePreview();
}
});
}
$rootScope.$on('incomingDataMenu.menuHidden', function() {

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('tabSendController', function($scope, $rootScope, $log, $timeout, $ionicScrollDelegate, $ionicLoading, addressbookService, profileService, lodash, $state, walletService, incomingData, popupService, platformInfo, bwcError, gettextCatalog, scannerService, configService, bitcoinCashJsService, $ionicPopup, $ionicNavBarDelegate, clipboardService) {
angular.module('copayApp.controllers').controller('tabSendController', function(bitcoinUriService, $scope, $log, $timeout, $ionicScrollDelegate, addressbookService, profileService, lodash, $state, walletService, platformInfo, sendFlowService, gettextCatalog, configService, $ionicPopup, $ionicNavBarDelegate, clipboardService, incomingDataService) {
var clipboardHasAddress = false;
var clipboardHasContent = false;
var originalList;
@ -28,6 +28,10 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
};
$scope.$on("$ionicView.enter", function(event, data) {
var stateParams = sendFlowService.state.getClone();
$scope.fromWallet = profileService.getWallet(stateParams.fromWalletId);
clipboardService.readFromClipboard(function(text) {
if (text.length > 200) {
text = text.substring(0, 200);
@ -35,7 +39,9 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
$scope.clipboardHasAddress = false;
$scope.clipboardHasContent = false;
if ((text.indexOf('bitcoincash:') === 0 || text[0] === 'C' || text[0] === 'H' || text[0] === 'p' || text[0] === 'q') && text.replace('bitcoincash:', '').length === 42) { // CashAddr
var parsed = bitcoinUriService.parse(text);
console.log('parsed', parsed);
if (parsed.isValid && parsed.publicAddress && parsed.coin === 'bch' && !parsed.testnet) { // CashAddr
$scope.clipboardHasAddress = true;
} else if ((text[0] === "1" || text[0] === "3" || text.substring(0, 3) === "bc1") && text.length >= 26 && text.length <= 35) { // Legacy Addresses
$scope.clipboardHasAddress = true;
@ -55,48 +61,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
});
});
var wallets;
var walletsBch;
var walletsBtc;
var walletToWalletFrom = false;
$scope.onWalletSelect = function(wallet) {
if (!$scope.walletToWalletFrom) {
$scope.walletToWalletFrom = wallet;
if (wallet.coin === 'bch') {
$scope.showWalletsBch = true;
} else if (wallet.coin === 'btc') {
$scope.showWalletsBtc = true;
}
$scope.walletSelectorTitleTo = gettextCatalog.getString('Send to');
} else {
$ionicLoading.show();
walletService.getAddress(wallet, true, function(err, addr) {
$ionicLoading.hide();
return $state.transitionTo('tabs.send.amount', {
displayAddress: $scope.walletToWalletFrom.coin === 'bch' ? bitcoinCashJsService.translateAddresses(addr).cashaddr : addr,
recipientType: 'wallet',
fromWalletId: $scope.walletToWalletFrom.id,
toAddress: addr,
coin: $scope.walletToWalletFrom.coin
});
});
}
};
$scope.showWalletSelector = function() {
$scope.walletToWalletFrom = false;
$scope.walletSelectorTitleFrom = gettextCatalog.getString('Send from');
$scope.showWallets = true;
};
$scope.findContact = function(search) {
if (incomingData.redir(search)) {
return;
}
if (!search || search.length < 1) {
$scope.list = originalList;
$timeout(function() {
@ -105,12 +70,16 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
return;
}
var result = lodash.filter(originalList, function(item) {
var val = item.name;
return lodash.startsWith(val.toLowerCase(), search.toLowerCase());
var params = sendFlowService.state.getClone();
params.data = search;
sendFlowService.start(params, function onError() {
var result = lodash.filter(originalList, function(item) {
var val = item.name;
return lodash.startsWith(val.toLowerCase(), search.toLowerCase());
});
$scope.list = result;
});
$scope.list = result;
};
var hasWallets = function() {
@ -133,7 +102,6 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
};
var updateHasFunds = function() {
$scope.hasFunds = false;
var index = 0;
lodash.each($scope.wallets, function(w) {
@ -179,10 +147,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
coin: v.coin,
displayCoin: (v.coin == 'bch'
? (config.bitcoinCashAlias || defaults.bitcoinCashAlias)
: (config.bitcoinAlias || defaults.bitcoinAlias)).toUpperCase(),
getAddress: function(cb) {
return cb(null, k);
},
: (config.bitcoinAlias || defaults.bitcoinAlias)).toUpperCase()
});
});
originalList = completeContacts;
@ -203,39 +168,37 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
};
$scope.searchBlurred = function() {
if ($scope.formData.search == null || $scope.formData.search.length == 0) {
if ($scope.formData.search == null || $scope.formData.search.length === 0) {
$scope.searchFocus = false;
}
};
$scope.goToAmount = function(item) {
$timeout(function() {
item.getAddress(function(err, addr) {
if (err || !addr) {
//Error is already formated
return popupService.showAlert(err);
}
$scope.sendToContact = function (item) {
$timeout(function () {
var toAddress = item.address;
if (item.recipientType && item.recipientType == 'contact') {
if (addr.indexOf('bch') == 0 || addr.indexOf('btc') == 0) {
addr = addr.substring(3);
}
if (item.recipientType && item.recipientType === 'contact') {
if (toAddress.indexOf('bch') === 0 || toAddress.indexOf('btc') === 0) {
toAddress = toAddress.substring(3);
}
}
$log.debug('Got toAddress:' + addr + ' | ' + item.name);
return $state.transitionTo('tabs.send.amount', {
recipientType: item.recipientType,
displayAddress: item.coin == 'bch' ? bitcoinCashJsService.translateAddresses(addr).cashaddr : addr,
toAddress: addr,
toName: item.name,
toEmail: item.email,
toColor: item.color,
coin: item.coin
});
});
$log.debug('Got toAddress:' + toAddress + ' | ' + item.name);
var stateParams = sendFlowService.state.getClone();
stateParams.toAddress = toAddress;
stateParams.coin = item.coin;
sendFlowService.start(stateParams);
});
};
$scope.startWalletToWalletTransfer = function() {
console.log('startWalletToWalletTransfer()');
var params = sendFlowService.state.getClone();
params.isWalletTransfer = true;
sendFlowService.start(params);
}
// This could probably be enhanced refactoring the routes abstract states
$scope.createWallet = function() {
$state.go('tabs.home').then(function() {
@ -250,6 +213,8 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
};
$scope.$on("$ionicView.beforeEnter", function(event, data) {
console.log(data);
console.log('tab-send onBeforeEnter sendflow ', sendFlowService.state);
$scope.isIOS = platformInfo.isIOS && platformInfo.isCordova;
$scope.showWalletsBch = $scope.showWalletsBtc = $scope.showWallets = false;
@ -264,5 +229,9 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
$scope.displayBalanceAsFiat = _config.wallet.settings.priceDisplay === 'fiat';
});
if (data.direction == "back") {
sendFlowService.state.clear();
}
});
});
});

View file

@ -16,7 +16,7 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct
isoCode: config.wallet.settings.alternativeIsoCode
};
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay === 'crypto' ? gettextCatalog.getString('Cryptocurrency') : gettextCatalog.getString('Fiat');
// TODO move this to a generic service
bitpayAccountService.getAccounts(function(err, data) {

View file

@ -1,11 +1,13 @@
'use strict';
angular.module('copayApp.controllers').controller('tabsController', function($rootScope, $log, $scope, $state, $stateParams, $timeout, platformInfo, incomingData, lodash, popupService, gettextCatalog, scannerService) {
angular.module('copayApp.controllers').controller('tabsController', function($rootScope, $log, $scope, $state, $stateParams, $timeout, platformInfo, incomingDataService, lodash, popupService, gettextCatalog, scannerService, sendFlowService) {
$scope.onScan = function(data) {
if (!incomingData.redir(data)) {
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Invalid data'));
}
incomingDataService.redir(data, function onError(err) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), err.message);
}
});
};
$scope.setScanFn = function(scanFn) {
@ -15,6 +17,10 @@ angular.module('copayApp.controllers').controller('tabsController', function($ro
};
};
$scope.startFreshSend = function() {
sendFlowService.start();
};
$scope.importInit = function() {
$scope.fromOnboarding = $stateParams.fromOnboarding;
$timeout(function() {
@ -23,7 +29,6 @@ angular.module('copayApp.controllers').controller('tabsController', function($ro
};
$scope.chooseScanner = function() {
var isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
if (!isWindowsPhoneApp) {
@ -33,10 +38,14 @@ angular.module('copayApp.controllers').controller('tabsController', function($ro
scannerService.useOldScanner(function(err, contents) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), err);
return;
popupService.showAlert(gettextCatalog.getString('Error'), err.message);
} else {
incomingDataService.redir(contents, function onError(err) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), err.message);
}
});
}
incomingData.redir(contents);
});
};

View file

@ -1,52 +1,65 @@
'use strict';
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, storageService, $ionicScrollDelegate, $window, bwcError, gettextCatalog, timeService, feeService, appConfigService, rateService) {
var HISTORY_SHOW_LIMIT = 10;
var currentTxHistoryPage = 0;
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, sendFlowService, storageService, $ionicScrollDelegate, $window, bwcError, gettextCatalog, timeService, feeService, appConfigService, rateService, walletHistoryService) {
// Desktop can display 13 rows of transactions, bump it up to a nice round 15.
var DISPLAY_PAGE_SIZE = 15;
var currentTxHistoryDisplayPage = 0;
var completeTxHistory = []
var listeners = [];
$scope.txps = [];
$scope.completeTxHistory = [];
$scope.openTxpModal = txpModalService.open;
// For gradual migration for doing it properly
$scope.vm = {
allowInfiniteScroll: false,
gettingCachedHistory: true,
gettingInitialHistory: true,
updatingTxHistory: false,
fetchedAllTxHistory: false,
//updateTxHistoryError: false
updateTxHistoryFailed: false
};
// Need flag for when to allow infinite scroll at bottom
// - ie not when loading initial data and there is no more cached data
$scope.amountIsCollapsible = false;
$scope.color = '#888888';
$scope.filteredTxHistory = [];
$scope.isCordova = platformInfo.isCordova;
$scope.isAndroid = platformInfo.isAndroid;
$scope.isIOS = platformInfo.isIOS;
$scope.isSearching = false;
$scope.openTxpModal = txpModalService.open;
$scope.requiresMultipleSignatures = false;
$scope.showBalanceButton = false;
$scope.status = null;
// Displaying 50 transactions when entering the screen takes a while, so only display a subset
// of everything we have, not the complete history.
$scope.txHistory = []; // This is what is displayed
$scope.txHistorySearchResults = [];
$scope.txps = [];
$scope.updatingStatus = false;
$scope.updateStatusError = null;
$scope.updatingTxHistoryProgress = 0;
$scope.wallet = null;
$scope.walletId = '';
$scope.walletNotRegistered = false;
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("wallet_details_open", [], [channel]);
window.BitAnalytics.LogEventHandlers.postEvent(log);
$scope.amountIsCollapsible = !$scope.isAndroid;
$scope.openExternalLink = function(url, target) {
externalLinkService.open(url, target);
};
var setPendingTxps = function(txps) {
/* Uncomment to test multiple outputs */
// var txp = {
// message: 'test multi-output',
// fee: 1000,
// createdOn: new Date() / 1000,
// outputs: [],
// wallet: $scope.wallet
// };
//
// function addOutput(n) {
// txp.outputs.push({
// amount: 600,
// toAddress: '2N8bhEwbKtMvR2jqMRcTCQqzHP6zXGToXcK',
// message: 'output #' + (Number(n) + 1)
// });
// };
// lodash.times(15, addOutput);
// txps.push(txp);
if (!txps) {
$scope.txps = [];
return;
@ -73,6 +86,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.updatingStatus = true;
$scope.updateStatusError = null;
$scope.walletNotRegistered = false;
$scope.vm.fetchedAllTxHistory = false;
walletService.getStatus($scope.wallet, {
force: !!force,
@ -156,68 +170,97 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
if (err) return;
$timeout(function() {
walletService.startScan($scope.wallet, function() {
$scope.updateAll();
$scope.updateAll(true, true);
$scope.$apply();
});
});
});
};
var updateTxHistory = function(cb) {
if (!cb) cb = function() {};
$scope.updateTxHistoryError = false;
$scope.updatingTxHistoryProgress = 0;
feeService.getFeeLevels($scope.wallet.coin, function(err, levels) {
walletService.getTxHistory($scope.wallet, {
feeLevels: levels
}, function(err, txHistory) {
$scope.updatingTxHistory = false;
if (err) {
$scope.txHistory = null;
$scope.updateTxHistoryError = true;
return;
}
applyCurrencyAliases(txHistory);
var config = configService.getSync();
var fiatCode = config.wallet.settings.alternativeIsoCode;
lodash.each(txHistory, function(t) {
var r = rateService.toFiat(t.amount, fiatCode, $scope.wallet.coin);
t.alternativeAmountStr = r.toFixed(2) + ' ' + fiatCode;
});
$scope.completeTxHistory = txHistory;
$scope.showHistory();
$timeout(function() {
$scope.$apply();
});
return cb();
});
});
};
function applyCurrencyAliases(txHistory) {
var defaults = configService.getDefaults();
var configCache = configService.getSync();
lodash.each(txHistory, function(t) {
t.amountUnitStr = $scope.wallet.coin == 'btc'
lodash.each(txHistory, function onTx(tx) {
tx.amountUnitStr = $scope.wallet.coin == 'btc'
? (configCache.bitcoinAlias || defaults.bitcoinAlias)
: (configCache.bitcoinCashAlias || defaults.bitcoinCashAlias);
t.amountUnitStr = t.amountUnitStr.toUpperCase();
tx.amountUnitStr = tx.amountUnitStr.toUpperCase();
});
}
$scope.showHistory = function() {
if ($scope.completeTxHistory) {
$scope.txHistory = $scope.completeTxHistory.slice(0, (currentTxHistoryPage + 1) * HISTORY_SHOW_LIMIT);
$scope.txHistoryShowMore = $scope.completeTxHistory.length > $scope.txHistory.length;
function formatTxHistoryForDisplay(txHistory) {
applyCurrencyAliases(txHistory);
var config = configService.getSync();
var fiatCode = config.wallet.settings.alternativeIsoCode;
lodash.each(txHistory, function(t) {
var r = rateService.toFiat(t.amount, fiatCode, $scope.wallet.coin);
t.alternativeAmountStr = r.toFixed(2) + ' ' + fiatCode;
});
}
function updateTxHistoryFromCachedData() {
$scope.vm.gettingCachedHistory = true;
walletHistoryService.getCachedTxHistory($scope.wallet.id, function onGetCachedTxHistory(err, txHistory){
$scope.vm.gettingCachedHistory = false;
if (err) {
// Don't display an error because we are also requesting the history.
$log.error('Error getting cached tx history.', err);
return;
}
if (!txHistory) {
$log.debug('No cached tx history.');
return;
}
formatTxHistoryForDisplay(txHistory);
completeTxHistory = txHistory;
showHistory(false);
$scope.$apply();
});
}
function fetchAndShowTxHistory(getLatest, flushCacheOnNew) {
$scope.vm.updatingTxHistory = true;
walletHistoryService.updateLocalTxHistoryByPage($scope.wallet, getLatest, flushCacheOnNew, function onUpdateLocalTxHistoryByPage(err, txHistory, fetchedAllTransactions) {
$scope.vm.gettingInitialHistory = false;
$scope.vm.updatingTxHistory = false;
$scope.$broadcast('scroll.infiniteScrollComplete');
if (err) {
console.error('pagination Failed to get history.', err);
$scope.vm.updateTxHistoryFailed = true;
return;
}
if (fetchedAllTransactions) {
$scope.vm.fetchedAllTxHistory = true;
}
formatTxHistoryForDisplay(txHistory);
completeTxHistory = txHistory;
showHistory(true);
$scope.$apply();
});
}
function showHistory(showAll) {
if (completeTxHistory) {
$scope.txHistory = showAll ? completeTxHistory : completeTxHistory.slice(0, (currentTxHistoryDisplayPage + 1) * DISPLAY_PAGE_SIZE);
$scope.vm.allowInfiniteScroll = !$scope.vm.fetchedAllTxHistory && !(completeTxHistory.length === $scope.txHistory.length && $scope.vm.gettingInitialHistory);
} else {
$scope.vm.allowInfiniteScroll = false;
}
};
}
$scope.getDate = function(txCreated) {
var date = new Date(txCreated * 1000);
@ -256,24 +299,35 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
return !tx.confirmations || tx.confirmations === 0;
};
// on-infinite="showMore()"
$scope.showMore = function() {
$timeout(function() {
currentTxHistoryPage++;
$scope.showHistory();
// Check if we have more than we are displaying
if (completeTxHistory.length > $scope.txHistory.length) {
currentTxHistoryDisplayPage++;
showHistory(false);
$scope.$broadcast('scroll.infiniteScrollComplete');
}, 100);
return;
}
if ($scope.vm.updatingTxHistory) {
return;
}
fetchAndShowTxHistory(false, false);
};
// on-refresh="onRefresh()"
$scope.onRefresh = function() {
$timeout(function() {
$scope.$broadcast('scroll.refreshComplete');
}, 300);
$scope.updateAll(true);
$scope.updateAll(true, false);
};
$scope.updateAll = function(force, cb)  {
updateStatus(force);
updateTxHistory(cb);
$scope.updateAll = function(forceStatusUpdate, flushTxCacheOnNew)  {
updateStatus(forceStatusUpdate);
//updateTxHistory(cb);
fetchAndShowTxHistory(true, flushTxCacheOnNew);
};
$scope.hideToggle = function() {
@ -283,97 +337,36 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
};
var prevPos;
$scope.txHistoryPaddingBottom = 0;
function getScrollPosition() {
var scrollPosition = $ionicScrollDelegate.getScrollPosition();
$timeout(function() {
getScrollPosition();
}, 200);
if (!scrollPosition) {
$window.requestAnimationFrame(function() {
getScrollPosition();
});
return;
}
var pos = scrollPosition.top;
if (pos > 0) {
$scope.txHistoryPaddingBottom = "200px";
}
if (pos === prevPos) {
$window.requestAnimationFrame(function() {
getScrollPosition();
});
return;
}
prevPos = pos;
refreshAmountSection(pos);
};
function refreshAmountSection(scrollPos) {
$scope.showBalanceButton = false;
if ($scope.status) {
$scope.showBalanceButton = ($scope.status.totalBalanceSat != $scope.status.spendableAmount);
}
if (!$scope.amountIsCollapsible) {
var t = ($scope.showBalanceButton ? 15 : 45);
$scope.amountScale = 'translateY(' + t + 'px)';
return;
}
scrollPos = scrollPos || 0;
var amountHeight = 210 - scrollPos;
if (amountHeight < 80) {
amountHeight = 80;
}
var contentMargin = amountHeight;
if (contentMargin > 210) {
contentMargin = 210;
}
var amountScale = (amountHeight / 210);
if (amountScale < 0.5) {
amountScale = 0.5;
}
if (amountScale > 1.1) {
amountScale = 1.1;
}
var s = amountScale;
// Make space for the balance button when it needs to display.
var TOP_NO_BALANCE_BUTTON = 115;
var TOP_BALANCE_BUTTON = 30;
var top = TOP_NO_BALANCE_BUTTON;
if ($scope.showBalanceButton) {
top = TOP_BALANCE_BUTTON;
}
var amountTop = ((amountScale - 0.7) / 0.7) * top;
if (amountTop < -10) {
amountTop = -10;
}
if (amountTop > top) {
amountTop = top;
}
var t = amountTop;
$scope.altAmountOpacity = (amountHeight - 100) / 80;
$window.requestAnimationFrame(function() {
$scope.amountHeight = amountHeight + 'px';
$scope.contentMargin = contentMargin + 'px';
$scope.amountScale = 'scale3d(' + s + ',' + s + ',' + s + ') translateY(' + t + 'px)';
$scope.$digest();
getScrollPosition();
});
$scope.scrollPosition = pos;
}
var scrollWatcherInitialized;
$scope.$on("$ionicView.enter", function(event, data) {
if ($scope.isCordova && $scope.isAndroid) setAndroidStatusBarColor();
if (scrollWatcherInitialized || !$scope.amountIsCollapsible) {
return;
}
scrollWatcherInitialized = true;
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
configService.whenAvailable(function (config) {
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
@ -387,7 +380,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
if (!$scope.wallet) return;
$scope.requiresMultipleSignatures = $scope.wallet.credentials.m > 1;
$scope.updatingTxHistory = true;
$scope.vm.gettingInitialHistory = true;
addressbookService.list(function(err, ab) {
if (err) $log.error(err);
@ -397,21 +390,25 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
listeners = [
$rootScope.$on('bwsEvent', function(e, walletId) {
if (walletId == $scope.wallet.id && e.type != 'NewAddress')
$scope.updateAll();
$scope.updateAll(false, false);
}),
$rootScope.$on('Local/TxAction', function(e, walletId) {
if (walletId == $scope.wallet.id)
$scope.updateAll();
$scope.updateAll(false, false);
}),
];
});
var refreshInterval;
$scope.$on("$ionicView.afterEnter", function(event, data) {
$scope.updateAll();
refreshAmountSection();
$scope.$on("$ionicView.afterEnter", function onAfterEnter(event, data) {
updateTxHistoryFromCachedData();
$scope.updateAll(true, true);
// refreshAmountSection();
refreshInterval = $interval($scope.onRefresh, 10 * 1000);
$timeout(function() {
getScrollPosition();
}, 1000);
});
$scope.$on("$ionicView.afterLeave", function(event, data) {
@ -469,4 +466,30 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
$scope.goToSend = function() {
sendFlowService.start({
fromWalletId: $scope.wallet.id
});
};
$scope.goToReceive = function() {
$state.go('tabs.home', {
walletId: $scope.wallet.id
}).then(function () {
$ionicHistory.clearHistory();
$state.go('tabs.receive', {
walletId: $scope.wallet.id
});
});
};
$scope.goToBuy = function() {
$state.go('tabs.home', {
walletId: $scope.wallet.id
}).then(function () {
$ionicHistory.clearHistory();
$state.go('tabs.buyandsell');
});
};
});

View file

@ -0,0 +1,204 @@
'use strict';
(function () {
angular
.module('copayApp.controllers')
.controller('walletSelectorController', walletSelectorController);
function walletSelectorController ($scope, $state, sendFlowService, configService, gettextCatalog, ongoingProcess, profileService, walletService, txFormatService) {
var fromWalletId = '';
var priceDisplayAsFiat = false;
var unitDecimals = 0;
var unitsFromSatoshis = 0;
$scope.$on("$ionicView.beforeEnter", onBeforeEnter);
$scope.$on("$ionicView.enter", onEnter);
function onBeforeEnter(event, data) {
if (data.direction == "back") {
sendFlowService.state.pop();
}
$scope.params = sendFlowService.state.getClone();
console.log('walletSelector onBeforeEnter after back sendflow', $scope.params);
var config = configService.getSync().wallet.settings;
priceDisplayAsFiat = config.priceDisplay === 'fiat';
unitDecimals = config.unitDecimals;
unitsFromSatoshis = 1 / config.unitToSatoshi;
if ($scope.params.isWalletTransfer) {
$scope.sendFlowTitle = gettextCatalog.getString('Transfer between wallets');
} else if (!$scope.params.thirdParty) {
$scope.sendFlowTitle = gettextCatalog.getString('Send');
}
$scope.coin = false; // Wallets to show (for destination screen or contacts)
$scope.type = $scope.params['fromWalletId'] ? 'destination' : 'origin'; // origin || destination
fromWalletId = $scope.params['fromWalletId'];
if ($scope.type === 'destination' && $scope.params.toAddress) {
$state.transitionTo(getNextStep($scope.params));
}
if ($scope.params.coin) {
$scope.coin = $scope.params.coin; // Contacts have a coin embedded
}
if ($scope.params.amount) { // There is an amount, so presume that it is a payment request
$scope.sendFlowTitle = gettextCatalog.getString('Payment Request');
$scope.specificAmount = $scope.specificAlternativeAmount = '';
$scope.isPaymentRequest = true;
}
if ($scope.params.thirdParty) {
$scope.thirdParty = $scope.params.thirdParty;
}
};
function onEnter (event, data) {
configService.whenAvailable(function(config) {
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
});
if ($scope.thirdParty) {
// Third party services specific logic
handleThirdPartyIfShapeshift();
}
prepareWalletLists();
formatRequestedAmount();
};
function formatRequestedAmount() {
if ($scope.params.amount) {
var cryptoAmount = (unitsFromSatoshis * $scope.params.amount).toFixed(unitDecimals);
var cryptoCoin = $scope.coin.toUpperCase();
txFormatService.formatAlternativeStr($scope.coin, $scope.params.amount, function onFormatAlternativeStr(formatted){
if (formatted) {
var fiatParts = formatted.split(' ');
var fiatAmount = fiatParts[0];
var fiatCurrrency = fiatParts.length > 1 ? fiatParts[1] : '';
if (priceDisplayAsFiat) {
$scope.requestAmount = fiatAmount;
$scope.requestCurrency = fiatCurrrency;
$scope.requestAmountSecondary = cryptoAmount;
$scope.requestCurrencySecondary = cryptoCoin;
} else {
$scope.requestAmount = cryptoAmount;
$scope.requestCurrency = cryptoCoin;
$scope.requestAmountSecondary = fiatAmount;
$scope.requestCurrencySecondary = fiatCurrrency;
}
$scope.$apply();
}
});
}
}
function handleThirdPartyIfShapeshift() {
console.log($scope.thirdParty, $scope.coin);
if ($scope.thirdParty.id === 'shapeshift' && $scope.type === 'destination') { // Shapeshift wants to know the
$scope.coin = profileService.getWallet(fromWalletId).coin;
if ($scope.coin === 'bch') {
$scope.coin = 'btc';
} else {
$scope.coin = 'bch';
}
}
}
function prepareWalletLists() {
var walletsAll = [];
var walletsSufficientFunds = [];
$scope.walletsInsufficientFunds = []; // For origin screen
if ($scope.type === 'origin') {
$scope.headerTitle = gettextCatalog.getString('Choose a wallet to send from');
if ($scope.params.amount || $scope.coin) {
walletsAll = profileService.getWallets({coin: $scope.coin});
ongoingProcess.set('scanning', true);
walletsAll.forEach(function forWallet(wallet) {
if (!wallet.status && !wallet.cachedStatus) {
walletService.getStatus(wallet, {}, function(err, status) {
wallet.status = status;
if (status.availableBalanceSat > ($scope.params.amount ? $scope.params.amount : 0)) {
walletsSufficientFunds.push(wallet);
} else {
$scope.walletsInsufficientFunds.push(wallet);
}
if ($scope.coin === 'btc') { // As this is a promise
$scope.walletsBtc = walletsSufficientFunds;
} else {
$scope.walletsBch = walletsSufficientFunds;
}
ongoingProcess.set('scanning', false);
});
} else {
var walletStatus = null;
if (wallet.status && wallet.status.isValid) {
walletStatus = wallet.status;
} else if (wallet.cachedStatus && wallet.status.isValid) {
walletStatus = wallet.cachedStatus;
}
if (walletStatus && walletStatus.availableBalanceSat > ($scope.params.amount ? $scope.params.amount : 0)) {
walletsSufficientFunds.push(wallet);
} else {
$scope.walletsInsufficientFunds.push(wallet);
}
ongoingProcess.set('scanning', false);
}
});
if ($scope.coin === 'btc') {
$scope.walletsBtc = walletsSufficientFunds;
} else {
$scope.walletsBch = walletsSufficientFunds;
}
} else {
$scope.walletsBch = profileService.getWallets({coin: 'bch', hasFunds: true});
$scope.walletsBtc = profileService.getWallets({coin: 'btc', hasFunds: true});
$scope.walletsInsufficientFunds = profileService.getWallets({coin: $scope.coin, hasNoFunds: true});
}
} else if ($scope.type === 'destination') {
if (!$scope.coin) { // Allow for the coin to be set by a third party
$scope.fromWallet = profileService.getWallet(fromWalletId);
$scope.coin = $scope.fromWallet.coin; // Only show wallets with the select origin wallet coin
}
$scope.headerTitle = gettextCatalog.getString('Choose a wallet to send to');
if ($scope.coin === 'btc') { // if no specific coin is set or coin is set btc
$scope.walletsBtc = profileService.getWallets({coin: $scope.coin});
} else {
$scope.walletsBch = profileService.getWallets({coin: $scope.coin});
}
}
}
$scope.useWallet = function(wallet) {
var params = sendFlowService.state.getClone();
if ($scope.type === 'origin') { // we're on the origin screen, set wallet to send from
params.fromWalletId = wallet.id;
} else { // we're on the destination screen, set wallet to send to
params.toWalletId = wallet.id;
}
sendFlowService.goNext(params);
};
$scope.goBack = function() {
sendFlowService.router.goBack();
}
}
})();

View file

@ -0,0 +1,198 @@
'use strict';
(function(){
/**
* @desc amount directive that can be used to display formatted financial values
* size-equal attribute is optional, defaults to false.
* @example fee = {
* value: 12.49382901,
* currency: 'BCH'
* }
* @example <formatted-amount value="fee.value" currency="fee.currency"></formatted-amount>
* @example <formatted-amount value="fee.value" currency="fee.currency" size-equal="true"></formatted-amount>
*/
angular
.module('bitcoincom.directives')
.directive('formattedAmount', function() {
return {
restrict: 'E',
scope: {
value: '@',
currency: '@',
sizeEqual: '@'
},
templateUrl: 'views/includes/formatted-amount.html',
controller: formattedAmountController
}
});
function formattedAmountController($scope, uxLanguage) {
$scope.vm = {};
var vm = $scope.vm;
vm.currency = '';
vm.value = '';
$scope.canShow = false
$scope.displaySizeEqual = !!$scope.sizeEqual;
var decimalPlaces = {
'0': ['BIF', 'CLP', 'DJF', 'GNF', 'ILS', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'],
'3': ['BHD', 'IQD', 'JOD', 'KWD', 'OMR', 'TND'],
'8': ['BCH', 'BTC']
};
$scope.$watch('value', function onFormattedAmountWatch() {
formatNumbers();
});
function buildAmount(start, middle, end) {
$scope.start = start;
$scope.middle = middle;
$scope.end = end;
};
/**
* On Android 4.4, toLocaleString() only returns 3 fractional digits when 8 is specified.
*/
function ensureEnoughFractionDigits(localizedString, number, desiredFractionDigits) {
if (desiredFractionDigits === 0) {
// Assume it is OK
return localizedString;
}
var fractionalRe = /^-*(\d*\D)(\d+)$/;
var match = fractionalRe.exec(localizedString);
if (!match || match.length !== 3) {
// Don't know what's happening, just return what we have
return localizedString;
}
var decimals = match[2];
var decimalCount = decimals.length;
if (decimalCount >= desiredFractionDigits) {
// Everything is OK.
return localizedString;
}
if (typeof number !== 'number') {
number = parseFloat(number);
}
var fixed = number.toFixed(desiredFractionDigits);
var fixedMatch = fractionalRe.exec(fixed);
if (!fixedMatch || fixedMatch.length !== 3) {
// Don't know what's happening, just return what we have
return localizedString;
}
// Keeps locale decimal separator.
var enough = match[1] + fixedMatch[2];
return enough;
}
function formatNumbers() {
// Might get "< 0.01 USD" being passed in.
// During watch, may be changed from having a separate currency value,
// to both being in value. Don't want to use previous currency value.
// Try to extract currency from value..
if (!$scope.currency || $scope.currency.length === 0) {
var currencySplit = $scope.value.split(" ");
if (currencySplit.length >= 2) {
vm.currency = currencySplit[currencySplit.length - 1];
}
} else {
vm.currency = $scope.currency;
}
// Redo this when we have proper formatting for low fees
if ($scope.value.indexOf("<") === 0) {
buildAmount($scope.value, '', '');
vm.currency = '';
$scope.canShow = true;
return;
}
// Remove thousands separators for parseFloat()
$scope.value = $scope.value.replace(',', '');
var parsed = parseFloat($scope.value);
var valueFormatted = '';
var valueProcessing = '';
switch (getDecimalPlaces(vm.currency)) {
case '0':
if (isNaN(parsed)) {
buildAmount('-', '', '');
} else {
valueFormatted = localizeNumbers(Math.round(parsed), 0);
buildAmount(valueFormatted, '', '');
}
break;
case '3':
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '---', '', '');
} else {
valueProcessing = parsed.toFixed(3);
valueFormatted = localizeNumbers(valueProcessing, 3);
buildAmount(valueFormatted, '', '');
}
break;
case '8':
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '---', '', '');
} else if (parsed === 0) {
buildAmount('0', '', '');
} else {
valueFormatted = parsed.toFixed(8);
valueFormatted = localizeNumbers(valueFormatted, 8);
var start = valueFormatted.slice(0, -5);
var middle = valueFormatted.slice(-5, -2);
var end = valueFormatted.substr(valueFormatted.length - 2);
buildAmount(start, middle, end);
}
break;
default: // 2
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '--', '', '');
} else {
valueProcessing = parseFloat(parsed.toFixed(2));
valueFormatted = localizeNumbers(valueProcessing, 2);
buildAmount(valueFormatted, '', '');
}
break;
}
$scope.canShow = true;
};
function getDecimalPlaces(currency) {
if (decimalPlaces['0'].indexOf(currency.toUpperCase()) > -1) return '0';
if (decimalPlaces['3'].indexOf(currency.toUpperCase()) > -1) return '3';
if (decimalPlaces['8'].indexOf(currency.toUpperCase()) > -1) return '8';
return '2';
};
function getDecimalSeparator() {
var testNum = 1.5;
var testString = testNum.toLocaleString(uxLanguage.getCurrentLanguage());
// Some environments let you set decimal separators that are more than one character
var separator = /^1(.+)5$/.exec(testString)[1]
return separator;
};
function localizeNumbers(x, minimumFractionDigits) {
var parsed = parseFloat(x);
var opts = {
minimumFractionDigits: minimumFractionDigits,
useGrouping: true
};
var lang = uxLanguage.getCurrentLanguage();
var localized = parsed.toLocaleString(lang, opts);
var corrected = ensureEnoughFractionDigits(localized, x, minimumFractionDigits);
return corrected;
};
}
})();

View file

@ -1,23 +1,28 @@
'use strict';
angular.module('copayApp.directives')
.directive('incomingDataMenu', function($timeout, $rootScope, $state, externalLinkService) {
.directive('incomingDataMenu', function($timeout, $rootScope, $state, externalLinkService, sendFlowService, bitcoinCashJsService) {
return {
restrict: 'E',
templateUrl: 'views/includes/incomingDataMenu.html',
link: function(scope, element, attrs) {
$rootScope.$on('incomingDataMenu.showMenu', function(event, data) {
$timeout(function() {
scope.data = data.data;
scope.type = data.type;
scope.showMenu = true;
scope.https = false;
scope.data = data;
if (scope.type === 'url') {
if (scope.data.indexOf('https://') === 0) {
scope.https = true;
}
if (scope.data.parsed.privateKey) {
scope.type = "privateKey";
} else if (scope.data.parsed.url) {
scope.type = "url";
} else if (scope.data.parsed.publicAddress) {
scope.type = "bitcoinAddress";
var prefix = scope.data.parsed.isTestnet ? 'bchtest:' : 'bitcoincash:';
scope.data.toAddress = (prefix + scope.data.parsed.publicAddress.cashAddr) || scope.data.parsed.publicAddress.legacy || scope.data.parsed.publicAddress.bitpay;
} else {
scope.type = "text";
}
scope.showMenu = true;
});
});
scope.hide = function() {
@ -28,18 +33,9 @@ angular.module('copayApp.directives')
externalLinkService.open(url);
};
scope.sendPaymentToAddress = function(bitcoinAddress) {
var noPrefixInAddress = 0;
if (bitcoinAddress.toLowerCase().indexOf('bitcoin') < 0) {
noPrefixInAddress = 1;
}
scope.showMenu = false;
$state.go('tabs.send').then(function() {
$timeout(function() {
$state.transitionTo('tabs.send.amount', {
toAddress: bitcoinAddress,
noPrefix: noPrefixInAddress
});
}, 50);
sendFlowService.start({
data: bitcoinAddress
});
};
scope.addToAddressBook = function(bitcoinAddress) {

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.directives').directive('shapeshiftCoinTrader', function($interval, shapeshiftApiService, profileService, incomingData, ongoingProcess) {
angular.module('copayApp.directives').directive('shapeshiftCoinTrader', function($interval, shapeshiftApiService, profileService, incomingDataService, ongoingProcess) {
return {
restrict: 'E',
transclude: true,
@ -111,7 +111,8 @@ angular.module('copayApp.directives').directive('shapeshiftCoinTrader', function
orderId: $scope.depositInfo.orderId
};
if (incomingData.redir(sendAddress, shapeshiftData)) {
// How to handle this
if (incomingDataService.redir(sendAddress, 'shapeshift', shapeshiftData)) {
ongoingProcess.set('connectingShapeshift', false);
return;
}

View file

@ -116,7 +116,8 @@ angular.module('copayApp.directives')
function getTransformStyle(translatePct) {
return {
'transform': 'translateX(' + translatePct + '%)'
'transform': 'translateX(' + translatePct + '%)',
'-webkit-transform': 'translateX(' + translatePct + '%)'
};
}

View file

@ -9,12 +9,12 @@ angular.module('copayApp.directives')
scope: {
isShown: '=slideSuccessShow',
onConfirm: '&slideSuccessOnConfirm',
hideOnConfirm: '=slideSuccessHideOnConfirm'
hideOnConfirm: '=slideSuccessHideOnConfirm',
onShare: '=slideSuccessOnShare',
},
link: function(scope, element, attrs) {
scope.isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
scope.isCordova = platformInfo.isCordova;
scope.hasShareFunction = typeof scope.onShare === 'function';
var elm = element[0];
elm.style.display = 'none';
scope.$watch('isShown', function() {
@ -32,6 +32,9 @@ angular.module('copayApp.directives')
elm.style.display = 'none';
}
};
scope.onShareButtonClick = function() {
scope.onShare();
}
}
};
});

View file

@ -0,0 +1,131 @@
'use strict';
(function(){
angular
.module('bitcoincom.directives')
.directive('walletBalance', function() {
return {
restrict: 'E',
scope: {
displayAsFiat: '@',
totalBalanceSat: '@',
// The Wallet object is sometimes not stringify()-able, so not interpolatable,
// so can't be passed to a directive.
walletCoin: '@',
walletStatus: '@',
walletCachedBalance: '@',
walletCachedBalanceUpdatedOn: '@',
walletCachedStatus: '@'
},
templateUrl: 'views/includes/wallet-balance.html',
controller: walletBalanceController
}
});
function walletBalanceController($log, $scope, txFormatService) {
var cryptoBalanceHasBeenDisplayed = false;
formatBalance();
$scope.$watchGroup(['displayAsFiat', 'totalBalanceSat'], function onWalletBalanceWatch() {
formatBalance();
});
function displayCryptoBalance(walletStatus, walletCachedBalance, walletCachedBalanceUpdatedOn, walletCachedStatus) {
if (walletStatus && walletStatus.isValid && walletStatus.totalBalanceStr) {
setDisplay(walletStatus.totalBalanceStr, '');
cryptoBalanceHasBeenDisplayed = true;
return;
}
if (walletCachedBalance) {
setDisplay(walletCachedBalance, walletCachedBalanceUpdatedOn);
return;
}
if (walletCachedStatus && walletCachedStatus.isValid && walletCachedStatus.totalBalanceStr) {
setDisplay(walletCachedStatus.totalBalanceStr, '');
return;
}
setDisplay('', '');
}
function displayFiatBalance(walletStatus, walletCachedStatus, walletCoin) {
var displayAmount = '';
if (walletStatus && walletStatus.isValid && walletStatus.alternativeBalanceAvailable) {
displayAmount = walletStatus.totalBalanceAlternative + ' ' + walletStatus.alternativeIsoCode;
setDisplay(displayAmount, '');
return;
}
if (walletCachedStatus && walletCachedStatus.isValid && walletCachedStatus.alternativeBalanceAvailable) {
displayAmount = walletCachedStatus.totalBalanceAlternative + ' ' + walletCachedStatus.alternativeIsoCode;
setDisplay(displayAmount, '');
return;
}
getFiatBalance(walletStatus, walletCachedStatus, walletCoin);
}
function formatBalance() {
var displayAsFiat = $scope.displayAsFiat === 'true';
var walletStatusObj = null;
var walletCachedBalance = null;
var walletCachedBalanceUpdatedOn = null;
var walletCachedStatusObj = null;
try {
walletStatusObj = JSON.parse($scope.walletStatus);
} catch (e) {
$log.warn('Failed to parse walletStatus.', e);
}
try {
walletCachedStatusObj = JSON.parse($scope.walletCachedStatus);
} catch (e) {
$log.warn('Failed to parse walletCachedStatus.', e);
}
if (!displayAsFiat || displayAsFiat && !cryptoBalanceHasBeenDisplayed) {
displayCryptoBalance(walletStatusObj, walletCachedBalance, walletCachedBalanceUpdatedOn, walletCachedStatusObj);
}
if (displayAsFiat) {
displayFiatBalance(walletStatusObj, walletCachedStatusObj, $scope.walletCoin);
}
}
function getFiatBalance(walletStatus, walletCachedStatus, walletCoin) {
var totalBalanceSat = null;
if (walletStatus && walletStatus.isValid) {
totalBalanceSat = walletStatus.totalBalanceSat
} else if (walletCachedStatus && walletCachedStatus.isValid) {
totalBalanceSat = walletCachedStatus.totalBalanceSat
}
// 0 is valid
if (totalBalanceSat === null) {
$log.warn('Abandoning call to get fiat balance, because no valid wallet status (cached or otherwise).');
return;
}
txFormatService.formatAlternativeStr(walletCoin, totalBalanceSat, function onFormatAlernativeStr(formatted) {
if (formatted) {
setDisplay(formatted, '');
} else {
$log.error('Failed to format fiat balance of wallet.');
}
});
}
function setDisplay(amount, cachedBalanceUpdatedOn) {
$scope.displayAmount = amount;
$scope.cachedBalanceUpdatedOn = cachedBalanceUpdatedOn;
}
}
})();

View file

@ -236,7 +236,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.receive', {
url: '/receive',
url: '/receive/:walletId',
views: {
'tab-receive': {
controller: 'tabReceiveController',
@ -287,16 +287,44 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
*/
.state('tabs.send.amount', {
url: '/amount/:recipientType/:toAddress/:toName/:toEmail/:toColor/:coin/:fixedUnit/:fromWalletId/:minShapeshiftAmount/:maxShapeshiftAmount/:shapeshiftOrderId/:displayAddress/:noPrefix',
url: '/amount',
views: {
'tab-send@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
}
})
.state('tabs.send.wallet-to-wallet', {
url: '/wallet-to-wallet',
views: {
'tab-send@tabs': {
controller: 'walletSelectorController',
templateUrl: 'views/walletSelector.html'
}
}
})
.state('tabs.send.origin', {
url: '/origin',
views: {
'tab-send@tabs': {
controller: 'walletSelectorController',
templateUrl: 'views/walletSelector.html',
}
}
})
.state('tabs.send.destination', {
url: '/destination',
views: {
'tab-send@tabs': {
controller: 'walletSelectorController',
templateUrl: 'views/walletSelector.html',
}
}
})
.state('tabs.send.confirm', {
url: '/confirm/:recipientType/:toAddress/:toName/:toAmount/:toEmail/:toColor/:description/:coin/:useSendMax/:fromWalletId/:displayAddress/:requiredFeeRate',
url: '/confirm',
views: {
'tab-send@tabs': {
controller: 'confirmController',
@ -316,6 +344,19 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
}
})
.state('tabs.send.review', {
url: '/review/:thirdParty/:amount/:fromWalletId/:sendMax/:toAddress/:toWalletId',
views: {
'tab-send@tabs': {
controller: 'reviewController',
controllerAs: 'vm',
templateUrl: 'views/review.html'
}
},
params: {
paypro: null
}
})
/*
*
@ -695,16 +736,17 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
})
.state('tabs.paymentRequest.amount', {
url: '/amount/:coin',
url: '/amount/:toWalletId',
views: {
'tab-receive@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
}
})
.state('tabs.paymentRequest.confirm', {
url: '/confirm/:amount/:currency/:coin',
url: '/confirm/:amount/:toWalletId',
views: {
'tab-receive@tabs': {
controller: 'customAmountController',
@ -845,6 +887,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
views: {
'tab-home@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
}
@ -910,6 +953,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
views: {
'tab-home@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
}
@ -968,7 +1012,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
/* Shapeshift */
.state('tabs.shapeshift', {
url: '/shapeshift',
url: '/shapeshift/:fromWalletId/:toWalletId',
views: {
'tab-home@tabs': {
controller: 'shapeshiftController',
@ -1029,6 +1073,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
views: {
'tab-home@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
},
@ -1081,6 +1126,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
views: {
'tab-home@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
},
@ -1137,6 +1183,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
views: {
'tab-home@tabs': {
controller: 'amountController',
controllerAs: 'vm',
templateUrl: 'views/amount.html'
}
}
@ -1160,7 +1207,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
});
})
.run(function($rootScope, $state, $location, $log, $timeout, startupService, ionicToast, fingerprintService, $ionicHistory, $ionicPlatform, $window, appConfigService, lodash, platformInfo, profileService, uxLanguage, gettextCatalog, openURLService, storageService, scannerService, configService, emailService, /* plugins START HERE => */ buydotbitcoindotcomService, glideraService, amazonService, bitpayCardService, applicationService, mercadoLibreService, rateService) {
.run(function($rootScope, $state, $location, $log, $timeout, startupService, ionicToast, fingerprintService, $ionicHistory, $ionicPlatform, $window, appConfigService, lodash, platformInfo, profileService, uxLanguage, gettextCatalog, openURLService, storageService, scannerService, configService, emailService, /* plugins START HERE => */ buydotbitcoindotcomService, pushNotificationsService, glideraService, amazonService, bitpayCardService, applicationService, mercadoLibreService, rateService) {
$ionicPlatform.ready(function() {
@ -1184,9 +1231,14 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
});
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
configService.whenAvailable(function(config) {
pushNotificationsService.init();
});
//firebaseEventsService.init();
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
// Send a log to test
@ -1225,6 +1277,13 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
});
window.BitAnalytics.ActionHandlers.trackAction(actionTabOpen);
var actionShapeShiftStart = new window.BitAnalytics.ActionFactory.createAction('click', {
name: 'shapeshift_start_click',
class: 'track_shapeshift_start_click',
channels: [channel]
});
window.BitAnalytics.ActionHandlers.trackAction(actionShapeShiftStart);
// Init language
uxLanguage.init(function (lang) {
@ -1264,7 +1323,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
if (screen.width < 768 && platformInfo.isCordova)
screen.lockOrientation('portrait');
if (ionic.Platform.isAndroid() && StatusBar) {
if (ionic.Platform.isAndroid() && platformInfo.isCordova && StatusBar) {
StatusBar.backgroundColorByHexString('#000000');
}

View file

@ -0,0 +1,416 @@
'use strict';
// https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki
// https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki
(function(){
angular
.module('bitcoincom.services')
.factory('bitcoinUriService', bitcoinUriService);
function bitcoinUriService(bitcoinCashJsService, bwcService, $log) {
var bch = bitcoinCashJsService.getBitcoinCashJs();
var bitcore = bwcService.getBitcore();
var service = {
parse: parse
};
return service;
function bitpayAddrOnMainnet(address) {
var Address = bch.Address;
var BitpayFormat = Address.BitpayFormat;
var mainnet = bch.Networks.mainnet;
var result = null;
if (address[0] == 'C') {
try {
result = Address.fromString(address, mainnet, 'pubkeyhash', BitpayFormat);
} catch (e) {};
} else if (address[0] == 'H') {
try {
result = Address.fromString(address, mainnet, 'scripthash', BitpayFormat);
} catch (e) {};
}
return result;
}
function cashAddrOnMainnet(address) {
var Address = bch.Address;
var CashAddrFormat = Address.CashAddrFormat;
var mainnet = bch.Networks.mainnet;
var prefixed = 'bitcoincash:' + address;
var result = null;
if (address[0] == 'q') {
try {
result = Address.fromString(prefixed, mainnet, 'pubkeyhash', CashAddrFormat);
} catch (e) {};
} else if (address[0] == 'p') {
try {
result = Address.fromString(prefixed, mainnet, 'scripthash', CashAddrFormat);
} catch (e) {};
}
return result;
}
function cashAddrOnTestnet(address) {
var Address = bch.Address;
var CashAddrFormat = Address.CashAddrFormat;
var testnet = bch.Networks.testnet;
var prefixed = 'bchtest:' + address;
var result = null;
if (address[0] == 'q') {
try {
result = Address.fromString(prefixed, testnet, 'pubkeyhash', CashAddrFormat);
} catch (e) {};
} else if (address[0] == 'p') {
try {
result = Address.fromString(prefixed, testnet, 'scripthash', CashAddrFormat);
} catch (e) {};
}
return result;
}
function infoFromWalletImportText(data) {
var split = data.split('|');
// Copay seems to use extra parameter for coin.
if (split.length < 5 || split.length > 6) {
return null;
}
var type = parseInt(split[0], 10);
if (isNaN(type)) {
return null;
}
var data = split[1];
var network = split[2];
if (!(network === 'livenet' || network === 'testnet')) {
return null;
}
var isTestnet = network === 'testnet';
var derivationPath = split[3];
if (!/^m\/\d+'\/\d+'\/\d+'$/.test(derivationPath)) {
return null;
}
var hasPassphraseText = split[4];
if (!(hasPassphraseText === 'true' || hasPassphraseText === 'false')) {
return null;
}
var hasPassphrase = hasPassphraseText === 'true';
var coin; // Intentionally undefined as may not be present
if (split.length > 5) {
var coinText = split[5];
if (!(coinText === 'bch' || coinText === 'btc')) {
return null;
}
coin = coinText;
}
return {
type: type,
data: data,
isTestnet: isTestnet,
derivationPath: derivationPath,
hasPassphrase: hasPassphrase,
coin: coin
};
}
/*
For parsing:
BIP21
BIP72
returns:
{
amount: '',
amountInSatoshis: 0,
bareUrl: '',
coin: '',
copayInvitation: '',
import: { // testnet info in root, coin info in root if available
data: '',
derivationPath: '',
hasPassphrase: false,
type: 1,
},
isValid: false,
label: '',
message: '',
other: {
somethingIDontUnderstand: 'Its value'
},
privateKey: {
encrypted: '',
wif: ''
}'',
publicAddress: {
bitpay: '',
cashAddr: '',
legacy: '',
},
req: {
"req-param0": '',
"req-param1": ''
},
testnet: false,
url: '' // For BIP70
}
Only fields that are present in the data are defined in the returned object. Both privateKey and publicAddress only have 1 field defined, if they exist at all.
The exception to this is the coin property, which is determined from other data, such as the prefix or address type.
*/
function parse(data) {
var parsed = {
isValid: false
};
if (typeof data !== 'string') {
return parsed;
}
// Identify prefix
var trimmed = data.trim();
var colonSplit = /^([\w-]*):?(.*)$/.exec(trimmed);
if (!colonSplit) {
return parsed;
}
var addressAndParams = '';
var preColonLower = colonSplit[1].toLowerCase();
if (preColonLower === 'bitcoin') {
parsed.coin = 'btc';
addressAndParams = colonSplit[2].trim();
console.log('Is btc');
} else if (/^(?:bitcoincash)|(?:bitcoin-cash)$/.test(preColonLower)) {
parsed.coin = 'bch';
parsed.test = false;
addressAndParams = colonSplit[2].trim();
console.log('Is bch');
} else if (/^(?:bchtest)$/.test(preColonLower)) {
parsed.coin = 'bch';
parsed.isTestnet = true;
addressAndParams = colonSplit[2].trim();
console.log('Is bch');
} else if (colonSplit[2] === '') {
// No colon and no coin specifier.
addressAndParams = colonSplit[1].trim();
console.log('No prefix.');
} else if (/^https?$/.test(colonSplit[1])) { // Plain URL
addressAndParams = trimmed;
} else if (colonSplit[2].indexOf('|') == 0) { // Import
addressAndParams = trimmed
} else {
// Something we don't recognise
return parsed;
}
// Remove erroneous leading slashes
//var leadingSlashes = /^\/*([^\/]+(?:.*))$/.exec(addressAndParams);
var leadingSlashes = /^\/*(.*)$/.exec(addressAndParams);
if (!leadingSlashes) {
return parsed;
}
addressAndParams = leadingSlashes[1];
var questionMarkSplit = /^([^\?]*)\??([^\?]*)$/.exec(addressAndParams);
if (!questionMarkSplit) {
return parsed;
}
var address = questionMarkSplit[1];
var params = questionMarkSplit[2];
if (params.length > 0) {
var paramsSplit = params.split('&');
var others;
var req;
var paramCount = paramsSplit.length;
for(var i = 0; i < paramCount; i++) {
var param = paramsSplit[i];
var valueSplit = param.split('=');
if (valueSplit.length !== 2) {
return parsed;
}
var key = valueSplit[0];
var value = valueSplit[1];
var decodedValue = decodeURIComponent(value);
switch(key) {
case 'amount':
var amount = parseFloat(decodedValue);
if (amount) { // Checking for NaN, or no numbers at all etc. & convert to satoshi
parsed.amount = decodedValue; // Need to check if a currency is precised
parsed.amountInSatoshis = amount * 100000000
} else {
return parsed;
}
break;
case 'label':
parsed.label = decodedValue;
break;
case 'message':
parsed.message = decodedValue;
break;
case 'r':
// Could use a more comprehesive regex to test URL validity, but then how would we know
// which part of the validation it failed?
if (decodedValue.startsWith('https://')) {
parsed.url = decodedValue;
} else {
return parsed;
}
break;
default:
if (key.startsWith('req-')) {
req = req || {};
req[key] = decodedValue;
} else {
others = others || {};
others[key] = decodedValue;
}
}
};
}
parsed.others = others;
parsed.req = req;
if (address) {
var addressLowerCase = address.toLowerCase();
var copayInvitationRe = /^[0-9A-HJ-NP-Za-km-z]{70,80}$/;
//var legacyRe = /^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/;
//var legacyTestnetRe = /^[mn][a-km-zA-HJ-NP-Z1-9]{25,34}$/;
var privateKeyEncryptedRe = /^6P[1-9A-HJ-NP-Za-km-z]{56}$/;
var privateKeyForUncompressedPublicKeyRe = /^5[1-9A-HJ-NP-Za-km-z]{50}$/;
var privateKeyForUncompressedPublicKeyTestnetRe = /^9[1-9A-HJ-NP-Za-km-z]{50}$/;
var privateKeyForCompressedPublicKeyRe = /^[KL][1-9A-HJ-NP-Za-km-z]{51}$/;
var privateKeyForCompressedPublicKeyTestnetRe = /^[c][1-9A-HJ-NP-Za-km-z]{51}$/;
var urlRe = /^https?:\/\/.+/;
var bitpayAddrMainnet = bitpayAddrOnMainnet(address);
var cashAddrTestnet = cashAddrOnTestnet(addressLowerCase);
var cashAddrMainnet = cashAddrOnMainnet(addressLowerCase);
var importInfo = infoFromWalletImportText(address);
var privateKey = '';
if (parsed.isTestnet && cashAddrTestnet) {
parsed.address = addressLowerCase;
parsed.coin = 'bch';
parsed.publicAddress = {
cashAddr: addressLowerCase
};
parsed.isValid = true;
} else if (cashAddrMainnet) {
parsed.coin = 'bch';
parsed.publicAddress = {
cashAddr: addressLowerCase
};
parsed.isTestnet = false;
parsed.isValid = true;
} else if (bitcore.Address.isValid(address, 'livenet')) {
parsed.publicAddress = {
legacy: address
};
parsed.isTestnet = false;
parsed.isValid = true;
} else if (bitcore.Address.isValid(address, 'testnet')) {
parsed.publicAddress = {
legacy: address
};
parsed.isTestnet = true;
parsed.isValid = true;
} else if (bitpayAddrMainnet) {
parsed.coin = 'bch';
parsed.publicAddress = {
bitpay: address
};
parsed.isTestnet = false;
parsed.isValid = true;
} else if (copayInvitationRe.test(address) ) {
parsed.copayInvitation = address;
parsed.isValid = true;
} else if (privateKeyForUncompressedPublicKeyRe.test(address) || privateKeyForCompressedPublicKeyRe.test(address)) {
privateKey = address;
try {
new bitcore.PrivateKey(privateKey, 'livenet');
parsed.privateKey = { wif: privateKey };
parsed.isTestnet = false;
parsed.isValid = true;
} catch (e) {}
} else if (privateKeyForUncompressedPublicKeyTestnetRe.test(address) || privateKeyForCompressedPublicKeyTestnetRe.test(address)) {
privateKey = address;
try {
new bitcore.PrivateKey(privateKey, 'testnet');
parsed.privateKey = { wif: privateKey };
parsed.isTestnet = true;
parsed.isValid = true;
} catch (e) {}
} else if (privateKeyEncryptedRe.test(address)) {
parsed.privateKey = { encrypted: address };
parsed.isValid = true;
} else if (urlRe.test(address)) {
parsed.bareUrl = trimmed;
parsed.isValid = true;
} else if (importInfo) {
parsed.import = {
type: importInfo.type,
data: importInfo.data,
derivationPath: importInfo.derivationPath,
hasPassphrase: importInfo.hasPassphrase
};
parsed.coin = importInfo.coin;
parsed.isTestnet = importInfo.isTestnet;
parsed.isValid = true;
}
} else {
parsed.isValid = !!parsed.url; // BIP72
}
return parsed;
}
}
})();

View file

@ -0,0 +1,429 @@
describe('bitcoinUriService', function() {
var bitcoinUriService;
beforeEach(function() {
module('bitcoinCashJsModule');
module('bitcoincom.services');
module('bwcModule');
inject(function($injector){
bitcoinUriService = $injector.get('bitcoinUriService');
});
});
it('Bitcoin BIP72', function() {
var parsed = bitcoinUriService.parse('bitcoin:?r=https://bitpay.com/i/CwzbKP3k3JNgXJBfuoerDr');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('btc');
expect(parsed.isTestnet).toBeUndefined();
expect(parsed.publicAddress).toBeUndefined();
expect(parsed.url).toBe('https://bitpay.com/i/CwzbKP3k3JNgXJBfuoerDr');
});
it('Bitcoin Cash BIP72', function() {
var parsed = bitcoinUriService.parse('bitcoincash:?r=https://bitpay.com/i/SmHdie5dvBnG5kouZzEPzu');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress).toBeUndefined();
expect(parsed.isTestnet).toBeUndefined();
expect(parsed.url).toBe('https://bitpay.com/i/SmHdie5dvBnG5kouZzEPzu');
});
it('Bitcoin Cash prefix with legacy address', function() {
var parsed = bitcoinUriService.parse('bitcoincash:1G9FA9fFnHfTYxvmXeAbBD9FwzPAVMbd3j');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.legacy).toBe('1G9FA9fFnHfTYxvmXeAbBD9FwzPAVMbd3j');
expect(parsed.isTestnet).toBe(false);
});
it('Bitcoin Cash prefix with legacy address on testnet', function() {
var parsed = bitcoinUriService.parse('bitcoincash:mkDQrKfSFD441JxrD1iPBsJFExgkvrPGQn');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.legacy).toBe('mkDQrKfSFD441JxrD1iPBsJFExgkvrPGQn');
expect(parsed.isTestnet).toBe(true);
});
it('Bitcoin Cash uri with extended params', function() {
var parsed = bitcoinUriService.parse('bitcoincash:qr8v2vqnzntykakht43rqmxq8cdjzjp795fc3vsjgc?unknown=something&mystery=Melton%20probang&req-one=ichi&req-beta=Ni%20san');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.others.mystery).toBe('Melton probang');
expect(parsed.others.unknown).toBe('something');
expect(parsed.publicAddress.cashAddr).toBe('qr8v2vqnzntykakht43rqmxq8cdjzjp795fc3vsjgc');
expect(parsed.req['req-beta']).toBe('Ni san');
expect(parsed.req['req-one']).toBe('ichi');
expect(parsed.isTestnet).toBe(false);
});
it('Bitcoin Cash uri with invalid amount', function() {
var parsed = bitcoinUriService.parse('bitcoincash:qq0knhwj4d5zy3kdph24w6etq58vwzua6sm7lhcmuk?amount=three');
expect(parsed.isValid).toBe(false);
});
it('Bitcoin testnet address', function() {
var parsed = bitcoinUriService.parse('mtWcoToWhbtPoCby5fvs8xdBujT5GGenD4');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBeUndefined();
expect(parsed.publicAddress.legacy).toBe('mtWcoToWhbtPoCby5fvs8xdBujT5GGenD4');
expect(parsed.isTestnet).toBe(true);
});
it('Bitcoin uri', function() {
var parsed = bitcoinUriService.parse('bitcoin:15yCdKWVKRvfXMJpPYZBqMhiGKwjKzZdLN');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('btc');
expect(parsed.publicAddress.legacy).toBe('15yCdKWVKRvfXMJpPYZBqMhiGKwjKzZdLN');
expect(parsed.isTestnet).toBe(false);
});
it('Bitcoin uri with encoded label', function() {
var parsed = bitcoinUriService.parse('bitcoin:1MxudKDEBWZ1yjizUSf6htacenNtb3DWbT?label=Mr.%20Smith');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('btc');
expect(parsed.label).toBe('Mr. Smith');
expect(parsed.publicAddress.legacy).toBe('1MxudKDEBWZ1yjizUSf6htacenNtb3DWbT');
expect(parsed.isTestnet).toBe(false);
});
it('Bitcoin uri with params', function() {
var parsed = bitcoinUriService.parse('bitcoin:12nCRhMDfxVnuF3uYMXv2fNxBohNmacfWu?amount=20.3&label=Luke-Jr&message=Donation%20for%20project%20xyz');
expect(parsed.isValid).toBe(true);
expect(parsed.amount).toBe('20.3');
expect(parsed.amountInSatoshis).toBe(2030000000);
expect(parsed.coin).toBe('btc');
expect(parsed.label).toBe('Luke-Jr');
expect(parsed.publicAddress.legacy).toBe('12nCRhMDfxVnuF3uYMXv2fNxBohNmacfWu');
expect(parsed.message).toBe('Donation for project xyz');
expect(parsed.isTestnet).toBe(false);
});
it('Bitcoin uri with slash', function() {
var parsed = bitcoinUriService.parse('bitcoin:/1GhpYmbRaf73AZRxDwAGr6653iZBGzdgeA');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('btc');
expect(parsed.publicAddress.legacy).toBe('1GhpYmbRaf73AZRxDwAGr6653iZBGzdgeA');
expect(parsed.isTestnet).toBe(false);
});
it('Bitcoin uri with slashes', function() {
var parsed = bitcoinUriService.parse('bitcoin://18PCPhgZJjLxe9g3Q1BXLpL5aVut1fW3aX');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('btc');
expect(parsed.publicAddress.legacy).toBe('18PCPhgZJjLxe9g3Q1BXLpL5aVut1fW3aX');
expect(parsed.isTestnet).toBe(false);
});
it('Bitcoin uri with space', function() {
var parsed = bitcoinUriService.parse('bitcoin: 19cPoKU5ZazY8NkLEsxK7drBqJnpGkax3d');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('btc');
expect(parsed.publicAddress.legacy).toBe('19cPoKU5ZazY8NkLEsxK7drBqJnpGkax3d');
expect(parsed.isTestnet).toBe(false);
});
it('Bitpay without prefix', function() {
var parsed = bitcoinUriService.parse('CJoRov8TirekvajiimQpb5Hk95evA7H2Yz');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.bitpay).toBe('CJoRov8TirekvajiimQpb5Hk95evA7H2Yz');
expect(parsed.isTestnet).toBe(false);
});
it('legacy address', function() {
var parsed = bitcoinUriService.parse('1JXeGEu7bNEAYu6URT6dU6g1Ys6ffSAWYW');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBeUndefined();
expect(parsed.publicAddress.legacy).toBe('1JXeGEu7bNEAYu6URT6dU6g1Ys6ffSAWYW');
expect(parsed.isTestnet).toBe(false);
});
it('cashAddr testnet with prefix', function() {
var parsed = bitcoinUriService.parse('bchtest:qpcz6pmurq9ctg5848trzz9zmuuygj4q5qam7ph3gt');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.cashAddr).toBe('qpcz6pmurq9ctg5848trzz9zmuuygj4q5qam7ph3gt');
expect(parsed.isTestnet).toBe(true);
});
it('cashAddr uppercase', function() {
var parsed = bitcoinUriService.parse('BITCOINCASH:QZZG9NMC5VX8GAP6XFATX3TWNSDN2YRMCSSULSMY44');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.cashAddr).toBe('qzzg9nmc5vx8gap6xfatx3twnsdn2yrmcssulsmy44');
expect(parsed.isTestnet).toBe(false);
});
it('cashAddr with dash', function() {
var parsed = bitcoinUriService.parse('bitcoin-cash:qpshfu3dk5s3e7zdcgdcun6xgxtra6uyxs7g580js0');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.cashAddr).toBe('qpshfu3dk5s3e7zdcgdcun6xgxtra6uyxs7g580js0');
expect(parsed.isTestnet).toBe(false);
});
it('cashAddr with prefix', function() {
var parsed = bitcoinUriService.parse('bitcoincash:qrq9p82a247lecv08ldk5p5h6ahtnjzpqcnh8yhq92');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.cashAddr).toBe('qrq9p82a247lecv08ldk5p5h6ahtnjzpqcnh8yhq92');
expect(parsed.isTestnet).toBe(false);
});
it('cashAddr with slash', function() {
var parsed = bitcoinUriService.parse('bitcoincash:/qzdectfmuw0xxztfx7mh045830dqcshj85hr44l35a');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.cashAddr).toBe('qzdectfmuw0xxztfx7mh045830dqcshj85hr44l35a');
expect(parsed.isTestnet).toBe(false);
});
it('cashAddr with slashes', function() {
var parsed = bitcoinUriService.parse('bitcoincash://qpj966w8utue75lqqq3rlgh20zkz3rmydqpq8syv9c');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.cashAddr).toBe('qpj966w8utue75lqqq3rlgh20zkz3rmydqpq8syv9c');
expect(parsed.isTestnet).toBe(false);
});
it('cashAddr with space', function() {
var parsed = bitcoinUriService.parse('bitcoincash: qpar9ldle8z6alcwgclejdhc24ha2xrg0szs5802ce');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.cashAddr).toBe('qpar9ldle8z6alcwgclejdhc24ha2xrg0szs5802ce');
expect(parsed.isTestnet).toBe(false);
});
it('cashAddr with space on testnet', function() {
var parsed = bitcoinUriService.parse('bchtest: qqjxkmtaxk4nv6w9h5ht2fjcj9c7ruh0fu7cnxsx5j');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.cashAddr).toBe('qqjxkmtaxk4nv6w9h5ht2fjcj9c7ruh0fu7cnxsx5j');
expect(parsed.isTestnet).toBe(true);
});
it('cashAddr without prefix', function() {
var parsed = bitcoinUriService.parse('qqen2y3l28dpk0dzsag8w027ds96u7z4pc0uxtl0nq');
expect(parsed.isValid).toBe(true);
expect(parsed.coin).toBe('bch');
expect(parsed.publicAddress.cashAddr).toBe('qqen2y3l28dpk0dzsag8w027ds96u7z4pc0uxtl0nq');
expect(parsed.isTestnet).toBe(false);
});
it('copay invitation', function() {
var parsed = bitcoinUriService.parse('PD5B7rEEj72st9d5nFszyuKxJP6FAGS7idVC2SMqiMxUcWVd8JifZDJw1UgjUctxefUFE3Sz6qLbch');
expect(parsed.isValid).toBe(true);
expect(parsed.copayInvitation).toBe('PD5B7rEEj72st9d5nFszyuKxJP6FAGS7idVC2SMqiMxUcWVd8JifZDJw1UgjUctxefUFE3Sz6qLbch');
});
it ('import BCH wallet no password', function() {
var parsed = bitcoinUriService.parse("1|suggest route obvious broccoli good position hidden tone history around final lobster|livenet|m/44'/0'/0'|false");
expect(parsed.isValid).toBe(true);
expect(parsed.import.type).toBe(1);
expect(parsed.import.data).toBe('suggest route obvious broccoli good position hidden tone history around final lobster');
expect(parsed.isTestnet).toBe(false);
expect(parsed.import.derivationPath).toBe("m/44'/0'/0'");
expect(parsed.import.hasPassphrase).toBe(false);
});
it ('import BCH wallet with passphrase', function() {
var parsed = bitcoinUriService.parse("1|fringe hazard all hobby trap myth fire stand sock empty soon east|livenet|m/44'/0'/0'|true");
expect(parsed.isValid).toBe(true);
expect(parsed.import.type).toBe(1);
expect(parsed.import.data).toBe('fringe hazard all hobby trap myth fire stand sock empty soon east');
expect(parsed.isTestnet).toBe(false);
expect(parsed.import.derivationPath).toBe("m/44'/0'/0'");
expect(parsed.import.hasPassphrase).toBe(true);
});
it ('import BTC wallet testnet', function() {
// From copay
var parsed = bitcoinUriService.parse("1|cat wealth column firm wet sauce tornado era feature monster click eyebrow|testnet|m/44'/1'/0'|false|btc");
expect(parsed.isValid).toBe(true);
expect(parsed.import.type).toBe(1);
expect(parsed.import.data).toBe('cat wealth column firm wet sauce tornado era feature monster click eyebrow');
expect(parsed.isTestnet).toBe(true);
expect(parsed.import.derivationPath).toBe("m/44'/1'/0'");
expect(parsed.import.hasPassphrase).toBe(false);
});
// Invalid addresses from https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md
it('invalid cashAddr style 1', function() {
var parsed = bitcoinUriService.parse('prefix:x64nx6hz');
expect(parsed.isValid).toBe(false);
});
it('invalid cashAddr style 2', function() {
var parsed = bitcoinUriService.parse('p:gpf8m4h7');
expect(parsed.isValid).toBe(false);
});
it('invalid cashAddr style 3', function() {
var parsed = bitcoinUriService.parse('bitcoincash:qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn');
expect(parsed.isValid).toBe(false);
});
it('invalid cashAddr style 4', function() {
var parsed = bitcoinUriService.parse('bchtest:testnetaddress4d6njnut');
expect(parsed.isValid).toBe(false);
});
it('invalid cashAddr style 5', function() {
var parsed = bitcoinUriService.parse('bchreg:555555555555555555555555555555555555555555555udxmlmrz');
expect(parsed.isValid).toBe(false);
});
it('non-string', function() {
var parsed = bitcoinUriService.parse([1, 2, 3, 4]);
expect(parsed.isValid).toBe(false);
});
it('private key encrypted with BIP38', function() {
var parsed = bitcoinUriService.parse('6PRN5nEDmX842gsBzJryPu8Tw5kcsaQq1GPLcjVQPcEStvbFAtz11JX9pX');
expect(parsed.isValid).toBe(true);
expect(parsed.privateKey.encrypted).toBe('6PRN5nEDmX842gsBzJryPu8Tw5kcsaQq1GPLcjVQPcEStvbFAtz11JX9pX');
});
it('private key for compressed pubkey mainnet', function() {
var parsed = bitcoinUriService.parse('5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ');
expect(parsed.isValid).toBe(true);
expect(parsed.privateKey.wif).toBe('5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ');
expect(parsed.isTestnet).toBe(false);
});
it('private key for compressed pubkey mainnet with wrong checksum', function() {
var parsed = bitcoinUriService.parse('5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTu');
expect(parsed.isValid).toBe(false);
});
it('private key for compressed pubkey testnet', function() {
var parsed = bitcoinUriService.parse('cNJFgo1driFnPcBdBX8BrJrpxchBWXwXCvNH5SoSkdcF6JXXwHMm');
expect(parsed.isValid).toBe(true);
expect(parsed.privateKey.wif).toBe('cNJFgo1driFnPcBdBX8BrJrpxchBWXwXCvNH5SoSkdcF6JXXwHMm');
expect(parsed.isTestnet).toBe(true);
});
it('private key for compressed pubkey testnet with wrong checksum', function() {
var parsed = bitcoinUriService.parse('cNJFgo1driFnPcBdBX8BrJrpxchBWXwXCvNH5SoSkdcF6JXXwHMM');
expect(parsed.isValid).toBe(false);
});
it('private key for uncompressed pubkey mainnet', function() {
var parsed = bitcoinUriService.parse('L18V3rAhCKEioPnJ4BHLCCsaYa8eSNFrMjNQ2EdwgeAdmBSnTMwx');
expect(parsed.isValid).toBe(true);
expect(parsed.privateKey.wif).toBe('L18V3rAhCKEioPnJ4BHLCCsaYa8eSNFrMjNQ2EdwgeAdmBSnTMwx');
expect(parsed.isTestnet).toBe(false);
});
it('private key for uncompressed pubkey mainnet with wrong checksum', function() {
var parsed = bitcoinUriService.parse('L18V3rAhCKEioPnJ4BHLCCsaYa8eSNFrMjNQ2EdwgeAdmBSnTTwx');
expect(parsed.isValid).toBe(false);
});
it('private key for uncompressed pubkey testnet', function() {
var parsed = bitcoinUriService.parse('92Pg46rUhgTT7romnV7iGW6W1gbGdeezqdbJCzShkCsYNzyyNcc');
expect(parsed.isValid).toBe(true);
expect(parsed.privateKey.wif).toBe('92Pg46rUhgTT7romnV7iGW6W1gbGdeezqdbJCzShkCsYNzyyNcc');
expect(parsed.isTestnet).toBe(true);
});
it('private key for uncompressed pubkey testnet with wrong checksum', function() {
var parsed = bitcoinUriService.parse('92Pg46rUhgTT7romnV7iGW6W1gbGdeezqdbJCzShkCsYNzyyNcC');
expect(parsed.isValid).toBe(false);
});
it('URL only, http', function() {
var parsed = bitcoinUriService.parse('http://paperwallet.bitcoin.com');
expect(parsed.isValid).toBe(true);
expect(parsed.bareUrl).toBe('http://paperwallet.bitcoin.com');
});
it('URL only, https with query', function() {
var parsed = bitcoinUriService.parse('https://purse.io/?one=two&three=four');
expect(parsed.isValid).toBe(true);
expect(parsed.bareUrl).toBe('https://purse.io/?one=two&three=four');
});
});

View file

@ -1,5 +1,5 @@
'use strict';
angular.module('copayApp.services').factory('bitcoincomService', function(platformInfo, nextStepsService) {
angular.module('copayApp.services').factory('bitcoincomService', function(gettextCatalog, nextStepsService, platformInfo) {
var root = {};
var credentials = {};
@ -19,42 +19,42 @@ angular.module('copayApp.services').factory('bitcoincomService', function(platfo
var cashGamesItem = {
name: 'games',
title: 'Bitcoin Cash Games',
title: gettextCatalog.getString('Bitcoin Cash Games'),
icon: 'icon-games',
href: 'https://cashgames.bitcoin.com'
};
var newsItem = {
name: 'news',
title: 'News',
title: gettextCatalog.getString('News'),
icon: 'icon-news',
href: 'https://news.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=News'
};
var poolItem = {
name: 'pool',
title: 'Mining Pool',
title: gettextCatalog.getString('Mining Pool'),
icon: 'icon-mining',
href: 'https://pool.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Pool'
};
var toolsItem = {
name: 'tools',
title: 'Tools',
title: gettextCatalog.getString('Tools'),
icon: 'icon-tools',
href: 'https://tools.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Tools'
};
var priceChartItem = {
name: 'pricechart',
title: 'Bitcoin Price Charts',
title: gettextCatalog.getString('Bitcoin Price Charts'),
icon: 'icon-chart',
sref: 'tabs.pricechart',
};
var faucetItem = {
name: 'faucet',
title: 'Free Bitcoin Cash',
title: gettextCatalog.getString('Free Bitcoin Cash'),
icon: 'icon-faucet',
href: 'https://free.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Faucet'
};
@ -85,7 +85,9 @@ angular.module('copayApp.services').factory('bitcoincomService', function(platfo
};
var register = function() {
nextStepsService.register(cashGamesItem);
if (!platformInfo.isAndroid) { // To comply with Google Play policies
nextStepsService.register(cashGamesItem);
}
nextStepsService.register(newsItem);
nextStepsService.register(poolItem);
nextStepsService.register(toolsItem);

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.services').factory('buyAndSellService', function($log, servicesService, lodash, $ionicScrollDelegate, $timeout) {
angular.module('copayApp.services').factory('buyAndSellService', function(gettextCatalog, $log, servicesService, lodash, $ionicScrollDelegate, $timeout) {
var root = {};
var services = [];
var linkedServices = [];
@ -23,7 +23,7 @@ angular.module('copayApp.services').factory('buyAndSellService', function($log,
if (linkedServices.length == 0) {
servicesService.register({
title: 'Buy Bitcoin',
title: gettextCatalog.getString('Buy Bitcoin'),
name: 'buyandsell',
icon: 'icon-buy-bitcoin2',
sref: 'tabs.buyandsell',

View file

@ -11,10 +11,15 @@ angular.module('copayApp.services').factory('clipboardService', function ($http,
cordova.plugins.clipboard.copy(data);
} else if (platformInfo.isNW) {
nodeWebkitService.writeToClipboard(data);
} else if (navigator && navigator.clipboard) {
$log.debug("Use navigator clipboard.")
navigator.clipboard.writeText(data).catch(function onClipboardError(err) {
$log.debug("Clipboard writing is not supported in your browser..");
});
} else if (clipboard.supported) {
clipboard.copyText(data);
} else {
// No supported
// Not supported
return;
}
};

View file

@ -1,5 +1,5 @@
'use strict'
angular.module('copayApp.services').factory('communityService', function(configService, $log, lodash) {
angular.module('copayApp.services').factory('communityService', function(configService, gettextCatalog, $log, lodash) {
var root = {};
var services = [];
@ -37,14 +37,14 @@ angular.module('copayApp.services').factory('communityService', function(configS
var bchRedditItem = {
name: 'bchreddit',
title: 'Bitcoin Cash Reddit',
title: gettextCatalog.getString('Bitcoin Cash Reddit'),
icon: 'icon-reddit-white',
href: 'http://reddit.com/r/btc'
};
var bitcoincomTwitterItem = {
name: 'bitcoincomTwitter',
title: 'Bitcoin.com Twitter',
title: gettextCatalog.getString('Bitcoin.com Twitter'),
icon: 'icon-twitter-white',
href: 'https://twitter.com/BTCTN'
};

View file

@ -18,7 +18,7 @@ angular.module('copayApp.services').factory('configService', function(storageSer
},
bwscash: {
url: 'https://bwscash.bitcoin.com/bws/api'
url: 'https://bws.freepages.dk/bws/api'
},
download: {

View file

@ -12,6 +12,7 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
normal: gettext('Normal'),
economy: gettext('Economy'),
superEconomy: gettext('Super Economy'),
// free: gettext('No fee (works only for BCH)'),
custom: gettext('Custom')
};
@ -31,6 +32,7 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
root.getFeeRate = function(coin, network, feeLevel, cb) {
if (feeLevel == 'custom') return cb();
// if (feeLevel == 'free') return cb(null, 0);
network = network || 'livenet';
@ -48,9 +50,9 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
})
});
}
var feeRate = feeLevelRate.feePerKb;
if (!fromCache) $log.debug('Dynamic fee: ' + feeLevel + '/' + network + ' ' + (feeLevelRate.feePerKb / 1000).toFixed() + ' SAT/B');
return cb(null, feeRate);

View file

@ -1,5 +1,5 @@
'use strict';
angular.module('copayApp.services').factory('firebaseEventsService', function firebaseEventsService($log, $state, $ionicHistory, sjcl, platformInfo, lodash, appConfigService, profileService, configService) {
angular.module('copayApp.services').factory('firebaseEventsService', function firebaseEventsService($log, platformInfo) {
var root = {};
var useEvents = platformInfo.isCordova && !platformInfo.isWP;

View file

@ -0,0 +1,79 @@
'use strict';
/**
* incomingDataService is an intermediate to redirect either to the sendFlow
* or to import/join a wallet.
*/
angular.module('copayApp.services').factory('incomingDataService', function(bitcoinUriService, $log, $state, $rootScope, scannerService, sendFlowService, gettextCatalog) {
var root = {};
root.showMenu = function(data) {
$rootScope.$broadcast('incomingDataMenu.showMenu', data);
};
root.redir = function(data, cbError) {
var parsed = bitcoinUriService.parse(data);
console.log(parsed);
$log.debug(parsed);
if (parsed.isValid) {
if (parsed.isTestnet) {
if (cbError) {
var errorMessage = gettextCatalog.getString('Testnet is not supported.');
cbError(new Error(errorMessage));
}
} else {
scannerService.pausePreview();
/**
* Strategy for the action
*/
if (parsed.copayInvitation) {
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.add.join', {
url: data
});
});
} else if (parsed.import) {
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.add.import', {
code: data
});
});
} else if (
!parsed.isValid
|| parsed.privateKey
|| (sendFlowService.state.isEmpty() && !parsed.url && !parsed.amount)
) {
root.showMenu({
original: data,
parsed: parsed
});
} else {
var state = sendFlowService.state.getClone();
state.data = data;
sendFlowService.start(state, function onError(err) {
/**
* OnError, open the menu (link not validated)
*/
root.showMenu({
original: data,
parsed: parsed
});
});
}
}
} else {
if (cbError) {
var errorMessage = gettextCatalog.getString('Data not recognised.');
cbError(new Error(errorMessage));
}
}
};
return root;
});

View file

@ -1,434 +0,0 @@
'use strict';
angular.module('copayApp.services').factory('incomingData', function($log, $state, $timeout, $ionicHistory, bitcore, bitcoreCash, $rootScope, payproService, scannerService, appConfigService, popupService, gettextCatalog, bitcoinCashJsService) {
var root = {};
root.showMenu = function(data) {
$rootScope.$broadcast('incomingDataMenu.showMenu', data);
};
root.redir = function(data, shapeshiftData) {
var originalAddress = null;
var noPrefixInAddress = 0;
if (data.toLowerCase().indexOf('bitcoin') < 0) {
noPrefixInAddress = 1;
}
if (typeof(data) == 'string' && !(/^bitcoin(cash)?:\?r=[\w+]/).exec(data) && (data.toLowerCase().indexOf('bitcoincash:') >= 0 || data[0] == 'q' || data[0] == 'p' || data[0] == 'C' || data[0] == 'H')) {
try {
noPrefixInAddress = 0;
if (data[0] == 'p' || data[0] == 'q') {
data = 'bitcoincash:' + data;
}
var paramString = '';
if (data.indexOf('?') >= 0) {
paramString = data.substring(data.indexOf('?'));
data = data.substring(0, data.indexOf('?'));
}
if (data.indexOf('BITCOINCASH:') >= 0) {
data = data.toLowerCase();
}
originalAddress = data.replace('bitcoincash:', '');
var legacyAddress = bitcoinCashJsService.readAddress(data).legacy;
data = 'bitcoincash:' + legacyAddress + paramString;
} catch (ex) {}
}
$log.debug('Processing incoming data: ' + data);
function sanitizeUri(data) {
// Fixes when a region uses comma to separate decimals
var regex = /[\?\&]amount=(\d+([\,\.]\d+)?)/i;
var match = regex.exec(data);
if (!match || match.length === 0) {
return data;
}
var value = match[0].replace(',', '.');
var newUri = data.replace(regex, value);
// mobile devices, uris like copay://glidera
newUri.replace('://', ':');
return newUri;
}
function getParameterByName(name, url) {
if (!url) return;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
function checkPrivateKey(privateKey) {
try {
new bitcore.PrivateKey(privateKey, 'livenet');
} catch (err) {
return false;
}
return true;
}
function goSend(addr, amount, message, coin, shapeshiftData) {
$state.go('tabs.send', {}, {
'reload': true,
'notify': $state.current.name == 'tabs.send' ? false : true
});
// Timeout is required to enable the "Back" button
$timeout(function() {
if (amount) {
$state.transitionTo('tabs.send.confirm', {
toAmount: amount,
toAddress: addr,
displayAddress: originalAddress ? originalAddress : addr,
description: message,
coin: coin
});
} else {
var params = {
toAddress: addr,
coin: coin,
displayAddress: originalAddress ? originalAddress : addr,
noPrefix: noPrefixInAddress
};
if (shapeshiftData) {
params['fromWalletId'] = shapeshiftData.fromWalletId;
params['minShapeshiftAmount'] = shapeshiftData.minAmount;
params['maxShapeshiftAmount'] = shapeshiftData.maxAmount;
params['shapeshiftOrderId'] = shapeshiftData.orderId;
}
$state.transitionTo('tabs.send.amount', params);
}
}, 100);
}
// data extensions for Payment Protocol with non-backwards-compatible request
if ((/^bitcoin(cash)?:\?r=[\w+]/).exec(data)) {
var coin = data.indexOf('bitcoincash') >= 0 ? 'bch' : 'btc';
data = decodeURIComponent(data.replace(/bitcoin(cash)?:\?r=/, ''));
if (coin == 'bch') {
payproService.getPayProDetailsViaHttp(data, function(err, details) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), err)
} else {
handlePayPro(createBchPayProObject(details), coin);
}
});
} else {
payproService.getPayProDetails(data, coin, function(err, details) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), err);
} else {
handlePayPro(details, coin);
}
});
}
return true;
}
data = sanitizeUri(data);
// Bitcoin URL
if (bitcore.URI.isValid(data)) {
var coin = 'btc';
var parsed = new bitcore.URI(data);
var addr = parsed.address ? parsed.address.toString() : '';
var message = parsed.message;
var amount = parsed.amount ? parsed.amount : '';
if (parsed.r) {
payproService.getPayProDetails(parsed.r, coin, function(err, details) {
if (err) {
if (addr && amount) goSend(addr, amount, message, coin, shapeshiftData);
else popupService.showAlert(gettextCatalog.getString('Error'), err);
} else handlePayPro(details, coin);
});
} else {
goSend(addr, amount, message, coin, shapeshiftData);
}
return true;
// Cash URI
} else if (bitcoreCash.URI.isValid(data)) {
var coin = 'bch';
var parsed = new bitcoreCash.URI(data);
var addr = parsed.address ? parsed.address.toString() : '';
var message = parsed.message;
var amount = parsed.amount ? parsed.amount : '';
// paypro not yet supported on cash
if (parsed.r) {
payproService.getPayProDetails(parsed.r, coin, function(err, details) {
if (err) {
if (addr && amount)
goSend(addr, amount, message, coin, shapeshiftData);
else
popupService.showAlert(gettextCatalog.getString('Error'), err);
}
handlePayPro(details, coin);
});
} else {
goSend(addr, amount, message, coin, shapeshiftData);
}
return true;
// Cash URI with bitcoin (btc) address version number?
} else if (bitcore.URI.isValid(data.replace(/^bitcoincash:/,'bitcoin:'))) {
$log.debug('Handling bitcoincash URI with legacy address');
var coin = 'bch';
var parsed = new bitcore.URI(data.replace(/^bitcoincash:/,'bitcoin:'));
var oldAddr = parsed.address ? parsed.address.toString() : '';
if (!oldAddr) return false;
var addr = '';
var a = bitcore.Address(oldAddr).toObject();
addr = bitcoreCash.Address.fromObject(a).toString();
// Translate address
$log.debug('address transalated to:' + addr);
popupService.showConfirm(
gettextCatalog.getString('Bitcoin cash Payment'),
gettextCatalog.getString('Payment address was translated to new Bitcoin Cash address format: ' + addr),
gettextCatalog.getString('OK'),
gettextCatalog.getString('Cancel'),
function(ret) {
if (!ret) return false;
var message = parsed.message;
var amount = parsed.amount ? parsed.amount : '';
// paypro not yet supported on cash
if (parsed.r) {
payproService.getPayProDetails(parsed.r, coin, function(err, details) {
if (err) {
if (addr && amount)
goSend(addr, amount, message, coin, shapeshiftData);
else
popupService.showAlert(gettextCatalog.getString('Error'), err);
}
handlePayPro(details, coin);
});
} else {
goSend(addr, amount, message, coin, shapeshiftData);
}
}
);
return true;
// Plain URL
} else if (/^https?:\/\//.test(data)) {
payproService.getPayProDetails(data, coin, function(err, details) {
if (err) {
if ($state.includes('tabs.scan')) {
root.showMenu({
data: data,
type: 'url'
});
}
return;
}
handlePayPro(details);
return true;
});
// Plain Address
} else if (bitcore.Address.isValid(data, 'livenet') || bitcore.Address.isValid(data, 'testnet')) {
if ($state.includes('tabs.scan')) {
root.showMenu({
data: data,
type: 'bitcoinAddress'
});
} else {
goToAmountPage(data);
}
} else if (bitcoreCash.Address.isValid(data, 'livenet')) {
if ($state.includes('tabs.scan')) {
root.showMenu({
data: data,
type: 'bitcoinAddress',
coin: 'bch',
});
} else {
goToAmountPage(data, 'bch');
}
} else if (data && data.indexOf(appConfigService.name + '://glidera') === 0) {
var code = getParameterByName('code', data);
$ionicHistory.nextViewOptions({
disableAnimate: true
});
$state.go('tabs.home', {}, {
'reload': true,
'notify': $state.current.name == 'tabs.home' ? false : true
}).then(function() {
$ionicHistory.nextViewOptions({
disableAnimate: true
});
$state.transitionTo('tabs.buyandsell.glidera', {
code: code
});
});
return true;
} else if (data && data.indexOf(appConfigService.name + '://coinbase') === 0) {
var code = getParameterByName('code', data);
$ionicHistory.nextViewOptions({
disableAnimate: true
});
$state.go('tabs.home', {}, {
'reload': true,
'notify': $state.current.name == 'tabs.home' ? false : true
}).then(function() {
$ionicHistory.nextViewOptions({
disableAnimate: true
});
$state.transitionTo('tabs.buyandsell.coinbase', {
code: code
});
});
return true;
// BitPayCard Authentication
} else if (data && data.indexOf(appConfigService.name + '://') === 0) {
// Disable BitPay Card
if (!appConfigService._enabledExtensions.debitcard) return false;
var secret = getParameterByName('secret', data);
var email = getParameterByName('email', data);
var otp = getParameterByName('otp', data);
var reason = getParameterByName('r', data);
$state.go('tabs.home', {}, {
'reload': true,
'notify': $state.current.name == 'tabs.home' ? false : true
}).then(function() {
switch (reason) {
default:
case '0':
/* For BitPay card binding */
$state.transitionTo('tabs.bitpayCardIntro', {
secret: secret,
email: email,
otp: otp
});
break;
}
});
return true;
// Join
} else if (data && data.match(/^copay:[0-9A-HJ-NP-Za-km-z]{70,80}$/)) {
$state.go('tabs.home', {}, {
'reload': true,
'notify': $state.current.name == 'tabs.home' ? false : true
}).then(function() {
$state.transitionTo('tabs.add.join', {
url: data
});
});
return true;
// Old join
} else if (data && data.match(/^[0-9A-HJ-NP-Za-km-z]{70,80}$/)) {
$state.go('tabs.home', {}, {
'reload': true,
'notify': $state.current.name == 'tabs.home' ? false : true
}).then(function() {
$state.transitionTo('tabs.add.join', {
url: data
});
});
return true;
} else if (data && (data.substring(0, 2) == '6P' || checkPrivateKey(data))) {
root.showMenu({
data: data,
type: 'privateKey'
});
} else if (data && ((data.substring(0, 2) == '1|') || (data.substring(0, 2) == '2|') || (data.substring(0, 2) == '3|'))) {
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.add.import', {
code: data
});
});
return true;
} else {
if ($state.includes('tabs.scan')) {
root.showMenu({
data: data,
type: 'text'
});
}
}
return false;
};
function goToAmountPage(toAddress, coin) {
$state.go('tabs.send', {}, {
'reload': true,
'notify': $state.current.name == 'tabs.send' ? false : true
});
$timeout(function() {
$state.transitionTo('tabs.send.amount', {
toAddress: toAddress,
coin: coin,
noPrefix: 1
});
}, 100);
}
function createBchPayProObject(payProData) {
var displayAddr = payProData.outputs[0].address;
var toAddr = bitcoinCashJsService.readAddress('bitcoincash:' + displayAddr).legacy;
return {
amount: payProData.outputs[0].amount,
caTrusted: true,
domain: 'bitpay.com',
expires: Math.floor(new Date(payProData.expires).getTime() / 1000),
memo: payProData.memo,
network: 'livenet',
requiredFeeRate: payProData.requiredFeeRate,
selfSigned: 0,
time: Math.ceil(new Date(payProData.time).getTime() / 1000),
displayAddress: displayAddr,
toAddress: toAddr,
url: payProData.paymentUrl,
verified: true
};
}
function handlePayPro(payProDetails, coin) {
var stateParams = {
toAmount: payProDetails.amount,
toAddress: payProDetails.toAddress,
description: payProDetails.memo,
paypro: payProDetails,
coin: coin,
};
// fee
if (payProDetails.requiredFeeRate) {
stateParams.requiredFeeRate = payProDetails.requiredFeeRate * 1024;
}
scannerService.pausePreview();
$state.go('tabs.send', {}, {
'reload': true,
'notify': $state.current.name == 'tabs.send' ? false : true
}).then(function() {
$timeout(function() {
$state.transitionTo('tabs.send.confirm', stateParams);
});
});
}
return root;
});

View file

@ -0,0 +1,180 @@
'use strict';
(function() {
angular
.module('bitcoincom.services')
.factory('latestReleaseService', latestReleaseService);
function latestReleaseService($log, $http, $ionicPopup, configService, externalLinkService, gettextCatalog, platformInfo) {
var service = {
// Functions
checkLatestRelease: checkLatestRelease,
requestLatestRelease: requestLatestRelease,
showUpdatePopup: showUpdatePopup
};
return service;
function checkLatestRelease(cb) {
var releaseURL = configService.getDefaults().release.url;
requestLatestRelease(releaseURL, function (err, releaseData) {
if (err) return cb(err);
var currentVersion = window.version;
var latestVersion = releaseData.tag_name;
if (!verifyTagFormat(currentVersion))
return cb('Cannot verify the format of version tag: ' + currentVersion);
if (!verifyTagFormat(latestVersion))
return cb('Cannot verify the format of latest release tag: ' + latestVersion);
var current = formatTagNumber(currentVersion);
var latest = formatTagNumber(latestVersion);
if (latest.major < current.major || (latest.major === current.major && latest.minor <= current.minor)) {
return cb(null, false);
}
var releaseSearchTerm = "";
if (platformInfo.isNW) { // XX SP: DESKTOP: Check if the latest release is already available for current OS
var platform = process.platform;
if (platform === "darwin") {
releaseSearchTerm = "osx";
} else if (platform === "win32") {
releaseSearchTerm = "win";
} else if (platform === "linux") {
releaseSearchTerm = "linux";
}
var foundNewVersion = false;
for (var i in releaseData.assets) {
if (releaseData.assets[i].name.indexOf(releaseSearchTerm) !== -1) {
foundNewVersion = true;
break;
}
}
}
$log.debug('A new version is available: ' + latestVersion);
var releaseNotes = false;
if (releaseData.body) {
var releaseLines = releaseData.body.split('\n');
for (var lineNum in releaseLines) {
if (releaseLines[lineNum].substring(0, 2) === "# ") {
releaseLines[lineNum] = "<strong>" + releaseLines[lineNum].substring(2) + "</strong>";
} else if (releaseLines[lineNum].substring(0, 2) === "- ") {
releaseLines[lineNum] = "&bull; " + releaseLines[lineNum].substring(2);
}
}
releaseNotes = releaseLines.join('\n');
}
return cb(null, {latestVersion: latestVersion, releaseNotes: releaseNotes});
});
function verifyTagFormat(tag) {
var regex = /^v?\d+\.\d+(\.\d+)?(-rc\d)?$/i;
return regex.exec(tag);
}
function formatTagNumber(tag) {
var label = false;
if (tag.split("-")[1]) { // Move postfixes like "-rc2" to a variable
label = tag.split("-")[1];
tag = tag.split("-")[0];
}
var formattedNumber = tag.replace(/^v/i, '').split('.');
return {
major: +(formattedNumber[0] ? +formattedNumber[0] : 0),
minor: +(formattedNumber[1] ? +formattedNumber[1] : 0),
patch: +(formattedNumber[2] ? +formattedNumber[2] : 0),
label: label /* XX SP: Maybe we can use this in a later stage (with for example 1.0.0-rc2 the value will be "rc2" and false if there is no label) */
};
}
}
function requestLatestRelease(releaseURL, cb) {
$log.debug('Retrieving latest release information...');
var request = {
url: releaseURL,
method: 'GET',
json: true
};
$http(request).then(function (release) {
$log.debug('Latest release: ' + release.data.name);
return cb(null, release.data);
}, function (err) {
return cb('Cannot get the release information: ' + err);
});
}
function showUpdatePopup() {
var buttons = [];
if (!platformInfo.isIOS) { // There is no GitHub-release for iPhone
buttons.push({
text: "GitHub",
type: 'button-positive',
onTap: function () {
var url = 'https://github.com/Bitcoin-com/Wallet/releases/latest';
externalLinkService.open(url, false);
}
});
}
if (platformInfo.isAndroid) {
buttons.unshift({
text: "Google Play Store",
type: 'button-positive',
onTap: function () {
var url = 'https://play.google.com/store/apps/details?id=com.bitcoin.mwallet';
externalLinkService.open(url, false);
}
});
}
if (platformInfo.isIOS) {
buttons.unshift({
text: "App Store",
type: 'button-positive',
onTap: function () {
var url = 'https://itunes.apple.com/app/id1252903728';
externalLinkService.open(url, false);
}
});
} else if (platformInfo.isNW) {
if (process.platform === 'darwin') {
buttons.unshift({
text: "Mac App Store",
type: 'button-positive',
onTap: function () {
var url = 'https://itunes.apple.com/app/bitcoin-com-wallet/id1383072453';
externalLinkService.open(url, false);
}
});
}
}
if (buttons.length === 1) { // There is only one source to download (probably on desktop, so open GitHub release page..)
buttons[0].onTap();
} else {
buttons.push({
text: gettextCatalog.getString('Go Back'),
type: 'button-positive',
onTap: function () {
return true;
}
});
$ionicPopup.show({
title: gettextCatalog.getString('Update Available'),
subTitle: gettextCatalog.getString('An update to this app is available. For your security, please update to the latest version.'),
cssClass: 'popup-update',
buttons: buttons
});
}
}
}
})();

View file

@ -1,63 +0,0 @@
'use strict';
angular.module('copayApp.services')
.factory('latestReleaseService', function latestReleaseServiceFactory($log, $http, configService) {
var root = {};
root.checkLatestRelease = function(cb) {
var releaseURL = configService.getDefaults().release.url;
requestLatestRelease(releaseURL, function(err, release) {
if (err) return cb(err);
var currentVersion = window.version;
var latestVersion = release.data.tag_name;
if (!verifyTagFormat(currentVersion))
return cb('Cannot verify the format of version tag: ' + currentVersion);
if (!verifyTagFormat(latestVersion))
return cb('Cannot verify the format of latest release tag: ' + latestVersion);
var current = formatTagNumber(currentVersion);
var latest = formatTagNumber(latestVersion);
if (latest.major < current.major || (latest.major == current.major && latest.minor <= current.minor))
return cb(null, false);
$log.debug('A new version is available: ' + latestVersion);
return cb(null, true);
});
function verifyTagFormat(tag) {
var regex = /^v?\d+\.\d+\.\d+$/i;
return regex.exec(tag);
};
function formatTagNumber(tag) {
var formattedNumber = tag.replace(/^v/i, '').split('.');
return {
major: +formattedNumber[0],
minor: +formattedNumber[1],
patch: +formattedNumber[2]
};
};
};
function requestLatestRelease(releaseURL, cb) {
$log.debug('Retrieving latest relsease information...');
var request = {
url: releaseURL,
method: 'GET',
json: true
};
$http(request).then(function(release) {
$log.debug('Latest release: ' + release.data.name);
return cb(null, release);
}, function(err) {
return cb('Cannot get the release information: ' + err);
});
};
return root;
});

View file

@ -52,11 +52,7 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
root.clear = function() {
ongoingProcess = {};
if (isCordova && !isWindowsPhoneApp) {
window.plugins.spinnerDialog.hide();
} else {
$ionicLoading.hide();
}
$ionicLoading.hide();
};
root.get = function(processName) {
@ -78,28 +74,21 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
root.onGoingProcessName = name;
var showName = $filter('translate')(processNames[name] || name);
if (root.onGoingProcessName) {
var tmpl;
if (isWindowsPhoneApp) tmpl = '<div>' + showName + '</div>';
else tmpl = '<div class="item-icon-left">' + showName + '<ion-spinner class="spinner-stable" icon="lines"></ion-spinner></div>';
$ionicLoading.show({
template: tmpl,
});
} else {
$ionicLoading.hide();
}
if (customHandler) {
customHandler(processName, showName, isOn);
} else if (root.onGoingProcessName) {
if (isCordova && !isWindowsPhoneApp) {
window.plugins.spinnerDialog.show(null, showName, root.clear);
} else {
var tmpl;
if (isWindowsPhoneApp) tmpl = '<div>' + showName + '</div>';
else tmpl = '<div class="item-icon-left">' + showName + '<ion-spinner class="spinner-stable" icon="lines"></ion-spinner></div>';
$ionicLoading.show({
template: tmpl
});
}
} else {
if (isCordova && !isWindowsPhoneApp) {
window.plugins.spinnerDialog.hide();
} else {
$ionicLoading.hide();
}
}
}
};
return root;

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.services').factory('openURLService', function($rootScope, $ionicHistory, $document, $log, $state, platformInfo, lodash, profileService, incomingData, appConfigService) {
angular.module('copayApp.services').factory('openURLService', function($rootScope, $ionicHistory, $document, $log, $state, platformInfo, lodash, profileService, incomingDataService, appConfigService) {
var root = {};
var handleOpenURL = function(args) {
@ -23,9 +23,12 @@ angular.module('copayApp.services').factory('openURLService', function($rootScop
document.addEventListener('handleopenurl', handleOpenURL, false);
if (!incomingData.redir(url)) {
$log.warn('Unknown URL! : ' + url);
}
incomingDataService.redir(url, function onError(err) {
if (err) {
$log.warn('Unknown URL! : ' + url);
popupService.showAlert(gettextCatalog.getString('Error'), err.message);
}
});
};
var handleResume = function() {

View file

@ -0,0 +1,78 @@
'use strict';
// For BIP70 Payment Protocol
angular
.module('copayApp.services')
.factory('payproService', payproService);
function payproService(gettextCatalog, $http, $log, ongoingProcess, platformInfo, profileService) {
var service = {
getPayProDetails: getPayProDetails,
getPayProDetailsViaHttp: getPayProDetailsViaHttp,
broadcastBchTx: broadcastBchTx
};
return service;
function getPayProDetails(uri, coin, cb, disableLoader) {
if (!cb) cb = function() {};
var wallet = profileService.getWallets({
onlyComplete: true,
coin: coin
})[0];
if (!wallet) return cb();
if (platformInfo.isChromeApp) {
return cb(gettextCatalog.getString('Payment Protocol not supported on Chrome App'));
}
$log.debug('Fetch PayPro Request...', uri);
if (!disableLoader) ongoingProcess.set('fetchingPayPro', true);
wallet.fetchPayPro({
payProUrl: uri,
}, function(err, paypro) {
if (!disableLoader) ongoingProcess.set('fetchingPayPro', false);
if (err) return cb(gettextCatalog.getString('Could Not Fetch Payment: Check if it is still valid'));
else if (!paypro.verified) {
$log.warn('Failed to verify payment protocol signatures');
return cb(gettextCatalog.getString('Payment Protocol Invalid'));
}
return cb(null, paypro);
});
}
function getPayProDetailsViaHttp(uri, cb) {
var config = {
headers: {'Accept': 'application/payment-request'}
};
$http.get(uri, config).then(function onGetPayProDetailsSuccess(response) {
return cb(null, response.data);
}, function onGetPayProDetailsError(error) {
return cb(error, null);
});
}
function broadcastBchTx(signedTxp, cb) {
var config = {
headers: {'Content-Type': 'application/payment'}
};
var data = {
currency: 'BCH',
transactions: [signedTxp.raw]
};
$http.post(signedTxp.payProUrl, data, config).then(function(response) {
signedTxp.response = response.data;
return cb(null, signedTxp);
}, function(error) {
return cb(error.data, null);
});
}
}

View file

@ -1,69 +0,0 @@
'use strict';
angular.module('copayApp.services').factory('payproService',
function(profileService, platformInfo, gettextCatalog, ongoingProcess, $log, $http) {
var ret = {};
ret.getPayProDetails = function(uri, coin, cb, disableLoader) {
if (!cb) cb = function() {};
var wallet = profileService.getWallets({
onlyComplete: true,
coin: coin
})[0];
if (!wallet) return cb();
if (platformInfo.isChromeApp) {
return cb(gettextCatalog.getString('Payment Protocol not supported on Chrome App'));
}
$log.debug('Fetch PayPro Request...', uri);
if (!disableLoader) ongoingProcess.set('fetchingPayPro', true);
wallet.fetchPayPro({
payProUrl: uri,
}, function(err, paypro) {
if (!disableLoader) ongoingProcess.set('fetchingPayPro', false);
if (err) return cb(gettextCatalog.getString('Could Not Fetch Payment: Check if it is still valid'));
else if (!paypro.verified) {
$log.warn('Failed to verify payment protocol signatures');
return cb(gettextCatalog.getString('Payment Protocol Invalid'));
}
return cb(null, paypro);
});
};
ret.getPayProDetailsViaHttp = function(uri, cb) {
var config = {
headers: {'Accept': 'application/payment-request'}
};
$http.get(uri, config).then(function(response) {
return cb(null, response.data);
}, function(error) {
return cb(error, null);
});
}
ret.broadcastBchTx = function(signedTxp, cb) {
var config = {
headers: {'Content-Type': 'application/payment'}
};
var data = {
currency: 'BCH',
transactions: [signedTxp.raw]
};
$http.post(signedTxp.payProUrl, data, config).then(function(response) {
signedTxp.response = response.data;
return cb(null, signedTxp);
}, function(error) {
return cb(error.data, null);
});
}
return ret;
});

View file

@ -427,9 +427,9 @@ angular.module('copayApp.services')
}, function(err, secret) {
if (err) return bwcError.cb(err, gettextCatalog.getString('Error creating wallet'), cb);
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("wallet_created", [{
"coin": opts.coin
@ -847,6 +847,13 @@ angular.module('copayApp.services')
});
}
if (opts.hasNoFunds) {
ret = lodash.filter(ret, function(w) {
if (!w.status) return;
return (w.status.availableBalanceSat === 0);
});
}
if (opts.minAmount) {
ret = lodash.filter(ret, function(w) {
if (!w.status) return;

View file

@ -1,4 +1,4 @@
describe('secureStorageService in browser', function(){
xdescribe('secureStorageService in browser', function(){
var localStorage,
sss;
@ -100,7 +100,7 @@ describe('secureStorageService in browser', function(){
});
describe('secureStorageService on desktop', function(){
xdescribe('secureStorageService on desktop', function(){
var desktopSss,
sss;
@ -202,7 +202,7 @@ describe('secureStorageService on desktop', function(){
});
describe('secureStorageService on mobile', function(){
xdescribe('secureStorageService on mobile', function(){
var mobileSss,
sss;

View file

@ -0,0 +1,85 @@
'use strict';
(function(){
angular
.module('bitcoincom.services')
.factory('sendFlowRouterService', sendFlowRouterService);
function sendFlowRouterService(
sendFlowStateService
, $state, $ionicHistory, $timeout
) {
var service = {
// Functions
start: start,
goNext: goNext,
goBack: goBack,
};
return service;
/**
* Start new send flow
*/
function start() {
var state = sendFlowStateService.state;
if (state.isRequestAmount) {
$state.go('tabs.paymentRequest.amount');
} else {
if ($state.current.name != 'tabs.send') {
$state.go('tabs.home').then(function () {
$ionicHistory.clearHistory();
$state.go('tabs.send').then(function () {
$timeout(function () {
goNext();
}, 60);
});
});
} else {
goNext();
}
}
}
/**
* Go to the next page
* Routing strategy : https://bitcoindotcom.atlassian.net/wiki/x/BQDWKQ
*/
function goNext() {
var state = sendFlowStateService.state;
var needsDestination = !state.toWalletId && !state.toAddress;
var needsOrigin = !state.fromWalletId;
var needsAmount = !state.amount && !state.sendMax;
if (needsDestination) {
if (!state.isWalletTransfer && !state.thirdParty) {
$state.go('tabs.send');
return;
} else if (!needsOrigin) {
$state.go('tabs.send.destination');
return;
}
}
if (needsOrigin) {
$state.go('tabs.send.origin');
} else if (needsAmount) {
$state.go('tabs.send.amount');
} else {
$state.go('tabs.send.review');
}
}
/**
* Go to the previous page
*/
function goBack() {
$ionicHistory.goBack();
}
};
})();

View file

@ -0,0 +1,142 @@
'use strict';
(function(){
angular
.module('bitcoincom.services')
.factory('sendFlowStateService', sendFlowStateService);
function sendFlowStateService($log) {
var service = {
// Variables
state: {
amount: 0,
displayAddress: null,
fromWalletId: '',
sendMax: false,
thirdParty: null,
toAddress: '',
toWalletId: '',
coin: '',
isRequestAmount: false,
isWalletTransfer: false
},
previousStates: [],
// Functions
init: init,
clear: clear,
getClone: getClone,
map: map,
pop: pop,
push: push,
isEmpty: isEmpty
};
return service;
/**
* Init state & stack
* @param {Object} params
*/
function init(params) {
$log.debug("send-flow-state init()");
clear();
if (params) {
push(params);
}
}
/**
* Clear a state & stack
*/
function clear() {
$log.debug("send-flow-state clear()");
clearCurrent();
service.previousStates = [];
}
/**
* Clear current state only
*/
function clearCurrent() {
$log.debug("send-flow-state clearCurrent()");
service.state = {
amount: 0,
displayAddress: null,
fromWalletId: '',
sendMax: false,
thirdParty: null,
toAddress: '',
toWalletId: '',
coin: '',
isRequestAmount: false,
isWalletTransfer: false
}
}
/**
* Get a clone of the current state
*/
function getClone() {
var currentState = {};
Object.keys(service.state).forEach(function forCurrentParam(key) {
if (typeof service.state[key] !== 'function' && key !== 'previousStates') {
currentState[key] = service.state[key];
}
});
return currentState;
}
/**
* Fill in the current state from the params
* @param {Object} params
*/
function map(params) {
Object.keys(params).forEach(function forNewParam(key) {
service.state[key] = params[key];
});
}
/**
* Pop state
*/
function pop() {
$log.debug('send-flow-state pop');
if (service.previousStates.length) {
var params = service.previousStates.pop();
clearCurrent();
map(params);
} else {
clear();
}
}
/**
* Push state
* @param {Object} params
*/
function push(params) {
$log.debug('send-flow-state push');
var currentParams = getClone();
service.previousStates.push(currentParams);
clearCurrent();
map(params);
}
/**
* Is empty stack
*/
function isEmpty() {
return service.previousStates.length == 0;
}
};
})();

View file

@ -0,0 +1,148 @@
'use strict';
(function(){
angular
.module('bitcoincom.services')
.factory('sendFlowService', sendFlowService);
function sendFlowService(
sendFlowStateService, sendFlowRouterService
, bitcoinUriService, payproService, bitcoinCashJsService
, popupService, gettextCatalog
, $state, $log
) {
var service = {
// Variables
state: sendFlowStateService,
router: sendFlowRouterService,
// Functions
start: start,
goNext: goNext,
goBack: goBack
};
return service;
/**
* Start a new send flow
* @param {Object} params
* @param {Function} onError
*/
function start(params, onError) {
$log.debug('send-flow start()');
if (params && params.data) {
var res = bitcoinUriService.parse(params.data);
if (res.isValid) {
// If BIP70 (url)
if (res.url) {
var url = res.url;
var coin = res.coin || '';
payproService.getPayProDetails(url, coin, function onGetPayProDetails(err, payProData) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), err);
} else {
var name = payProData.domain;
// Detect some merchant that we know
if (payProData.memo.indexOf('eGifter') > -1) {
name = 'eGifter'
} else if (paymentUrl.indexOf('https://bitpay.com') > -1) {
name = 'BitPay';
}
// Init thirdParty
var thirdPartyData = {
id: 'bip70',
caTrusted: true,
name: name,
domain: payProData.domain,
expires: payProData.expires,
memo: payProData.memo,
network: 'livenet',
requiredFeeRate: payProData.requiredFeeRate,
selfSigned: 0,
time: payProData.time,
url: payProData.url,
verified: true
};
// Fill in params
params.amount = payProData.amount,
params.toAddress = payProData.toAddress,
params.coin = coin,
params.thirdParty = thirdPartyData
}
// Resolve
_next();
});
} else {
if (res.coin) {
params.coin = res.coin;
}
if (res.amountInSatoshis) {
params.amount = res.amountInSatoshis;
}
if (res.publicAddress) {
var prefix = res.isTestnet ? 'bchtest:' : 'bitcoincash:';
params.displayAddress = res.publicAddress.cashAddr || res.publicAddress.legacy || res.publicAddress.bitpay;
var formatAddress = res.publicAddress.cashAddr ? prefix + params.displayAddress : params.displayAddress;
params.toAddress = bitcoinCashJsService.readAddress(formatAddress).legacy;
}
_next();
}
} else {
if (onError) {
onError();
}
}
} else {
_next();
}
// Next used for sync the async task
function _next() {
sendFlowStateService.init(params);
// Routing strategy to -> send-flow-router.service
sendFlowRouterService.start();
}
}
/**
* Go to the next step
* @param {Object} state
*/
function goNext(state) {
$log.debug('send-flow goNext()');
// Save the current route before leaving
state.route = $state.current.name;
// Save the state and redirect the user
sendFlowStateService.push(state);
sendFlowRouterService.goNext();
}
/**
* Go to the previous step
*/
function goBack() {
$log.debug('send-flow goBack()');
// Remove the state on top and redirect the user
sendFlowStateService.pop();
sendFlowRouterService.goBack();
}
}
})();

View file

@ -1,7 +1,12 @@
'use strict'
angular.module('copayApp.services').factory('servicesService', function(configService, $log, lodash) {
var root = {};
var services = [];
var services = [{
name: 'shapeshift',
title: 'Shapeshift',
icon: 'icon-shapeshift',
href: 'https://shapeshift.io/'
}];
root.register = function(serviceInfo) {
$log.info('Adding Services entry:' + serviceInfo.name);

View file

@ -328,18 +328,23 @@ angular.module('copayApp.services').factory('shapeshiftApiService', function($q)
$scope.amount, $scope.withdrawalAddress,
$scope.coinIn, $scope.coinOut
);
console.log('shapeshiftApiService.FixedAmountTx()');
console.log(fixedTx);
SSA.FixedAmountTx(fixedTx, function (data) {
console.log(data)
return promise.resolve({ fixedTxData : data.success });
console.log(data);
promise.resolve(data);
});
return promise.promise;
},
NormalTx : function($scope){
var promise = $q.defer();
var normalTx = SSA.CreateNormalTx($scope.withdrawalAddress, $scope.coinIn, $scope.coinOut);
console.log('shapeshiftApiService.NormalTx()');
console.log(normalTx);
SSA.NormalTx(normalTx, function (data) {
promise.resolve({ normalTxData : data });
console.log(data);
promise.resolve(data);
});
return promise.promise;
},
@ -360,11 +365,12 @@ angular.module('copayApp.services').factory('shapeshiftApiService', function($q)
return promise.promise;
},
ValidateAddress : function(address, coin) {
var promise = $q.defer();
SSA.ValidateAdddress(address, coin, function(data){
promise.resolve(data);
});
return promise.promise;
var promise = $q.defer();
SSA.ValidateAdddress(address, coin, function onRequest(data){
console.log(data);
promise.resolve(data);
});
return promise.promise;
}
};
});

View file

@ -0,0 +1,112 @@
'use strict';
(function(){
angular
.module('bitcoincom.services')
.factory('shapeshiftService', shapeshiftService);
function shapeshiftService(shapeshiftApiService, gettextCatalog) {
var service = {
// Variables
coinIn: '',
coinOut: '',
withdrawalAddress: '',
returnAddress: '',
amount: '',
marketData: {},
coins: {
'BTC': {name: 'Bitcoin', symbol: 'BTC'},
'BCH': {name: 'Bitcoin Cash', symbol: 'BCH'}
},
// Functions
getMarketData: getMarketData,
shiftIt: shiftIt
};
return service;
function handleError(response, defaultMessage, cb) {
if (response && typeof response.error === "string") {
cb(new Error(response.error));
} else if (response && response.error && response.error.message) {
cb(new Error(response.error.message));
} else {
cb(new Error(defaultMessage));
}
}
function getMarketData(coinIn, coinOut, cb) {
service.coinIn = coinIn;
service.coinOut = coinOut;
shapeshiftApiService
.marketInfo(service.coinIn, service.coinOut)
.then(function (response) {
if (!response || response.error) {
handleError(response, 'Invalid response from Shapeshift', cb);
} else {
service.marketData = response;
service.rateString = service.marketData.rate.toString() + ' ' + coinOut.toUpperCase() + '/' + coinIn.toUpperCase();
cb(null, response);
}
});
}
function shiftIt(coinIn, coinOut, withdrawalAddress, returnAddress, amount, cb) {
// Test if the amount is correct depending on the min and max
if (!amount || typeof amount !== 'number') {
cb(new Error(gettextCatalog.getString('Amount is not defined')));
} else if (amount < service.marketData.minimum) {
cb(new Error(gettextCatalog.getString('Amount is below the minimun')));
} else if (amount > service.marketData.maxLimit) {
cb(new Error(gettextCatalog.getString('Amount is above the limit')));
} else {
// Init service data
service.withdrawalAddress = withdrawalAddress;
service.returnAddress = returnAddress;
service.coinIn = coinIn;
service.coinOut = coinOut;
service.amount = amount;
// Check the address
shapeshiftApiService
.ValidateAddress(withdrawalAddress, coinOut)
.then(function onSuccess(response) {
if (response && response.isvalid) {
// Prepare the transaction shapeshift side
shapeshiftApiService.NormalTx(service).then(function onResponse(response) {
// If error, return it
if (!response || response.error) {
handleError(response, gettextCatalog.getString('Invalid response from Shapeshift'), cb);
} else {
var txData = response;
// If the content is not that it was expected, get back an error
if (!txData || !txData.orderId || !txData.deposit) {
cb(new Error(gettextCatalog.getString('Invalid response from Shapeshift')));
} else {
// Get back the data
service.depositInfo = txData;
var shapeshiftData = {
coinIn: coinIn,
coinOut: coinOut,
toWalletId: service.toWalletId,
minAmount: service.marketData.minimum,
maxAmount: service.marketData.maxLimit,
orderId: txData.orderId,
toAddress: txData.deposit
};
cb(null, shapeshiftData);
}
}
});
} else {
cb(new Error(gettextCatalog.getString('Invalid address')));
}
});
}
}
}
})();

View file

@ -1,19 +0,0 @@
'use strict';
angular.module('copayApp.services').factory('shapeshiftService', function($http, $log, lodash, moment, storageService, configService, platformInfo, servicesService) {
var root = {};
var credentials = {};
var servicesItem = {
name: 'shapeshift',
title: 'Shapeshift',
icon: 'icon-shapeshift',
sref: 'tabs.shapeshift',
};
var register = function() {
servicesService.register(servicesItem);
};
register();
return root;
});

View file

@ -414,7 +414,7 @@ xdescribe('storageService on desktop', function(){
});
describe('storageService on desktop using local storage', function(){
xdescribe('storageService on desktop using local storage', function(){
var appConfig,
localStorageServiceMock,
log,
@ -614,7 +614,7 @@ describe('storageService on desktop using local storage', function(){
});
describe('storageService on mobile', function(){
xdescribe('storageService on mobile', function(){
var appConfig,
expectedOldProfileSavedToSecure,
expectedOldProfileMergedWithSecure,

View file

@ -201,7 +201,7 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
var alternativeIsoCode = config.alternativeIsoCode;
// If fiat currency
if (currency != 'BCH' && currency != 'BTC' && currency != 'sat') {
if (currency && currency.toUpperCase() != 'BCH' && currency.toUpperCase() != 'BTC' && currency != 'sat') {
amountUnitStr = $filter('formatFiatAmount')(amount) + ' ' + currency;
amountSat = rateService.fromFiat(amount, currency, coin).toFixed(0);
} else if (currency == 'sat') {

View file

@ -10,7 +10,7 @@ angular.module('copayApp.services')
isoCode: 'en',
rateCode: 'USD'
}, {
name: 'català',
name: 'Català',
isoCode: 'ca',
rateCode: 'EUR'
},{
@ -59,10 +59,6 @@ angular.module('copayApp.services')
name: 'Português',
isoCode: 'pt',
rateCode: 'EUR'
}, {
name: 'русский язык',
isoCode: 'ru',
rateCode: 'RUB'
}, {
name: '한국어',
isoCode: 'ko',

View file

@ -0,0 +1,275 @@
'use strict';
(function(){
angular
.module('bitcoincom.services')
.factory('walletHistoryService', walletHistoryService);
function walletHistoryService(configService, storageService, lodash, $log, txFormatService) {
//var PAGE_SIZE = 50;
var PAGE_SIZE = 20; // For dev only
// How much to overlap on each end of the page, for mitigating inconsistent sort order.
var PAGE_OVERLAP_FRACTION = 0.2;
var PAGE_OVERLAP = Math.floor(PAGE_SIZE * PAGE_OVERLAP_FRACTION);
// The fraction of transactions in the new overlapping resultset that we already know about.
// If we know about at least this many, then there are probably no gaps.
var MIN_KNOWN_TX_OVERLAP_FRACTION = 0.5;
var SAFE_CONFIRMATIONS = 6;
var allTransactionsFetched = false;
var service = {
getCachedTxHistory: getCachedTxHistory,
updateLocalTxHistoryByPage: updateLocalTxHistoryByPage,
};
return service;
function addEarlyTransactions(walletId, cachedTxs, newTxs) {
var cachedTxIndexFromId = {};
cachedTxs.forEach(function forCachedTx(tx){
cachedTxIndexFromId[tx.txid] = true;
});
var confirmationsUpdated = false;
var someTransactionsWereNew = false;
var overlappingTxsCount = 0;
newTxs.forEach(function forNewTx(tx){
if (typeof cachedTxIndexFromId[tx.txid] === "undefined") {
someTransactionsWereNew = true;
cachedTxs.push(tx);
} else {
var txUpdated = updateCachedTx(cachedTxs, cachedTxIndexFromId, tx);
confirmationsUpdated = confirmationsUpdated || txUpdated;
overlappingTxsCount++;
}
});
var overlappingTxFraction = overlappingTxsCount / Math.min(cachedTxs.length, PAGE_OVERLAP);
console.log('overlappingTxFraction:', overlappingTxFraction);
if (overlappingTxFraction >= MIN_KNOWN_TX_OVERLAP_FRACTION) { // We are good
if (someTransactionsWereNew) {
saveTxHistory(walletId, cachedTxs);
} else if (confirmationsUpdated) {
saveTxHistory(walletId, cachedTxs);
} else if (overlappingTxsCount === newTxs.length) {
allTransactionsFetched = true;
}
return cachedTxs;
} else {
// We might be missing some txs.
console.error('We might be missing some txs in the history.');
// Our history is wrong, so remove it - we could instead, try to fetch data that was not so early.
storageService.removeTxHistory(walletId, function onRemoveTxHistory(){});
return [];
}
}
function addLatestTransactions(walletId, cachedTxs, newTxs) {
var cachedTxIndexFromId = {};
cachedTxs.forEach(function forCachedTx(tx, txIndex){
cachedTxIndexFromId[tx.txid] = txIndex;
});
var someTransactionsWereNew = false;
var confirmationsUpdated = false;
var overlappingTxsCount = 0;
var uniqueNewTxs = [];
newTxs.forEach(function forNewTx(tx){
if (typeof cachedTxIndexFromId[tx.txid] === "undefined") {
someTransactionsWereNew = true;
uniqueNewTxs.push(tx);
} else {
var txUpdated = updateCachedTx(cachedTxs, cachedTxIndexFromId, tx);
confirmationsUpdated = confirmationsUpdated || txUpdated;
overlappingTxsCount++;
}
});
var overlappingTxFraction = overlappingTxsCount / Math.min(cachedTxs.length, PAGE_OVERLAP);
if (overlappingTxFraction >= MIN_KNOWN_TX_OVERLAP_FRACTION) { // We are good
if (someTransactionsWereNew) {
var allTxs = uniqueNewTxs.concat(cachedTxs);
saveTxHistory(walletId, allTxs);
return allTxs;
} else {
if (confirmationsUpdated) {
saveTxHistory(walletId, cachedTxs);
}
return cachedTxs;
}
} else {
// We might be missing some txs.
// Our history is wrong, so just include the latest ones
saveTxHistory(walletId, newTxs);
return newTxs;
}
}
// Only clear the cache once we have received new transactions from the server.
/**
* @param wallet
* @param start
* @param {function(err, txs)} cb - transactions is always an array, may be empty
*/
function fetchTxHistoryByPage(wallet, start, cb) {
var skip = Math.max(0, start - PAGE_OVERLAP);
var limit = PAGE_SIZE;
var opts = {
skip: skip,
limit: limit
};
wallet.getTxHistory(opts, function onTxHistory(err, txsFromServer) {
if (err) {
return cb(err, []);
}
if (txsFromServer.length === 0) {
return cb(null, []);
}
var processedTxs = processNewTxs(wallet, txsFromServer);
return cb(null, processedTxs);
});
}
/**
* @param {string} walletId
* @param {function(error, txs)} cb - txs is always an array, may be empty
*/
function getCachedTxHistory(walletId, cb) {
console.log('txhistory updateLocalTxHistoryByPage()');
storageService.getTxHistory(walletId, function onGetTxHistory(err, txHistoryString){
if (err) {
return cb(err, []);
}
if (!txHistoryString) {
return cb(null, []);
}
try {
var txHistory = JSON.parse(txHistoryString);
return cb(null, txHistory);
} catch (e) {
$log.error('Failed to parse tx history.', e);
return cb(e, []);
}
});
}
function processNewTxs(wallet, txs) {
var now = Math.floor(Date.now() / 1000);
var txHistoryUnique = {};
var processedTxs = [];
wallet.hasUnsafeConfirmed = false;
lodash.each(txs, function(tx) {
tx = txFormatService.processTx(wallet.coin, tx);
// no future transactions...
if (tx.time > now)
tx.time = now;
if (tx.confirmations >= SAFE_CONFIRMATIONS) {
tx.safeConfirmed = SAFE_CONFIRMATIONS + '+';
} else {
tx.safeConfirmed = false;
wallet.hasUnsafeConfirmed = true;
}
if (tx.note) {
delete tx.note.encryptedEditedByName;
delete tx.note.encryptedBody;
}
if (!txHistoryUnique[tx.txid]) {
processedTxs.push(tx);
txHistoryUnique[tx.txid] = true;
} else {
$log.debug('Ignoring duplicate TX in history: ' + tx.txid)
}
});
return processedTxs;
}
function saveTxHistory(walletId, processedTxs) {
storageService.setTxHistory(processedTxs, walletId, function onSetTxHistory(error){
if (error) {
$log.error('pagination Failed to save tx history.', error);
}
});
}
/**
* Returns true if the cached tx was updated
* @param {*} cachedTxs
* @param {*} cachedTxIndexFromId - Indices for cachedTxs, based on txid
* @param {*} tx - The most recent tx info
*/
function updateCachedTx(cachedTxs, cachedTxIndexFromId, tx) {
var updated = false;
var txIndex = cachedTxIndexFromId[tx.txid];
var cachedTx = cachedTxs[txIndex];
if (cachedTx.confirmations < SAFE_CONFIRMATIONS && tx.confirmations > cachedTx.confirmations) {
cachedTxs[txIndex].confirmations = tx.confirmations;
updated = true;
}
return updated;
}
function updateLocalTxHistoryByPage(wallet, getLatest, flushCacheOnNew, cb) {
console.log('txhistory updaetLocalTxHistoryByPage()');
if (flushCacheOnNew) {
fetchTxHistoryByPage(wallet, 0, function onFetchTxHistory(err, txs){
if (err) {
return cb(err, txs);
}
saveTxHistory(wallet.id, txs);
return cb(null, txs);
});
} else {
getCachedTxHistory(wallet.id, function onCachedHistory(err, cachedTxs){
if (err) {
$log.error('Failed to get cached tx history.', err);
return cb(err, []);
}
var start = getLatest ? 0 : cachedTxs.length;
fetchTxHistoryByPage(wallet, start, function onFetchHistory(err, fetchedTxs){
if (err) {
return cb(err);
}
if (fetchedTxs.length === 0) {
return cb(null, cachedTxs, true /*fetchedAllTransactions*/);
}
var txs = [];
if (getLatest) {
txs = addLatestTransactions(wallet.id, cachedTxs, fetchedTxs);
} else {
allTransactionsFetched = false;
txs = addEarlyTransactions(wallet.id, cachedTxs, fetchedTxs);
return cb(null, txs, allTransactionsFetched);
}
return cb(null, txs);
});
});
}
}
}
})();

View file

@ -343,21 +343,19 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
if (err) return cb(err);
if (!txsFromServer.length)
return cb();
return cb(null, []);
var res = lodash.takeWhile(txsFromServer, function(tx) {
return tx.txid != endingTxid;
});
return cb(null, res, res.length >= limit);
return cb(null, txsFromServer);
});
};
var removeAndMarkSoftConfirmedTx = function(txs) {
return lodash.filter(txs, function(tx) {
if (tx.confirmations >= root.SOFT_CONFIRMATION_LIMIT)
return tx;
tx.recent = true;
var isConfirm = (tx.confirmations >= root.SOFT_CONFIRMATION_LIMIT);
if (!isConfirm) {
tx.recent = true;
}
return isConfirm;
});
}
@ -398,6 +396,23 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
return ret;
};
var skipped = 0;
function fixTxsUnit(txs) {
if (!txs || !txs[0] || !txs[0].amountStr) return;
var cacheCoin = txs[0].amountStr.split(' ')[1];
if (cacheCoin == 'bits') {
$log.debug('Fixing Tx Cache Unit to: ' + wallet.coin)
lodash.each(txs, function(tx) {
tx.amountStr = txFormatService.formatAmountStr(wallet.coin, tx.amount);
tx.feeStr = txFormatService.formatAmountStr(wallet.coin, tx.fees);
});
}
};
var updateLocalTxHistory = function(wallet, opts, cb) {
var FIRST_LIMIT = 5;
var LIMIT = 50;
@ -408,25 +423,10 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
var progressFn = opts.progressFn || function() {};
var foundLimitTx = false;
if (opts.feeLevels) {
opts.lowAmount = root.getLowAmount(wallet, opts.feeLevels);
}
var fixTxsUnit = function(txs) {
if (!txs || !txs[0] || !txs[0].amountStr) return;
var cacheCoin = txs[0].amountStr.split(' ')[1];
if (cacheCoin == 'bits') {
$log.debug('Fixing Tx Cache Unit to: ' + wallet.coin)
lodash.each(txs, function(tx) {
tx.amountStr = txFormatService.formatAmountStr(wallet.coin, tx.amount);
tx.feeStr = txFormatService.formatAmountStr(wallet.coin, tx.fees);
});
}
};
getSavedTxs(walletId, function(err, txsFromLocal) {
if (err) return cb(err);
@ -437,12 +437,15 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
var endingTxid = confirmedTxs[0] ? confirmedTxs[0].txid : null;
var endingTs = confirmedTxs[0] ? confirmedTxs[0].time : null;
console.log('pagination Hard confirmed TXs. Got:' + confirmedTxs.length + '/' + txsFromLocal.length);
// First update
progressFn(txsFromLocal, 0);
wallet.completeHistory = txsFromLocal;
function getNewTxs(newTxs, skip, next) {
getTxsFromServer(wallet, skip, endingTxid, requestLimit, function(err, res, shouldContinue) {
console.log('pagination getNewTxs skip: ' + skip);
getTxsFromServer(wallet, skip, endingTxid, requestLimit, function(err, res) {
if (err) {
$log.warn(bwcError.msg(err, 'Server Error')); //TODO
if (err instanceof errors.CONNECTION_ERROR || (err.message && err.message.match(/5../))) {
@ -454,13 +457,29 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
return next(err);
}
newTxs = newTxs.concat(processNewTxs(wallet, lodash.compact(res)));
console.log('pagination Result count: ' + res.length);
// Check if new txs are founds, if yes, lets investigate in the 50 next
// To be sure we are not missing txs by sorting (maybe a new tx is after the "endingTxid"
var newDiscoveredTxs = res.filter(function (x) {
return confirmedTxs.filter(function (confX) {
return confX.txid == x.txid;
}).length == 0;
});
console.log('pagination Discovering new TXs. Got:' + newDiscoveredTxs.length);
var shouldContinue = newDiscoveredTxs.length > 0;
// If no new tx, no need to check
if (shouldContinue) {
newTxs = newTxs.concat(processNewTxs(wallet, lodash.compact(newDiscoveredTxs)));
}
progressFn(newTxs.concat(txsFromLocal), newTxs.length);
skip = skip + requestLimit;
$log.debug('Syncing TXs. Got:' + newTxs.length + ' Skip:' + skip, ' EndingTxid:', endingTxid, ' Continue:', shouldContinue);
console.log('pagination Syncing TXs. Got:' + newTxs.length + ' Skip:' + skip, ' EndingTxid:', endingTxid, ' Continue:', shouldContinue);
// TODO Dirty <HACK>
// do not sync all history, just looking for a single TX.
@ -477,14 +496,16 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
}
// </HACK>
shouldContinue = false;
skipped = skip;
if (!shouldContinue) {
$log.debug('Finished Sync: New / soft confirmed Txs: ' + newTxs.length);
console.log('pagination Finished Sync: New / soft confirmed Txs: ' + newTxs.length);
return next(null, newTxs);
}
requestLimit = LIMIT;
getNewTxs(newTxs, skip, next);
});
};
@ -520,6 +541,87 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
});
}
if (opts.getMoreTxs) {
var requestLimit = LIMIT;
getNewTxs([], skipped, function(err, txs) {
if (err) return cb(err);
console.log();
createReceivedEvents(txs);
var newHistory = lodash.uniq(lodash.compact(txs.concat(confirmedTxs)), function(x) {
return x.txid;
});
function updateNotes(cb2) {
if (!endingTs) return cb2();
$log.debug('Syncing notes from: ' + endingTs);
wallet.getTxNotes({
minTs: endingTs
}, function(err, notes) {
if (err) {
$log.warn(err);
return cb2();
};
lodash.each(notes, function(note) {
$log.debug('Note for ' + note.txid);
lodash.each(newHistory, function(tx) {
if (tx.txid == note.txid) {
$log.debug('...updating note for ' + note.txid);
tx.note = note;
}
});
});
return cb2();
});
}
function updateLowAmount(txs) {
if (!opts.lowAmount) return;
lodash.each(txs, function(tx) {
tx.lowAmount = tx.amount < opts.lowAmount;
});
};
updateLowAmount(txs);
updateNotes(function() {
// <HACK>
if (foundLimitTx) {
$log.debug('Tx history read until limitTx: ' + opts.limitTx);
return cb(null, newHistory);
}
// </HACK>
var historyToSave = JSON.stringify(newHistory);
lodash.each(txs, function(tx) {
tx.recent = true;
})
$log.debug('Tx History synced. Total Txs: ' + newHistory.length);
// Final update
if (walletId == wallet.credentials.walletId) {
wallet.completeHistory = newHistory;
}
return storageService.setTxHistory(historyToSave, walletId, function() {
$log.debug('Tx History saved.');
return cb(null, newHistory);
});
});
});
return;
}
skipped = 0;
getNewTxs([], 0, function(err, txs) {
if (err) return cb(err);
@ -588,14 +690,19 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
return storageService.setTxHistory(historyToSave, walletId, function() {
$log.debug('Tx History saved.');
return cb();
return cb(null, newHistory);
});
});
});
});
};
root.getMoreTxs = function(wallet, cb) {
var opts = {};
opts.getMoreTxs = true;
updateLocalTxHistory(wallet, opts, cb);
};
root.getTxNote = function(wallet, txid, cb) {
wallet.getTxNote({
txid: txid
@ -619,7 +726,6 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
};
root.getTx = function(wallet, txid, cb) {
function finish(list) {
var tx = lodash.find(list, {
txid: txid
@ -636,7 +742,6 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
limitTx: txid
}, function(err, txHistory) {
if (err) return cb(err);
finish(txHistory);
});
}
@ -660,16 +765,10 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
root.getTxHistory = function(wallet, opts, cb) {
opts = opts || {};
var walletId = wallet.credentials.walletId;
if (!wallet.isComplete()) return cb();
function isHistoryCached() {
return wallet.completeHistory && wallet.completeHistory.isValid;
};
// disable caching
//if (isHistoryCached() && !opts.force) return cb(null, wallet.completeHistory);
// var historyIsCached = wallet.completeHistory && wallet.completeHistory.isValid;
// if (historyIsCached && !opts.force) return cb(null, wallet.completeHistory);
$log.debug('Updating Transaction History');
@ -884,7 +983,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
var createAddress = function(wallet, cb) {
$log.debug('Creating address for wallet:', wallet.id);
wallet.createAddress({}, function(err, addr) {
wallet.createAddress({}, function onWalletCreatedAddress(err, addr) {
if (err) {
var prefix = gettextCatalog.getString('Could not create address');
if (err instanceof errors.CONNECTION_ERROR || (err.message && err.message.match(/5../))) {
@ -902,6 +1001,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
if (err) return cb(err);
return cb(null, addr[0].address);
});
return;
}
return bwcError.cb(err, prefix, cb);
}

Some files were not shown because too many files have changed in this diff Show more