Compare commits
	
		
			485 Commits
		
	
	
		
			@0x/testne
			...
			@0x/abi-ge
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					b4a11de097 | ||
| 
						 | 
					a22d78e273 | ||
| 
						 | 
					12bc6f5d58 | ||
| 
						 | 
					b147cd8885 | ||
| 
						 | 
					ca6f99da61 | ||
| 
						 | 
					3eac119399 | ||
| 
						 | 
					8755737344 | ||
| 
						 | 
					cd44470a29 | ||
| 
						 | 
					211163b372 | ||
| 
						 | 
					f44c5b2292 | ||
| 
						 | 
					5d74421e43 | ||
| 
						 | 
					4f4d901eca | ||
| 
						 | 
					6a84877f9a | ||
| 
						 | 
					117e2f583f | ||
| 
						 | 
					b074fe2de5 | ||
| 
						 | 
					3dad385533 | ||
| 
						 | 
					15a12cfa22 | ||
| 
						 | 
					c448a409c1 | ||
| 
						 | 
					dfef33bc41 | ||
| 
						 | 
					27ea271842 | ||
| 
						 | 
					316f3e2e76 | ||
| 
						 | 
					fd73c17db1 | ||
| 
						 | 
					689f8f1fbc | ||
| 
						 | 
					5ffd20214c | ||
| 
						 | 
					3395b8d095 | ||
| 
						 | 
					b388d54962 | ||
| 
						 | 
					c27194a357 | ||
| 
						 | 
					8493d619b4 | ||
| 
						 | 
					adcfe51190 | ||
| 
						 | 
					d71362af99 | ||
| 
						 | 
					a5665a6875 | ||
| 
						 | 
					7a99b2099d | ||
| 
						 | 
					c84e163edb | ||
| 
						 | 
					cde192df0d | ||
| 
						 | 
					d0c009adff | ||
| 
						 | 
					f6abc007ff | ||
| 
						 | 
					88eb642aa5 | ||
| 
						 | 
					8b09286173 | ||
| 
						 | 
					bfe708533f | ||
| 
						 | 
					d7742029c7 | ||
| 
						 | 
					1151371e57 | ||
| 
						 | 
					ecb92a44bc | ||
| 
						 | 
					f7642c06f0 | ||
| 
						 | 
					94d1e427c1 | ||
| 
						 | 
					4181a040b5 | ||
| 
						 | 
					c0d8ceca82 | ||
| 
						 | 
					771f8a6a6c | ||
| 
						 | 
					54b51830d0 | ||
| 
						 | 
					c6e7ad5a53 | ||
| 
						 | 
					6d5f65b77e | ||
| 
						 | 
					370452238f | ||
| 
						 | 
					28df5bfd94 | ||
| 
						 | 
					eb8f7b0ef5 | ||
| 
						 | 
					dfbf10c94b | ||
| 
						 | 
					95b2898b9c | ||
| 
						 | 
					094f710662 | ||
| 
						 | 
					d1186e08b4 | ||
| 
						 | 
					cab71fd4d1 | ||
| 
						 | 
					4cf6fbc6a3 | ||
| 
						 | 
					10da1e24e1 | ||
| 
						 | 
					c30dca6961 | ||
| 
						 | 
					42c441fafa | ||
| 
						 | 
					6861cd7462 | ||
| 
						 | 
					d59027f0bc | ||
| 
						 | 
					d1444f228d | ||
| 
						 | 
					9cc7090e28 | ||
| 
						 | 
					a73522e7f1 | ||
| 
						 | 
					d941901e32 | ||
| 
						 | 
					eb3fda059a | ||
| 
						 | 
					0823bd24d6 | ||
| 
						 | 
					897c15fd28 | ||
| 
						 | 
					006a13448f | ||
| 
						 | 
					88c7d907fa | ||
| 
						 | 
					e8814ecbe7 | ||
| 
						 | 
					f90486c99c | ||
| 
						 | 
					a2bc62b17a | ||
| 
						 | 
					ce4081bb18 | ||
| 
						 | 
					b7a111366b | ||
| 
						 | 
					f6487122d1 | ||
| 
						 | 
					7c9d47451b | ||
| 
						 | 
					8b06b36274 | ||
| 
						 | 
					188e317504 | ||
| 
						 | 
					ecae3f9c48 | ||
| 
						 | 
					543ff7739a | ||
| 
						 | 
					18d24f8db1 | ||
| 
						 | 
					58a65d0ed9 | ||
| 
						 | 
					338594d3e5 | ||
| 
						 | 
					e4f9ae6ad5 | ||
| 
						 | 
					7e2acb6e7e | ||
| 
						 | 
					04e70df330 | ||
| 
						 | 
					eb46570a38 | ||
| 
						 | 
					bb9c21fb14 | ||
| 
						 | 
					245fa95424 | ||
| 
						 | 
					16fa0fdda1 | ||
| 
						 | 
					66261102de | ||
| 
						 | 
					6748c36b03 | ||
| 
						 | 
					d0f20a4fd5 | ||
| 
						 | 
					f5c7a3c26a | ||
| 
						 | 
					cfa748e206 | ||
| 
						 | 
					8284f9c2ba | ||
| 
						 | 
					18fef7ade4 | ||
| 
						 | 
					5fc2483be7 | ||
| 
						 | 
					d5521ea5e0 | ||
| 
						 | 
					cc4ccda623 | ||
| 
						 | 
					389665d3a1 | ||
| 
						 | 
					d160792923 | ||
| 
						 | 
					819ba14303 | ||
| 
						 | 
					b0f2ab45e9 | ||
| 
						 | 
					620f439816 | ||
| 
						 | 
					6a57a7b5be | ||
| 
						 | 
					1f3055c1bc | ||
| 
						 | 
					ec83a1d9e7 | ||
| 
						 | 
					b895b855cb | ||
| 
						 | 
					a770ea56ea | ||
| 
						 | 
					5e66cc8a40 | ||
| 
						 | 
					4fda2a2d04 | ||
| 
						 | 
					e7e9c2a2eb | ||
| 
						 | 
					7619bc4f13 | ||
| 
						 | 
					515b8712a1 | ||
| 
						 | 
					e2ff7b7c84 | ||
| 
						 | 
					209b2c9dcb | ||
| 
						 | 
					cdaa1407da | ||
| 
						 | 
					92706a4b43 | ||
| 
						 | 
					ab245fe7de | ||
| 
						 | 
					f5623632d8 | ||
| 
						 | 
					7de33c5dd9 | ||
| 
						 | 
					180f176716 | ||
| 
						 | 
					a2e1bf0e62 | ||
| 
						 | 
					ad96e953ce | ||
| 
						 | 
					695d1453ac | ||
| 
						 | 
					7c30fd4b2d | ||
| 
						 | 
					5573b092a9 | ||
| 
						 | 
					d16499da4e | ||
| 
						 | 
					c50c4a4669 | ||
| 
						 | 
					32de4862ba | ||
| 
						 | 
					f341626e29 | ||
| 
						 | 
					c2645b26b4 | ||
| 
						 | 
					ce19ec207b | ||
| 
						 | 
					7858dafce4 | ||
| 
						 | 
					0955feb023 | ||
| 
						 | 
					9fd931f799 | ||
| 
						 | 
					57fba86154 | ||
| 
						 | 
					0a3af4eb22 | ||
| 
						 | 
					7fc1a88680 | ||
| 
						 | 
					9f5f31d39f | ||
| 
						 | 
					bda9d4c1b0 | ||
| 
						 | 
					b55ba3a318 | ||
| 
						 | 
					dc655fd903 | ||
| 
						 | 
					82b6a81a22 | ||
| 
						 | 
					f9d13cd43a | ||
| 
						 | 
					771e01162d | ||
| 
						 | 
					61a1a0be97 | ||
| 
						 | 
					3430896eb7 | ||
| 
						 | 
					cd79a2fad1 | ||
| 
						 | 
					f82d16a5b0 | ||
| 
						 | 
					9990f8720c | ||
| 
						 | 
					544ddd44a0 | ||
| 
						 | 
					66b485c7d4 | ||
| 
						 | 
					9ef6f82a95 | ||
| 
						 | 
					a148db5022 | ||
| 
						 | 
					f9a38fcb32 | ||
| 
						 | 
					3f918622bc | ||
| 
						 | 
					6091ee732d | ||
| 
						 | 
					906909e33f | ||
| 
						 | 
					d192a7d466 | ||
| 
						 | 
					096f9decee | ||
| 
						 | 
					ae84dac463 | ||
| 
						 | 
					8c33692560 | ||
| 
						 | 
					44a34ee541 | ||
| 
						 | 
					76f88a0a62 | ||
| 
						 | 
					c1defba429 | ||
| 
						 | 
					c1ad1d203d | ||
| 
						 | 
					3061afdafb | ||
| 
						 | 
					59ad2b75c1 | ||
| 
						 | 
					935e5da78e | ||
| 
						 | 
					28ded5d02d | ||
| 
						 | 
					27258fe3d4 | ||
| 
						 | 
					ad0129fa02 | ||
| 
						 | 
					5911879639 | ||
| 
						 | 
					cc2719492d | ||
| 
						 | 
					d675547208 | ||
| 
						 | 
					d938ba4606 | ||
| 
						 | 
					9a5b52036b | ||
| 
						 | 
					229f11f164 | ||
| 
						 | 
					91f8487947 | ||
| 
						 | 
					0e1e9b27f6 | ||
| 
						 | 
					9787d1085d | ||
| 
						 | 
					1c0569cfc6 | ||
| 
						 | 
					9cc82308e5 | ||
| 
						 | 
					5d6fde356a | ||
| 
						 | 
					96fcbeaba6 | ||
| 
						 | 
					d21487d0c0 | ||
| 
						 | 
					dc90136529 | ||
| 
						 | 
					abaa39a5e2 | ||
| 
						 | 
					4456c3ee14 | ||
| 
						 | 
					a49bf353f8 | ||
| 
						 | 
					05f059492b | ||
| 
						 | 
					13b41c976b | ||
| 
						 | 
					bcb633e5cb | ||
| 
						 | 
					05b74ba1c8 | ||
| 
						 | 
					a918e7099d | ||
| 
						 | 
					12dad41143 | ||
| 
						 | 
					9a0595a607 | ||
| 
						 | 
					37405038e8 | ||
| 
						 | 
					25039a036c | ||
| 
						 | 
					728f70f51b | ||
| 
						 | 
					f9eba65aee | ||
| 
						 | 
					d0a0af5130 | ||
| 
						 | 
					4cba70f32e | ||
| 
						 | 
					5901ee7e96 | ||
| 
						 | 
					09ee7d84f7 | ||
| 
						 | 
					2ad2644b6b | ||
| 
						 | 
					30454fe467 | ||
| 
						 | 
					475698ed92 | ||
| 
						 | 
					274e4b3bcd | ||
| 
						 | 
					a49fc27042 | ||
| 
						 | 
					17f024056a | ||
| 
						 | 
					10e6c3cd90 | ||
| 
						 | 
					cd419edf69 | ||
| 
						 | 
					ac72df4188 | ||
| 
						 | 
					9610ada446 | ||
| 
						 | 
					8ab8c27998 | ||
| 
						 | 
					48ff13e3e2 | ||
| 
						 | 
					25ca3d4c29 | ||
| 
						 | 
					02a975dde4 | ||
| 
						 | 
					aeec8f47ef | ||
| 
						 | 
					fdf9e860de | ||
| 
						 | 
					3f35239b27 | ||
| 
						 | 
					aab9bedd7f | ||
| 
						 | 
					4e4291eccd | ||
| 
						 | 
					7ed44f7b2f | ||
| 
						 | 
					8288e8cce9 | ||
| 
						 | 
					1bb7a28690 | ||
| 
						 | 
					8d1689073b | ||
| 
						 | 
					3052c8d303 | ||
| 
						 | 
					ff295daa5c | ||
| 
						 | 
					bb307a55d3 | ||
| 
						 | 
					ae6202ed3d | ||
| 
						 | 
					0e55f76db8 | ||
| 
						 | 
					667b1e03dd | ||
| 
						 | 
					4f5ab1a72d | ||
| 
						 | 
					6ad8ac6a48 | ||
| 
						 | 
					86febc3cce | ||
| 
						 | 
					e73fceaa20 | ||
| 
						 | 
					cacfcc291a | ||
| 
						 | 
					e1ae551560 | ||
| 
						 | 
					476cbbb6cb | ||
| 
						 | 
					1880c34ce0 | ||
| 
						 | 
					cc7321cb5b | ||
| 
						 | 
					ae64fc15e0 | ||
| 
						 | 
					6f4dbc71f2 | ||
| 
						 | 
					4bd4ff46cf | ||
| 
						 | 
					edfb56de6c | ||
| 
						 | 
					03007e420c | ||
| 
						 | 
					7fa1f25e06 | ||
| 
						 | 
					341d7b3407 | ||
| 
						 | 
					9be4c47499 | ||
| 
						 | 
					9512978de9 | ||
| 
						 | 
					ffecba21f4 | ||
| 
						 | 
					af91a56a55 | ||
| 
						 | 
					51da5311b5 | ||
| 
						 | 
					a414dc9b83 | ||
| 
						 | 
					0f63071696 | ||
| 
						 | 
					951a5271e1 | ||
| 
						 | 
					4c5b26db18 | ||
| 
						 | 
					e1306f55ed | ||
| 
						 | 
					d2bf23de71 | ||
| 
						 | 
					3206e1528b | ||
| 
						 | 
					68182fb6c4 | ||
| 
						 | 
					80711eafeb | ||
| 
						 | 
					cbe595af54 | ||
| 
						 | 
					dcae27c1a4 | ||
| 
						 | 
					3e8d9510ec | ||
| 
						 | 
					a3d4482c4a | ||
| 
						 | 
					1c5745dbd9 | ||
| 
						 | 
					22d0c76bf1 | ||
| 
						 | 
					30809e646b | ||
| 
						 | 
					27d9e516e1 | ||
| 
						 | 
					948d62200a | ||
| 
						 | 
					39f92e4c95 | ||
| 
						 | 
					d5d99b9d2e | ||
| 
						 | 
					4a96dbe085 | ||
| 
						 | 
					ced4c893ba | ||
| 
						 | 
					a2d09a68b0 | ||
| 
						 | 
					98cf046b4c | ||
| 
						 | 
					e3510f3bcf | ||
| 
						 | 
					89e59cca28 | ||
| 
						 | 
					0515a914e0 | ||
| 
						 | 
					f04eba7773 | ||
| 
						 | 
					cd06c0e913 | ||
| 
						 | 
					23b1656692 | ||
| 
						 | 
					d06b40bd8a | ||
| 
						 | 
					de18fa0069 | ||
| 
						 | 
					1a10715fcb | ||
| 
						 | 
					062187f28d | ||
| 
						 | 
					e55d8802e1 | ||
| 
						 | 
					3adc6b6daa | ||
| 
						 | 
					c5e8bb1763 | ||
| 
						 | 
					acefeff5f0 | ||
| 
						 | 
					2a1c2a55ed | ||
| 
						 | 
					45d828e154 | ||
| 
						 | 
					dc3b867b35 | ||
| 
						 | 
					b7f4062ac8 | ||
| 
						 | 
					73f5ea2906 | ||
| 
						 | 
					11bc10a3ae | ||
| 
						 | 
					e45ce4c167 | ||
| 
						 | 
					85b7362073 | ||
| 
						 | 
					46a8aad87a | ||
| 
						 | 
					ab2759f431 | ||
| 
						 | 
					379f7c7883 | ||
| 
						 | 
					c7a063ca47 | ||
| 
						 | 
					db3ad83ebc | ||
| 
						 | 
					979527a5ee | ||
| 
						 | 
					2d9c961d4f | ||
| 
						 | 
					11f7f2d29f | ||
| 
						 | 
					c5554fe30c | ||
| 
						 | 
					6da6540c03 | ||
| 
						 | 
					059868e994 | ||
| 
						 | 
					f89b314a94 | ||
| 
						 | 
					06ba26a6d3 | ||
| 
						 | 
					e50decfa8a | ||
| 
						 | 
					78fb43f59c | ||
| 
						 | 
					09f0bf7f00 | ||
| 
						 | 
					05ce8aa124 | ||
| 
						 | 
					ce5bc3c1c9 | ||
| 
						 | 
					33d8044f02 | ||
| 
						 | 
					fefb64442a | ||
| 
						 | 
					119c4e2dc6 | ||
| 
						 | 
					c1f9f2e8d9 | ||
| 
						 | 
					38f47a380b | ||
| 
						 | 
					8635f8d732 | ||
| 
						 | 
					47737d4d0f | ||
| 
						 | 
					b737313d16 | ||
| 
						 | 
					9c26334eff | ||
| 
						 | 
					2c04ee3f5e | ||
| 
						 | 
					4df8e60f42 | ||
| 
						 | 
					df7a1bd8de | ||
| 
						 | 
					657ae0cf57 | ||
| 
						 | 
					d43f89fa0a | ||
| 
						 | 
					2e184f081e | ||
| 
						 | 
					3cd9f40e63 | ||
| 
						 | 
					8e501e5ec7 | ||
| 
						 | 
					4c4286ac66 | ||
| 
						 | 
					4a72dc6c6f | ||
| 
						 | 
					7ccfa8a8af | ||
| 
						 | 
					751b87af96 | ||
| 
						 | 
					2110ac32b7 | ||
| 
						 | 
					c2e8390d21 | ||
| 
						 | 
					075f3c9bfe | ||
| 
						 | 
					6027e275b1 | ||
| 
						 | 
					a5edb0b421 | ||
| 
						 | 
					da54fc3296 | ||
| 
						 | 
					053e147afc | ||
| 
						 | 
					f0c79473bd | ||
| 
						 | 
					864f89c535 | ||
| 
						 | 
					4db33ba2b3 | ||
| 
						 | 
					37f87ab267 | ||
| 
						 | 
					104b2ed759 | ||
| 
						 | 
					56953320b3 | ||
| 
						 | 
					af2bf053bc | ||
| 
						 | 
					117ee19370 | ||
| 
						 | 
					dcd428a4a2 | ||
| 
						 | 
					e086c7b8e6 | ||
| 
						 | 
					1f0c7f8fbe | ||
| 
						 | 
					b75fe10c79 | ||
| 
						 | 
					b7a5e40c62 | ||
| 
						 | 
					28f0deb3eb | ||
| 
						 | 
					bdf623dab5 | ||
| 
						 | 
					921492e818 | ||
| 
						 | 
					194cbc3ba9 | ||
| 
						 | 
					1ba207f1fe | ||
| 
						 | 
					c5014af7fe | ||
| 
						 | 
					579a49ba91 | ||
| 
						 | 
					071f9a5a73 | ||
| 
						 | 
					4bf1ca0d17 | ||
| 
						 | 
					5e67756037 | ||
| 
						 | 
					48e4452a04 | ||
| 
						 | 
					be97eebe02 | ||
| 
						 | 
					37c5165319 | ||
| 
						 | 
					15ed3b35df | ||
| 
						 | 
					19f9649e74 | ||
| 
						 | 
					d52a04e725 | ||
| 
						 | 
					daf447361f | ||
| 
						 | 
					1a3b1607b1 | ||
| 
						 | 
					2bb53d5b1d | ||
| 
						 | 
					38eaacdd44 | ||
| 
						 | 
					77a4d7e2b7 | ||
| 
						 | 
					dbf75a43c3 | ||
| 
						 | 
					39c7f3dc88 | ||
| 
						 | 
					01f82ddf78 | ||
| 
						 | 
					24b5b35a74 | ||
| 
						 | 
					4dfbc6747e | ||
| 
						 | 
					528ae4376e | ||
| 
						 | 
					e0149618f3 | ||
| 
						 | 
					632d7b6fc1 | ||
| 
						 | 
					b9dccf9da3 | ||
| 
						 | 
					7e24c04c0b | ||
| 
						 | 
					a766d78706 | ||
| 
						 | 
					bf0a4bd91b | ||
| 
						 | 
					51779fec38 | ||
| 
						 | 
					ac2d93ab22 | ||
| 
						 | 
					092d010c2d | ||
| 
						 | 
					30b0770993 | ||
| 
						 | 
					a017f5e385 | ||
| 
						 | 
					6510454337 | ||
| 
						 | 
					d2766d7ced | ||
| 
						 | 
					6c79a858df | ||
| 
						 | 
					f06541ec94 | ||
| 
						 | 
					d5105b5c9f | ||
| 
						 | 
					17b282b1d7 | ||
| 
						 | 
					43ad2fe23b | ||
| 
						 | 
					2c308c0f4c | ||
| 
						 | 
					d8001e696e | ||
| 
						 | 
					aeb607d485 | ||
| 
						 | 
					c070142dc0 | ||
| 
						 | 
					6f80c7e6d9 | ||
| 
						 | 
					48dd9569f7 | ||
| 
						 | 
					c66e2f6704 | ||
| 
						 | 
					b49e5c76e4 | ||
| 
						 | 
					ce4da870d7 | ||
| 
						 | 
					6588cf919e | ||
| 
						 | 
					2f4e498a09 | ||
| 
						 | 
					66465816ca | ||
| 
						 | 
					bce9031868 | ||
| 
						 | 
					100f446031 | ||
| 
						 | 
					0de654bbd5 | ||
| 
						 | 
					eb3a4d2fab | ||
| 
						 | 
					48f1e6057c | ||
| 
						 | 
					d129c922ed | ||
| 
						 | 
					6f2217570f | ||
| 
						 | 
					90ba8e0e8d | ||
| 
						 | 
					669ea191a5 | ||
| 
						 | 
					3f2b6482c3 | ||
| 
						 | 
					16ba01cd2e | ||
| 
						 | 
					7282e3ce03 | ||
| 
						 | 
					977e20edc3 | ||
| 
						 | 
					17643d98aa | ||
| 
						 | 
					724f3b9cf7 | ||
| 
						 | 
					a7a17c85dc | ||
| 
						 | 
					7742df8614 | ||
| 
						 | 
					26cd5ec149 | ||
| 
						 | 
					da0c5dd9d3 | ||
| 
						 | 
					a60cf44d45 | ||
| 
						 | 
					62f219ea74 | ||
| 
						 | 
					c26b3f5dfc | ||
| 
						 | 
					0eb9769cd4 | ||
| 
						 | 
					eca862f818 | ||
| 
						 | 
					3f43f9bb4c | ||
| 
						 | 
					ee6bb229e0 | ||
| 
						 | 
					f3a6800306 | ||
| 
						 | 
					7bc2df5602 | ||
| 
						 | 
					1737411ab7 | ||
| 
						 | 
					7a8adf9db5 | ||
| 
						 | 
					ad6dc8e891 | ||
| 
						 | 
					44635f34f0 | ||
| 
						 | 
					b4fb6b5ff3 | ||
| 
						 | 
					c87e68f833 | ||
| 
						 | 
					ff1f0a9678 | ||
| 
						 | 
					aa0e07b058 | ||
| 
						 | 
					a42347a776 | ||
| 
						 | 
					8ff5e19269 | ||
| 
						 | 
					8a6e077664 | ||
| 
						 | 
					f9d8610383 | ||
| 
						 | 
					b4af27dd44 | ||
| 
						 | 
					9aa6753823 | ||
| 
						 | 
					94ace00e0c | ||
| 
						 | 
					12b6877aeb | ||
| 
						 | 
					65d85ca500 | ||
| 
						 | 
					3f0059d4bb | ||
| 
						 | 
					4b348e1e60 | ||
| 
						 | 
					a764dfa789 | ||
| 
						 | 
					c2038eae5b | ||
| 
						 | 
					c4ae91c7c5 | ||
| 
						 | 
					857eb95ac0 | ||
| 
						 | 
					4fd3f12aeb | ||
| 
						 | 
					a7336d3c65 | ||
| 
						 | 
					f74080fe0d | ||
| 
						 | 
					9f61735f94 | ||
| 
						 | 
					91ca80b248 | ||
| 
						 | 
					59743d32da | ||
| 
						 | 
					e40a4addc9 | ||
| 
						 | 
					ad0fe2f079 | ||
| 
						 | 
					9b4f5dfdda | ||
| 
						 | 
					71a61a4dc3 | ||
| 
						 | 
					1053aed74d | 
@@ -31,7 +31,7 @@ jobs:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
                  keys:
 | 
			
		||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
            - run: cd packages/website && yarn build
 | 
			
		||||
            - run: cd packages/website && yarn build:prod
 | 
			
		||||
    test-contracts-ganache:
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: circleci/node:9
 | 
			
		||||
@@ -162,6 +162,9 @@ jobs:
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: circleci/python
 | 
			
		||||
            - image: 0xorg/ganache-cli
 | 
			
		||||
              command: |
 | 
			
		||||
                  ganache-cli --gasLimit 10000000 --noVMErrorsOnRPCResponse --db /snapshot --noVMErrorsOnRPCResponse -p 8545 --networkId 50 -m "concert load couple harbor equip island argue ramp clarify fence smart topic"
 | 
			
		||||
        steps:
 | 
			
		||||
            - checkout
 | 
			
		||||
            - run: sudo chown -R circleci:circleci /usr/local/bin
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -99,6 +99,7 @@ packages/*/scripts/
 | 
			
		||||
.mypy_cache
 | 
			
		||||
.tox
 | 
			
		||||
python-packages/*/build
 | 
			
		||||
python-packages/*/dist
 | 
			
		||||
__pycache__
 | 
			
		||||
python-packages/*/src/*.egg-info
 | 
			
		||||
python-packages/*/.coverage
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ lib
 | 
			
		||||
/packages/contracts/generated-artifacts
 | 
			
		||||
/packages/abi-gen-wrappers/src/generated-wrappers
 | 
			
		||||
/packages/contract-artifacts/artifacts
 | 
			
		||||
/python-packages/order_utils/src/zero_ex/contract_artifacts/artifacts
 | 
			
		||||
/packages/json-schemas/schemas
 | 
			
		||||
/packages/metacoin/src/contract_wrappers
 | 
			
		||||
/packages/metacoin/artifacts
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								CODEOWNERS
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								CODEOWNERS
									
									
									
									
									
								
							@@ -10,19 +10,26 @@ packages/instant/  @BMillman19 @fragosti @steveklebanoff
 | 
			
		||||
packages/website/  @BMillman19 @fragosti @fabioberger @steveklebanoff
 | 
			
		||||
 | 
			
		||||
# Dev tools & setup
 | 
			
		||||
.circleci/ @LogvinovLeon
 | 
			
		||||
packages/abi-gen/ @LogvinovLeon
 | 
			
		||||
packages/base-contract/ @LogvinovLeon
 | 
			
		||||
packages/connect/ @fragosti 
 | 
			
		||||
packages/contract_templates/ @LogvinovLeon
 | 
			
		||||
packages/contract-addresses/ @albrow
 | 
			
		||||
packages/contract-artifacts/ @albrow
 | 
			
		||||
packages/dev-utils/ @LogvinovLeon @fabioberger
 | 
			
		||||
 | 
			
		||||
packages/devnet/ @albrow
 | 
			
		||||
packages/ethereum-types/ @LogvinovLeon
 | 
			
		||||
packages/metacoin/ @LogvinovLeon
 | 
			
		||||
packages/monorepo-scripts/ @fabioberger
 | 
			
		||||
packages/order-utils/ @fabioberger @LogvinovLeon 
 | 
			
		||||
packages/sol-compiler/ @LogvinovLeon
 | 
			
		||||
packages/sol-cov/ @LogvinovLeon
 | 
			
		||||
packages/sol-resolver/ @LogvinovLeon
 | 
			
		||||
packages/web3-wrapper/ @LogvinovLeon @fabioberger
 | 
			
		||||
.circleci/ @LogvinovLeon
 | 
			
		||||
packages/subproviders/ @fabioberger @dekz
 | 
			
		||||
packages/connect/ @fragosti 
 | 
			
		||||
packages/monorepo-scripts/ @fabioberger
 | 
			
		||||
packages/order-utils/ @fabioberger @LogvinovLeon 
 | 
			
		||||
packages/verdaccio/ @albrow
 | 
			
		||||
packages/web3-wrapper/ @LogvinovLeon @fabioberger
 | 
			
		||||
python-packages/ @feuGeneA
 | 
			
		||||
 | 
			
		||||
# Protocol/smart contracts
 | 
			
		||||
packages/contracts/test/ @albrow
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										58
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								README.md
									
									
									
									
									
								
							@@ -20,29 +20,37 @@ If you're developing on 0x now or are interested in using 0x infrastructure in t
 | 
			
		||||
 | 
			
		||||
### Published Packages
 | 
			
		||||
 | 
			
		||||
| Package                                                  | Version                                                                                                                 | Description                                                                                                               |
 | 
			
		||||
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
 | 
			
		||||
| [`0x.js`](/packages/0x.js)                               | [](https://www.npmjs.com/package/0x.js)                                   | A Javascript library for interacting with the 0x protocol                                                                 |
 | 
			
		||||
| [`@0x/abi-gen`](/packages/abi-gen)                       | [](https://www.npmjs.com/package/@0x/abi-gen)                       | Tool to generate TS wrappers from smart contract ABIs                                                                     |
 | 
			
		||||
| [`@0x/assert`](/packages/assert)                         | [](https://www.npmjs.com/package/@0x/assert)                         | Type and schema assertions used by our packages                                                                           |
 | 
			
		||||
| [`@0x/asset-buyer`](/packages/asset-buyer)               | [](https://www.npmjs.com/package/@0x/asset-buyer)               | Convenience package for discovering and buying assets with Ether.                                                         |
 | 
			
		||||
| [`@0x/base-contract`](/packages/base-contract)           | [](https://www.npmjs.com/package/@0x/base-contract)           | BaseContract used by auto-generated `abi-gen` wrapper contracts                                                           |
 | 
			
		||||
| [`@0x/connect`](/packages/connect)                       | [](https://www.npmjs.com/package/@0x/connect)                       | A Javascript library for interacting with the Standard Relayer API                                                        |
 | 
			
		||||
| [`@0x/dev-utils`](/packages/dev-utils)                   | [](https://www.npmjs.com/package/@0x/dev-utils)                   | Dev utils to be shared across 0x projects and packages                                                                    |
 | 
			
		||||
| [`@0x/json-schemas`](/packages/json-schemas)             | [](https://www.npmjs.com/package/@0x/json-schemas)             | 0x-related json schemas                                                                                                   |
 | 
			
		||||
| [`@0x/monorepo-scripts`](/packages/monorepo-scripts)     | [](https://www.npmjs.com/package/@0x/monorepo-scripts)     | Monorepo scripts                                                                                                          |
 | 
			
		||||
| [`@0x/order-utils`](/packages/order-utils)               | [](https://www.npmjs.com/package/@0x/order-utils)               | A set of utilities for generating, parsing, signing and validating 0x orders.                                             |
 | 
			
		||||
| [`@0x/react-docs`](/packages/react-docs)                 | [](https://www.npmjs.com/package/@0x/react-docs)                 | React documentation component for rendering TypeDoc & Doxity generated JSON                                               |
 | 
			
		||||
| [`@0x/react-shared`](/packages/react-shared)             | [](https://www.npmjs.com/package/@0x/react-shared)             | 0x shared react components                                                                                                |
 | 
			
		||||
| [`@0x/sol-compiler`](/packages/sol-compiler)             | [](https://www.npmjs.com/package/@0x/sol-compiler)             | A thin wrapper around Solc.js that outputs artifacts, resolves imports, only re-compiles when needed, and other niceties. |
 | 
			
		||||
| [`@0x/sol-cov`](/packages/sol-cov)                       | [](https://www.npmjs.com/package/@0x/sol-cov)                       | Solidity test coverage tool                                                                                               |
 | 
			
		||||
| [`@0x/sra-spec`](/packages/sra-spec)                     | [](https://www.npmjs.com/package/@0x/sra-spec)                     | OpenAPI specification for the standard relayer API                                                                        |
 | 
			
		||||
| [`@0x/subproviders`](/packages/subproviders)             | [](https://www.npmjs.com/package/@0x/subproviders)             | Useful web3 subproviders (e.g LedgerSubprovider)                                                                          |
 | 
			
		||||
| [`@0x/tslint-config`](/packages/tslint-config)           | [](https://www.npmjs.com/package/@0x/tslint-config)           | Custom 0x development TSLint rules                                                                                        |
 | 
			
		||||
| [`@0x/types`](/packages/types)                           | [](https://www.npmjs.com/package/@0x/types)                           | Shared type declarations                                                                                                  |
 | 
			
		||||
| [`@0x/typescript-typings`](/packages/typescript-typings) | [](https://www.npmjs.com/package/@0x/typescript-typings) | Repository of types for external packages                                                                                 |
 | 
			
		||||
| [`@0x/utils`](/packages/utils)                           | [](https://www.npmjs.com/package/@0x/utils)                           | Shared utilities                                                                                                          |
 | 
			
		||||
| [`@0x/web3-wrapper`](/packages/web3-wrapper)             | [](https://www.npmjs.com/package/@0x/web3-wrapper)             | Web3 wrapper                                                                                                              |
 | 
			
		||||
| Package                                                  | Version                                                                                                                 | Description                                                                                                              |
 | 
			
		||||
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
 | 
			
		||||
| [`0x.js`](/packages/0x.js)                               | [](https://www.npmjs.com/package/0x.js)                                   | A Javascript library for interacting with the 0x protocol                                                                |
 | 
			
		||||
| [`@0x/abi-gen`](/packages/abi-gen)                       | [](https://www.npmjs.com/package/@0x/abi-gen)                       | Tool to generate TS wrappers from smart contract ABIs                                                                    |
 | 
			
		||||
| [`@0x/abi-gen-wrappers`](/packages/abi-gen-wrappers)     | [](https://www.npmjs.com/package/@0x/abi-gen-wrappers)     | Low-level 0x smart contract wrappers generated using @0x/abi-gen                                                         |
 | 
			
		||||
| [`@0x/assert`](/packages/assert)                         | [](https://www.npmjs.com/package/@0x/assert)                         | Type and schema assertions used by our packages                                                                          |
 | 
			
		||||
| [`@0x/asset-buyer`](/packages/asset-buyer)               | [](https://www.npmjs.com/package/@0x/asset-buyer)               | Convenience package for discovering and buying assets with Ether                                                         |
 | 
			
		||||
| [`@0x/base-contract`](/packages/base-contract)           | [](https://www.npmjs.com/package/@0x/base-contract)           | BaseContract used by auto-generated `abi-gen` wrapper contracts                                                          |
 | 
			
		||||
| [`@0x/connect`](/packages/connect)                       | [](https://www.npmjs.com/package/@0x/connect)                       | A Javascript library for interacting with the Standard Relayer API                                                       |
 | 
			
		||||
| [`@0x/contract-addresses`](/packages/contract-addresses) | [](https://www.npmjs.com/package/@0x/contract-addresses) | Used to get known addresses of deployed 0x contracts                                                                     |
 | 
			
		||||
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts                                                                                  |
 | 
			
		||||
| [`@0x/contract-wrappers`](/packages/contract-wrappers)   | [](https://www.npmjs.com/package/@0x/contract-wrappers)   | Smart TS wrappers for 0x smart contracts                                                                                 |
 | 
			
		||||
| [`@0x/dev-utils`](/packages/dev-utils)                   | [](https://www.npmjs.com/package/@0x/dev-utils)                   | Dev utils to be shared across 0x projects and packages                                                                   |
 | 
			
		||||
| [`@0x/fill-scenarios`](/packages/fill-scenarios)         | [](https://www.npmjs.com/package/@0x/fill-scenarios)         | 0x order fill scenario generation                                                                                        |
 | 
			
		||||
| [`@0x/json-schemas`](/packages/json-schemas)             | [](https://www.npmjs.com/package/@0x/json-schemas)             | 0x-related json schemas                                                                                                  |
 | 
			
		||||
| [`@0x/migrations`](/packages/migrations)                 | [](https://www.npmjs.com/package/@0x/migrations)                 | 0x smart contract migrations                                                                                             |
 | 
			
		||||
| [`@0x/order-utils`](/packages/order-utils)               | [](https://www.npmjs.com/package/@0x/order-utils)               | A set of utilities for generating, parsing, signing and validating 0x orders                                             |
 | 
			
		||||
| [`@0x/order-watcher`](/packages/order-watcher)           | [](https://www.npmjs.com/package/@0x/order-watcher)           | An order watcher daemon that watches for order validity                                                                  |
 | 
			
		||||
| [`@0x/react-docs`](/packages/react-docs)                 | [](https://www.npmjs.com/package/@0x/react-docs)                 | React documentation component for rendering TypeDoc & Doxity generated JSON                                              |
 | 
			
		||||
| [`@0x/react-shared`](/packages/react-shared)             | [](https://www.npmjs.com/package/@0x/react-shared)             | 0x shared react components                                                                                               |
 | 
			
		||||
| [`@0x/sol-compiler`](/packages/sol-compiler)             | [](https://www.npmjs.com/package/@0x/sol-compiler)             | A thin wrapper around Solc.js that outputs artifacts, resolves imports, only re-compiles when needed, and other niceties |
 | 
			
		||||
| [`@0x/sol-cov`](/packages/sol-cov)                       | [](https://www.npmjs.com/package/@0x/sol-cov)                       | Solidity test coverage tool                                                                                              |
 | 
			
		||||
| [`@0x/sol-doc`](/packages/sol-doc)                       | [](https://www.npmjs.com/package/@0x/sol-doc)                       | Solidity documentation generator                                                                                         |
 | 
			
		||||
| [`@0x/sol-resolver`](/packages/sol-resolver)             | [](https://www.npmjs.com/package/@0x/sol-resolver)             | Import resolver for smart contracts dependencies                                                                         |
 | 
			
		||||
| [`@0x/sra-spec`](/packages/sra-spec)                     | [](https://www.npmjs.com/package/@0x/sra-spec)                     | OpenAPI specification for the standard relayer API                                                                       |
 | 
			
		||||
| [`@0x/subproviders`](/packages/subproviders)             | [](https://www.npmjs.com/package/@0x/subproviders)             | Useful web3 subproviders (e.g. LedgerSubprovider)                                                                        |
 | 
			
		||||
| [`@0x/tslint-config`](/packages/tslint-config)           | [](https://www.npmjs.com/package/@0x/tslint-config)           | Custom 0x development TSLint rules                                                                                       |
 | 
			
		||||
| [`@0x/types`](/packages/types)                           | [](https://www.npmjs.com/package/@0x/types)                           | Shared type declarations                                                                                                 |
 | 
			
		||||
| [`@0x/typescript-typings`](/packages/typescript-typings) | [](https://www.npmjs.com/package/@0x/typescript-typings) | Repository of types for external packages                                                                                |
 | 
			
		||||
| [`@0x/utils`](/packages/utils)                           | [](https://www.npmjs.com/package/@0x/utils)                           | Shared utilities                                                                                                         |
 | 
			
		||||
| [`@0x/web3-wrapper`](/packages/web3-wrapper)             | [](https://www.npmjs.com/package/@0x/web3-wrapper)             | Web3 wrapper                                                                                                             |
 | 
			
		||||
 | 
			
		||||
### Private Packages
 | 
			
		||||
 | 
			
		||||
@@ -86,6 +94,10 @@ We strongly recommend that the community help us make improvements and determine
 | 
			
		||||
 | 
			
		||||
Make sure you are using Yarn v1.9.4. To install using brew:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
brew install yarn@1.9.4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Then install dependencies
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "path": "packages/instant/public/main.bundle.js",
 | 
			
		||||
                "maxSize": "500kB"
 | 
			
		||||
                "maxSize": "1000kB"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "ci": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "2.0.1",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "2.0.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v2.0.1 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v2.0.0 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Add support for `eth_signTypedData`. (#1102)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "0x.js",
 | 
			
		||||
    "version": "2.0.0",
 | 
			
		||||
    "version": "2.0.1",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
        "build": "yarn build:all",
 | 
			
		||||
        "build:ci": "yarn build:commonjs",
 | 
			
		||||
        "build:all": "run-p build:umd:prod build:commonjs",
 | 
			
		||||
        "lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/*",
 | 
			
		||||
        "lint": "tslint --format stylish --project .",
 | 
			
		||||
        "test:circleci": "run-s test:coverage",
 | 
			
		||||
        "rebuild_and_test": "run-s build test",
 | 
			
		||||
        "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
 | 
			
		||||
@@ -42,13 +42,12 @@
 | 
			
		||||
    },
 | 
			
		||||
    "license": "Apache-2.0",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/abi-gen": "^1.0.14",
 | 
			
		||||
        "@0x/abi-gen-wrappers": "^1.0.1",
 | 
			
		||||
        "@0x/contract-addresses": "^1.0.1",
 | 
			
		||||
        "@0x/dev-utils": "^1.0.13",
 | 
			
		||||
        "@0x/migrations": "^2.0.0",
 | 
			
		||||
        "@0x/monorepo-scripts": "^1.0.12",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/abi-gen": "^1.0.15",
 | 
			
		||||
        "@0x/abi-gen-wrappers": "^1.0.2",
 | 
			
		||||
        "@0x/contract-addresses": "^1.1.0",
 | 
			
		||||
        "@0x/dev-utils": "^1.0.14",
 | 
			
		||||
        "@0x/migrations": "^2.0.1",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^2.2.42",
 | 
			
		||||
        "@types/node": "*",
 | 
			
		||||
@@ -74,18 +73,18 @@
 | 
			
		||||
        "webpack": "^4.20.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/assert": "^1.0.14",
 | 
			
		||||
        "@0x/base-contract": "^3.0.2",
 | 
			
		||||
        "@0x/contract-wrappers": "^3.0.0",
 | 
			
		||||
        "@0x/order-utils": "^2.0.0",
 | 
			
		||||
        "@0x/order-watcher": "^2.2.0",
 | 
			
		||||
        "@0x/subproviders": "^2.1.0",
 | 
			
		||||
        "@0x/types": "^1.2.0",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.0",
 | 
			
		||||
        "@0x/assert": "^1.0.15",
 | 
			
		||||
        "@0x/base-contract": "^3.0.3",
 | 
			
		||||
        "@0x/contract-wrappers": "^3.0.1",
 | 
			
		||||
        "@0x/order-utils": "^2.0.1",
 | 
			
		||||
        "@0x/order-watcher": "^2.2.1",
 | 
			
		||||
        "@0x/subproviders": "^2.1.1",
 | 
			
		||||
        "@0x/types": "^1.2.1",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.1",
 | 
			
		||||
        "@types/web3-provider-engine": "^14.0.0",
 | 
			
		||||
        "ethereum-types": "^1.1.1",
 | 
			
		||||
        "ethereum-types": "^1.1.2",
 | 
			
		||||
        "ethers": "~4.0.4",
 | 
			
		||||
        "lodash": "^4.17.5",
 | 
			
		||||
        "web3-provider-engine": "14.0.6"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.2",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1539871071,
 | 
			
		||||
        "version": "1.0.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.0.2 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.0.1 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/abi-gen-wrappers",
 | 
			
		||||
    "version": "1.0.1",
 | 
			
		||||
    "version": "1.0.2",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "build": "yarn pre_build && tsc -b",
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
        "lint": "tslint --project .",
 | 
			
		||||
        "lint": "tslint --format stylish --project .",
 | 
			
		||||
        "pre_build": "yarn generate_contract_wrappers",
 | 
			
		||||
        "clean": "shx rm -rf lib wrappers",
 | 
			
		||||
        "generate_contract_wrappers": "abi-gen --abis  ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated-wrappers --backend ethers"
 | 
			
		||||
@@ -30,17 +30,17 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen-wrappers/README.md",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/abi-gen": "^1.0.14",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.0",
 | 
			
		||||
        "ethereum-types": "^1.1.1",
 | 
			
		||||
        "@0x/abi-gen": "^1.0.15",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.1",
 | 
			
		||||
        "ethereum-types": "^1.1.2",
 | 
			
		||||
        "ethers": "~4.0.4",
 | 
			
		||||
        "lodash": "^4.17.5",
 | 
			
		||||
        "shx": "^0.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^3.0.2"
 | 
			
		||||
        "@0x/base-contract": "^3.0.3"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "access": "public"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.15",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1539871071,
 | 
			
		||||
        "version": "1.0.14",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.0.15 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.0.14 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/abi-gen",
 | 
			
		||||
    "version": "1.0.14",
 | 
			
		||||
    "version": "1.0.15",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
    "main": "lib/src/index.js",
 | 
			
		||||
    "types": "lib/src/index.d.ts",
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "lint": "tslint --project .",
 | 
			
		||||
        "lint": "tslint --format stylish --project .",
 | 
			
		||||
        "clean": "shx rm -rf lib",
 | 
			
		||||
        "build": "tsc -b",
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
@@ -31,10 +31,10 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md",
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "chalk": "^2.3.0",
 | 
			
		||||
        "ethereum-types": "^1.1.1",
 | 
			
		||||
        "ethereum-types": "^1.1.2",
 | 
			
		||||
        "glob": "^7.1.2",
 | 
			
		||||
        "handlebars": "^4.0.11",
 | 
			
		||||
        "lodash": "^4.17.5",
 | 
			
		||||
@@ -45,7 +45,7 @@
 | 
			
		||||
        "yargs": "^10.0.3"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@types/glob": "5.0.35",
 | 
			
		||||
        "@types/handlebars": "^4.0.36",
 | 
			
		||||
        "@types/mkdirp": "^0.5.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.15",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1539871071,
 | 
			
		||||
        "version": "1.0.14",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.0.15 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.0.14 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/assert",
 | 
			
		||||
    "version": "1.0.14",
 | 
			
		||||
    "version": "1.0.15",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
        "build": "tsc -b",
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
        "clean": "shx rm -rf lib test_temp",
 | 
			
		||||
        "lint": "tslint --project .",
 | 
			
		||||
        "lint": "tslint --format stylish --project .",
 | 
			
		||||
        "run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --exit",
 | 
			
		||||
        "test": "yarn run_mocha",
 | 
			
		||||
        "rebuild_and_test": "run-s clean build test",
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^2.2.42",
 | 
			
		||||
        "@types/valid-url": "^1.0.2",
 | 
			
		||||
@@ -44,9 +44,9 @@
 | 
			
		||||
        "typescript": "3.0.1"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/json-schemas": "^2.0.0",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/json-schemas": "^2.0.1",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "lodash": "^4.17.5",
 | 
			
		||||
        "valid-url": "^1.0.9"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,37 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "2.2.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "`getAssetBuyerForProvidedOrders` factory function now takes 3 args instead of 4",
 | 
			
		||||
                "pr": 1187
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note":
 | 
			
		||||
                    "the `OrderProvider` now requires a new method `getAvailableMakerAssetDatasAsync` and the `StandardRelayerAPIOrderProvider` requires the network id at init.",
 | 
			
		||||
                "pr": 1203
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "No longer require that provided orders all have the same maker and taker asset data",
 | 
			
		||||
                "pr": 1197
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note":
 | 
			
		||||
                    "Fix bug where `BuyQuoteInfo` objects could return `totalEthAmount` and `feeEthAmount` that were not whole numbers",
 | 
			
		||||
                "pr": 1207
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note":
 | 
			
		||||
                    "Fix bug where default values for `AssetBuyer` public facing methods could get overriden by `undefined` values",
 | 
			
		||||
                "pr": 1207
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Lower default expiry buffer from 5 minutes to 2 minutes",
 | 
			
		||||
                "pr": 1217
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "2.1.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
@@ -25,6 +58,10 @@
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add missing types to public interface",
 | 
			
		||||
                "pr": 1139
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Throw `SignatureRequestDenied` and `TransactionValueTooLow` errors when executing buy",
 | 
			
		||||
                "pr": 1147
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1539871071
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,15 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v2.2.0 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * `getAssetBuyerForProvidedOrders` factory function now takes 3 args instead of 4 (#1187)
 | 
			
		||||
    * the `OrderProvider` now requires a new method `getAvailableMakerAssetDatasAsync` and the `StandardRelayerAPIOrderProvider` requires the network id at init. (#1203)
 | 
			
		||||
    * No longer require that provided orders all have the same maker and taker asset data (#1197)
 | 
			
		||||
    * Fix bug where `BuyQuoteInfo` objects could return `totalEthAmount` and `feeEthAmount` that were not whole numbers (#1207)
 | 
			
		||||
    * Fix bug where default values for `AssetBuyer` public facing methods could get overriden by `undefined` values (#1207)
 | 
			
		||||
    * Lower default expiry buffer from 5 minutes to 2 minutes (#1217)
 | 
			
		||||
 | 
			
		||||
## v2.1.0 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Add `gasLimit` and `gasPrice` as optional properties on `BuyQuoteExecutionOpts`
 | 
			
		||||
@@ -13,6 +22,7 @@ CHANGELOG
 | 
			
		||||
    * Add `gasLimit` and `gasPrice` as optional properties on `BuyQuoteExecutionOpts` (#1116)
 | 
			
		||||
    * Add `docs:json` command to package.json (#1139)
 | 
			
		||||
    * Add missing types to public interface (#1139)
 | 
			
		||||
    * Throw `SignatureRequestDenied` and `TransactionValueTooLow` errors when executing buy (#1147)
 | 
			
		||||
 | 
			
		||||
## v2.0.0 - _October 4, 2018_
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/asset-buyer",
 | 
			
		||||
    "version": "2.1.0",
 | 
			
		||||
    "version": "2.2.0",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "build": "yarn tsc -b",
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
        "lint": "tslint --project .",
 | 
			
		||||
        "lint": "tslint --format stylish --project .",
 | 
			
		||||
        "test": "yarn run_mocha",
 | 
			
		||||
        "rebuild_and_test": "run-s clean build test",
 | 
			
		||||
        "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
 | 
			
		||||
@@ -36,21 +36,21 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/asset-buyer/README.md",
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/assert": "^1.0.14",
 | 
			
		||||
        "@0x/connect": "^3.0.2",
 | 
			
		||||
        "@0x/contract-wrappers": "^3.0.0",
 | 
			
		||||
        "@0x/json-schemas": "^2.0.0",
 | 
			
		||||
        "@0x/order-utils": "^2.0.0",
 | 
			
		||||
        "@0x/subproviders": "^2.1.0",
 | 
			
		||||
        "@0x/types": "^1.2.0",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.0",
 | 
			
		||||
        "ethereum-types": "^1.1.1",
 | 
			
		||||
        "@0x/assert": "^1.0.15",
 | 
			
		||||
        "@0x/connect": "^3.0.3",
 | 
			
		||||
        "@0x/contract-wrappers": "^3.0.1",
 | 
			
		||||
        "@0x/json-schemas": "^2.0.1",
 | 
			
		||||
        "@0x/order-utils": "^2.0.1",
 | 
			
		||||
        "@0x/subproviders": "^2.1.1",
 | 
			
		||||
        "@0x/types": "^1.2.1",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.1",
 | 
			
		||||
        "ethereum-types": "^1.1.2",
 | 
			
		||||
        "lodash": "^4.17.10"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@types/lodash": "^4.14.116",
 | 
			
		||||
        "@types/mocha": "^2.2.42",
 | 
			
		||||
        "@types/node": "*",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { ContractWrappers } from '@0x/contract-wrappers';
 | 
			
		||||
import { ContractWrappers, ContractWrappersError, ForwarderWrapperError } from '@0x/contract-wrappers';
 | 
			
		||||
import { schemas } from '@0x/json-schemas';
 | 
			
		||||
import { SignedOrder } from '@0x/order-utils';
 | 
			
		||||
import { ObjectMap } from '@0x/types';
 | 
			
		||||
@@ -52,16 +52,12 @@ export class AssetBuyer {
 | 
			
		||||
    public static getAssetBuyerForProvidedOrders(
 | 
			
		||||
        provider: Provider,
 | 
			
		||||
        orders: SignedOrder[],
 | 
			
		||||
        feeOrders: SignedOrder[] = [],
 | 
			
		||||
        options: Partial<AssetBuyerOpts> = {},
 | 
			
		||||
    ): AssetBuyer {
 | 
			
		||||
        assert.isWeb3Provider('provider', provider);
 | 
			
		||||
        assert.doesConformToSchema('orders', orders, schemas.signedOrdersSchema);
 | 
			
		||||
        assert.doesConformToSchema('feeOrders', feeOrders, schemas.signedOrdersSchema);
 | 
			
		||||
        assert.areValidProvidedOrders('orders', orders);
 | 
			
		||||
        assert.areValidProvidedOrders('feeOrders', feeOrders);
 | 
			
		||||
        assert.assert(orders.length !== 0, `Expected orders to contain at least one order`);
 | 
			
		||||
        const orderProvider = new BasicOrderProvider(_.concat(orders, feeOrders));
 | 
			
		||||
        const orderProvider = new BasicOrderProvider(orders);
 | 
			
		||||
        const assetBuyer = new AssetBuyer(provider, orderProvider, options);
 | 
			
		||||
        return assetBuyer;
 | 
			
		||||
    }
 | 
			
		||||
@@ -80,7 +76,8 @@ export class AssetBuyer {
 | 
			
		||||
    ): AssetBuyer {
 | 
			
		||||
        assert.isWeb3Provider('provider', provider);
 | 
			
		||||
        assert.isWebUri('sraApiUrl', sraApiUrl);
 | 
			
		||||
        const orderProvider = new StandardRelayerAPIOrderProvider(sraApiUrl);
 | 
			
		||||
        const networkId = options.networkId || constants.DEFAULT_ASSET_BUYER_OPTS.networkId;
 | 
			
		||||
        const orderProvider = new StandardRelayerAPIOrderProvider(sraApiUrl, networkId);
 | 
			
		||||
        const assetBuyer = new AssetBuyer(provider, orderProvider, options);
 | 
			
		||||
        return assetBuyer;
 | 
			
		||||
    }
 | 
			
		||||
@@ -93,10 +90,11 @@ export class AssetBuyer {
 | 
			
		||||
     * @return  An instance of AssetBuyer
 | 
			
		||||
     */
 | 
			
		||||
    constructor(provider: Provider, orderProvider: OrderProvider, options: Partial<AssetBuyerOpts> = {}) {
 | 
			
		||||
        const { networkId, orderRefreshIntervalMs, expiryBufferSeconds } = {
 | 
			
		||||
            ...constants.DEFAULT_ASSET_BUYER_OPTS,
 | 
			
		||||
            ...options,
 | 
			
		||||
        };
 | 
			
		||||
        const { networkId, orderRefreshIntervalMs, expiryBufferSeconds } = _.merge(
 | 
			
		||||
            {},
 | 
			
		||||
            constants.DEFAULT_ASSET_BUYER_OPTS,
 | 
			
		||||
            options,
 | 
			
		||||
        );
 | 
			
		||||
        assert.isWeb3Provider('provider', provider);
 | 
			
		||||
        assert.isValidOrderProvider('orderProvider', orderProvider);
 | 
			
		||||
        assert.isNumber('networkId', networkId);
 | 
			
		||||
@@ -125,19 +123,25 @@ export class AssetBuyer {
 | 
			
		||||
        assetBuyAmount: BigNumber,
 | 
			
		||||
        options: Partial<BuyQuoteRequestOpts> = {},
 | 
			
		||||
    ): Promise<BuyQuote> {
 | 
			
		||||
        const { feePercentage, shouldForceOrderRefresh, slippagePercentage } = {
 | 
			
		||||
            ...constants.DEFAULT_BUY_QUOTE_REQUEST_OPTS,
 | 
			
		||||
            ...options,
 | 
			
		||||
        };
 | 
			
		||||
        const { feePercentage, shouldForceOrderRefresh, slippagePercentage } = _.merge(
 | 
			
		||||
            {},
 | 
			
		||||
            constants.DEFAULT_BUY_QUOTE_REQUEST_OPTS,
 | 
			
		||||
            options,
 | 
			
		||||
        );
 | 
			
		||||
        assert.isString('assetData', assetData);
 | 
			
		||||
        assert.isBigNumber('assetBuyAmount', assetBuyAmount);
 | 
			
		||||
        assert.isValidPercentage('feePercentage', feePercentage);
 | 
			
		||||
        assert.isBoolean('shouldForceOrderRefresh', shouldForceOrderRefresh);
 | 
			
		||||
        assert.isNumber('slippagePercentage', slippagePercentage);
 | 
			
		||||
        const zrxTokenAssetData = this._getZrxTokenAssetDataOrThrow();
 | 
			
		||||
        const isMakerAssetZrxToken = assetData === zrxTokenAssetData;
 | 
			
		||||
        // get the relevant orders for the makerAsset and fees
 | 
			
		||||
        // if the requested assetData is ZRX, don't get the fee info
 | 
			
		||||
        const [ordersAndFillableAmounts, feeOrdersAndFillableAmounts] = await Promise.all([
 | 
			
		||||
            this._getOrdersAndFillableAmountsAsync(assetData, shouldForceOrderRefresh),
 | 
			
		||||
            this._getOrdersAndFillableAmountsAsync(zrxTokenAssetData, shouldForceOrderRefresh),
 | 
			
		||||
            isMakerAssetZrxToken
 | 
			
		||||
                ? Promise.resolve(constants.EMPTY_ORDERS_AND_FILLABLE_AMOUNTS)
 | 
			
		||||
                : this._getOrdersAndFillableAmountsAsync(zrxTokenAssetData, shouldForceOrderRefresh),
 | 
			
		||||
            shouldForceOrderRefresh,
 | 
			
		||||
        ]);
 | 
			
		||||
        if (ordersAndFillableAmounts.orders.length === 0) {
 | 
			
		||||
@@ -149,6 +153,7 @@ export class AssetBuyer {
 | 
			
		||||
            assetBuyAmount,
 | 
			
		||||
            feePercentage,
 | 
			
		||||
            slippagePercentage,
 | 
			
		||||
            isMakerAssetZrxToken,
 | 
			
		||||
        );
 | 
			
		||||
        return buyQuote;
 | 
			
		||||
    }
 | 
			
		||||
@@ -183,10 +188,11 @@ export class AssetBuyer {
 | 
			
		||||
        buyQuote: BuyQuote,
 | 
			
		||||
        options: Partial<BuyQuoteExecutionOpts> = {},
 | 
			
		||||
    ): Promise<string> {
 | 
			
		||||
        const { ethAmount, takerAddress, feeRecipient, gasLimit, gasPrice } = {
 | 
			
		||||
            ...constants.DEFAULT_BUY_QUOTE_EXECUTION_OPTS,
 | 
			
		||||
            ...options,
 | 
			
		||||
        };
 | 
			
		||||
        const { ethAmount, takerAddress, feeRecipient, gasLimit, gasPrice } = _.merge(
 | 
			
		||||
            {},
 | 
			
		||||
            constants.DEFAULT_BUY_QUOTE_EXECUTION_OPTS,
 | 
			
		||||
            options,
 | 
			
		||||
        );
 | 
			
		||||
        assert.isValidBuyQuote('buyQuote', buyQuote);
 | 
			
		||||
        if (!_.isUndefined(ethAmount)) {
 | 
			
		||||
            assert.isBigNumber('ethAmount', ethAmount);
 | 
			
		||||
@@ -195,6 +201,12 @@ export class AssetBuyer {
 | 
			
		||||
            assert.isETHAddressHex('takerAddress', takerAddress);
 | 
			
		||||
        }
 | 
			
		||||
        assert.isETHAddressHex('feeRecipient', feeRecipient);
 | 
			
		||||
        if (!_.isUndefined(gasLimit)) {
 | 
			
		||||
            assert.isNumber('gasLimit', gasLimit);
 | 
			
		||||
        }
 | 
			
		||||
        if (!_.isUndefined(gasPrice)) {
 | 
			
		||||
            assert.isBigNumber('gasPrice', gasPrice);
 | 
			
		||||
        }
 | 
			
		||||
        const { orders, feeOrders, feePercentage, assetBuyAmount, worstCaseQuoteInfo } = buyQuote;
 | 
			
		||||
        // if no takerAddress is provided, try to get one from the provider
 | 
			
		||||
        let finalTakerAddress;
 | 
			
		||||
@@ -210,21 +222,41 @@ export class AssetBuyer {
 | 
			
		||||
                throw new Error(AssetBuyerError.NoAddressAvailable);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // if no ethAmount is provided, default to the worst ethAmount from buyQuote
 | 
			
		||||
        const txHash = await this._contractWrappers.forwarder.marketBuyOrdersWithEthAsync(
 | 
			
		||||
            orders,
 | 
			
		||||
            assetBuyAmount,
 | 
			
		||||
            finalTakerAddress,
 | 
			
		||||
            ethAmount || worstCaseQuoteInfo.totalEthAmount,
 | 
			
		||||
            feeOrders,
 | 
			
		||||
            feePercentage,
 | 
			
		||||
            feeRecipient,
 | 
			
		||||
            {
 | 
			
		||||
                gasLimit,
 | 
			
		||||
                gasPrice,
 | 
			
		||||
            },
 | 
			
		||||
        );
 | 
			
		||||
        return txHash;
 | 
			
		||||
        try {
 | 
			
		||||
            // if no ethAmount is provided, default to the worst ethAmount from buyQuote
 | 
			
		||||
            const txHash = await this._contractWrappers.forwarder.marketBuyOrdersWithEthAsync(
 | 
			
		||||
                orders,
 | 
			
		||||
                assetBuyAmount,
 | 
			
		||||
                finalTakerAddress,
 | 
			
		||||
                ethAmount || worstCaseQuoteInfo.totalEthAmount,
 | 
			
		||||
                feeOrders,
 | 
			
		||||
                feePercentage,
 | 
			
		||||
                feeRecipient,
 | 
			
		||||
                {
 | 
			
		||||
                    gasLimit,
 | 
			
		||||
                    gasPrice,
 | 
			
		||||
                    shouldValidate: true,
 | 
			
		||||
                },
 | 
			
		||||
            );
 | 
			
		||||
            return txHash;
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            if (_.includes(err.message, ContractWrappersError.SignatureRequestDenied)) {
 | 
			
		||||
                throw new Error(AssetBuyerError.SignatureRequestDenied);
 | 
			
		||||
            } else if (_.includes(err.message, ForwarderWrapperError.CompleteFillFailed)) {
 | 
			
		||||
                throw new Error(AssetBuyerError.TransactionValueTooLow);
 | 
			
		||||
            } else {
 | 
			
		||||
                throw err;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the asset data of all assets that are purchaseable with ether token (wETH) in the order provider passed in at init.
 | 
			
		||||
     *
 | 
			
		||||
     * @return  An array of asset data strings that can be purchased using wETH.
 | 
			
		||||
     */
 | 
			
		||||
    public async getAvailableAssetDatasAsync(): Promise<string[]> {
 | 
			
		||||
        const etherTokenAssetData = this._getEtherTokenAssetDataOrThrow();
 | 
			
		||||
        return this.orderProvider.getAvailableMakerAssetDatasAsync(etherTokenAssetData);
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Grab orders from the map, if there is a miss or it is time to refresh, fetch and process the orders
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import { SignedOrder } from '@0x/types';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
import { AssetBuyerOpts, BuyQuoteExecutionOpts, BuyQuoteRequestOpts } from './types';
 | 
			
		||||
import { AssetBuyerOpts, BuyQuoteExecutionOpts, BuyQuoteRequestOpts, OrdersAndFillableAmounts } from './types';
 | 
			
		||||
 | 
			
		||||
const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
 | 
			
		||||
const MAINNET_NETWORK_ID = 1;
 | 
			
		||||
@@ -8,7 +9,7 @@ const MAINNET_NETWORK_ID = 1;
 | 
			
		||||
const DEFAULT_ASSET_BUYER_OPTS: AssetBuyerOpts = {
 | 
			
		||||
    networkId: MAINNET_NETWORK_ID,
 | 
			
		||||
    orderRefreshIntervalMs: 10000, // 10 seconds
 | 
			
		||||
    expiryBufferSeconds: 300, // 5 minutes
 | 
			
		||||
    expiryBufferSeconds: 120, // 2 minutes
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const DEFAULT_BUY_QUOTE_REQUEST_OPTS: BuyQuoteRequestOpts = {
 | 
			
		||||
@@ -22,6 +23,11 @@ const DEFAULT_BUY_QUOTE_EXECUTION_OPTS: BuyQuoteExecutionOpts = {
 | 
			
		||||
    feeRecipient: NULL_ADDRESS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const EMPTY_ORDERS_AND_FILLABLE_AMOUNTS: OrdersAndFillableAmounts = {
 | 
			
		||||
    orders: [] as SignedOrder[],
 | 
			
		||||
    remainingFillableMakerAssetAmounts: [] as BigNumber[],
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const constants = {
 | 
			
		||||
    ZERO_AMOUNT: new BigNumber(0),
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
@@ -30,5 +36,5 @@ export const constants = {
 | 
			
		||||
    DEFAULT_ASSET_BUYER_OPTS,
 | 
			
		||||
    DEFAULT_BUY_QUOTE_EXECUTION_OPTS,
 | 
			
		||||
    DEFAULT_BUY_QUOTE_REQUEST_OPTS,
 | 
			
		||||
    MAX_PER_PAGE: 10000,
 | 
			
		||||
    EMPTY_ORDERS_AND_FILLABLE_AMOUNTS,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -29,4 +29,13 @@ export class BasicOrderProvider implements OrderProvider {
 | 
			
		||||
        });
 | 
			
		||||
        return { orders };
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Given a taker asset data string, return all availabled paired maker asset data strings.
 | 
			
		||||
     * @param   takerAssetData   A string representing the taker asset data.
 | 
			
		||||
     * @return  An array of asset data strings that can be purchased using takerAssetData.
 | 
			
		||||
     */
 | 
			
		||||
    public async getAvailableMakerAssetDatasAsync(takerAssetData: string): Promise<string[]> {
 | 
			
		||||
        const ordersWithTakerAssetData = _.filter(this.orders, { takerAssetData });
 | 
			
		||||
        return _.map(ordersWithTakerAssetData, order => order.makerAssetData);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import { HttpClient } from '@0x/connect';
 | 
			
		||||
import { APIOrder, OrderbookResponse } from '@0x/types';
 | 
			
		||||
import { APIOrder, AssetPairsResponse, OrderbookResponse } from '@0x/types';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
@@ -14,6 +14,7 @@ import { orderUtils } from '../utils/order_utils';
 | 
			
		||||
 | 
			
		||||
export class StandardRelayerAPIOrderProvider implements OrderProvider {
 | 
			
		||||
    public readonly apiUrl: string;
 | 
			
		||||
    public readonly networkId: number;
 | 
			
		||||
    private readonly _sraClient: HttpClient;
 | 
			
		||||
    /**
 | 
			
		||||
     * Given an array of APIOrder objects from a standard relayer api, return an array
 | 
			
		||||
@@ -30,7 +31,7 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider {
 | 
			
		||||
                'remainingTakerAssetAmount',
 | 
			
		||||
                order.takerAssetAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const remainingFillableMakerAssetAmount = orderUtils.calculateRemainingMakerAssetAmount(
 | 
			
		||||
            const remainingFillableMakerAssetAmount = orderUtils.getRemainingMakerAmount(
 | 
			
		||||
                order,
 | 
			
		||||
                remainingFillableTakerAssetAmount,
 | 
			
		||||
            );
 | 
			
		||||
@@ -44,12 +45,15 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider {
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new StandardRelayerAPIOrderProvider instance
 | 
			
		||||
     * @param   apiUrl  The standard relayer API base HTTP url you would like to source orders from.
 | 
			
		||||
     * @param   apiUrl      The standard relayer API base HTTP url you would like to source orders from.
 | 
			
		||||
     * @param   networkId   The ethereum network id.
 | 
			
		||||
     * @return  An instance of StandardRelayerAPIOrderProvider
 | 
			
		||||
     */
 | 
			
		||||
    constructor(apiUrl: string) {
 | 
			
		||||
    constructor(apiUrl: string, networkId: number) {
 | 
			
		||||
        assert.isWebUri('apiUrl', apiUrl);
 | 
			
		||||
        assert.isNumber('networkId', networkId);
 | 
			
		||||
        this.apiUrl = apiUrl;
 | 
			
		||||
        this.networkId = networkId;
 | 
			
		||||
        this._sraClient = new HttpClient(apiUrl);
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
@@ -59,9 +63,9 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider {
 | 
			
		||||
     */
 | 
			
		||||
    public async getOrdersAsync(orderProviderRequest: OrderProviderRequest): Promise<OrderProviderResponse> {
 | 
			
		||||
        assert.isValidOrderProviderRequest('orderProviderRequest', orderProviderRequest);
 | 
			
		||||
        const { makerAssetData, takerAssetData, networkId } = orderProviderRequest;
 | 
			
		||||
        const { makerAssetData, takerAssetData } = orderProviderRequest;
 | 
			
		||||
        const orderbookRequest = { baseAssetData: makerAssetData, quoteAssetData: takerAssetData };
 | 
			
		||||
        const requestOpts = { networkId };
 | 
			
		||||
        const requestOpts = { networkId: this.networkId };
 | 
			
		||||
        let orderbook: OrderbookResponse;
 | 
			
		||||
        try {
 | 
			
		||||
            orderbook = await this._sraClient.getOrderbookAsync(orderbookRequest, requestOpts);
 | 
			
		||||
@@ -76,4 +80,26 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider {
 | 
			
		||||
            orders,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Given a taker asset data string, return all availabled paired maker asset data strings.
 | 
			
		||||
     * @param   takerAssetData   A string representing the taker asset data.
 | 
			
		||||
     * @return  An array of asset data strings that can be purchased using takerAssetData.
 | 
			
		||||
     */
 | 
			
		||||
    public async getAvailableMakerAssetDatasAsync(takerAssetData: string): Promise<string[]> {
 | 
			
		||||
        // Return a maximum of 1000 asset datas
 | 
			
		||||
        const maxPerPage = 1000;
 | 
			
		||||
        const requestOpts = { networkId: this.networkId, perPage: maxPerPage };
 | 
			
		||||
        const assetPairsRequest = { assetDataA: takerAssetData };
 | 
			
		||||
        const fullRequest = {
 | 
			
		||||
            ...requestOpts,
 | 
			
		||||
            ...assetPairsRequest,
 | 
			
		||||
        };
 | 
			
		||||
        let response: AssetPairsResponse;
 | 
			
		||||
        try {
 | 
			
		||||
            response = await this._sraClient.getAssetPairsAsync(fullRequest);
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            throw new Error(AssetBuyerError.StandardRelayerApiError);
 | 
			
		||||
        }
 | 
			
		||||
        return _.map(response.records, item => item.assetDataB.assetData);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,6 @@ import { BigNumber } from '@0x/utils';
 | 
			
		||||
export interface OrderProviderRequest {
 | 
			
		||||
    makerAssetData: string;
 | 
			
		||||
    takerAssetData: string;
 | 
			
		||||
    networkId: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -27,10 +26,12 @@ export interface SignedOrderWithRemainingFillableMakerAssetAmount extends Signed
 | 
			
		||||
    remainingFillableMakerAssetAmount?: BigNumber;
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * Given an OrderProviderRequest, get an OrderProviderResponse.
 | 
			
		||||
 * gerOrdersAsync: Given an OrderProviderRequest, get an OrderProviderResponse.
 | 
			
		||||
 * getAvailableMakerAssetDatasAsync: Given a taker asset data string, return all availabled paired maker asset data strings.
 | 
			
		||||
 */
 | 
			
		||||
export interface OrderProvider {
 | 
			
		||||
    getOrdersAsync: (orderProviderRequest: OrderProviderRequest) => Promise<OrderProviderResponse>;
 | 
			
		||||
    getAvailableMakerAssetDatasAsync: (takerAssetData: string) => Promise<string[]>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -112,6 +113,8 @@ export enum AssetBuyerError {
 | 
			
		||||
    NoAddressAvailable = 'NO_ADDRESS_AVAILABLE',
 | 
			
		||||
    InvalidOrderProviderResponse = 'INVALID_ORDER_PROVIDER_RESPONSE',
 | 
			
		||||
    AssetUnavailable = 'ASSET_UNAVAILABLE',
 | 
			
		||||
    SignatureRequestDenied = 'SIGNATURE_REQUEST_DENIED',
 | 
			
		||||
    TransactionValueTooLow = 'TRANSACTION_VALUE_TOO_LOW',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface OrdersAndFillableAmounts {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
import { assert as sharedAssert } from '@0x/assert';
 | 
			
		||||
import { schemas } from '@0x/json-schemas';
 | 
			
		||||
import { SignedOrder } from '@0x/types';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { BuyQuote, BuyQuoteInfo, OrderProvider, OrderProviderRequest } from '../types';
 | 
			
		||||
@@ -29,22 +28,6 @@ export const assert = {
 | 
			
		||||
    isValidOrderProviderRequest(variableName: string, orderFetcherRequest: OrderProviderRequest): void {
 | 
			
		||||
        sharedAssert.isHexString(`${variableName}.makerAssetData`, orderFetcherRequest.makerAssetData);
 | 
			
		||||
        sharedAssert.isHexString(`${variableName}.takerAssetData`, orderFetcherRequest.takerAssetData);
 | 
			
		||||
        sharedAssert.isNumber(`${variableName}.networkId`, orderFetcherRequest.networkId);
 | 
			
		||||
    },
 | 
			
		||||
    areValidProvidedOrders(variableName: string, orders: SignedOrder[]): void {
 | 
			
		||||
        if (orders.length === 0) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        const makerAssetData = orders[0].makerAssetData;
 | 
			
		||||
        const takerAssetData = orders[0].takerAssetData;
 | 
			
		||||
        const filteredOrders = _.filter(
 | 
			
		||||
            orders,
 | 
			
		||||
            order => order.makerAssetData === makerAssetData && order.takerAssetData === takerAssetData,
 | 
			
		||||
        );
 | 
			
		||||
        sharedAssert.assert(
 | 
			
		||||
            orders.length === filteredOrders.length,
 | 
			
		||||
            `Expected all orders in ${variableName} to have the same makerAssetData and takerAssetData.`,
 | 
			
		||||
        );
 | 
			
		||||
    },
 | 
			
		||||
    isValidPercentage(variableName: string, percentage: number): void {
 | 
			
		||||
        assert.isNumber(variableName, percentage);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,12 @@
 | 
			
		||||
import { marketUtils, rateUtils } from '@0x/order-utils';
 | 
			
		||||
import { marketUtils, SignedOrder } from '@0x/order-utils';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { constants } from '../constants';
 | 
			
		||||
import { AssetBuyerError, BuyQuote, BuyQuoteInfo, OrdersAndFillableAmounts } from '../types';
 | 
			
		||||
 | 
			
		||||
import { orderUtils } from './order_utils';
 | 
			
		||||
 | 
			
		||||
// Calculates a buy quote for orders that have WETH as the takerAsset
 | 
			
		||||
export const buyQuoteCalculator = {
 | 
			
		||||
    calculate(
 | 
			
		||||
@@ -13,6 +15,7 @@ export const buyQuoteCalculator = {
 | 
			
		||||
        assetBuyAmount: BigNumber,
 | 
			
		||||
        feePercentage: number,
 | 
			
		||||
        slippagePercentage: number,
 | 
			
		||||
        isMakerAssetZrxToken: boolean,
 | 
			
		||||
    ): BuyQuote {
 | 
			
		||||
        const orders = ordersAndFillableAmounts.orders;
 | 
			
		||||
        const remainingFillableMakerAssetAmounts = ordersAndFillableAmounts.remainingFillableMakerAssetAmounts;
 | 
			
		||||
@@ -32,22 +35,31 @@ export const buyQuoteCalculator = {
 | 
			
		||||
        if (remainingFillAmount.gt(constants.ZERO_AMOUNT)) {
 | 
			
		||||
            throw new Error(AssetBuyerError.InsufficientAssetLiquidity);
 | 
			
		||||
        }
 | 
			
		||||
        // if we are not buying ZRX:
 | 
			
		||||
        // given the orders calculated above, find the fee-orders that cover the desired assetBuyAmount (with slippage)
 | 
			
		||||
        // TODO(bmillman): optimization
 | 
			
		||||
        // update this logic to find the minimum amount of feeOrders to cover the worst case as opposed to
 | 
			
		||||
        // finding order that cover all fees, this will help with estimating ETH and minimizing gas usage
 | 
			
		||||
        const {
 | 
			
		||||
            resultFeeOrders,
 | 
			
		||||
            remainingFeeAmount,
 | 
			
		||||
            feeOrdersRemainingFillableMakerAssetAmounts,
 | 
			
		||||
        } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(resultOrders, feeOrders, {
 | 
			
		||||
            remainingFillableMakerAssetAmounts: ordersRemainingFillableMakerAssetAmounts,
 | 
			
		||||
            remainingFillableFeeAmounts,
 | 
			
		||||
        });
 | 
			
		||||
        // if we do not have enough feeOrders to cover the fees, throw
 | 
			
		||||
        if (remainingFeeAmount.gt(constants.ZERO_AMOUNT)) {
 | 
			
		||||
            throw new Error(AssetBuyerError.InsufficientZrxLiquidity);
 | 
			
		||||
        let resultFeeOrders = [] as SignedOrder[];
 | 
			
		||||
        let feeOrdersRemainingFillableMakerAssetAmounts = [] as BigNumber[];
 | 
			
		||||
        if (!isMakerAssetZrxToken) {
 | 
			
		||||
            const feeOrdersAndRemainingFeeAmount = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
 | 
			
		||||
                resultOrders,
 | 
			
		||||
                feeOrders,
 | 
			
		||||
                {
 | 
			
		||||
                    remainingFillableMakerAssetAmounts: ordersRemainingFillableMakerAssetAmounts,
 | 
			
		||||
                    remainingFillableFeeAmounts,
 | 
			
		||||
                },
 | 
			
		||||
            );
 | 
			
		||||
            // if we do not have enough feeOrders to cover the fees, throw
 | 
			
		||||
            if (feeOrdersAndRemainingFeeAmount.remainingFeeAmount.gt(constants.ZERO_AMOUNT)) {
 | 
			
		||||
                throw new Error(AssetBuyerError.InsufficientZrxLiquidity);
 | 
			
		||||
            }
 | 
			
		||||
            resultFeeOrders = feeOrdersAndRemainingFeeAmount.resultFeeOrders;
 | 
			
		||||
            feeOrdersRemainingFillableMakerAssetAmounts =
 | 
			
		||||
                feeOrdersAndRemainingFeeAmount.feeOrdersRemainingFillableMakerAssetAmounts;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // assetData information for the result
 | 
			
		||||
        const assetData = orders[0].makerAssetData;
 | 
			
		||||
        // compile the resulting trimmed set of orders for makerAsset and feeOrders that are needed for assetBuyAmount
 | 
			
		||||
@@ -64,6 +76,7 @@ export const buyQuoteCalculator = {
 | 
			
		||||
            trimmedFeeOrdersAndFillableAmounts,
 | 
			
		||||
            assetBuyAmount,
 | 
			
		||||
            feePercentage,
 | 
			
		||||
            isMakerAssetZrxToken,
 | 
			
		||||
        );
 | 
			
		||||
        // in order to calculate the maxRate, reverse the ordersAndFillableAmounts such that they are sorted from worst rate to best rate
 | 
			
		||||
        const worstCaseQuoteInfo = calculateQuoteInfo(
 | 
			
		||||
@@ -71,6 +84,7 @@ export const buyQuoteCalculator = {
 | 
			
		||||
            reverseOrdersAndFillableAmounts(trimmedFeeOrdersAndFillableAmounts),
 | 
			
		||||
            assetBuyAmount,
 | 
			
		||||
            feePercentage,
 | 
			
		||||
            isMakerAssetZrxToken,
 | 
			
		||||
        );
 | 
			
		||||
        return {
 | 
			
		||||
            assetData,
 | 
			
		||||
@@ -89,22 +103,30 @@ function calculateQuoteInfo(
 | 
			
		||||
    feeOrdersAndFillableAmounts: OrdersAndFillableAmounts,
 | 
			
		||||
    assetBuyAmount: BigNumber,
 | 
			
		||||
    feePercentage: number,
 | 
			
		||||
    isMakerAssetZrxToken: boolean,
 | 
			
		||||
): BuyQuoteInfo {
 | 
			
		||||
    // find the total eth and zrx needed to buy assetAmount from the resultOrders from left to right
 | 
			
		||||
    const [ethAmountToBuyAsset, zrxAmountToBuyAsset] = findEthAndZrxAmountNeededToBuyAsset(
 | 
			
		||||
        ordersAndFillableAmounts,
 | 
			
		||||
        assetBuyAmount,
 | 
			
		||||
    );
 | 
			
		||||
    // find the total eth needed to buy fees
 | 
			
		||||
    const ethAmountToBuyFees = findEthAmountNeededToBuyFees(feeOrdersAndFillableAmounts, zrxAmountToBuyAsset);
 | 
			
		||||
    const affiliateFeeEthAmount = ethAmountToBuyAsset.mul(feePercentage);
 | 
			
		||||
    const totalEthAmountWithoutAffiliateFee = ethAmountToBuyAsset.plus(ethAmountToBuyFees);
 | 
			
		||||
    const totalEthAmount = totalEthAmountWithoutAffiliateFee.plus(affiliateFeeEthAmount);
 | 
			
		||||
    let ethAmountToBuyAsset = constants.ZERO_AMOUNT;
 | 
			
		||||
    let ethAmountToBuyZrx = constants.ZERO_AMOUNT;
 | 
			
		||||
    if (isMakerAssetZrxToken) {
 | 
			
		||||
        ethAmountToBuyAsset = findEthAmountNeededToBuyZrx(ordersAndFillableAmounts, assetBuyAmount);
 | 
			
		||||
    } else {
 | 
			
		||||
        // find eth and zrx amounts needed to buy
 | 
			
		||||
        const ethAndZrxAmountToBuyAsset = findEthAndZrxAmountNeededToBuyAsset(ordersAndFillableAmounts, assetBuyAmount);
 | 
			
		||||
        ethAmountToBuyAsset = ethAndZrxAmountToBuyAsset[0];
 | 
			
		||||
        const zrxAmountToBuyAsset = ethAndZrxAmountToBuyAsset[1];
 | 
			
		||||
        // find eth amount needed to buy zrx
 | 
			
		||||
        ethAmountToBuyZrx = findEthAmountNeededToBuyZrx(feeOrdersAndFillableAmounts, zrxAmountToBuyAsset);
 | 
			
		||||
    }
 | 
			
		||||
    /// find the eth amount needed to buy the affiliate fee
 | 
			
		||||
    const ethAmountToBuyAffiliateFee = ethAmountToBuyAsset.mul(feePercentage).ceil();
 | 
			
		||||
    const totalEthAmountWithoutAffiliateFee = ethAmountToBuyAsset.plus(ethAmountToBuyZrx);
 | 
			
		||||
    const ethAmountTotal = totalEthAmountWithoutAffiliateFee.plus(ethAmountToBuyAffiliateFee);
 | 
			
		||||
    // divide into the assetBuyAmount in order to find rate of makerAsset / WETH
 | 
			
		||||
    const ethPerAssetPrice = totalEthAmountWithoutAffiliateFee.div(assetBuyAmount);
 | 
			
		||||
    return {
 | 
			
		||||
        totalEthAmount,
 | 
			
		||||
        feeEthAmount: affiliateFeeEthAmount,
 | 
			
		||||
        totalEthAmount: ethAmountTotal,
 | 
			
		||||
        feeEthAmount: ethAmountToBuyAffiliateFee,
 | 
			
		||||
        ethPerAssetPrice,
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
@@ -119,29 +141,38 @@ function reverseOrdersAndFillableAmounts(ordersAndFillableAmounts: OrdersAndFill
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function findEthAmountNeededToBuyFees(
 | 
			
		||||
function findEthAmountNeededToBuyZrx(
 | 
			
		||||
    feeOrdersAndFillableAmounts: OrdersAndFillableAmounts,
 | 
			
		||||
    feeAmount: BigNumber,
 | 
			
		||||
    zrxBuyAmount: BigNumber,
 | 
			
		||||
): BigNumber {
 | 
			
		||||
    const { orders, remainingFillableMakerAssetAmounts } = feeOrdersAndFillableAmounts;
 | 
			
		||||
    const result = _.reduce(
 | 
			
		||||
        orders,
 | 
			
		||||
        (acc, order, index) => {
 | 
			
		||||
            const { totalEthAmount, remainingZrxBuyAmount } = acc;
 | 
			
		||||
            const remainingFillableMakerAssetAmount = remainingFillableMakerAssetAmounts[index];
 | 
			
		||||
            const amountToFill = BigNumber.min(acc.remainingFeeAmount, remainingFillableMakerAssetAmount);
 | 
			
		||||
            const feeAdjustedRate = rateUtils.getFeeAdjustedRateOfFeeOrder(order);
 | 
			
		||||
            const ethAmountForThisOrder = feeAdjustedRate.mul(amountToFill);
 | 
			
		||||
            const makerFillAmount = BigNumber.min(remainingZrxBuyAmount, remainingFillableMakerAssetAmount);
 | 
			
		||||
            const [takerFillAmount, adjustedMakerFillAmount] = orderUtils.getTakerFillAmountForFeeOrder(
 | 
			
		||||
                order,
 | 
			
		||||
                makerFillAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const extraFeeAmount = remainingFillableMakerAssetAmount.greaterThanOrEqualTo(adjustedMakerFillAmount)
 | 
			
		||||
                ? constants.ZERO_AMOUNT
 | 
			
		||||
                : adjustedMakerFillAmount.sub(makerFillAmount);
 | 
			
		||||
            return {
 | 
			
		||||
                ethAmount: acc.ethAmount.plus(ethAmountForThisOrder),
 | 
			
		||||
                remainingFeeAmount: BigNumber.max(constants.ZERO_AMOUNT, acc.remainingFeeAmount.minus(amountToFill)),
 | 
			
		||||
                totalEthAmount: totalEthAmount.plus(takerFillAmount),
 | 
			
		||||
                remainingZrxBuyAmount: BigNumber.max(
 | 
			
		||||
                    constants.ZERO_AMOUNT,
 | 
			
		||||
                    remainingZrxBuyAmount.minus(makerFillAmount).plus(extraFeeAmount),
 | 
			
		||||
                ),
 | 
			
		||||
            };
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            ethAmount: constants.ZERO_AMOUNT,
 | 
			
		||||
            remainingFeeAmount: feeAmount,
 | 
			
		||||
            totalEthAmount: constants.ZERO_AMOUNT,
 | 
			
		||||
            remainingZrxBuyAmount: zrxBuyAmount,
 | 
			
		||||
        },
 | 
			
		||||
    );
 | 
			
		||||
    return result.ethAmount;
 | 
			
		||||
    return result.totalEthAmount;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function findEthAndZrxAmountNeededToBuyAsset(
 | 
			
		||||
@@ -152,28 +183,25 @@ function findEthAndZrxAmountNeededToBuyAsset(
 | 
			
		||||
    const result = _.reduce(
 | 
			
		||||
        orders,
 | 
			
		||||
        (acc, order, index) => {
 | 
			
		||||
            const { totalEthAmount, totalZrxAmount, remainingAssetBuyAmount } = acc;
 | 
			
		||||
            const remainingFillableMakerAssetAmount = remainingFillableMakerAssetAmounts[index];
 | 
			
		||||
            const amountToFill = BigNumber.min(acc.remainingAssetBuyAmount, remainingFillableMakerAssetAmount);
 | 
			
		||||
            // find the amount of eth required to fill amountToFill (amountToFill / makerAssetAmount) * takerAssetAmount
 | 
			
		||||
            const ethAmountForThisOrder = amountToFill
 | 
			
		||||
                .mul(order.takerAssetAmount)
 | 
			
		||||
                .dividedToIntegerBy(order.makerAssetAmount);
 | 
			
		||||
            // find the amount of zrx required to fill fees for amountToFill (amountToFill / makerAssetAmount) * takerFee
 | 
			
		||||
            const zrxAmountForThisOrder = amountToFill.mul(order.takerFee).dividedToIntegerBy(order.makerAssetAmount);
 | 
			
		||||
            const makerFillAmount = BigNumber.min(acc.remainingAssetBuyAmount, remainingFillableMakerAssetAmount);
 | 
			
		||||
            const takerFillAmount = orderUtils.getTakerFillAmount(order, makerFillAmount);
 | 
			
		||||
            const takerFeeAmount = orderUtils.getTakerFeeAmount(order, takerFillAmount);
 | 
			
		||||
            return {
 | 
			
		||||
                ethAmount: acc.ethAmount.plus(ethAmountForThisOrder),
 | 
			
		||||
                zrxAmount: acc.zrxAmount.plus(zrxAmountForThisOrder),
 | 
			
		||||
                totalEthAmount: totalEthAmount.plus(takerFillAmount),
 | 
			
		||||
                totalZrxAmount: totalZrxAmount.plus(takerFeeAmount),
 | 
			
		||||
                remainingAssetBuyAmount: BigNumber.max(
 | 
			
		||||
                    constants.ZERO_AMOUNT,
 | 
			
		||||
                    acc.remainingAssetBuyAmount.minus(amountToFill),
 | 
			
		||||
                    remainingAssetBuyAmount.minus(makerFillAmount),
 | 
			
		||||
                ),
 | 
			
		||||
            };
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            ethAmount: constants.ZERO_AMOUNT,
 | 
			
		||||
            zrxAmount: constants.ZERO_AMOUNT,
 | 
			
		||||
            totalEthAmount: constants.ZERO_AMOUNT,
 | 
			
		||||
            totalZrxAmount: constants.ZERO_AMOUNT,
 | 
			
		||||
            remainingAssetBuyAmount: assetBuyAmount,
 | 
			
		||||
        },
 | 
			
		||||
    );
 | 
			
		||||
    return [result.ethAmount, result.zrxAmount];
 | 
			
		||||
    return [result.totalEthAmount, result.totalZrxAmount];
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -110,10 +110,7 @@ function getValidOrdersWithRemainingFillableMakerAssetAmountsFromOnChain(
 | 
			
		||||
                traderInfo.makerZrxBalance,
 | 
			
		||||
            ]);
 | 
			
		||||
            const remainingTakerAssetAmount = order.takerAssetAmount.minus(orderInfo.orderTakerAssetFilledAmount);
 | 
			
		||||
            const remainingMakerAssetAmount = orderUtils.calculateRemainingMakerAssetAmount(
 | 
			
		||||
                order,
 | 
			
		||||
                remainingTakerAssetAmount,
 | 
			
		||||
            );
 | 
			
		||||
            const remainingMakerAssetAmount = orderUtils.getRemainingMakerAmount(order, remainingTakerAssetAmount);
 | 
			
		||||
            const remainingFillableCalculator = new RemainingFillableCalculator(
 | 
			
		||||
                order.makerFee,
 | 
			
		||||
                order.makerAssetAmount,
 | 
			
		||||
 
 | 
			
		||||
@@ -12,19 +12,63 @@ export const orderUtils = {
 | 
			
		||||
        const currentUnixTimestampSec = new BigNumber(Date.now() / millisecondsInSecond).round();
 | 
			
		||||
        return order.expirationTimeSeconds.lessThan(currentUnixTimestampSec.plus(secondsFromNow));
 | 
			
		||||
    },
 | 
			
		||||
    calculateRemainingMakerAssetAmount(order: SignedOrder, remainingTakerAssetAmount: BigNumber): BigNumber {
 | 
			
		||||
        if (remainingTakerAssetAmount.eq(0)) {
 | 
			
		||||
            return constants.ZERO_AMOUNT;
 | 
			
		||||
        }
 | 
			
		||||
        return remainingTakerAssetAmount.times(order.makerAssetAmount).dividedToIntegerBy(order.takerAssetAmount);
 | 
			
		||||
    },
 | 
			
		||||
    calculateRemainingTakerAssetAmount(order: SignedOrder, remainingMakerAssetAmount: BigNumber): BigNumber {
 | 
			
		||||
        if (remainingMakerAssetAmount.eq(0)) {
 | 
			
		||||
            return constants.ZERO_AMOUNT;
 | 
			
		||||
        }
 | 
			
		||||
        return remainingMakerAssetAmount.times(order.takerAssetAmount).dividedToIntegerBy(order.makerAssetAmount);
 | 
			
		||||
    },
 | 
			
		||||
    isOpenOrder(order: SignedOrder): boolean {
 | 
			
		||||
        return order.takerAddress === constants.NULL_ADDRESS;
 | 
			
		||||
    },
 | 
			
		||||
    // given a remaining amount of takerAsset, calculate how much makerAsset is available
 | 
			
		||||
    getRemainingMakerAmount(order: SignedOrder, remainingTakerAmount: BigNumber): BigNumber {
 | 
			
		||||
        const remainingMakerAmount = remainingTakerAmount
 | 
			
		||||
            .times(order.makerAssetAmount)
 | 
			
		||||
            .div(order.takerAssetAmount)
 | 
			
		||||
            .floor();
 | 
			
		||||
        return remainingMakerAmount;
 | 
			
		||||
    },
 | 
			
		||||
    // given a desired amount of makerAsset, calculate how much takerAsset is required to fill that amount
 | 
			
		||||
    getTakerFillAmount(order: SignedOrder, makerFillAmount: BigNumber): BigNumber {
 | 
			
		||||
        // Round up because exchange rate favors Maker
 | 
			
		||||
        const takerFillAmount = makerFillAmount
 | 
			
		||||
            .mul(order.takerAssetAmount)
 | 
			
		||||
            .div(order.makerAssetAmount)
 | 
			
		||||
            .ceil();
 | 
			
		||||
        return takerFillAmount;
 | 
			
		||||
    },
 | 
			
		||||
    // given a desired amount of takerAsset to fill, calculate how much fee is required by the taker to fill that amount
 | 
			
		||||
    getTakerFeeAmount(order: SignedOrder, takerFillAmount: BigNumber): BigNumber {
 | 
			
		||||
        // Round down because Taker fee rate favors Taker
 | 
			
		||||
        const takerFeeAmount = takerFillAmount
 | 
			
		||||
            .mul(order.takerFee)
 | 
			
		||||
            .div(order.takerAssetAmount)
 | 
			
		||||
            .floor();
 | 
			
		||||
        return takerFeeAmount;
 | 
			
		||||
    },
 | 
			
		||||
    // given a desired amount of takerAsset to fill, calculate how much makerAsset will be filled
 | 
			
		||||
    getMakerFillAmount(order: SignedOrder, takerFillAmount: BigNumber): BigNumber {
 | 
			
		||||
        // Round down because exchange rate favors Maker
 | 
			
		||||
        const makerFillAmount = takerFillAmount
 | 
			
		||||
            .mul(order.makerAssetAmount)
 | 
			
		||||
            .div(order.takerAssetAmount)
 | 
			
		||||
            .floor();
 | 
			
		||||
        return makerFillAmount;
 | 
			
		||||
    },
 | 
			
		||||
    // given a desired amount of makerAsset, calculate how much fee is required by the maker to fill that amount
 | 
			
		||||
    getMakerFeeAmount(order: SignedOrder, makerFillAmount: BigNumber): BigNumber {
 | 
			
		||||
        // Round down because Maker fee rate favors Maker
 | 
			
		||||
        const makerFeeAmount = makerFillAmount
 | 
			
		||||
            .mul(order.makerFee)
 | 
			
		||||
            .div(order.makerAssetAmount)
 | 
			
		||||
            .floor();
 | 
			
		||||
        return makerFeeAmount;
 | 
			
		||||
    },
 | 
			
		||||
    // given a desired amount of ZRX from a fee order, calculate how much takerAsset is required to fill that amount
 | 
			
		||||
    // also calculate how much ZRX needs to be bought in order fill the desired amount + takerFee
 | 
			
		||||
    getTakerFillAmountForFeeOrder(order: SignedOrder, makerFillAmount: BigNumber): [BigNumber, BigNumber] {
 | 
			
		||||
        // For each unit of TakerAsset we buy (MakerAsset - TakerFee)
 | 
			
		||||
        const adjustedTakerFillAmount = makerFillAmount
 | 
			
		||||
            .mul(order.takerAssetAmount)
 | 
			
		||||
            .div(order.makerAssetAmount.sub(order.takerFee))
 | 
			
		||||
            .ceil();
 | 
			
		||||
        // The amount that we buy will be greater than makerFillAmount, since we buy some amount for fees.
 | 
			
		||||
        const adjustedMakerFillAmount = orderUtils.getMakerFillAmount(order, adjustedTakerFillAmount);
 | 
			
		||||
        return [adjustedTakerFillAmount, adjustedMakerFillAmount];
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -49,9 +49,9 @@ describe('buyQuoteCalculator', () => {
 | 
			
		||||
                remainingFillableMakerAssetAmounts: [smallFeeOrder.makerAssetAmount],
 | 
			
		||||
            };
 | 
			
		||||
            const largeFeeOrder = orderFactory.createSignedOrderFromPartial({
 | 
			
		||||
                makerAssetAmount: new BigNumber(110),
 | 
			
		||||
                makerAssetAmount: new BigNumber(113),
 | 
			
		||||
                takerAssetAmount: new BigNumber(200),
 | 
			
		||||
                takerFee: new BigNumber(10),
 | 
			
		||||
                takerFee: new BigNumber(11),
 | 
			
		||||
            });
 | 
			
		||||
            allFeeOrdersAndFillableAmounts = {
 | 
			
		||||
                orders: [smallFeeOrder, largeFeeOrder],
 | 
			
		||||
@@ -70,6 +70,7 @@ describe('buyQuoteCalculator', () => {
 | 
			
		||||
                    new BigNumber(500),
 | 
			
		||||
                    0,
 | 
			
		||||
                    0,
 | 
			
		||||
                    false,
 | 
			
		||||
                ),
 | 
			
		||||
            ).to.throw(AssetBuyerError.InsufficientAssetLiquidity);
 | 
			
		||||
        });
 | 
			
		||||
@@ -82,6 +83,7 @@ describe('buyQuoteCalculator', () => {
 | 
			
		||||
                    new BigNumber(300),
 | 
			
		||||
                    0,
 | 
			
		||||
                    0,
 | 
			
		||||
                    false,
 | 
			
		||||
                ),
 | 
			
		||||
            ).to.throw(AssetBuyerError.InsufficientZrxLiquidity);
 | 
			
		||||
        });
 | 
			
		||||
@@ -97,6 +99,7 @@ describe('buyQuoteCalculator', () => {
 | 
			
		||||
                assetBuyAmount,
 | 
			
		||||
                feePercentage,
 | 
			
		||||
                slippagePercentage,
 | 
			
		||||
                false,
 | 
			
		||||
            );
 | 
			
		||||
            // test if orders are correct
 | 
			
		||||
            expect(buyQuote.orders).to.deep.equal([ordersAndFillableAmounts.orders[0]]);
 | 
			
		||||
@@ -134,6 +137,7 @@ describe('buyQuoteCalculator', () => {
 | 
			
		||||
                assetBuyAmount,
 | 
			
		||||
                feePercentage,
 | 
			
		||||
                slippagePercentage,
 | 
			
		||||
                false,
 | 
			
		||||
            );
 | 
			
		||||
            // test if orders are correct
 | 
			
		||||
            expect(buyQuote.orders).to.deep.equal(ordersAndFillableAmounts.orders);
 | 
			
		||||
@@ -149,9 +153,9 @@ describe('buyQuoteCalculator', () => {
 | 
			
		||||
            expect(buyQuote.bestCaseQuoteInfo.feeEthAmount).to.bignumber.equal(expectedFeeEthAmount);
 | 
			
		||||
            expect(buyQuote.bestCaseQuoteInfo.totalEthAmount).to.bignumber.equal(expectedTotalEthAmount);
 | 
			
		||||
            expect(buyQuote.bestCaseQuoteInfo.ethPerAssetPrice).to.bignumber.equal(expectedEthPerAssetPrice);
 | 
			
		||||
            // 100 eth to fill the first order + 200 eth for fees
 | 
			
		||||
            // 100 eth to fill the first order + 208 eth for fees
 | 
			
		||||
            const expectedWorstEthAmountForAsset = new BigNumber(100);
 | 
			
		||||
            const expectedWorstEthAmountForZrxFees = new BigNumber(200);
 | 
			
		||||
            const expectedWorstEthAmountForZrxFees = new BigNumber(208);
 | 
			
		||||
            const expectedWorstFillEthAmount = expectedWorstEthAmountForAsset.plus(expectedWorstEthAmountForZrxFees);
 | 
			
		||||
            const expectedWorstFeeEthAmount = expectedWorstEthAmountForAsset.mul(feePercentage);
 | 
			
		||||
            const expectedWorstTotalEthAmount = expectedWorstFillEthAmount.plus(expectedWorstFeeEthAmount);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "3.0.3",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1539871071,
 | 
			
		||||
        "version": "3.0.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v3.0.3 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.0.2 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/base-contract",
 | 
			
		||||
    "version": "3.0.2",
 | 
			
		||||
    "version": "3.0.3",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
        "run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --bail --exit",
 | 
			
		||||
        "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
 | 
			
		||||
        "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
 | 
			
		||||
        "lint": "tslint --project . --exclude **/src/contract_wrappers/**/*"
 | 
			
		||||
        "lint": "tslint --format stylish --project ."
 | 
			
		||||
    },
 | 
			
		||||
    "license": "Apache-2.0",
 | 
			
		||||
    "repository": {
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "chai": "^4.0.1",
 | 
			
		||||
        "make-promises-safe": "^1.1.0",
 | 
			
		||||
@@ -40,10 +40,10 @@
 | 
			
		||||
        "typescript": "3.0.1"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.0",
 | 
			
		||||
        "ethereum-types": "^1.1.1",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.1",
 | 
			
		||||
        "ethereum-types": "^1.1.2",
 | 
			
		||||
        "ethers": "~4.0.4",
 | 
			
		||||
        "lodash": "^4.17.5"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "3.0.3",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1539871071,
 | 
			
		||||
        "version": "3.0.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v3.0.3 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.0.2 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/connect",
 | 
			
		||||
    "version": "3.0.2",
 | 
			
		||||
    "version": "3.0.3",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
        "clean": "shx rm -rf lib test_temp generated_docs",
 | 
			
		||||
        "copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures",
 | 
			
		||||
        "lint": "tslint --project .",
 | 
			
		||||
        "lint": "tslint --format stylish --project .",
 | 
			
		||||
        "run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --exit",
 | 
			
		||||
        "test": "run-s copy_test_fixtures run_mocha",
 | 
			
		||||
        "rebuild_and_test": "run-s clean build test",
 | 
			
		||||
@@ -44,12 +44,12 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md",
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/assert": "^1.0.14",
 | 
			
		||||
        "@0x/json-schemas": "^2.0.0",
 | 
			
		||||
        "@0x/order-utils": "^2.0.0",
 | 
			
		||||
        "@0x/types": "^1.2.0",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/assert": "^1.0.15",
 | 
			
		||||
        "@0x/json-schemas": "^2.0.1",
 | 
			
		||||
        "@0x/order-utils": "^2.0.1",
 | 
			
		||||
        "@0x/types": "^1.2.1",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "lodash": "^4.17.5",
 | 
			
		||||
        "query-string": "^5.0.1",
 | 
			
		||||
        "sinon": "^4.0.0",
 | 
			
		||||
@@ -57,7 +57,7 @@
 | 
			
		||||
        "websocket": "^1.0.25"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@types/fetch-mock": "^6.0.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^2.2.42",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,14 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.1.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "pr": 1192,
 | 
			
		||||
                "note": "Update Forwarder addresses"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.1",
 | 
			
		||||
        "changes": [
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.1.0 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Update Forwarder addresses (#1192)
 | 
			
		||||
 | 
			
		||||
## v1.0.1 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Initial release (#1105)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contract-addresses",
 | 
			
		||||
    "version": "1.0.1",
 | 
			
		||||
    "version": "1.1.0",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = {
 | 
			
		||||
        etherToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
 | 
			
		||||
        exchange: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b',
 | 
			
		||||
        assetProxyOwner: '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6',
 | 
			
		||||
        forwarder: '0x7afc2d5107af94c462a194d2c21b5bdd238709d6',
 | 
			
		||||
        forwarder: '0x5468a1dc173652ee28d249c271fa9933144746b1',
 | 
			
		||||
        orderValidator: '0x9463e518dea6810309563c81d5266c1b1d149138',
 | 
			
		||||
    },
 | 
			
		||||
    3: {
 | 
			
		||||
@@ -35,7 +35,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = {
 | 
			
		||||
        etherToken: '0xc778417e063141139fce010982780140aa0cd5ab',
 | 
			
		||||
        exchange: '0x4530c0483a1633c7a1c97d2c53721caff2caaaaf',
 | 
			
		||||
        assetProxyOwner: '0xf5fa5b5fed2727a0e44ac67f6772e97977aa358b',
 | 
			
		||||
        forwarder: '0x3983e204b12b3c02fb0638caf2cd406a62e0ead3',
 | 
			
		||||
        forwarder: '0x2240dab907db71e64d3e0dba4800c83b5c502d4e',
 | 
			
		||||
        orderValidator: '0x90431a90516ab49af23a0530e04e8c7836e7122f',
 | 
			
		||||
    },
 | 
			
		||||
    42: {
 | 
			
		||||
@@ -45,7 +45,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = {
 | 
			
		||||
        etherToken: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
 | 
			
		||||
        exchange: '0x35dd2932454449b14cee11a94d3674a936d5d7b2',
 | 
			
		||||
        assetProxyOwner: '0x2c824d2882baa668e0d5202b1e7f2922278703f8',
 | 
			
		||||
        forwarder: '0xd85e2fa7e7e252b27b01bf0d65c946959d2f45b8',
 | 
			
		||||
        forwarder: '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6',
 | 
			
		||||
        orderValidator: '0xb389da3d204b412df2f75c6afb3d0a7ce0bc283d',
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,14 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.1.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "pr": 1192,
 | 
			
		||||
                "note": "Update Forwarder artifact"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.1",
 | 
			
		||||
        "changes": [
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.1.0 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Update Forwarder artifact (#1192)
 | 
			
		||||
 | 
			
		||||
## v1.0.1 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Initial release (#1105)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										887
									
								
								packages/contract-artifacts/artifacts/Forwarder.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										887
									
								
								packages/contract-artifacts/artifacts/Forwarder.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contract-artifacts",
 | 
			
		||||
    "version": "1.0.1",
 | 
			
		||||
    "version": "1.1.0",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,14 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "3.0.1",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Fix bug in `ForwarderWrapper` where `feeRecipientAddress` was not correctly normalized.",
 | 
			
		||||
                "pr": 1178
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "3.0.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
@@ -37,6 +47,14 @@
 | 
			
		||||
                "note":
 | 
			
		||||
                    "Removed ContractNotFound errors. Checking for this error was somewhat ineffecient. Relevant methods/functions now return the default error from web3-wrapper, which we feel provides enough information.",
 | 
			
		||||
                "pr": 1105
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add `ForwarderWrapperError` to public interface",
 | 
			
		||||
                "pr": 1147
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add `ContractWrapperError.SignatureRequestDenied` to public interface",
 | 
			
		||||
                "pr": 1147
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1539871071
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v3.0.1 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Fix bug in `ForwarderWrapper` where `feeRecipientAddress` was not correctly normalized. (#1178)
 | 
			
		||||
 | 
			
		||||
## v3.0.0 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Add optional validation to the forwarder wrapper methods
 | 
			
		||||
@@ -15,6 +19,8 @@ CHANGELOG
 | 
			
		||||
    * Removed `setProvider` method in top-level `ContractWrapper` class and added new `unsubscribeAll` method. (#1105)
 | 
			
		||||
    * Some properties and methods have been renamed. For example, some methods that previously could throw no longer can, and so their names have been updated accordingly. (#1105)
 | 
			
		||||
    * Removed ContractNotFound errors. Checking for this error was somewhat ineffecient. Relevant methods/functions now return the default error from web3-wrapper, which we feel provides enough information. (#1105)
 | 
			
		||||
    * Add `ForwarderWrapperError` to public interface (#1147)
 | 
			
		||||
    * Add `ContractWrapperError.SignatureRequestDenied` to public interface (#1147)
 | 
			
		||||
 | 
			
		||||
## v2.0.2 - _October 4, 2018_
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contract-wrappers",
 | 
			
		||||
    "version": "3.0.0",
 | 
			
		||||
    "version": "3.0.1",
 | 
			
		||||
    "description": "Smart TS wrappers for 0x smart contracts",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "0xproject",
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "build": "tsc -b",
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
        "lint": "tslint --project . --exclude **/src/contract_wrappers/**/* --exclude **/lib/**/*",
 | 
			
		||||
        "lint": "tslint --format stylish --project . --exclude **/lib/**/*",
 | 
			
		||||
        "test:circleci": "run-s test:coverage",
 | 
			
		||||
        "test": "yarn run_mocha",
 | 
			
		||||
        "rebuild_and_test": "run-s build test",
 | 
			
		||||
@@ -37,10 +37,10 @@
 | 
			
		||||
        "node": ">=6.0.0"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/dev-utils": "^1.0.13",
 | 
			
		||||
        "@0x/migrations": "^2.0.0",
 | 
			
		||||
        "@0x/subproviders": "^2.1.0",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/dev-utils": "^1.0.14",
 | 
			
		||||
        "@0x/migrations": "^2.0.1",
 | 
			
		||||
        "@0x/subproviders": "^2.1.1",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^2.2.42",
 | 
			
		||||
        "@types/node": "*",
 | 
			
		||||
@@ -65,18 +65,18 @@
 | 
			
		||||
        "web3-provider-engine": "14.0.6"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/abi-gen-wrappers": "^1.0.1",
 | 
			
		||||
        "@0x/assert": "^1.0.14",
 | 
			
		||||
        "@0x/contract-addresses": "^1.0.1",
 | 
			
		||||
        "@0x/contract-artifacts": "^1.0.1",
 | 
			
		||||
        "@0x/fill-scenarios": "^1.0.8",
 | 
			
		||||
        "@0x/json-schemas": "^2.0.0",
 | 
			
		||||
        "@0x/order-utils": "^2.0.0",
 | 
			
		||||
        "@0x/types": "^1.2.0",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.0",
 | 
			
		||||
        "ethereum-types": "^1.1.1",
 | 
			
		||||
        "@0x/abi-gen-wrappers": "^1.0.2",
 | 
			
		||||
        "@0x/assert": "^1.0.15",
 | 
			
		||||
        "@0x/contract-addresses": "^1.1.0",
 | 
			
		||||
        "@0x/contract-artifacts": "^1.1.0",
 | 
			
		||||
        "@0x/fill-scenarios": "^1.0.9",
 | 
			
		||||
        "@0x/json-schemas": "^2.0.1",
 | 
			
		||||
        "@0x/order-utils": "^2.0.1",
 | 
			
		||||
        "@0x/types": "^1.2.1",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.1",
 | 
			
		||||
        "ethereum-types": "^1.1.2",
 | 
			
		||||
        "ethereumjs-blockstream": "6.0.0",
 | 
			
		||||
        "ethereumjs-util": "^5.1.1",
 | 
			
		||||
        "ethers": "~4.0.4",
 | 
			
		||||
 
 | 
			
		||||
@@ -28,10 +28,10 @@ export abstract class ContractWrapper {
 | 
			
		||||
    protected _networkId: number;
 | 
			
		||||
    protected _web3Wrapper: Web3Wrapper;
 | 
			
		||||
    private _blockAndLogStreamerIfExists: BlockAndLogStreamer<Block, Log> | undefined;
 | 
			
		||||
    private _blockPollingIntervalMs: number;
 | 
			
		||||
    private readonly _blockPollingIntervalMs: number;
 | 
			
		||||
    private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer;
 | 
			
		||||
    private _filters: { [filterToken: string]: FilterObject };
 | 
			
		||||
    private _filterCallbacks: {
 | 
			
		||||
    private readonly _filters: { [filterToken: string]: FilterObject };
 | 
			
		||||
    private readonly _filterCallbacks: {
 | 
			
		||||
        [filterToken: string]: EventCallback<ContractEventArgs>;
 | 
			
		||||
    };
 | 
			
		||||
    private _onLogAddedSubscriptionToken: string | undefined;
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,9 @@ export class ERC20ProxyWrapper extends ContractWrapper {
 | 
			
		||||
     */
 | 
			
		||||
    public async getProxyIdAsync(): Promise<AssetProxyId> {
 | 
			
		||||
        const ERC20ProxyContractInstance = this._getERC20ProxyContract();
 | 
			
		||||
        // Note(albrow): Below is a TSLint false positive. Code won't compile if
 | 
			
		||||
        // you remove the type assertion.
 | 
			
		||||
        /* tslint:disable-next-line:no-unnecessary-type-assertion */
 | 
			
		||||
        const proxyId = (await ERC20ProxyContractInstance.getProxyId.callAsync()) as AssetProxyId;
 | 
			
		||||
        return proxyId;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -18,12 +18,11 @@ import {
 | 
			
		||||
} from '../types';
 | 
			
		||||
import { assert } from '../utils/assert';
 | 
			
		||||
import { constants } from '../utils/constants';
 | 
			
		||||
import { utils } from '../utils/utils';
 | 
			
		||||
 | 
			
		||||
import { ContractWrapper } from './contract_wrapper';
 | 
			
		||||
import { ERC20ProxyWrapper } from './erc20_proxy_wrapper';
 | 
			
		||||
 | 
			
		||||
const removeUndefinedProperties = _.pickBy;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class includes all the functionality related to interacting with ERC20 token contracts.
 | 
			
		||||
 * All ERC20 method calls are supported, along with some convenience methods for getting/setting allowances
 | 
			
		||||
@@ -32,8 +31,8 @@ const removeUndefinedProperties = _.pickBy;
 | 
			
		||||
export class ERC20TokenWrapper extends ContractWrapper {
 | 
			
		||||
    public abi: ContractAbi = ERC20Token.compilerOutput.abi;
 | 
			
		||||
    public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
 | 
			
		||||
    private _tokenContractsByAddress: { [address: string]: ERC20TokenContract };
 | 
			
		||||
    private _erc20ProxyWrapper: ERC20ProxyWrapper;
 | 
			
		||||
    private readonly _tokenContractsByAddress: { [address: string]: ERC20TokenContract };
 | 
			
		||||
    private readonly _erc20ProxyWrapper: ERC20ProxyWrapper;
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiate ERC20TokenWrapper
 | 
			
		||||
     * @param web3Wrapper Web3Wrapper instance to use
 | 
			
		||||
@@ -108,7 +107,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
 | 
			
		||||
        const txHash = await tokenContract.approve.sendTransactionAsync(
 | 
			
		||||
            normalizedSpenderAddress,
 | 
			
		||||
            amountInBaseUnits,
 | 
			
		||||
            removeUndefinedProperties({
 | 
			
		||||
            utils.removeUndefinedProperties({
 | 
			
		||||
                from: normalizedOwnerAddress,
 | 
			
		||||
                gas: txOpts.gasLimit,
 | 
			
		||||
                gasPrice: txOpts.gasPrice,
 | 
			
		||||
@@ -278,7 +277,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
 | 
			
		||||
        const txHash = await tokenContract.transfer.sendTransactionAsync(
 | 
			
		||||
            normalizedToAddress,
 | 
			
		||||
            amountInBaseUnits,
 | 
			
		||||
            removeUndefinedProperties({
 | 
			
		||||
            utils.removeUndefinedProperties({
 | 
			
		||||
                from: normalizedFromAddress,
 | 
			
		||||
                gas: txOpts.gasLimit,
 | 
			
		||||
                gasPrice: txOpts.gasPrice,
 | 
			
		||||
@@ -339,7 +338,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
 | 
			
		||||
            normalizedFromAddress,
 | 
			
		||||
            normalizedToAddress,
 | 
			
		||||
            amountInBaseUnits,
 | 
			
		||||
            removeUndefinedProperties({
 | 
			
		||||
            utils.removeUndefinedProperties({
 | 
			
		||||
                from: normalizedSenderAddress,
 | 
			
		||||
                gas: txOpts.gasLimit,
 | 
			
		||||
                gasPrice: txOpts.gasPrice,
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,9 @@ export class ERC721ProxyWrapper extends ContractWrapper {
 | 
			
		||||
     */
 | 
			
		||||
    public async getProxyIdAsync(): Promise<AssetProxyId> {
 | 
			
		||||
        const ERC721ProxyContractInstance = await this._getERC721ProxyContract();
 | 
			
		||||
        // Note(albrow): Below is a TSLint false positive. Code won't compile if
 | 
			
		||||
        // you remove the type assertion.
 | 
			
		||||
        /* tslint:disable-next-line:no-unnecessary-type-assertion */
 | 
			
		||||
        const proxyId = (await ERC721ProxyContractInstance.getProxyId.callAsync()) as AssetProxyId;
 | 
			
		||||
        return proxyId;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -18,12 +18,11 @@ import {
 | 
			
		||||
} from '../types';
 | 
			
		||||
import { assert } from '../utils/assert';
 | 
			
		||||
import { constants } from '../utils/constants';
 | 
			
		||||
import { utils } from '../utils/utils';
 | 
			
		||||
 | 
			
		||||
import { ContractWrapper } from './contract_wrapper';
 | 
			
		||||
import { ERC721ProxyWrapper } from './erc721_proxy_wrapper';
 | 
			
		||||
 | 
			
		||||
const removeUndefinedProperties = _.pickBy;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class includes all the functionality related to interacting with ERC721 token contracts.
 | 
			
		||||
 * All ERC721 method calls are supported, along with some convenience methods for getting/setting allowances
 | 
			
		||||
@@ -31,8 +30,8 @@ const removeUndefinedProperties = _.pickBy;
 | 
			
		||||
 */
 | 
			
		||||
export class ERC721TokenWrapper extends ContractWrapper {
 | 
			
		||||
    public abi: ContractAbi = ERC721Token.compilerOutput.abi;
 | 
			
		||||
    private _tokenContractsByAddress: { [address: string]: ERC721TokenContract };
 | 
			
		||||
    private _erc721ProxyWrapper: ERC721ProxyWrapper;
 | 
			
		||||
    private readonly _tokenContractsByAddress: { [address: string]: ERC721TokenContract };
 | 
			
		||||
    private readonly _erc721ProxyWrapper: ERC721ProxyWrapper;
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiate ERC721TokenWrapper
 | 
			
		||||
     * @param web3Wrapper Web3Wrapper instance to use
 | 
			
		||||
@@ -235,7 +234,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
 | 
			
		||||
        const txHash = await tokenContract.setApprovalForAll.sendTransactionAsync(
 | 
			
		||||
            normalizedOperatorAddress,
 | 
			
		||||
            isApproved,
 | 
			
		||||
            removeUndefinedProperties({
 | 
			
		||||
            utils.removeUndefinedProperties({
 | 
			
		||||
                gas: txOpts.gasLimit,
 | 
			
		||||
                gasPrice: txOpts.gasPrice,
 | 
			
		||||
                from: normalizedOwnerAddress,
 | 
			
		||||
@@ -295,7 +294,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
 | 
			
		||||
        const txHash = await tokenContract.approve.sendTransactionAsync(
 | 
			
		||||
            normalizedApprovedAddress,
 | 
			
		||||
            tokenId,
 | 
			
		||||
            removeUndefinedProperties({
 | 
			
		||||
            utils.removeUndefinedProperties({
 | 
			
		||||
                gas: txOpts.gasLimit,
 | 
			
		||||
                gasPrice: txOpts.gasPrice,
 | 
			
		||||
                from: tokenOwnerAddress,
 | 
			
		||||
@@ -366,7 +365,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
 | 
			
		||||
            ownerAddress,
 | 
			
		||||
            normalizedReceiverAddress,
 | 
			
		||||
            tokenId,
 | 
			
		||||
            removeUndefinedProperties({
 | 
			
		||||
            utils.removeUndefinedProperties({
 | 
			
		||||
                gas: txOpts.gasLimit,
 | 
			
		||||
                gasPrice: txOpts.gasPrice,
 | 
			
		||||
                from: normalizedSenderAddress,
 | 
			
		||||
 
 | 
			
		||||
@@ -8,22 +8,21 @@ import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { BlockRange, ContractWrappersError, EventCallback, IndexedFilterValues, TransactionOpts } from '../types';
 | 
			
		||||
import { assert } from '../utils/assert';
 | 
			
		||||
import { utils } from '../utils/utils';
 | 
			
		||||
 | 
			
		||||
import { ContractWrapper } from './contract_wrapper';
 | 
			
		||||
import { ERC20TokenWrapper } from './erc20_token_wrapper';
 | 
			
		||||
 | 
			
		||||
const removeUndefinedProperties = _.pickBy;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class includes all the functionality related to interacting with a wrapped Ether ERC20 token contract.
 | 
			
		||||
 * The caller can convert ETH into the equivalent number of wrapped ETH ERC20 tokens and back.
 | 
			
		||||
 */
 | 
			
		||||
export class EtherTokenWrapper extends ContractWrapper {
 | 
			
		||||
    public abi: ContractAbi = WETH9.compilerOutput.abi;
 | 
			
		||||
    private _etherTokenContractsByAddress: {
 | 
			
		||||
    private readonly _etherTokenContractsByAddress: {
 | 
			
		||||
        [address: string]: WETH9Contract;
 | 
			
		||||
    } = {};
 | 
			
		||||
    private _erc20TokenWrapper: ERC20TokenWrapper;
 | 
			
		||||
    private readonly _erc20TokenWrapper: ERC20TokenWrapper;
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiate EtherTokenWrapper.
 | 
			
		||||
     * @param web3Wrapper Web3Wrapper instance to use
 | 
			
		||||
@@ -67,7 +66,7 @@ export class EtherTokenWrapper extends ContractWrapper {
 | 
			
		||||
 | 
			
		||||
        const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress);
 | 
			
		||||
        const txHash = await wethContract.deposit.sendTransactionAsync(
 | 
			
		||||
            removeUndefinedProperties({
 | 
			
		||||
            utils.removeUndefinedProperties({
 | 
			
		||||
                from: normalizedDepositorAddress,
 | 
			
		||||
                value: amountInWei,
 | 
			
		||||
                gas: txOpts.gasLimit,
 | 
			
		||||
@@ -109,7 +108,7 @@ export class EtherTokenWrapper extends ContractWrapper {
 | 
			
		||||
        const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress);
 | 
			
		||||
        const txHash = await wethContract.withdraw.sendTransactionAsync(
 | 
			
		||||
            amountInWei,
 | 
			
		||||
            removeUndefinedProperties({
 | 
			
		||||
            utils.removeUndefinedProperties({
 | 
			
		||||
                from: normalizedWithdrawerAddress,
 | 
			
		||||
                gas: txOpts.gasLimit,
 | 
			
		||||
                gasPrice: txOpts.gasPrice,
 | 
			
		||||
 
 | 
			
		||||
@@ -46,8 +46,8 @@ export class ExchangeWrapper extends ContractWrapper {
 | 
			
		||||
    public address: string;
 | 
			
		||||
    public zrxTokenAddress: string;
 | 
			
		||||
    private _exchangeContractIfExists?: ExchangeContract;
 | 
			
		||||
    private _erc721TokenWrapper: ERC721TokenWrapper;
 | 
			
		||||
    private _erc20TokenWrapper: ERC20TokenWrapper;
 | 
			
		||||
    private readonly _erc721TokenWrapper: ERC721TokenWrapper;
 | 
			
		||||
    private readonly _erc20TokenWrapper: ERC20TokenWrapper;
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiate ExchangeWrapper
 | 
			
		||||
     * @param web3Wrapper Web3Wrapper instance to use.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import { ForwarderContract } from '@0x/abi-gen-wrappers';
 | 
			
		||||
import { Forwarder } from '@0x/contract-artifacts';
 | 
			
		||||
import { schemas } from '@0x/json-schemas';
 | 
			
		||||
import { AssetProxyId, SignedOrder } from '@0x/types';
 | 
			
		||||
import { SignedOrder } from '@0x/types';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
			
		||||
import { ContractAbi } from 'ethereum-types';
 | 
			
		||||
@@ -118,7 +118,7 @@ export class ForwarderWrapper extends ContractWrapper {
 | 
			
		||||
                optimizedFeeOrders,
 | 
			
		||||
                feeSignatures,
 | 
			
		||||
                formattedFeePercentage,
 | 
			
		||||
                feeRecipientAddress,
 | 
			
		||||
                normalizedFeeRecipientAddress,
 | 
			
		||||
                {
 | 
			
		||||
                    value: ethAmount,
 | 
			
		||||
                    from: normalizedTakerAddress,
 | 
			
		||||
@@ -207,7 +207,7 @@ export class ForwarderWrapper extends ContractWrapper {
 | 
			
		||||
                optimizedFeeOrders,
 | 
			
		||||
                feeSignatures,
 | 
			
		||||
                formattedFeePercentage,
 | 
			
		||||
                feeRecipientAddress,
 | 
			
		||||
                normalizedFeeRecipientAddress,
 | 
			
		||||
                {
 | 
			
		||||
                    value: ethAmount,
 | 
			
		||||
                    from: normalizedTakerAddress,
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@ export { TransactionEncoder } from './utils/transaction_encoder';
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
    ContractWrappersError,
 | 
			
		||||
    ForwarderWrapperError,
 | 
			
		||||
    IndexedFilterValues,
 | 
			
		||||
    BlockRange,
 | 
			
		||||
    ContractWrappersConfig,
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,10 @@ export enum ExchangeWrapperError {
 | 
			
		||||
    AssetDataMismatch = 'ASSET_DATA_MISMATCH',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum ForwarderWrapperError {
 | 
			
		||||
    CompleteFillFailed = 'COMPLETE_FILL_FAILED',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum ContractWrappersError {
 | 
			
		||||
    ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK',
 | 
			
		||||
    InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER',
 | 
			
		||||
@@ -30,6 +34,7 @@ export enum ContractWrappersError {
 | 
			
		||||
    SubscriptionAlreadyPresent = 'SUBSCRIPTION_ALREADY_PRESENT',
 | 
			
		||||
    ERC721OwnerNotFound = 'ERC_721_OWNER_NOT_FOUND',
 | 
			
		||||
    ERC721NoApproval = 'ERC_721_NO_APPROVAL',
 | 
			
		||||
    SignatureRequestDenied = 'SIGNATURE_REQUEST_DENIED',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum InternalContractWrappersError {
 | 
			
		||||
 
 | 
			
		||||
@@ -14,4 +14,5 @@ export const constants = {
 | 
			
		||||
    ZERO_AMOUNT: new BigNumber(0),
 | 
			
		||||
    ONE_AMOUNT: new BigNumber(1),
 | 
			
		||||
    ETHER_TOKEN_DECIMALS: 18,
 | 
			
		||||
    USER_DENIED_SIGNATURE_PATTERN: 'User denied transaction signature',
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,14 @@ const schemaErrorTransformer = (error: Error) => {
 | 
			
		||||
    return error;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const signatureRequestErrorTransformer = (error: Error) => {
 | 
			
		||||
    if (_.includes(error.message, constants.USER_DENIED_SIGNATURE_PATTERN)) {
 | 
			
		||||
        const errMsg = ContractWrappersError.SignatureRequestDenied;
 | 
			
		||||
        return new Error(errMsg);
 | 
			
		||||
    }
 | 
			
		||||
    return error;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Source: https://stackoverflow.com/a/29837695/3546986
 | 
			
		||||
 */
 | 
			
		||||
@@ -87,7 +95,11 @@ const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// _.flow(f, g) = f ∘ g
 | 
			
		||||
const zeroExErrorTransformer = _.flow(schemaErrorTransformer, contractCallErrorTransformer);
 | 
			
		||||
const zeroExErrorTransformer = _.flow(
 | 
			
		||||
    schemaErrorTransformer,
 | 
			
		||||
    contractCallErrorTransformer,
 | 
			
		||||
    signatureRequestErrorTransformer,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const decorators = {
 | 
			
		||||
    asyncZeroExErrorHandler: asyncErrorHandlerFactory(zeroExErrorTransformer),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { constants } from './constants';
 | 
			
		||||
 | 
			
		||||
@@ -14,4 +15,7 @@ export const utils = {
 | 
			
		||||
    numberPercentageToEtherTokenAmountPercentage(percentage: number): BigNumber {
 | 
			
		||||
        return Web3Wrapper.toBaseUnitAmount(constants.ONE_AMOUNT, constants.ETHER_TOKEN_DECIMALS).mul(percentage);
 | 
			
		||||
    },
 | 
			
		||||
    removeUndefinedProperties<T extends object>(obj: T): Partial<T> {
 | 
			
		||||
        return _.pickBy(obj);
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -4,29 +4,23 @@ Smart contracts that implement the 0x protocol. Addresses of the deployed contra
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
### 2.0.0
 | 
			
		||||
Contracts that make up and interact with version 2.0.0 of the protocol can be found in the [contracts](./contracts) directory. The contents of this directory are broken down into the following subdirectories:
 | 
			
		||||
 | 
			
		||||
Contracts that make up and interact with version 2.0.0 of the protocol can be found in the `src/2.0.0` directory. The contents of this directory are broken down into the following subdirectories:
 | 
			
		||||
 | 
			
		||||
*   protocol
 | 
			
		||||
*   [protocol](./contracts/protocol)
 | 
			
		||||
    *   This directory contains the contracts that make up version 2.0.0. A full specification can be found [here](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
 | 
			
		||||
*   extensions
 | 
			
		||||
*   [extensions](./contracts/extensions)
 | 
			
		||||
    *   This directory contains contracts that interact with the 2.0.0 contracts and will be used in production, such as the [Forwarder](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/forwarder-specification.md) contract.
 | 
			
		||||
*   examples
 | 
			
		||||
*   [examples](./contracts/examples)
 | 
			
		||||
    *   This directory contains example implementations of contracts that interact with the protocol but are _not_ intended for use in production. Examples include [filter](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#filter-contracts) contracts, a [Wallet](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#wallet) contract, and a [Validator](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#validator) contract, among others.
 | 
			
		||||
*   tokens
 | 
			
		||||
*   [tokens](./contracts/tokens)
 | 
			
		||||
    *   This directory contains implementations of different tokens and token standards, including [wETH](https://weth.io/), ZRX, [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md), and [ERC721](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md).
 | 
			
		||||
*   multisig
 | 
			
		||||
*   [multisig](./contracts/multisig)
 | 
			
		||||
    *   This directory contains the [Gnosis MultiSigWallet](https://github.com/gnosis/MultiSigWallet) and a custom extension that adds a timelock to transactions within the MultiSigWallet.
 | 
			
		||||
*   utils
 | 
			
		||||
*   [utils](./contracts/utils)
 | 
			
		||||
    *   This directory contains libraries and utils that are shared across all of the other directories.
 | 
			
		||||
*   test
 | 
			
		||||
*   [test](./contracts/test)
 | 
			
		||||
    *   This directory contains mocks and other contracts that are used solely for testing contracts within the other directories.
 | 
			
		||||
 | 
			
		||||
### 1.0.0
 | 
			
		||||
 | 
			
		||||
Contracts that make up version 1.0.0 of the protocol can be found in `src/1.0.0`. These contracts are considered deprecated and will have limited support going forward.
 | 
			
		||||
 | 
			
		||||
## Bug bounty
 | 
			
		||||
 | 
			
		||||
A bug bounty for the 2.0.0 contracts is ongoing! Instructions can be found [here](https://0xproject.com/wiki#Bug-Bounty).
 | 
			
		||||
 
 | 
			
		||||
@@ -155,8 +155,10 @@ contract MixinExchangeWrapper is
 | 
			
		||||
            uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);
 | 
			
		||||
 | 
			
		||||
            // Convert the remaining amount of makerAsset to buy into remaining amount
 | 
			
		||||
            // of takerAsset to sell, assuming entire amount can be sold in the current order
 | 
			
		||||
            uint256 remainingTakerAssetFillAmount = getPartialAmountFloor(
 | 
			
		||||
            // of takerAsset to sell, assuming entire amount can be sold in the current order.
 | 
			
		||||
            // We round up because the exchange rate computed by fillOrder rounds in favor
 | 
			
		||||
            // of the Maker. In this case we want to overestimate the amount of takerAsset.
 | 
			
		||||
            uint256 remainingTakerAssetFillAmount = getPartialAmountCeil(
 | 
			
		||||
                orders[i].takerAssetAmount,
 | 
			
		||||
                orders[i].makerAssetAmount,
 | 
			
		||||
                remainingMakerAssetFillAmount
 | 
			
		||||
@@ -224,7 +226,9 @@ contract MixinExchangeWrapper is
 | 
			
		||||
 | 
			
		||||
            // Convert the remaining amount of ZRX to buy into remaining amount
 | 
			
		||||
            // of WETH to sell, assuming entire amount can be sold in the current order.
 | 
			
		||||
            uint256 remainingWethSellAmount = getPartialAmountFloor(
 | 
			
		||||
            // We round up because the exchange rate computed by fillOrder rounds in favor
 | 
			
		||||
            // of the Maker. In this case we want to overestimate the amount of takerAsset.
 | 
			
		||||
            uint256 remainingWethSellAmount = getPartialAmountCeil(
 | 
			
		||||
                orders[i].takerAssetAmount,
 | 
			
		||||
                safeSub(orders[i].makerAssetAmount, orders[i].takerFee),  // our exchange rate after fees 
 | 
			
		||||
                remainingZrxBuyAmount
 | 
			
		||||
@@ -233,7 +237,7 @@ contract MixinExchangeWrapper is
 | 
			
		||||
            // Attempt to sell the remaining amount of WETH.
 | 
			
		||||
            FillResults memory singleFillResult = fillOrderNoThrow(
 | 
			
		||||
                orders[i],
 | 
			
		||||
                safeAdd(remainingWethSellAmount, 1),  // we add 1 wei to the fill amount to make up for rounding errors
 | 
			
		||||
                remainingWethSellAmount,
 | 
			
		||||
                signatures[i]
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "private": true,
 | 
			
		||||
    "name": "contracts",
 | 
			
		||||
    "version": "2.1.50",
 | 
			
		||||
    "version": "2.1.51",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
        "compile": "sol-compiler --contracts-dir contracts",
 | 
			
		||||
        "clean": "shx rm -rf lib generated-artifacts generated-wrappers",
 | 
			
		||||
        "generate_contract_wrappers": "abi-gen --abis  ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
 | 
			
		||||
        "lint": "tslint --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
 | 
			
		||||
        "lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
 | 
			
		||||
        "coverage:report:text": "istanbul report text",
 | 
			
		||||
        "coverage:report:html": "istanbul report html && open coverage/index.html",
 | 
			
		||||
        "profiler:report:html": "istanbul report html && open coverage/index.html",
 | 
			
		||||
@@ -45,12 +45,12 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/abi-gen": "^1.0.14",
 | 
			
		||||
        "@0x/dev-utils": "^1.0.13",
 | 
			
		||||
        "@0x/sol-compiler": "^1.1.8",
 | 
			
		||||
        "@0x/sol-cov": "^2.1.8",
 | 
			
		||||
        "@0x/subproviders": "^2.1.0",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/abi-gen": "^1.0.15",
 | 
			
		||||
        "@0x/dev-utils": "^1.0.14",
 | 
			
		||||
        "@0x/sol-compiler": "^1.1.9",
 | 
			
		||||
        "@0x/sol-cov": "^2.1.9",
 | 
			
		||||
        "@0x/subproviders": "^2.1.1",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@types/bn.js": "^4.11.0",
 | 
			
		||||
        "@types/ethereumjs-abi": "^0.6.0",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
@@ -71,15 +71,15 @@
 | 
			
		||||
        "yargs": "^10.0.3"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^3.0.2",
 | 
			
		||||
        "@0x/order-utils": "^2.0.0",
 | 
			
		||||
        "@0x/types": "^1.2.0",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.0",
 | 
			
		||||
        "@0x/base-contract": "^3.0.3",
 | 
			
		||||
        "@0x/order-utils": "^2.0.1",
 | 
			
		||||
        "@0x/types": "^1.2.1",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.1",
 | 
			
		||||
        "@types/js-combinatorics": "^0.5.29",
 | 
			
		||||
        "bn.js": "^4.11.8",
 | 
			
		||||
        "ethereum-types": "^1.1.1",
 | 
			
		||||
        "ethereum-types": "^1.1.2",
 | 
			
		||||
        "ethereumjs-abi": "0.6.5",
 | 
			
		||||
        "ethereumjs-util": "^5.1.1",
 | 
			
		||||
        "ethers": "~4.0.4",
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,7 @@ describe(ContractName.Forwarder, () => {
 | 
			
		||||
 | 
			
		||||
    let weth: DummyERC20TokenContract;
 | 
			
		||||
    let zrxToken: DummyERC20TokenContract;
 | 
			
		||||
    let erc20TokenA: DummyERC20TokenContract;
 | 
			
		||||
    let erc721Token: DummyERC721TokenContract;
 | 
			
		||||
    let forwarderContract: ForwarderContract;
 | 
			
		||||
    let wethContract: WETH9Contract;
 | 
			
		||||
@@ -77,7 +78,6 @@ describe(ContractName.Forwarder, () => {
 | 
			
		||||
        erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
 | 
			
		||||
 | 
			
		||||
        const numDummyErc20ToDeploy = 3;
 | 
			
		||||
        let erc20TokenA;
 | 
			
		||||
        [erc20TokenA, zrxToken] = await erc20Wrapper.deployDummyTokensAsync(
 | 
			
		||||
            numDummyErc20ToDeploy,
 | 
			
		||||
            constants.DUMMY_TOKEN_DECIMALS,
 | 
			
		||||
@@ -902,6 +902,269 @@ describe(ContractName.Forwarder, () => {
 | 
			
		||||
            );
 | 
			
		||||
            expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
        });
 | 
			
		||||
        it('Should buy slightly greater MakerAsset when exchange rate is rounded', async () => {
 | 
			
		||||
            // The 0x Protocol contracts round the exchange rate in favor of the Maker.
 | 
			
		||||
            // In this case, the taker must round up how much they're going to spend, which
 | 
			
		||||
            // in turn increases the amount of MakerAsset being purchased.
 | 
			
		||||
            // Example:
 | 
			
		||||
            //  The taker wants to buy 5 units of the MakerAsset at a rate of 3M/2T.
 | 
			
		||||
            //  For every 2 units of TakerAsset, the taker will receive 3 units of MakerAsset.
 | 
			
		||||
            //  To purchase 5 units, the taker must spend 10/3 = 3.33 units of TakerAssset.
 | 
			
		||||
            //  However, the Taker can only spend whole units.
 | 
			
		||||
            //  Spending floor(10/3) = 3 units will yield a profit of Floor(3*3/2) = Floor(4.5) = 4 units of MakerAsset.
 | 
			
		||||
            //  Spending ceil(10/3) = 4 units will yield a profit of Floor(4*3/2) = 6 units of MakerAsset.
 | 
			
		||||
            //
 | 
			
		||||
            //  The forwarding contract will opt for the second option, which overbuys, to ensure the taker
 | 
			
		||||
            //  receives at least the amount of MakerAsset they requested.
 | 
			
		||||
            //
 | 
			
		||||
            // Construct test case using values from example above
 | 
			
		||||
            orderWithoutFee = await orderFactory.newSignedOrderAsync({
 | 
			
		||||
                makerAssetAmount: new BigNumber('30'),
 | 
			
		||||
                takerAssetAmount: new BigNumber('20'),
 | 
			
		||||
                makerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenA.address),
 | 
			
		||||
                takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
 | 
			
		||||
                makerFee: new BigNumber(0),
 | 
			
		||||
                takerFee: new BigNumber(0),
 | 
			
		||||
            });
 | 
			
		||||
            const ordersWithoutFee = [orderWithoutFee];
 | 
			
		||||
            const feeOrders: SignedOrder[] = [];
 | 
			
		||||
            const desiredMakerAssetFillAmount = new BigNumber('5');
 | 
			
		||||
            const makerAssetFillAmount = new BigNumber('6');
 | 
			
		||||
            const ethValue = new BigNumber('4');
 | 
			
		||||
            // Execute test case
 | 
			
		||||
            tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
 | 
			
		||||
                ordersWithoutFee,
 | 
			
		||||
                feeOrders,
 | 
			
		||||
                desiredMakerAssetFillAmount,
 | 
			
		||||
                {
 | 
			
		||||
                    value: ethValue,
 | 
			
		||||
                    from: takerAddress,
 | 
			
		||||
                },
 | 
			
		||||
            );
 | 
			
		||||
            // Fetch end balances and construct expected outputs
 | 
			
		||||
            const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
 | 
			
		||||
            const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
 | 
			
		||||
            const newBalances = await erc20Wrapper.getBalancesAsync();
 | 
			
		||||
            const primaryTakerAssetFillAmount = ethValue;
 | 
			
		||||
            const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
 | 
			
		||||
            // Validate test case
 | 
			
		||||
            expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
 | 
			
		||||
            expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
 | 
			
		||||
            expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
            expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
 | 
			
		||||
                constants.ZERO_AMOUNT,
 | 
			
		||||
            );
 | 
			
		||||
            expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
        });
 | 
			
		||||
        it('Should buy slightly greater MakerAsset when exchange rate is rounded, and MakerAsset is ZRX', async () => {
 | 
			
		||||
            // See the test case above for a detailed description of this case.
 | 
			
		||||
            // The difference here is that the MakerAsset is ZRX. We expect the same result as above,
 | 
			
		||||
            // but this tests a different code path.
 | 
			
		||||
            //
 | 
			
		||||
            // Construct test case using values from example above
 | 
			
		||||
            orderWithoutFee = await orderFactory.newSignedOrderAsync({
 | 
			
		||||
                makerAssetAmount: new BigNumber('30'),
 | 
			
		||||
                takerAssetAmount: new BigNumber('20'),
 | 
			
		||||
                makerAssetData: zrxAssetData,
 | 
			
		||||
                takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
 | 
			
		||||
                makerFee: new BigNumber(0),
 | 
			
		||||
                takerFee: new BigNumber(0),
 | 
			
		||||
            });
 | 
			
		||||
            const ordersWithoutFee = [orderWithoutFee];
 | 
			
		||||
            const feeOrders: SignedOrder[] = [];
 | 
			
		||||
            const desiredMakerAssetFillAmount = new BigNumber('5');
 | 
			
		||||
            const makerAssetFillAmount = new BigNumber('6');
 | 
			
		||||
            const ethValue = new BigNumber('4');
 | 
			
		||||
            // Execute test case
 | 
			
		||||
            tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
 | 
			
		||||
                ordersWithoutFee,
 | 
			
		||||
                feeOrders,
 | 
			
		||||
                desiredMakerAssetFillAmount,
 | 
			
		||||
                {
 | 
			
		||||
                    value: ethValue,
 | 
			
		||||
                    from: takerAddress,
 | 
			
		||||
                },
 | 
			
		||||
            );
 | 
			
		||||
            // Fetch end balances and construct expected outputs
 | 
			
		||||
            const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
 | 
			
		||||
            const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
 | 
			
		||||
            const newBalances = await erc20Wrapper.getBalancesAsync();
 | 
			
		||||
            const primaryTakerAssetFillAmount = ethValue;
 | 
			
		||||
            const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
 | 
			
		||||
            // Validate test case
 | 
			
		||||
            expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
 | 
			
		||||
            expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
 | 
			
		||||
            expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[takerAddress][zrxToken.address].plus(makerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
            expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
        });
 | 
			
		||||
        it('Should buy slightly greater MakerAsset when exchange rate is rounded (Regression Test)', async () => {
 | 
			
		||||
            // Order taken from a transaction on mainnet that failed due to a rounding error.
 | 
			
		||||
            orderWithoutFee = await orderFactory.newSignedOrderAsync({
 | 
			
		||||
                makerAssetAmount: new BigNumber('268166666666666666666'),
 | 
			
		||||
                takerAssetAmount: new BigNumber('219090625878836371'),
 | 
			
		||||
                makerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenA.address),
 | 
			
		||||
                takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
 | 
			
		||||
                makerFee: new BigNumber(0),
 | 
			
		||||
                takerFee: new BigNumber(0),
 | 
			
		||||
            });
 | 
			
		||||
            const ordersWithoutFee = [orderWithoutFee];
 | 
			
		||||
            const feeOrders: SignedOrder[] = [];
 | 
			
		||||
            // The taker will receive more than the desired amount of makerAsset due to rounding
 | 
			
		||||
            const desiredMakerAssetFillAmount = new BigNumber('5000000000000000000');
 | 
			
		||||
            const ethValue = new BigNumber('4084971271824171');
 | 
			
		||||
            const makerAssetFillAmount = ethValue
 | 
			
		||||
                .times(orderWithoutFee.makerAssetAmount)
 | 
			
		||||
                .dividedToIntegerBy(orderWithoutFee.takerAssetAmount);
 | 
			
		||||
            // Execute test case
 | 
			
		||||
            tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
 | 
			
		||||
                ordersWithoutFee,
 | 
			
		||||
                feeOrders,
 | 
			
		||||
                desiredMakerAssetFillAmount,
 | 
			
		||||
                {
 | 
			
		||||
                    value: ethValue,
 | 
			
		||||
                    from: takerAddress,
 | 
			
		||||
                },
 | 
			
		||||
            );
 | 
			
		||||
            // Fetch end balances and construct expected outputs
 | 
			
		||||
            const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
 | 
			
		||||
            const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
 | 
			
		||||
            const newBalances = await erc20Wrapper.getBalancesAsync();
 | 
			
		||||
            const primaryTakerAssetFillAmount = ethValue;
 | 
			
		||||
            const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
 | 
			
		||||
            // Validate test case
 | 
			
		||||
            expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
 | 
			
		||||
            expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
 | 
			
		||||
            expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
            expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
 | 
			
		||||
                constants.ZERO_AMOUNT,
 | 
			
		||||
            );
 | 
			
		||||
            expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
        });
 | 
			
		||||
        it('Should buy slightly greater MakerAsset when exchange rate is rounded, and MakerAsset is ZRX (Regression Test)', async () => {
 | 
			
		||||
            // Order taken from a transaction on mainnet that failed due to a rounding error.
 | 
			
		||||
            orderWithoutFee = await orderFactory.newSignedOrderAsync({
 | 
			
		||||
                makerAssetAmount: new BigNumber('268166666666666666666'),
 | 
			
		||||
                takerAssetAmount: new BigNumber('219090625878836371'),
 | 
			
		||||
                makerAssetData: zrxAssetData,
 | 
			
		||||
                takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
 | 
			
		||||
                makerFee: new BigNumber(0),
 | 
			
		||||
                takerFee: new BigNumber(0),
 | 
			
		||||
            });
 | 
			
		||||
            const ordersWithoutFee = [orderWithoutFee];
 | 
			
		||||
            const feeOrders: SignedOrder[] = [];
 | 
			
		||||
            // The taker will receive more than the desired amount of makerAsset due to rounding
 | 
			
		||||
            const desiredMakerAssetFillAmount = new BigNumber('5000000000000000000');
 | 
			
		||||
            const ethValue = new BigNumber('4084971271824171');
 | 
			
		||||
            const makerAssetFillAmount = ethValue
 | 
			
		||||
                .times(orderWithoutFee.makerAssetAmount)
 | 
			
		||||
                .dividedToIntegerBy(orderWithoutFee.takerAssetAmount);
 | 
			
		||||
            // Execute test case
 | 
			
		||||
            tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
 | 
			
		||||
                ordersWithoutFee,
 | 
			
		||||
                feeOrders,
 | 
			
		||||
                desiredMakerAssetFillAmount,
 | 
			
		||||
                {
 | 
			
		||||
                    value: ethValue,
 | 
			
		||||
                    from: takerAddress,
 | 
			
		||||
                },
 | 
			
		||||
            );
 | 
			
		||||
            // Fetch end balances and construct expected outputs
 | 
			
		||||
            const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
 | 
			
		||||
            const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
 | 
			
		||||
            const newBalances = await erc20Wrapper.getBalancesAsync();
 | 
			
		||||
            const primaryTakerAssetFillAmount = ethValue;
 | 
			
		||||
            const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
 | 
			
		||||
            // Validate test case
 | 
			
		||||
            expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
 | 
			
		||||
            expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
 | 
			
		||||
            expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[takerAddress][zrxToken.address].plus(makerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
            expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
        });
 | 
			
		||||
        it('Should buy correct MakerAsset when exchange rate is NOT rounded, and MakerAsset is ZRX (Regression Test)', async () => {
 | 
			
		||||
            // An extra unit of TakerAsset was sent to the exchange contract to account for rounding errors, in Forwarder v1.
 | 
			
		||||
            // Specifically, the takerFillAmount was calculated using Floor(desiredMakerAmount * exchangeRate) + 1
 | 
			
		||||
            // We have since changed this to be Ceil(desiredMakerAmount * exchangeRate)
 | 
			
		||||
            // These calculations produce different results when `desiredMakerAmount * exchangeRate` is an integer.
 | 
			
		||||
            //
 | 
			
		||||
            // This test verifies that `ceil` is sufficient:
 | 
			
		||||
            //  Let TakerAssetAmount = MakerAssetAmount * 2
 | 
			
		||||
            //  -> exchangeRate = TakerAssetAmount / MakerAssetAmount = (2*MakerAssetAmount)/MakerAssetAmount = 2
 | 
			
		||||
            //  .: desiredMakerAmount * exchangeRate is an integer.
 | 
			
		||||
            //
 | 
			
		||||
            // Construct test case using values from example above
 | 
			
		||||
            orderWithoutFee = await orderFactory.newSignedOrderAsync({
 | 
			
		||||
                makerAssetAmount: new BigNumber('30'),
 | 
			
		||||
                takerAssetAmount: new BigNumber('60'),
 | 
			
		||||
                makerAssetData: zrxAssetData,
 | 
			
		||||
                takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
 | 
			
		||||
                makerFee: new BigNumber(0),
 | 
			
		||||
                takerFee: new BigNumber(0),
 | 
			
		||||
            });
 | 
			
		||||
            const ordersWithoutFee = [orderWithoutFee];
 | 
			
		||||
            const feeOrders: SignedOrder[] = [];
 | 
			
		||||
            const makerAssetFillAmount = new BigNumber('5');
 | 
			
		||||
            const ethValue = new BigNumber('10');
 | 
			
		||||
            // Execute test case
 | 
			
		||||
            tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithoutFee, feeOrders, makerAssetFillAmount, {
 | 
			
		||||
                value: ethValue,
 | 
			
		||||
                from: takerAddress,
 | 
			
		||||
            });
 | 
			
		||||
            // Fetch end balances and construct expected outputs
 | 
			
		||||
            const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
 | 
			
		||||
            const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
 | 
			
		||||
            const newBalances = await erc20Wrapper.getBalancesAsync();
 | 
			
		||||
            const primaryTakerAssetFillAmount = ethValue;
 | 
			
		||||
            const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
 | 
			
		||||
            // Validate test case
 | 
			
		||||
            expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
 | 
			
		||||
            expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[takerAddress][zrxToken.address].plus(makerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
 | 
			
		||||
                erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
 | 
			
		||||
            );
 | 
			
		||||
            expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
            expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('marketBuyOrdersWithEth with extra fees', () => {
 | 
			
		||||
        it('should buy an asset and send fee to feeRecipient', async () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -26,9 +26,12 @@ export class ForwarderWrapper {
 | 
			
		||||
        _.forEach(feeOrders, feeOrder => {
 | 
			
		||||
            const feeAvailable = feeOrder.makerAssetAmount.minus(feeOrder.takerFee);
 | 
			
		||||
            if (!remainingFeeAmount.isZero() && feeAvailable.gt(remainingFeeAmount)) {
 | 
			
		||||
                wethAmount = wethAmount
 | 
			
		||||
                    .plus(feeOrder.takerAssetAmount.times(remainingFeeAmount).dividedToIntegerBy(feeAvailable))
 | 
			
		||||
                    .plus(1);
 | 
			
		||||
                wethAmount = wethAmount.plus(
 | 
			
		||||
                    feeOrder.takerAssetAmount
 | 
			
		||||
                        .times(remainingFeeAmount)
 | 
			
		||||
                        .dividedBy(feeAvailable)
 | 
			
		||||
                        .ceil(),
 | 
			
		||||
                );
 | 
			
		||||
                remainingFeeAmount = new BigNumber(0);
 | 
			
		||||
            } else if (!remainingFeeAmount.isZero()) {
 | 
			
		||||
                wethAmount = wethAmount.plus(feeOrder.takerAssetAmount);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/dev-tools-pages",
 | 
			
		||||
    "version": "0.0.2",
 | 
			
		||||
    "version": "0.0.3",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -11,12 +11,12 @@
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
        "build:dev": "../../node_modules/.bin/webpack --mode development",
 | 
			
		||||
        "clean": "shx rm -f public/bundle*",
 | 
			
		||||
        "lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
 | 
			
		||||
        "lint": "tslint --format stylish --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
 | 
			
		||||
        "dev": "webpack-dev-server --mode development --content-base public"
 | 
			
		||||
    },
 | 
			
		||||
    "license": "Apache-2.0",
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/react-shared": "^1.0.17",
 | 
			
		||||
        "@0x/react-shared": "^1.0.18",
 | 
			
		||||
        "basscss": "^8.0.3",
 | 
			
		||||
        "bowser": "^1.9.3",
 | 
			
		||||
        "less": "^2.7.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.14",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.13",
 | 
			
		||||
        "changes": [
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.0.14 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.0.13 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Make web3-provider-engine types a 'dependency' so it's available to users of the library (#1105)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/dev-utils",
 | 
			
		||||
    "version": "1.0.13",
 | 
			
		||||
    "version": "1.0.14",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
        "test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
 | 
			
		||||
        "coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
 | 
			
		||||
        "clean": "shx rm -rf lib",
 | 
			
		||||
        "lint": "tslint --project ."
 | 
			
		||||
        "lint": "tslint --format stylish --project ."
 | 
			
		||||
    },
 | 
			
		||||
    "license": "Apache-2.0",
 | 
			
		||||
    "repository": {
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/dev-utils/README.md",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^2.2.42",
 | 
			
		||||
        "make-promises-safe": "^1.1.0",
 | 
			
		||||
@@ -41,14 +41,14 @@
 | 
			
		||||
        "typescript": "3.0.1"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/subproviders": "^2.1.0",
 | 
			
		||||
        "@0x/types": "^1.2.0",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.0",
 | 
			
		||||
        "@0x/subproviders": "^2.1.1",
 | 
			
		||||
        "@0x/types": "^1.2.1",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.1",
 | 
			
		||||
        "@types/web3-provider-engine": "^14.0.0",
 | 
			
		||||
        "chai": "^4.0.1",
 | 
			
		||||
        "ethereum-types": "^1.1.1",
 | 
			
		||||
        "ethereum-types": "^1.1.2",
 | 
			
		||||
        "lodash": "^4.17.5"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.1.2",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.1.1",
 | 
			
		||||
        "changes": [
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.1.2 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.1.1 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Add `JSONRPCResponseError` and error field on `JSONRPCResponsePayload`. (#1102)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "ethereum-types",
 | 
			
		||||
    "version": "1.1.1",
 | 
			
		||||
    "version": "1.1.2",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
        "build": "tsc -b",
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
        "clean": "shx rm -rf lib generated_docs",
 | 
			
		||||
        "lint": "tslint --project .",
 | 
			
		||||
        "lint": "tslint --format stylish --project .",
 | 
			
		||||
        "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
 | 
			
		||||
    },
 | 
			
		||||
    "config": {
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/ethereum-types/README.md",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "make-promises-safe": "^1.1.0",
 | 
			
		||||
        "shx": "^0.2.2",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.9",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1541740904
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.0.8",
 | 
			
		||||
        "changes": [
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.0.9 - _November 9, 2018_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.0.8 - _October 18, 2018_
 | 
			
		||||
 | 
			
		||||
    * Updated to use new @0xproject/contract-artifacts and @0xproject/abi-gen-wrappers packages (#1105)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/fill-scenarios",
 | 
			
		||||
    "version": "1.0.8",
 | 
			
		||||
    "version": "1.0.9",
 | 
			
		||||
    "description": "0x order fill scenario generator",
 | 
			
		||||
    "main": "lib/index.js",
 | 
			
		||||
    "types": "lib/index.d.ts",
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
        "build": "yarn tsc -b",
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
        "clean": "shx rm -rf lib src/generated_contract_wrappers",
 | 
			
		||||
        "lint": "tslint --project ."
 | 
			
		||||
        "lint": "tslint --format stylish --project ."
 | 
			
		||||
    },
 | 
			
		||||
    "license": "Apache-2.0",
 | 
			
		||||
    "repository": {
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/fill-scenarios/README.md",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "make-promises-safe": "^1.1.0",
 | 
			
		||||
        "shx": "^0.2.2",
 | 
			
		||||
@@ -28,15 +28,15 @@
 | 
			
		||||
        "typescript": "3.0.1"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/abi-gen-wrappers": "^1.0.1",
 | 
			
		||||
        "@0x/base-contract": "^3.0.2",
 | 
			
		||||
        "@0x/contract-artifacts": "^1.0.1",
 | 
			
		||||
        "@0x/order-utils": "^2.0.0",
 | 
			
		||||
        "@0x/types": "^1.2.0",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.0",
 | 
			
		||||
        "ethereum-types": "^1.1.1",
 | 
			
		||||
        "@0x/abi-gen-wrappers": "^1.0.2",
 | 
			
		||||
        "@0x/base-contract": "^3.0.3",
 | 
			
		||||
        "@0x/contract-artifacts": "^1.1.0",
 | 
			
		||||
        "@0x/order-utils": "^2.0.1",
 | 
			
		||||
        "@0x/types": "^1.2.1",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.1",
 | 
			
		||||
        "ethereum-types": "^1.1.2",
 | 
			
		||||
        "ethers": "~4.0.4",
 | 
			
		||||
        "lodash": "^4.17.5"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								packages/instant/.dogfood.discharge.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								packages/instant/.dogfood.discharge.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
{
 | 
			
		||||
    "domain": "0x-instant-dogfood",
 | 
			
		||||
    "build_command": "yarn build:umd:prod",
 | 
			
		||||
    "upload_directory": "public",
 | 
			
		||||
    "index_key": "index.html",
 | 
			
		||||
    "error_key": "index.html",
 | 
			
		||||
    "trailing_slashes": true,
 | 
			
		||||
    "cache": 3600,
 | 
			
		||||
    "aws_profile": "default",
 | 
			
		||||
    "aws_region": "us-east-1",
 | 
			
		||||
    "cdn": false,
 | 
			
		||||
    "dns_configured": true
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								packages/instant/.staging.discharge.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								packages/instant/.staging.discharge.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
{
 | 
			
		||||
    "domain": "0x-instant-staging",
 | 
			
		||||
    "build_command": "yarn build:umd:prod",
 | 
			
		||||
    "upload_directory": "public",
 | 
			
		||||
    "index_key": "index.html",
 | 
			
		||||
    "error_key": "index.html",
 | 
			
		||||
    "trailing_slashes": true,
 | 
			
		||||
    "cache": 3600,
 | 
			
		||||
    "aws_profile": "default",
 | 
			
		||||
    "aws_region": "us-east-1",
 | 
			
		||||
    "cdn": false,
 | 
			
		||||
    "dns_configured": true
 | 
			
		||||
}
 | 
			
		||||
@@ -46,6 +46,26 @@ The package is also available as a UMD module named `zeroExInstant`.
 | 
			
		||||
</body>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Deploying
 | 
			
		||||
 | 
			
		||||
You can deploy a work-in-progress version of 0x Instant at http://0x-instant-dogfood.s3-website-us-east-1.amazonaws.com for easy sharing.
 | 
			
		||||
 | 
			
		||||
To build and deploy the site run
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
yarn deploy_dogfood
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
We also have a staging bucket that is to be updated less frequently can be used to share instant externally: http://0x-instant-staging.s3-website-us-east-1.amazonaws.com/
 | 
			
		||||
 | 
			
		||||
To build and deploy to this bucket, run
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
yarn deploy_staging
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**NOTE: On deploying the site, it will say the site is available at a non-existent URL. Please ignore and use the (now updated) URL above.**
 | 
			
		||||
 | 
			
		||||
## Contributing
 | 
			
		||||
 | 
			
		||||
We welcome improvements and fixes from the wider community! To report bugs within this package, please create an issue in this repository.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/instant",
 | 
			
		||||
    "version": "0.0.3",
 | 
			
		||||
    "version": "0.0.4",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -16,12 +16,14 @@
 | 
			
		||||
        "build:ci": "yarn build",
 | 
			
		||||
        "watch_without_deps": "tsc -w",
 | 
			
		||||
        "dev": "webpack-dev-server --mode development",
 | 
			
		||||
        "lint": "tslint --project .",
 | 
			
		||||
        "lint": "tslint --format stylish --project .",
 | 
			
		||||
        "test": "jest",
 | 
			
		||||
        "test:coverage": "jest --coverage",
 | 
			
		||||
        "rebuild_and_test": "run-s clean build test",
 | 
			
		||||
        "test:circleci": "yarn test:coverage",
 | 
			
		||||
        "clean": "shx rm -rf lib coverage scripts",
 | 
			
		||||
        "deploy_dogfood": "discharge deploy -c .dogfood.discharge.json",
 | 
			
		||||
        "deploy_staging": "discharge deploy -c .staging.discharge.json",
 | 
			
		||||
        "manual:postpublish": "yarn build; node ./scripts/postpublish.js"
 | 
			
		||||
    },
 | 
			
		||||
    "config": {
 | 
			
		||||
@@ -43,12 +45,17 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/0x-monorepo/packages/instant/README.md",
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/asset-buyer": "^2.1.0",
 | 
			
		||||
        "@0x/types": "^1.2.0",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.3",
 | 
			
		||||
        "@0x/utils": "^2.0.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.0",
 | 
			
		||||
        "ethereum-types": "^1.1.1",
 | 
			
		||||
        "@0x/assert": "^1.0.15",
 | 
			
		||||
        "@0x/asset-buyer": "^2.2.0",
 | 
			
		||||
        "@0x/json-schemas": "^2.0.1",
 | 
			
		||||
        "@0x/order-utils": "^2.0.1",
 | 
			
		||||
        "@0x/subproviders": "^2.1.1",
 | 
			
		||||
        "@0x/types": "^1.2.1",
 | 
			
		||||
        "@0x/typescript-typings": "^3.0.4",
 | 
			
		||||
        "@0x/utils": "^2.0.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^3.1.1",
 | 
			
		||||
        "copy-to-clipboard": "^3.0.8",
 | 
			
		||||
        "ethereum-types": "^1.1.2",
 | 
			
		||||
        "lodash": "^4.17.10",
 | 
			
		||||
        "polished": "^2.2.0",
 | 
			
		||||
        "react": "^16.5.2",
 | 
			
		||||
@@ -56,11 +63,12 @@
 | 
			
		||||
        "react-redux": "^5.0.7",
 | 
			
		||||
        "redux": "^4.0.0",
 | 
			
		||||
        "redux-devtools-extension": "^2.13.5",
 | 
			
		||||
        "styled-components": "^3.4.9",
 | 
			
		||||
        "styled-components": "^4.0.2",
 | 
			
		||||
        "ts-optchain": "^0.1.1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/tslint-config": "^1.0.9",
 | 
			
		||||
        "@0x/tslint-config": "^1.0.10",
 | 
			
		||||
        "@static/discharge": "https://github.com/0xProject/discharge.git",
 | 
			
		||||
        "@types/enzyme": "^3.1.14",
 | 
			
		||||
        "@types/enzyme-adapter-react-16": "^1.0.3",
 | 
			
		||||
        "@types/jest": "^23.3.5",
 | 
			
		||||
@@ -70,6 +78,7 @@
 | 
			
		||||
        "@types/react-dom": "^16.0.8",
 | 
			
		||||
        "@types/react-redux": "^6.0.9",
 | 
			
		||||
        "@types/redux": "^3.6.0",
 | 
			
		||||
        "@types/styled-components": "^4.0.1",
 | 
			
		||||
        "awesome-typescript-loader": "^5.2.1",
 | 
			
		||||
        "enzyme": "^3.6.0",
 | 
			
		||||
        "enzyme-adapter-react-16": "^1.5.0",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								packages/instant/public/external.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								packages/instant/public/external.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
/*
 | 
			
		||||
  CSS file meant to represent an external (integrators) stylesheet and 
 | 
			
		||||
  help ensure that instant looks consistent across environments. 
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
button {
 | 
			
		||||
    font-size: 50px;
 | 
			
		||||
    height: 200px;
 | 
			
		||||
    background-color: red;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
input {
 | 
			
		||||
    padding: 100px;
 | 
			
		||||
    font-size: 50px;
 | 
			
		||||
    height: 100px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div {
 | 
			
		||||
    padding: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
p {
 | 
			
		||||
    background-color: green;
 | 
			
		||||
    margin: 10px;
 | 
			
		||||
}
 | 
			
		||||
@@ -5,7 +5,10 @@
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
    <title>0x Instant Dev Environment</title>
 | 
			
		||||
    <link rel="stylesheet" href="/external.css">
 | 
			
		||||
    <script type="text/javascript" src="/main.bundle.js" charset="utf-8"></script>
 | 
			
		||||
    <script type="text/javascript" src="https://unpkg.com/jsuri@1.3.1/Uri.js" charset="utf-8"></script>
 | 
			
		||||
    <script type="text/javascript" src="https://unpkg.com/bignumber.js@4.1.0/bignumber.js" charset="utf-8"></script>
 | 
			
		||||
    <style>
 | 
			
		||||
        #zeroExInstantContainer {
 | 
			
		||||
            display: flex;
 | 
			
		||||
@@ -24,9 +27,110 @@
 | 
			
		||||
<body>
 | 
			
		||||
    <div id="zeroExInstantContainer"></div>
 | 
			
		||||
    <script>
 | 
			
		||||
        zeroExInstant.render({
 | 
			
		||||
 | 
			
		||||
        const removeUndefined = (obj) => {
 | 
			
		||||
            for (let k in obj) if (obj[k] === undefined) delete obj[k];
 | 
			
		||||
            return obj;
 | 
			
		||||
        }
 | 
			
		||||
        BigNumber.config({
 | 
			
		||||
            EXPONENTIAL_AT: 1000,
 | 
			
		||||
            DECIMAL_PLACES: 78,
 | 
			
		||||
        });
 | 
			
		||||
        const providedOrders = [
 | 
			
		||||
            // Order selling REP
 | 
			
		||||
            {
 | 
			
		||||
                senderAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
 | 
			
		||||
                takerAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                makerFee: new BigNumber('0'),
 | 
			
		||||
                takerFee: new BigNumber('0'),
 | 
			
		||||
                makerAssetAmount: new BigNumber('200000000000000000000'),
 | 
			
		||||
                takerAssetAmount: new BigNumber('10000000000000000000'),
 | 
			
		||||
                makerAssetData: '0xf47261b00000000000000000000000008cb3971b8eb709c14616bd556ff6683019e90d9c',
 | 
			
		||||
                takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
 | 
			
		||||
                expirationTimeSeconds: new BigNumber('1601535600'),
 | 
			
		||||
                feeRecipientAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                salt: new BigNumber('3101985707338942582579795423923841749956600670712030922928319824580764688653'),
 | 
			
		||||
                signature: '0x1bd4d5686fea801fe33c68c4944356085e7e6cb553eb7073160abd815609f714e85fb47f44b7ffd0a2a1321ac40d72d55163869d0a50fdb5a402132150fe33a08403',
 | 
			
		||||
                exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2'
 | 
			
		||||
            },
 | 
			
		||||
            // Order selling ZRX
 | 
			
		||||
            {
 | 
			
		||||
                senderAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
 | 
			
		||||
                takerAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                makerFee: new BigNumber('0'),
 | 
			
		||||
                takerFee: new BigNumber('0'),
 | 
			
		||||
                makerAssetAmount: new BigNumber('300000000000000000000'),
 | 
			
		||||
                takerAssetAmount: new BigNumber('31000000000000000000'),
 | 
			
		||||
                makerAssetData: '0xf47261b00000000000000000000000002002d3812f58e35f0ea1ffbf80a75a38c32175fa',
 | 
			
		||||
                takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
 | 
			
		||||
                expirationTimeSeconds: new BigNumber('2524636800'),
 | 
			
		||||
                feeRecipientAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                salt: new BigNumber('64592004666704945574675477805199411288137454783320798602050822322450089238268'),
 | 
			
		||||
                signature: '0x1c13cacddca8d7d8248e91f412377e68f8f1f9891a59a6c1b2eea9f7b33558c30c4fb86a448e08ab7def40a28fb3a3062dcb33bb3c45302447fce5c4288b7c7f5b03',
 | 
			
		||||
                exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2'
 | 
			
		||||
            },
 | 
			
		||||
            // Order selling GNT
 | 
			
		||||
            {
 | 
			
		||||
                senderAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
 | 
			
		||||
                takerAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                makerFee: new BigNumber('0'),
 | 
			
		||||
                takerFee: new BigNumber('0'),
 | 
			
		||||
                makerAssetAmount: new BigNumber('250000000000000000000'),
 | 
			
		||||
                takerAssetAmount: new BigNumber('10000000000000000000'),
 | 
			
		||||
                makerAssetData: '0xf47261b000000000000000000000000031fb614e223706f15d0d3c5f4b08bdf0d5c78623',
 | 
			
		||||
                takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
 | 
			
		||||
                expirationTimeSeconds: new BigNumber('1601535600'),
 | 
			
		||||
                feeRecipientAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                salt: new BigNumber('40204378562212615907903051460421336779451270522691667164301816101569427926606'),
 | 
			
		||||
                signature: '0x1c788bf4b93769da1e8f195f52f0f59b4a298ac6da30cf6d05a87ed4be5ee974f61352ed1bc6a0844d0962b8c894c9ca08e452431255958a4e98dd93cbe1fbc73803',
 | 
			
		||||
                exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2'
 | 
			
		||||
            },
 | 
			
		||||
            // Order selling MKR
 | 
			
		||||
            {
 | 
			
		||||
                senderAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
 | 
			
		||||
                takerAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                makerFee: new BigNumber('0'),
 | 
			
		||||
                takerFee: new BigNumber('0'),
 | 
			
		||||
                makerAssetAmount: new BigNumber('200000000000000000000'),
 | 
			
		||||
                takerAssetAmount: new BigNumber('5000000000000000000'),
 | 
			
		||||
                makerAssetData: '0xf47261b00000000000000000000000007b6b10caa9e8e9552ba72638ea5b47c25afea1f3',
 | 
			
		||||
                takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
 | 
			
		||||
                expirationTimeSeconds: new BigNumber('1601535600'),
 | 
			
		||||
                feeRecipientAddress: '0x0000000000000000000000000000000000000000',
 | 
			
		||||
                salt: new BigNumber('71338269924068280039932133924198049371838034090153601678083172009862985793828'),
 | 
			
		||||
                signature: '0x1bb3151d57ee1e8fa697767ce83ee4ba77d1ceb8cc1e79c7d77126b3687517704c50c6b3d9cb42c7e7d4478d574b297dfbd1626c5c18a7bc9c2a792c4c07f0797c03',
 | 
			
		||||
                exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2'
 | 
			
		||||
            }
 | 
			
		||||
        ];
 | 
			
		||||
        const queryParams = new Uri(window.location.search);
 | 
			
		||||
        const renderOptionsDefaults = {
 | 
			
		||||
            orderSource: 'https://api.radarrelay.com/0x/v2/',
 | 
			
		||||
            onClose: () => { console.log('0x Instant Closed') }
 | 
			
		||||
        }
 | 
			
		||||
        const orderSourceOverride = queryParams.getQueryParamValue('orderSource');
 | 
			
		||||
        const availableAssetDatasString = queryParams.getQueryParamValue('availableAssetDatas');
 | 
			
		||||
        const feeRecipientOverride = queryParams.getQueryParamValue('feeRecipient');
 | 
			
		||||
        const feePercentageOverride = +queryParams.getQueryParamValue('feePercentage');
 | 
			
		||||
        let affiliateInfoOverride;
 | 
			
		||||
        if (feeRecipientOverride !== undefined && feePercentageOverride !== undefined) {
 | 
			
		||||
            affiliateInfoOverride = {
 | 
			
		||||
                feeRecipient: feeRecipientOverride,
 | 
			
		||||
                feePercentage: feePercentageOverride
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        const renderOptionsOverrides = {
 | 
			
		||||
            orderSource: orderSourceOverride === 'provided' ? providedOrders : orderSourceOverride,
 | 
			
		||||
            networkId: +queryParams.getQueryParamValue('networkId') || undefined,
 | 
			
		||||
            defaultAssetBuyAmount: +queryParams.getQueryParamValue('defaultAssetBuyAmount') || undefined,
 | 
			
		||||
            availableAssetDatas: availableAssetDatasString ? JSON.parse(availableAssetDatasString) : undefined,
 | 
			
		||||
            defaultSelectedAssetData: queryParams.getQueryParamValue('defaultSelectedAssetData'),
 | 
			
		||||
            affiliateInfo: affiliateInfoOverride,
 | 
			
		||||
        }
 | 
			
		||||
        const renderOptions = Object.assign({}, renderOptionsDefaults, removeUndefined(renderOptionsOverrides));
 | 
			
		||||
        zeroExInstant.render(renderOptions);
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,49 +0,0 @@
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { util } from '../util/util';
 | 
			
		||||
 | 
			
		||||
import { Container, Input } from './ui';
 | 
			
		||||
 | 
			
		||||
export interface AmountInputProps {
 | 
			
		||||
    fontColor?: ColorOption;
 | 
			
		||||
    fontSize?: string;
 | 
			
		||||
    value?: BigNumber;
 | 
			
		||||
    onChange: (value?: BigNumber) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class AmountInput extends React.Component<AmountInputProps> {
 | 
			
		||||
    public static defaultProps = {
 | 
			
		||||
        onChange: util.boundNoop,
 | 
			
		||||
    };
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { fontColor, fontSize, value } = this.props;
 | 
			
		||||
        return (
 | 
			
		||||
            <Container borderBottom="1px solid rgba(255,255,255,0.3)" display="inline-block">
 | 
			
		||||
                <Input
 | 
			
		||||
                    fontColor={fontColor}
 | 
			
		||||
                    fontSize={fontSize}
 | 
			
		||||
                    onChange={this._handleChange}
 | 
			
		||||
                    value={!_.isUndefined(value) ? value.toString() : ''}
 | 
			
		||||
                    placeholder="0.00"
 | 
			
		||||
                    width="2.2em"
 | 
			
		||||
                />
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private readonly _handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
 | 
			
		||||
        const value = event.target.value;
 | 
			
		||||
        let bigNumberValue;
 | 
			
		||||
        if (!_.isEmpty(value)) {
 | 
			
		||||
            try {
 | 
			
		||||
                bigNumberValue = new BigNumber(event.target.value);
 | 
			
		||||
            } catch {
 | 
			
		||||
                // We don't want to allow values that can't be a BigNumber, so don't even call onChange.
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        this.props.onChange(bigNumberValue);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								packages/instant/src/components/amount_placeholder.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								packages/instant/src/components/amount_placeholder.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
 | 
			
		||||
import { Pulse } from './animations/pulse';
 | 
			
		||||
 | 
			
		||||
import { Text } from './ui/text';
 | 
			
		||||
 | 
			
		||||
interface PlainPlaceholder {
 | 
			
		||||
    color: ColorOption;
 | 
			
		||||
}
 | 
			
		||||
const PlainPlaceholder: React.StatelessComponent<PlainPlaceholder> = props => (
 | 
			
		||||
    <Text fontWeight="bold" fontColor={props.color}>
 | 
			
		||||
        —
 | 
			
		||||
    </Text>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export interface AmountPlaceholderProps {
 | 
			
		||||
    color: ColorOption;
 | 
			
		||||
    isPulsating: boolean;
 | 
			
		||||
}
 | 
			
		||||
export const AmountPlaceholder: React.StatelessComponent<AmountPlaceholderProps> = props => {
 | 
			
		||||
    if (props.isPulsating) {
 | 
			
		||||
        return (
 | 
			
		||||
            <Pulse>
 | 
			
		||||
                <PlainPlaceholder color={props.color} />
 | 
			
		||||
            </Pulse>
 | 
			
		||||
        );
 | 
			
		||||
    } else {
 | 
			
		||||
        return <PlainPlaceholder color={props.color} />;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										24
									
								
								packages/instant/src/components/animations/full_rotation.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								packages/instant/src/components/animations/full_rotation.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
import { keyframes, styled } from '../../style/theme';
 | 
			
		||||
 | 
			
		||||
interface FullRotationProps {
 | 
			
		||||
    height: string;
 | 
			
		||||
    width: string;
 | 
			
		||||
}
 | 
			
		||||
const rotatingKeyframes = keyframes`
 | 
			
		||||
from {
 | 
			
		||||
  transform: rotate(0deg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
to {
 | 
			
		||||
  transform: rotate(360deg);
 | 
			
		||||
}
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
export const FullRotation =
 | 
			
		||||
    styled.div <
 | 
			
		||||
    FullRotationProps >
 | 
			
		||||
    `
 | 
			
		||||
    animation: ${rotatingKeyframes} 2s linear infinite;
 | 
			
		||||
    height: ${props => props.height};
 | 
			
		||||
    width: ${props => props.width};
 | 
			
		||||
`;
 | 
			
		||||
@@ -0,0 +1,110 @@
 | 
			
		||||
import { InterpolationValue } from 'styled-components';
 | 
			
		||||
 | 
			
		||||
import { media, OptionallyScreenSpecific, stylesForMedia } from '../../style/media';
 | 
			
		||||
import { css, keyframes, styled } from '../../style/theme';
 | 
			
		||||
 | 
			
		||||
export interface TransitionInfo {
 | 
			
		||||
    from: string;
 | 
			
		||||
    to: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const generateTransitionInfoCss = (
 | 
			
		||||
    key: keyof TransitionInfo,
 | 
			
		||||
    top?: TransitionInfo,
 | 
			
		||||
    bottom?: TransitionInfo,
 | 
			
		||||
    left?: TransitionInfo,
 | 
			
		||||
    right?: TransitionInfo,
 | 
			
		||||
): string => {
 | 
			
		||||
    const topStringIfExists = top ? `top: ${top[key]};` : '';
 | 
			
		||||
    const bottomStringIfExists = bottom ? `bottom: ${bottom[key]};` : '';
 | 
			
		||||
    const leftStringIfExists = left ? `left: ${left[key]};` : '';
 | 
			
		||||
    const rightStringIfExists = right ? `right: ${right[key]};` : '';
 | 
			
		||||
    return `
 | 
			
		||||
    ${topStringIfExists}
 | 
			
		||||
    ${bottomStringIfExists}
 | 
			
		||||
    ${leftStringIfExists}
 | 
			
		||||
    ${rightStringIfExists}
 | 
			
		||||
    `;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const slideKeyframeGenerator = (
 | 
			
		||||
    position: string,
 | 
			
		||||
    top?: TransitionInfo,
 | 
			
		||||
    bottom?: TransitionInfo,
 | 
			
		||||
    left?: TransitionInfo,
 | 
			
		||||
    right?: TransitionInfo,
 | 
			
		||||
) => keyframes`
 | 
			
		||||
    from {
 | 
			
		||||
        position: ${position};
 | 
			
		||||
        ${generateTransitionInfoCss('from', top, bottom, left, right)}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    to {
 | 
			
		||||
        position: ${position};
 | 
			
		||||
        ${generateTransitionInfoCss('to', top, bottom, left, right)}
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
export interface PositionAnimationSettings {
 | 
			
		||||
    top?: TransitionInfo;
 | 
			
		||||
    bottom?: TransitionInfo;
 | 
			
		||||
    left?: TransitionInfo;
 | 
			
		||||
    right?: TransitionInfo;
 | 
			
		||||
    timingFunction: string;
 | 
			
		||||
    duration?: string;
 | 
			
		||||
    position?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const generatePositionAnimationCss = (positionSettings: PositionAnimationSettings) => {
 | 
			
		||||
    return css`
 | 
			
		||||
        animation-name: ${slideKeyframeGenerator(
 | 
			
		||||
            positionSettings.position || 'relative',
 | 
			
		||||
            positionSettings.top,
 | 
			
		||||
            positionSettings.bottom,
 | 
			
		||||
            positionSettings.left,
 | 
			
		||||
            positionSettings.right,
 | 
			
		||||
        )};
 | 
			
		||||
        animation-duration: ${positionSettings.duration || '0.3s'};
 | 
			
		||||
        animation-timing-function: ${positionSettings.timingFunction};
 | 
			
		||||
        animation-delay: 0s;
 | 
			
		||||
        animation-iteration-count: 1;
 | 
			
		||||
        animation-fill-mode: forwards;
 | 
			
		||||
        position: ${positionSettings.position || 'relative'};
 | 
			
		||||
        width: 100%;
 | 
			
		||||
    `;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export interface PositionAnimationProps {
 | 
			
		||||
    positionSettings: OptionallyScreenSpecific<PositionAnimationSettings>;
 | 
			
		||||
    zIndex?: OptionallyScreenSpecific<number>;
 | 
			
		||||
    height?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const defaultAnimation = (positionSettings: OptionallyScreenSpecific<PositionAnimationSettings>) => {
 | 
			
		||||
    const bestDefault = 'default' in positionSettings ? positionSettings.default : positionSettings;
 | 
			
		||||
    return generatePositionAnimationCss(bestDefault);
 | 
			
		||||
};
 | 
			
		||||
const animationForSize = (
 | 
			
		||||
    positionSettings: OptionallyScreenSpecific<PositionAnimationSettings>,
 | 
			
		||||
    sizeKey: 'sm' | 'md' | 'lg',
 | 
			
		||||
    mediaFn: (...args: any[]) => InterpolationValue[],
 | 
			
		||||
) => {
 | 
			
		||||
    // checking default makes sure we have a PositionAnimationSettings object
 | 
			
		||||
    // and then we check to see if we have a setting for the specific `sizeKey`
 | 
			
		||||
    const animationSettingsForSize = 'default' in positionSettings && positionSettings[sizeKey];
 | 
			
		||||
    return animationSettingsForSize && mediaFn`${generatePositionAnimationCss(animationSettingsForSize)}`;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const PositionAnimation =
 | 
			
		||||
    styled.div <
 | 
			
		||||
    PositionAnimationProps >
 | 
			
		||||
    `
 | 
			
		||||
    && {
 | 
			
		||||
        ${props => props.zIndex && stylesForMedia<number>('z-index', props.zIndex)}
 | 
			
		||||
        ${props => defaultAnimation(props.positionSettings)}
 | 
			
		||||
        ${props => animationForSize(props.positionSettings, 'sm', media.small)}
 | 
			
		||||
        ${props => animationForSize(props.positionSettings, 'md', media.medium)}
 | 
			
		||||
        ${props => animationForSize(props.positionSettings, 'lg', media.large)}
 | 
			
		||||
        ${props => (props.height ? `height: ${props.height};` : '')}
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
							
								
								
									
										15
									
								
								packages/instant/src/components/animations/pulse.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								packages/instant/src/components/animations/pulse.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
import { keyframes, styled } from '../../style/theme';
 | 
			
		||||
 | 
			
		||||
const pulsingKeyframes = keyframes`
 | 
			
		||||
    0%, 100% {
 | 
			
		||||
        opacity: 0.2;
 | 
			
		||||
    }
 | 
			
		||||
    50% {
 | 
			
		||||
        opacity: 100;
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
export const Pulse = styled.div`
 | 
			
		||||
    animation-name: ${pulsingKeyframes}
 | 
			
		||||
    animation-duration: 2s;
 | 
			
		||||
    animation-iteration-count: infinite;
 | 
			
		||||
`;
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { OptionallyScreenSpecific } from '../../style/media';
 | 
			
		||||
 | 
			
		||||
import { PositionAnimation, PositionAnimationSettings } from './position_animation';
 | 
			
		||||
 | 
			
		||||
export type SlideAnimationState = 'slidIn' | 'slidOut' | 'none';
 | 
			
		||||
export interface SlideAnimationProps {
 | 
			
		||||
    animationState: SlideAnimationState;
 | 
			
		||||
    slideInSettings: OptionallyScreenSpecific<PositionAnimationSettings>;
 | 
			
		||||
    slideOutSettings: OptionallyScreenSpecific<PositionAnimationSettings>;
 | 
			
		||||
    zIndex?: OptionallyScreenSpecific<number>;
 | 
			
		||||
    height?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const SlideAnimation: React.StatelessComponent<SlideAnimationProps> = props => {
 | 
			
		||||
    if (props.animationState === 'none') {
 | 
			
		||||
        return <React.Fragment>{props.children}</React.Fragment>;
 | 
			
		||||
    }
 | 
			
		||||
    const positionSettings = props.animationState === 'slidIn' ? props.slideInSettings : props.slideOutSettings;
 | 
			
		||||
    return (
 | 
			
		||||
        <PositionAnimation height={props.height} positionSettings={positionSettings} zIndex={props.zIndex}>
 | 
			
		||||
            {props.children}
 | 
			
		||||
        </PositionAnimation>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
@@ -1,54 +0,0 @@
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { keyframes, styled } from '../../style/theme';
 | 
			
		||||
 | 
			
		||||
const slideKeyframeGenerator = (fromY: string, toY: string) => keyframes`
 | 
			
		||||
    from {
 | 
			
		||||
        position: relative;
 | 
			
		||||
        top: ${fromY};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    to {
 | 
			
		||||
        position: relative;
 | 
			
		||||
        top: ${toY};
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
export interface SlideAnimationProps {
 | 
			
		||||
    keyframes: string;
 | 
			
		||||
    animationType: string;
 | 
			
		||||
    animationDirection?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const SlideAnimation =
 | 
			
		||||
    styled.div <
 | 
			
		||||
    SlideAnimationProps >
 | 
			
		||||
    `
 | 
			
		||||
    animation-name: ${props => props.keyframes};
 | 
			
		||||
    animation-duration: 0.3s;
 | 
			
		||||
    animation-timing-function: ${props => props.animationType};
 | 
			
		||||
    animation-delay: 0s;
 | 
			
		||||
    animation-iteration-count: 1;
 | 
			
		||||
    animation-fill-mode: ${props => props.animationDirection || 'none'};
 | 
			
		||||
    position: relative;
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
export interface SlideAnimationComponentProps {
 | 
			
		||||
    downY: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const SlideUpAnimation: React.StatelessComponent<SlideAnimationComponentProps> = props => (
 | 
			
		||||
    <SlideAnimation animationType="ease-in" keyframes={slideKeyframeGenerator(props.downY, '0px')}>
 | 
			
		||||
        {props.children}
 | 
			
		||||
    </SlideAnimation>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const SlideDownAnimation: React.StatelessComponent<SlideAnimationComponentProps> = props => (
 | 
			
		||||
    <SlideAnimation
 | 
			
		||||
        animationDirection="forwards"
 | 
			
		||||
        animationType="cubic-bezier(0.25, 0.1, 0.25, 1)"
 | 
			
		||||
        keyframes={slideKeyframeGenerator('0px', props.downY)}
 | 
			
		||||
    >
 | 
			
		||||
        {props.children}
 | 
			
		||||
    </SlideAnimation>
 | 
			
		||||
);
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { assetDataUtil } from '../util/asset_data';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { util } from '../util/util';
 | 
			
		||||
 | 
			
		||||
import { AmountInput, AmountInputProps } from './amount_input';
 | 
			
		||||
import { Container, Text } from './ui';
 | 
			
		||||
 | 
			
		||||
export interface AssetAmountInputProps extends AmountInputProps {
 | 
			
		||||
    assetData?: string;
 | 
			
		||||
    onChange: (value?: BigNumber, assetData?: string) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class AssetAmountInput extends React.Component<AssetAmountInputProps> {
 | 
			
		||||
    public static defaultProps = {
 | 
			
		||||
        onChange: util.boundNoop,
 | 
			
		||||
    };
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { assetData, onChange, ...rest } = this.props;
 | 
			
		||||
        return (
 | 
			
		||||
            <Container>
 | 
			
		||||
                <AmountInput {...rest} onChange={this._handleChange} />
 | 
			
		||||
                <Container display="inline-block" marginLeft="10px">
 | 
			
		||||
                    <Text fontSize={rest.fontSize} fontColor={ColorOption.white} textTransform="uppercase">
 | 
			
		||||
                        {assetDataUtil.bestNameForAsset(this.props.assetData, '???')}
 | 
			
		||||
                    </Text>
 | 
			
		||||
                </Container>
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private readonly _handleChange = (value?: BigNumber): void => {
 | 
			
		||||
        this.props.onChange(value, this.props.assetData);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +1,31 @@
 | 
			
		||||
import { BuyQuote } from '@0x/asset-buyer';
 | 
			
		||||
import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
import { oc } from 'ts-optchain';
 | 
			
		||||
 | 
			
		||||
import { WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants';
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { assetBuyer } from '../util/asset_buyer';
 | 
			
		||||
import { AffiliateInfo, ZeroExInstantError } from '../types';
 | 
			
		||||
import { gasPriceEstimator } from '../util/gas_price_estimator';
 | 
			
		||||
import { util } from '../util/util';
 | 
			
		||||
import { web3Wrapper } from '../util/web3_wrapper';
 | 
			
		||||
 | 
			
		||||
import { Button, Container, Text } from './ui';
 | 
			
		||||
import { Button } from './ui/button';
 | 
			
		||||
 | 
			
		||||
export interface BuyButtonProps {
 | 
			
		||||
    accountAddress?: string;
 | 
			
		||||
    accountEthBalanceInWei?: BigNumber;
 | 
			
		||||
    buyQuote?: BuyQuote;
 | 
			
		||||
    onClick: (buyQuote: BuyQuote) => void;
 | 
			
		||||
    onBuySuccess: (buyQuote: BuyQuote, txnHash: string) => void;
 | 
			
		||||
    onBuyFailure: (buyQuote: BuyQuote, tnxHash?: string) => void;
 | 
			
		||||
    text: string;
 | 
			
		||||
    assetBuyer: AssetBuyer;
 | 
			
		||||
    web3Wrapper: Web3Wrapper;
 | 
			
		||||
    affiliateInfo?: AffiliateInfo;
 | 
			
		||||
    onValidationPending: (buyQuote: BuyQuote) => void;
 | 
			
		||||
    onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void;
 | 
			
		||||
    onSignatureDenied: (buyQuote: BuyQuote) => void;
 | 
			
		||||
    onBuyProcessing: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void;
 | 
			
		||||
    onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void;
 | 
			
		||||
    onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class BuyButton extends React.Component<BuyButtonProps> {
 | 
			
		||||
@@ -24,30 +35,67 @@ export class BuyButton extends React.Component<BuyButtonProps> {
 | 
			
		||||
        onBuyFailure: util.boundNoop,
 | 
			
		||||
    };
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const shouldDisableButton = _.isUndefined(this.props.buyQuote);
 | 
			
		||||
        const { buyQuote, accountAddress } = this.props;
 | 
			
		||||
        const shouldDisableButton = _.isUndefined(buyQuote) || _.isUndefined(accountAddress);
 | 
			
		||||
        return (
 | 
			
		||||
            <Container padding="20px" width="100%">
 | 
			
		||||
                <Button width="100%" onClick={this._handleClick} isDisabled={shouldDisableButton}>
 | 
			
		||||
                    <Text fontColor={ColorOption.white} fontWeight={600} fontSize="20px">
 | 
			
		||||
                        {this.props.text}
 | 
			
		||||
                    </Text>
 | 
			
		||||
                </Button>
 | 
			
		||||
            </Container>
 | 
			
		||||
            <Button
 | 
			
		||||
                width="100%"
 | 
			
		||||
                onClick={this._handleClick}
 | 
			
		||||
                isDisabled={shouldDisableButton}
 | 
			
		||||
                fontColor={ColorOption.white}
 | 
			
		||||
                fontSize="20px"
 | 
			
		||||
            >
 | 
			
		||||
                Buy
 | 
			
		||||
            </Button>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private readonly _handleClick = async () => {
 | 
			
		||||
        // The button is disabled when there is no buy quote anyway.
 | 
			
		||||
        if (_.isUndefined(this.props.buyQuote)) {
 | 
			
		||||
        const { buyQuote, assetBuyer, affiliateInfo, accountAddress, accountEthBalanceInWei, web3Wrapper } = this.props;
 | 
			
		||||
        if (_.isUndefined(buyQuote) || _.isUndefined(accountAddress)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        this.props.onClick(this.props.buyQuote);
 | 
			
		||||
        let txnHash;
 | 
			
		||||
        try {
 | 
			
		||||
            txnHash = await assetBuyer.executeBuyQuoteAsync(this.props.buyQuote);
 | 
			
		||||
            await web3Wrapper.awaitTransactionSuccessAsync(txnHash);
 | 
			
		||||
            this.props.onBuySuccess(this.props.buyQuote, txnHash);
 | 
			
		||||
        } catch {
 | 
			
		||||
            this.props.onBuyFailure(this.props.buyQuote, txnHash);
 | 
			
		||||
        this.props.onValidationPending(buyQuote);
 | 
			
		||||
        const ethNeededForBuy = buyQuote.worstCaseQuoteInfo.totalEthAmount;
 | 
			
		||||
        // if we don't have a balance for the user, let the transaction through, it will be handled by the wallet
 | 
			
		||||
        const hasSufficientEth = _.isUndefined(accountEthBalanceInWei) || accountEthBalanceInWei.gte(ethNeededForBuy);
 | 
			
		||||
        if (!hasSufficientEth) {
 | 
			
		||||
            this.props.onValidationFail(buyQuote, ZeroExInstantError.InsufficientETH);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        let txHash: string | undefined;
 | 
			
		||||
        const gasInfo = await gasPriceEstimator.getGasInfoAsync();
 | 
			
		||||
        const feeRecipient = oc(affiliateInfo).feeRecipient();
 | 
			
		||||
        try {
 | 
			
		||||
            txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, {
 | 
			
		||||
                feeRecipient,
 | 
			
		||||
                takerAddress: accountAddress,
 | 
			
		||||
                gasPrice: gasInfo.gasPriceInWei,
 | 
			
		||||
            });
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            if (e instanceof Error) {
 | 
			
		||||
                if (e.message === AssetBuyerError.SignatureRequestDenied) {
 | 
			
		||||
                    this.props.onSignatureDenied(buyQuote);
 | 
			
		||||
                    return;
 | 
			
		||||
                } else if (e.message === AssetBuyerError.TransactionValueTooLow) {
 | 
			
		||||
                    this.props.onValidationFail(buyQuote, AssetBuyerError.TransactionValueTooLow);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
        const startTimeUnix = new Date().getTime();
 | 
			
		||||
        const expectedEndTimeUnix = startTimeUnix + gasInfo.estimatedTimeMs;
 | 
			
		||||
        this.props.onBuyProcessing(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix);
 | 
			
		||||
        try {
 | 
			
		||||
            await web3Wrapper.awaitTransactionSuccessAsync(txHash);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            if (e instanceof Error && e.message.startsWith(WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX)) {
 | 
			
		||||
                this.props.onBuyFailure(buyQuote, txHash);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
        this.props.onBuySuccess(buyQuote, txHash);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								packages/instant/src/components/buy_order_progress.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								packages/instant/src/components/buy_order_progress.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { TimedProgressBar } from '../components/timed_progress_bar';
 | 
			
		||||
 | 
			
		||||
import { TimeCounter } from '../components/time_counter';
 | 
			
		||||
import { Container } from '../components/ui/container';
 | 
			
		||||
import { OrderProcessState, OrderState } from '../types';
 | 
			
		||||
 | 
			
		||||
export interface BuyOrderProgressProps {
 | 
			
		||||
    buyOrderState: OrderState;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const BuyOrderProgress: React.StatelessComponent<BuyOrderProgressProps> = props => {
 | 
			
		||||
    const { buyOrderState } = props;
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
        buyOrderState.processState === OrderProcessState.Processing ||
 | 
			
		||||
        buyOrderState.processState === OrderProcessState.Success ||
 | 
			
		||||
        buyOrderState.processState === OrderProcessState.Failure
 | 
			
		||||
    ) {
 | 
			
		||||
        const progress = buyOrderState.progress;
 | 
			
		||||
        const hasEnded = buyOrderState.processState !== OrderProcessState.Processing;
 | 
			
		||||
        const expectedTimeMs = progress.expectedEndTimeUnix - progress.startTimeUnix;
 | 
			
		||||
        return (
 | 
			
		||||
            <Container padding="20px 20px 0px 20px" width="100%">
 | 
			
		||||
                <Container marginBottom="5px">
 | 
			
		||||
                    <TimeCounter estimatedTimeMs={expectedTimeMs} hasEnded={hasEnded} key={progress.startTimeUnix} />
 | 
			
		||||
                </Container>
 | 
			
		||||
                <TimedProgressBar expectedTimeMs={expectedTimeMs} hasEnded={hasEnded} key={progress.startTimeUnix} />
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return null;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										71
									
								
								packages/instant/src/components/buy_order_state_buttons.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								packages/instant/src/components/buy_order_state_buttons.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { AffiliateInfo, OrderProcessState, ZeroExInstantError } from '../types';
 | 
			
		||||
 | 
			
		||||
import { BuyButton } from './buy_button';
 | 
			
		||||
import { PlacingOrderButton } from './placing_order_button';
 | 
			
		||||
import { SecondaryButton } from './secondary_button';
 | 
			
		||||
 | 
			
		||||
import { Button } from './ui/button';
 | 
			
		||||
import { Flex } from './ui/flex';
 | 
			
		||||
 | 
			
		||||
export interface BuyOrderStateButtonProps {
 | 
			
		||||
    accountAddress?: string;
 | 
			
		||||
    accountEthBalanceInWei?: BigNumber;
 | 
			
		||||
    buyQuote?: BuyQuote;
 | 
			
		||||
    buyOrderProcessingState: OrderProcessState;
 | 
			
		||||
    assetBuyer: AssetBuyer;
 | 
			
		||||
    web3Wrapper: Web3Wrapper;
 | 
			
		||||
    affiliateInfo?: AffiliateInfo;
 | 
			
		||||
    onViewTransaction: () => void;
 | 
			
		||||
    onValidationPending: (buyQuote: BuyQuote) => void;
 | 
			
		||||
    onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void;
 | 
			
		||||
    onSignatureDenied: (buyQuote: BuyQuote) => void;
 | 
			
		||||
    onBuyProcessing: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void;
 | 
			
		||||
    onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void;
 | 
			
		||||
    onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void;
 | 
			
		||||
    onRetry: () => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const BuyOrderStateButtons: React.StatelessComponent<BuyOrderStateButtonProps> = props => {
 | 
			
		||||
    if (props.buyOrderProcessingState === OrderProcessState.Failure) {
 | 
			
		||||
        return (
 | 
			
		||||
            <Flex justify="space-between">
 | 
			
		||||
                <Button width="48%" onClick={props.onRetry} fontColor={ColorOption.white} fontSize="16px">
 | 
			
		||||
                    Back
 | 
			
		||||
                </Button>
 | 
			
		||||
                <SecondaryButton width="48%" onClick={props.onViewTransaction}>
 | 
			
		||||
                    Details
 | 
			
		||||
                </SecondaryButton>
 | 
			
		||||
            </Flex>
 | 
			
		||||
        );
 | 
			
		||||
    } else if (
 | 
			
		||||
        props.buyOrderProcessingState === OrderProcessState.Success ||
 | 
			
		||||
        props.buyOrderProcessingState === OrderProcessState.Processing
 | 
			
		||||
    ) {
 | 
			
		||||
        return <SecondaryButton onClick={props.onViewTransaction}>View Transaction</SecondaryButton>;
 | 
			
		||||
    } else if (props.buyOrderProcessingState === OrderProcessState.Validating) {
 | 
			
		||||
        return <PlacingOrderButton />;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <BuyButton
 | 
			
		||||
            accountAddress={props.accountAddress}
 | 
			
		||||
            accountEthBalanceInWei={props.accountEthBalanceInWei}
 | 
			
		||||
            buyQuote={props.buyQuote}
 | 
			
		||||
            assetBuyer={props.assetBuyer}
 | 
			
		||||
            web3Wrapper={props.web3Wrapper}
 | 
			
		||||
            affiliateInfo={props.affiliateInfo}
 | 
			
		||||
            onValidationPending={props.onValidationPending}
 | 
			
		||||
            onValidationFail={props.onValidationFail}
 | 
			
		||||
            onSignatureDenied={props.onSignatureDenied}
 | 
			
		||||
            onBuyProcessing={props.onBuyProcessing}
 | 
			
		||||
            onBuySuccess={props.onBuySuccess}
 | 
			
		||||
            onBuyFailure={props.onBuyFailure}
 | 
			
		||||
        />
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										32
									
								
								packages/instant/src/components/css_reset.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								packages/instant/src/components/css_reset.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
import { INJECTED_DIV_CLASS } from '../constants';
 | 
			
		||||
import { createGlobalStyle } from '../style/theme';
 | 
			
		||||
 | 
			
		||||
export interface CSSResetProps {}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* Derived from
 | 
			
		||||
* https://github.com/jtrost/Complete-CSS-Reset
 | 
			
		||||
*/
 | 
			
		||||
export const CSSReset = createGlobalStyle`
 | 
			
		||||
    .${INJECTED_DIV_CLASS} {
 | 
			
		||||
        a, abbr, area, article, aside, audio, b, bdo, blockquote, body, button,
 | 
			
		||||
        canvas, caption, cite, code, col, colgroup, command, datalist, dd, del,
 | 
			
		||||
        details, dialog, dfn, div, dl, dt, em, embed, fieldset, figure, form,
 | 
			
		||||
        h1, h2, h3, h4, h5, h6, head, header, hgroup, hr, html, i, iframe, img,
 | 
			
		||||
        input, ins, keygen, kbd, label, legend, li, map, mark, menu, meter, nav,
 | 
			
		||||
        noscript, object, ol, optgroup, option, output, p, param, pre, progress,
 | 
			
		||||
        q, rp, rt, ruby, samp, section, select, small, span, strong, sub, sup,
 | 
			
		||||
        table, tbody, td, textarea, tfoot, th, thead, time, tr, ul, var, video {
 | 
			
		||||
            background: transparent;
 | 
			
		||||
            border: 0;
 | 
			
		||||
            font-size: 100%;
 | 
			
		||||
            font: inherit;
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            outline: none;
 | 
			
		||||
            padding: 0;
 | 
			
		||||
            text-align: left;
 | 
			
		||||
            text-decoration: none;
 | 
			
		||||
            vertical-align: baseline;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
							
								
								
									
										161
									
								
								packages/instant/src/components/erc20_asset_amount_input.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								packages/instant/src/components/erc20_asset_amount_input.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { ColorOption, transparentWhite } from '../style/theme';
 | 
			
		||||
import { ERC20Asset, SimpleHandler } from '../types';
 | 
			
		||||
import { assetUtils } from '../util/asset';
 | 
			
		||||
import { util } from '../util/util';
 | 
			
		||||
 | 
			
		||||
import { ScalingAmountInput } from './scaling_amount_input';
 | 
			
		||||
 | 
			
		||||
import { Container } from './ui/container';
 | 
			
		||||
import { Flex } from './ui/flex';
 | 
			
		||||
import { Icon } from './ui/icon';
 | 
			
		||||
import { Text } from './ui/text';
 | 
			
		||||
 | 
			
		||||
// Asset amounts only apply to ERC20 assets
 | 
			
		||||
export interface ERC20AssetAmountInputProps {
 | 
			
		||||
    asset?: ERC20Asset;
 | 
			
		||||
    value?: BigNumber;
 | 
			
		||||
    onChange: (value?: BigNumber, asset?: ERC20Asset) => void;
 | 
			
		||||
    onSelectAssetClick?: (asset?: ERC20Asset) => void;
 | 
			
		||||
    startingFontSizePx: number;
 | 
			
		||||
    fontColor?: ColorOption;
 | 
			
		||||
    isDisabled: boolean;
 | 
			
		||||
    numberOfAssetsAvailable?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ERC20AssetAmountInputState {
 | 
			
		||||
    currentFontSizePx: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ERC20AssetAmountInput extends React.Component<ERC20AssetAmountInputProps, ERC20AssetAmountInputState> {
 | 
			
		||||
    public static defaultProps = {
 | 
			
		||||
        onChange: util.boundNoop,
 | 
			
		||||
        isDisabled: false,
 | 
			
		||||
    };
 | 
			
		||||
    constructor(props: ERC20AssetAmountInputProps) {
 | 
			
		||||
        super(props);
 | 
			
		||||
        this.state = {
 | 
			
		||||
            currentFontSizePx: props.startingFontSizePx,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { asset } = this.props;
 | 
			
		||||
        return (
 | 
			
		||||
            <Container whiteSpace="nowrap">
 | 
			
		||||
                {_.isUndefined(asset) ? this._renderTokenSelectionContent() : this._renderContentForAsset(asset)}
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private readonly _renderContentForAsset = (asset: ERC20Asset): React.ReactNode => {
 | 
			
		||||
        const { onChange, ...rest } = this.props;
 | 
			
		||||
        const amountBorderBottom = this.props.isDisabled ? '' : `1px solid ${transparentWhite}`;
 | 
			
		||||
        const onSymbolClick = this._generateSelectAssetClickHandler();
 | 
			
		||||
        return (
 | 
			
		||||
            <React.Fragment>
 | 
			
		||||
                <Container borderBottom={amountBorderBottom} display="inline-block">
 | 
			
		||||
                    <ScalingAmountInput
 | 
			
		||||
                        {...rest}
 | 
			
		||||
                        textLengthThreshold={this._textLengthThresholdForAsset(asset)}
 | 
			
		||||
                        maxFontSizePx={this.props.startingFontSizePx}
 | 
			
		||||
                        onAmountChange={this._handleChange}
 | 
			
		||||
                        onFontSizeChange={this._handleFontSizeChange}
 | 
			
		||||
                    />
 | 
			
		||||
                </Container>
 | 
			
		||||
                <Container
 | 
			
		||||
                    display="inline-block"
 | 
			
		||||
                    marginLeft="8px"
 | 
			
		||||
                    title={assetUtils.bestNameForAsset(asset, undefined)}
 | 
			
		||||
                >
 | 
			
		||||
                    <Flex inline={true}>
 | 
			
		||||
                        <Text
 | 
			
		||||
                            fontSize={`${this.state.currentFontSizePx}px`}
 | 
			
		||||
                            fontColor={ColorOption.white}
 | 
			
		||||
                            textTransform="uppercase"
 | 
			
		||||
                            onClick={onSymbolClick}
 | 
			
		||||
                        >
 | 
			
		||||
                            {assetUtils.formattedSymbolForAsset(asset)}
 | 
			
		||||
                        </Text>
 | 
			
		||||
                        {this._renderChevronIcon()}
 | 
			
		||||
                    </Flex>
 | 
			
		||||
                </Container>
 | 
			
		||||
            </React.Fragment>
 | 
			
		||||
        );
 | 
			
		||||
    };
 | 
			
		||||
    private readonly _renderTokenSelectionContent = (): React.ReactNode => {
 | 
			
		||||
        const { numberOfAssetsAvailable } = this.props;
 | 
			
		||||
        let text = 'Select Token';
 | 
			
		||||
        if (_.isUndefined(numberOfAssetsAvailable)) {
 | 
			
		||||
            text = 'Loading...';
 | 
			
		||||
        } else if (numberOfAssetsAvailable === 0) {
 | 
			
		||||
            text = 'Assets Unavailable';
 | 
			
		||||
        }
 | 
			
		||||
        return (
 | 
			
		||||
            <Flex>
 | 
			
		||||
                <Text
 | 
			
		||||
                    fontSize="30px"
 | 
			
		||||
                    fontColor={ColorOption.white}
 | 
			
		||||
                    opacity={0.7}
 | 
			
		||||
                    fontWeight="500"
 | 
			
		||||
                    onClick={this._generateSelectAssetClickHandler()}
 | 
			
		||||
                >
 | 
			
		||||
                    {text}
 | 
			
		||||
                </Text>
 | 
			
		||||
                {this._renderChevronIcon()}
 | 
			
		||||
            </Flex>
 | 
			
		||||
        );
 | 
			
		||||
    };
 | 
			
		||||
    private readonly _renderChevronIcon = (): React.ReactNode => {
 | 
			
		||||
        if (!this._areMultipleAssetsAvailable()) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        return (
 | 
			
		||||
            <Container marginLeft="5px">
 | 
			
		||||
                <Icon icon="chevron" width={12} stroke={ColorOption.white} onClick={this._handleSelectAssetClick} />
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    };
 | 
			
		||||
    private readonly _handleChange = (value?: BigNumber): void => {
 | 
			
		||||
        this.props.onChange(value, this.props.asset);
 | 
			
		||||
    };
 | 
			
		||||
    private readonly _handleFontSizeChange = (fontSizePx: number): void => {
 | 
			
		||||
        this.setState({
 | 
			
		||||
            currentFontSizePx: fontSizePx,
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
    private readonly _generateSelectAssetClickHandler = (): SimpleHandler | undefined => {
 | 
			
		||||
        // We don't want to allow opening the token selection panel if there are no assets.
 | 
			
		||||
        // Since styles are inferred from the presence of a click handler, we want to return undefined
 | 
			
		||||
        // instead of providing a noop.
 | 
			
		||||
        if (!this._areMultipleAssetsAvailable() || _.isUndefined(this.props.onSelectAssetClick)) {
 | 
			
		||||
            return undefined;
 | 
			
		||||
        }
 | 
			
		||||
        return this._handleSelectAssetClick;
 | 
			
		||||
    };
 | 
			
		||||
    private readonly _areMultipleAssetsAvailable = (): boolean => {
 | 
			
		||||
        const { numberOfAssetsAvailable } = this.props;
 | 
			
		||||
        return !_.isUndefined(numberOfAssetsAvailable) && numberOfAssetsAvailable > 1;
 | 
			
		||||
    };
 | 
			
		||||
    private readonly _handleSelectAssetClick = (): void => {
 | 
			
		||||
        if (this.props.onSelectAssetClick) {
 | 
			
		||||
            this.props.onSelectAssetClick();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    // For assets with symbols of different length,
 | 
			
		||||
    // start scaling the input at different character lengths
 | 
			
		||||
    private readonly _textLengthThresholdForAsset = (asset?: ERC20Asset): number => {
 | 
			
		||||
        if (_.isUndefined(asset)) {
 | 
			
		||||
            return 3;
 | 
			
		||||
        }
 | 
			
		||||
        const symbol = asset.metaData.symbol;
 | 
			
		||||
        if (symbol.length <= 3) {
 | 
			
		||||
            return 5;
 | 
			
		||||
        }
 | 
			
		||||
        if (symbol.length === 5) {
 | 
			
		||||
            return 3;
 | 
			
		||||
        }
 | 
			
		||||
        return 4;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										111
									
								
								packages/instant/src/components/erc20_token_selector.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								packages/instant/src/components/erc20_token_selector.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { ERC20Asset } from '../types';
 | 
			
		||||
import { assetUtils } from '../util/asset';
 | 
			
		||||
 | 
			
		||||
import { SearchInput } from './search_input';
 | 
			
		||||
 | 
			
		||||
import { Circle } from './ui/circle';
 | 
			
		||||
import { Container } from './ui/container';
 | 
			
		||||
import { Flex } from './ui/flex';
 | 
			
		||||
import { Text } from './ui/text';
 | 
			
		||||
 | 
			
		||||
export interface ERC20TokenSelectorProps {
 | 
			
		||||
    tokens: ERC20Asset[];
 | 
			
		||||
    onTokenSelect: (token: ERC20Asset) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ERC20TokenSelectorState {
 | 
			
		||||
    searchQuery?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ERC20TokenSelector extends React.Component<ERC20TokenSelectorProps> {
 | 
			
		||||
    public state: ERC20TokenSelectorState = {
 | 
			
		||||
        searchQuery: undefined,
 | 
			
		||||
    };
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { tokens, onTokenSelect } = this.props;
 | 
			
		||||
        return (
 | 
			
		||||
            <Container height="100%">
 | 
			
		||||
                <SearchInput
 | 
			
		||||
                    placeholder="Search tokens..."
 | 
			
		||||
                    width="100%"
 | 
			
		||||
                    value={this.state.searchQuery}
 | 
			
		||||
                    onChange={this._handleSearchInputChange}
 | 
			
		||||
                />
 | 
			
		||||
                <Container overflow="scroll" height="calc(100% - 80px)" marginTop="10px">
 | 
			
		||||
                    {_.map(tokens, token => {
 | 
			
		||||
                        if (!this._isTokenQueryMatch(token)) {
 | 
			
		||||
                            return null;
 | 
			
		||||
                        }
 | 
			
		||||
                        return <TokenSelectorRow key={token.assetData} token={token} onClick={onTokenSelect} />;
 | 
			
		||||
                    })}
 | 
			
		||||
                </Container>
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private readonly _handleSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
 | 
			
		||||
        const searchQuery = event.target.value;
 | 
			
		||||
        this.setState({
 | 
			
		||||
            searchQuery,
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
    private readonly _isTokenQueryMatch = (token: ERC20Asset): boolean => {
 | 
			
		||||
        const { searchQuery } = this.state;
 | 
			
		||||
        if (_.isUndefined(searchQuery)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        const stringToSearch = `${token.metaData.name} ${token.metaData.symbol}`;
 | 
			
		||||
        return _.includes(stringToSearch.toLowerCase(), searchQuery.toLowerCase());
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface TokenSelectorRowProps {
 | 
			
		||||
    token: ERC20Asset;
 | 
			
		||||
    onClick: (token: ERC20Asset) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class TokenSelectorRow extends React.Component<TokenSelectorRowProps> {
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { token } = this.props;
 | 
			
		||||
        const displaySymbol = assetUtils.bestNameForAsset(token);
 | 
			
		||||
        return (
 | 
			
		||||
            <Container
 | 
			
		||||
                padding="12px 0px"
 | 
			
		||||
                borderBottom="1px solid"
 | 
			
		||||
                borderColor={ColorOption.feintGrey}
 | 
			
		||||
                backgroundColor={ColorOption.white}
 | 
			
		||||
                width="100%"
 | 
			
		||||
                onClick={this._handleClick}
 | 
			
		||||
                darkenOnHover={true}
 | 
			
		||||
                cursor="pointer"
 | 
			
		||||
            >
 | 
			
		||||
                <Container marginLeft="5px">
 | 
			
		||||
                    <Flex justify="flex-start">
 | 
			
		||||
                        <Container marginRight="10px">
 | 
			
		||||
                            <Circle diameter={30} rawColor={token.metaData.primaryColor}>
 | 
			
		||||
                                <Flex height="100%">
 | 
			
		||||
                                    <Text fontColor={ColorOption.white} fontSize="8px">
 | 
			
		||||
                                        {displaySymbol}
 | 
			
		||||
                                    </Text>
 | 
			
		||||
                                </Flex>
 | 
			
		||||
                            </Circle>
 | 
			
		||||
                        </Container>
 | 
			
		||||
                        <Text fontSize="14px" fontWeight={700} fontColor={ColorOption.black}>
 | 
			
		||||
                            {displaySymbol}
 | 
			
		||||
                        </Text>
 | 
			
		||||
                        <Container margin="0px 5px">
 | 
			
		||||
                            <Text fontSize="14px"> - </Text>
 | 
			
		||||
                        </Container>
 | 
			
		||||
                        <Text fontSize="14px">{token.metaData.name}</Text>
 | 
			
		||||
                    </Flex>
 | 
			
		||||
                </Container>
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private readonly _handleClick = (): void => {
 | 
			
		||||
        this.props.onClick(this.props.token);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
@@ -2,84 +2,136 @@ import { BigNumber } from '@0x/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { SelectedAssetAmountInput } from '../containers/selected_asset_amount_input';
 | 
			
		||||
import { SelectedERC20AssetAmountInput } from '../containers/selected_erc20_asset_amount_input';
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { AsyncProcessState } from '../types';
 | 
			
		||||
import { AsyncProcessState, ERC20Asset, OrderProcessState, OrderState } from '../types';
 | 
			
		||||
import { format } from '../util/format';
 | 
			
		||||
 | 
			
		||||
import { Container, Flex, Text } from './ui';
 | 
			
		||||
import { AmountPlaceholder } from './amount_placeholder';
 | 
			
		||||
import { Container } from './ui/container';
 | 
			
		||||
import { Flex } from './ui/flex';
 | 
			
		||||
import { Icon } from './ui/icon';
 | 
			
		||||
import { Spinner } from './ui/spinner';
 | 
			
		||||
import { Text } from './ui/text';
 | 
			
		||||
 | 
			
		||||
export interface InstantHeadingProps {
 | 
			
		||||
    selectedAssetAmount?: BigNumber;
 | 
			
		||||
    totalEthBaseAmount?: BigNumber;
 | 
			
		||||
    ethUsdPrice?: BigNumber;
 | 
			
		||||
    quoteState: AsyncProcessState;
 | 
			
		||||
    quoteRequestState: AsyncProcessState;
 | 
			
		||||
    buyOrderState: OrderState;
 | 
			
		||||
    onSelectAssetClick?: (asset?: ERC20Asset) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Placeholder = () => (
 | 
			
		||||
    <Text fontWeight="bold" fontColor={ColorOption.white}>
 | 
			
		||||
        —
 | 
			
		||||
    </Text>
 | 
			
		||||
);
 | 
			
		||||
const displaytotalEthBaseAmount = ({
 | 
			
		||||
    selectedAssetAmount,
 | 
			
		||||
    totalEthBaseAmount,
 | 
			
		||||
}: InstantHeadingProps): React.ReactNode => {
 | 
			
		||||
    if (_.isUndefined(selectedAssetAmount)) {
 | 
			
		||||
        return '0 ETH';
 | 
			
		||||
    }
 | 
			
		||||
    return format.ethBaseAmount(totalEthBaseAmount, 4, <Placeholder />);
 | 
			
		||||
};
 | 
			
		||||
const PLACEHOLDER_COLOR = ColorOption.white;
 | 
			
		||||
const ICON_WIDTH = 34;
 | 
			
		||||
const ICON_HEIGHT = 34;
 | 
			
		||||
const ICON_COLOR = ColorOption.white;
 | 
			
		||||
 | 
			
		||||
const displayUsdAmount = ({
 | 
			
		||||
    totalEthBaseAmount,
 | 
			
		||||
    selectedAssetAmount,
 | 
			
		||||
    ethUsdPrice,
 | 
			
		||||
}: InstantHeadingProps): React.ReactNode => {
 | 
			
		||||
    if (_.isUndefined(selectedAssetAmount)) {
 | 
			
		||||
        return '$0.00';
 | 
			
		||||
    }
 | 
			
		||||
    return format.ethBaseAmountInUsd(totalEthBaseAmount, ethUsdPrice, 2, <Placeholder />);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const loadingOrAmount = (quoteState: AsyncProcessState, amount: React.ReactNode): React.ReactNode => {
 | 
			
		||||
    if (quoteState === AsyncProcessState.PENDING) {
 | 
			
		||||
export class InstantHeading extends React.Component<InstantHeadingProps, {}> {
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const iconOrAmounts = this._renderIcon() || this._renderAmountsSection();
 | 
			
		||||
        return (
 | 
			
		||||
            <Text fontWeight="bold" fontColor={ColorOption.white}>
 | 
			
		||||
                …loading
 | 
			
		||||
            </Text>
 | 
			
		||||
        );
 | 
			
		||||
    } else {
 | 
			
		||||
        return amount;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const InstantHeading: React.StatelessComponent<InstantHeadingProps> = props => (
 | 
			
		||||
    <Container backgroundColor={ColorOption.primaryColor} padding="20px" width="100%" borderRadius="3px 3px 0px 0px">
 | 
			
		||||
        <Container marginBottom="5px">
 | 
			
		||||
            <Text
 | 
			
		||||
                letterSpacing="1px"
 | 
			
		||||
                fontColor={ColorOption.white}
 | 
			
		||||
                opacity={0.7}
 | 
			
		||||
                fontWeight={500}
 | 
			
		||||
                textTransform="uppercase"
 | 
			
		||||
                fontSize="12px"
 | 
			
		||||
            <Container
 | 
			
		||||
                backgroundColor={ColorOption.primaryColor}
 | 
			
		||||
                padding="20px"
 | 
			
		||||
                width="100%"
 | 
			
		||||
                borderRadius="3px 3px 0px 0px"
 | 
			
		||||
            >
 | 
			
		||||
                I want to buy
 | 
			
		||||
            </Text>
 | 
			
		||||
        </Container>
 | 
			
		||||
        <Flex direction="row" justify="space-between">
 | 
			
		||||
            <SelectedAssetAmountInput fontSize="45px" />
 | 
			
		||||
            <Flex direction="column" justify="space-between">
 | 
			
		||||
                <Container marginBottom="5px">
 | 
			
		||||
                    <Text fontSize="16px" fontColor={ColorOption.white} fontWeight={500}>
 | 
			
		||||
                        {loadingOrAmount(props.quoteState, displaytotalEthBaseAmount(props))}
 | 
			
		||||
                    <Text
 | 
			
		||||
                        letterSpacing="1px"
 | 
			
		||||
                        fontColor={ColorOption.white}
 | 
			
		||||
                        opacity={0.7}
 | 
			
		||||
                        fontWeight={500}
 | 
			
		||||
                        textTransform="uppercase"
 | 
			
		||||
                        fontSize="12px"
 | 
			
		||||
                    >
 | 
			
		||||
                        {this._renderTopText()}
 | 
			
		||||
                    </Text>
 | 
			
		||||
                </Container>
 | 
			
		||||
                <Text fontSize="16px" fontColor={ColorOption.white} opacity={0.7}>
 | 
			
		||||
                    {loadingOrAmount(props.quoteState, displayUsdAmount(props))}
 | 
			
		||||
                </Text>
 | 
			
		||||
            </Flex>
 | 
			
		||||
        </Flex>
 | 
			
		||||
    </Container>
 | 
			
		||||
);
 | 
			
		||||
                <Flex direction="row" justify="space-between">
 | 
			
		||||
                    <Flex height="60px">
 | 
			
		||||
                        <SelectedERC20AssetAmountInput
 | 
			
		||||
                            startingFontSizePx={38}
 | 
			
		||||
                            onSelectAssetClick={this.props.onSelectAssetClick}
 | 
			
		||||
                        />
 | 
			
		||||
                    </Flex>
 | 
			
		||||
                    <Flex direction="column" justify="space-between">
 | 
			
		||||
                        {iconOrAmounts}
 | 
			
		||||
                    </Flex>
 | 
			
		||||
                </Flex>
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private _renderAmountsSection(): React.ReactNode {
 | 
			
		||||
        return (
 | 
			
		||||
            <Container>
 | 
			
		||||
                <Container marginBottom="5px">{this._renderPlaceholderOrAmount(this._renderEthAmount)}</Container>
 | 
			
		||||
                <Container opacity={0.7}>{this._renderPlaceholderOrAmount(this._renderDollarAmount)}</Container>
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private _renderIcon(): React.ReactNode {
 | 
			
		||||
        const processState = this.props.buyOrderState.processState;
 | 
			
		||||
 | 
			
		||||
        if (processState === OrderProcessState.Failure) {
 | 
			
		||||
            return <Icon icon="failed" width={ICON_WIDTH} height={ICON_HEIGHT} color={ICON_COLOR} />;
 | 
			
		||||
        } else if (processState === OrderProcessState.Processing) {
 | 
			
		||||
            return <Spinner widthPx={ICON_HEIGHT} heightPx={ICON_HEIGHT} />;
 | 
			
		||||
        } else if (processState === OrderProcessState.Success) {
 | 
			
		||||
            return <Icon icon="success" width={ICON_WIDTH} height={ICON_HEIGHT} color={ICON_COLOR} />;
 | 
			
		||||
        }
 | 
			
		||||
        return undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private _renderTopText(): React.ReactNode {
 | 
			
		||||
        const processState = this.props.buyOrderState.processState;
 | 
			
		||||
        if (processState === OrderProcessState.Failure) {
 | 
			
		||||
            return 'Order failed';
 | 
			
		||||
        } else if (processState === OrderProcessState.Processing) {
 | 
			
		||||
            return 'Processing Order...';
 | 
			
		||||
        } else if (processState === OrderProcessState.Success) {
 | 
			
		||||
            return 'Tokens received!';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 'I want to buy';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private _renderPlaceholderOrAmount(amountFunction: () => React.ReactNode): React.ReactNode {
 | 
			
		||||
        if (this.props.quoteRequestState === AsyncProcessState.Pending) {
 | 
			
		||||
            return <AmountPlaceholder isPulsating={true} color={PLACEHOLDER_COLOR} />;
 | 
			
		||||
        }
 | 
			
		||||
        if (_.isUndefined(this.props.selectedAssetAmount)) {
 | 
			
		||||
            return <AmountPlaceholder isPulsating={false} color={PLACEHOLDER_COLOR} />;
 | 
			
		||||
        }
 | 
			
		||||
        return amountFunction();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private readonly _renderEthAmount = (): React.ReactNode => {
 | 
			
		||||
        return (
 | 
			
		||||
            <Text fontSize="16px" fontColor={ColorOption.white} fontWeight={500}>
 | 
			
		||||
                {format.ethBaseAmount(
 | 
			
		||||
                    this.props.totalEthBaseAmount,
 | 
			
		||||
                    4,
 | 
			
		||||
                    <AmountPlaceholder isPulsating={false} color={PLACEHOLDER_COLOR} />,
 | 
			
		||||
                )}
 | 
			
		||||
            </Text>
 | 
			
		||||
        );
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private readonly _renderDollarAmount = (): React.ReactNode => {
 | 
			
		||||
        return (
 | 
			
		||||
            <Text fontSize="16px" fontColor={ColorOption.white}>
 | 
			
		||||
                {format.ethBaseAmountInUsd(
 | 
			
		||||
                    this.props.totalEthBaseAmount,
 | 
			
		||||
                    this.props.ethUsdPrice,
 | 
			
		||||
                    2,
 | 
			
		||||
                    <AmountPlaceholder isPulsating={false} color={ColorOption.white} />,
 | 
			
		||||
                )}
 | 
			
		||||
            </Text>
 | 
			
		||||
        );
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,13 +7,17 @@ import { oc } from 'ts-optchain';
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { format } from '../util/format';
 | 
			
		||||
 | 
			
		||||
import { Container, Flex, Text } from './ui';
 | 
			
		||||
import { AmountPlaceholder } from './amount_placeholder';
 | 
			
		||||
 | 
			
		||||
import { Container } from './ui/container';
 | 
			
		||||
import { Flex } from './ui/flex';
 | 
			
		||||
import { Text } from './ui/text';
 | 
			
		||||
 | 
			
		||||
export interface OrderDetailsProps {
 | 
			
		||||
    buyQuoteInfo?: BuyQuoteInfo;
 | 
			
		||||
    ethUsdPrice?: BigNumber;
 | 
			
		||||
    isLoading: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class OrderDetails extends React.Component<OrderDetailsProps> {
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { buyQuoteInfo, ethUsdPrice } = this.props;
 | 
			
		||||
@@ -22,7 +26,7 @@ export class OrderDetails extends React.Component<OrderDetailsProps> {
 | 
			
		||||
        const ethTokenFee = buyQuoteAccessor.feeEthAmount();
 | 
			
		||||
        const totalEthAmount = buyQuoteAccessor.totalEthAmount();
 | 
			
		||||
        return (
 | 
			
		||||
            <Container padding="20px" width="100%">
 | 
			
		||||
            <Container padding="20px" width="100%" flexGrow={1}>
 | 
			
		||||
                <Container marginBottom="10px">
 | 
			
		||||
                    <Text
 | 
			
		||||
                        letterSpacing="1px"
 | 
			
		||||
@@ -39,13 +43,20 @@ export class OrderDetails extends React.Component<OrderDetailsProps> {
 | 
			
		||||
                    ethAmount={ethAssetPrice}
 | 
			
		||||
                    ethUsdPrice={ethUsdPrice}
 | 
			
		||||
                    isEthAmountInBaseUnits={false}
 | 
			
		||||
                    isLoading={this.props.isLoading}
 | 
			
		||||
                />
 | 
			
		||||
                <EthAmountRow
 | 
			
		||||
                    rowLabel="Fee"
 | 
			
		||||
                    ethAmount={ethTokenFee}
 | 
			
		||||
                    ethUsdPrice={ethUsdPrice}
 | 
			
		||||
                    isLoading={this.props.isLoading}
 | 
			
		||||
                />
 | 
			
		||||
                <EthAmountRow rowLabel="Fee" ethAmount={ethTokenFee} ethUsdPrice={ethUsdPrice} />
 | 
			
		||||
                <EthAmountRow
 | 
			
		||||
                    rowLabel="Total Cost"
 | 
			
		||||
                    ethAmount={totalEthAmount}
 | 
			
		||||
                    ethUsdPrice={ethUsdPrice}
 | 
			
		||||
                    shouldEmphasize={true}
 | 
			
		||||
                    isLoading={this.props.isLoading}
 | 
			
		||||
                />
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
@@ -58,43 +69,50 @@ export interface EthAmountRowProps {
 | 
			
		||||
    isEthAmountInBaseUnits?: boolean;
 | 
			
		||||
    ethUsdPrice?: BigNumber;
 | 
			
		||||
    shouldEmphasize?: boolean;
 | 
			
		||||
    isLoading: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const EthAmountRow: React.StatelessComponent<EthAmountRowProps> = ({
 | 
			
		||||
    rowLabel,
 | 
			
		||||
    ethAmount,
 | 
			
		||||
    isEthAmountInBaseUnits,
 | 
			
		||||
    ethUsdPrice,
 | 
			
		||||
    shouldEmphasize,
 | 
			
		||||
}) => {
 | 
			
		||||
    const fontWeight = shouldEmphasize ? 700 : 400;
 | 
			
		||||
    const usdFormatter = isEthAmountInBaseUnits ? format.ethBaseAmountInUsd : format.ethUnitAmountInUsd;
 | 
			
		||||
    const ethFormatter = isEthAmountInBaseUnits ? format.ethBaseAmount : format.ethUnitAmount;
 | 
			
		||||
    const usdPriceSection = _.isUndefined(ethUsdPrice) ? null : (
 | 
			
		||||
        <Container marginRight="3px" display="inline-block">
 | 
			
		||||
            <Text fontColor={ColorOption.lightGrey}>({usdFormatter(ethAmount, ethUsdPrice)})</Text>
 | 
			
		||||
        </Container>
 | 
			
		||||
    );
 | 
			
		||||
    return (
 | 
			
		||||
        <Container padding="10px 0px" borderTop="1px dashed" borderColor={ColorOption.feintGrey}>
 | 
			
		||||
            <Flex justify="space-between">
 | 
			
		||||
                <Text fontWeight={fontWeight} fontColor={ColorOption.grey}>
 | 
			
		||||
                    {rowLabel}
 | 
			
		||||
                </Text>
 | 
			
		||||
                <Container>
 | 
			
		||||
                    {usdPriceSection}
 | 
			
		||||
export class EthAmountRow extends React.Component<EthAmountRowProps> {
 | 
			
		||||
    public static defaultProps = {
 | 
			
		||||
        shouldEmphasize: false,
 | 
			
		||||
        isEthAmountInBaseUnits: true,
 | 
			
		||||
    };
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { rowLabel, ethAmount, isEthAmountInBaseUnits, shouldEmphasize, isLoading } = this.props;
 | 
			
		||||
 | 
			
		||||
        const fontWeight = shouldEmphasize ? 700 : 400;
 | 
			
		||||
        const ethFormatter = isEthAmountInBaseUnits ? format.ethBaseAmount : format.ethUnitAmount;
 | 
			
		||||
        return (
 | 
			
		||||
            <Container padding="10px 0px" borderTop="1px dashed" borderColor={ColorOption.feintGrey}>
 | 
			
		||||
                <Flex justify="space-between">
 | 
			
		||||
                    <Text fontWeight={fontWeight} fontColor={ColorOption.grey}>
 | 
			
		||||
                        {ethFormatter(ethAmount)}
 | 
			
		||||
                        {rowLabel}
 | 
			
		||||
                    </Text>
 | 
			
		||||
                </Container>
 | 
			
		||||
            </Flex>
 | 
			
		||||
        </Container>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
EthAmountRow.defaultProps = {
 | 
			
		||||
    shouldEmphasize: false,
 | 
			
		||||
    isEthAmountInBaseUnits: true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
EthAmountRow.displayName = 'EthAmountRow';
 | 
			
		||||
                    <Container>
 | 
			
		||||
                        {this._renderUsdSection()}
 | 
			
		||||
                        <Text fontWeight={fontWeight} fontColor={ColorOption.grey}>
 | 
			
		||||
                            {ethFormatter(
 | 
			
		||||
                                ethAmount,
 | 
			
		||||
                                4,
 | 
			
		||||
                                <Container opacity={0.5}>
 | 
			
		||||
                                    <AmountPlaceholder color={ColorOption.lightGrey} isPulsating={isLoading} />
 | 
			
		||||
                                </Container>,
 | 
			
		||||
                            )}
 | 
			
		||||
                        </Text>
 | 
			
		||||
                    </Container>
 | 
			
		||||
                </Flex>
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private _renderUsdSection(): React.ReactNode {
 | 
			
		||||
        const usdFormatter = this.props.isEthAmountInBaseUnits ? format.ethBaseAmountInUsd : format.ethUnitAmountInUsd;
 | 
			
		||||
        const shouldHideUsdPriceSection = _.isUndefined(this.props.ethUsdPrice) || _.isUndefined(this.props.ethAmount);
 | 
			
		||||
        return shouldHideUsdPriceSection ? null : (
 | 
			
		||||
            <Container marginRight="3px" display="inline-block">
 | 
			
		||||
                <Text fontColor={ColorOption.lightGrey}>
 | 
			
		||||
                    ({usdFormatter(this.props.ethAmount, this.props.ethUsdPrice)})
 | 
			
		||||
                </Text>
 | 
			
		||||
            </Container>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								packages/instant/src/components/payment_method.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								packages/instant/src/components/payment_method.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { ColorOption } from '../style/theme';
 | 
			
		||||
import { Network } from '../types';
 | 
			
		||||
 | 
			
		||||
import { PaymentMethodDropdown } from './payment_method_dropdown';
 | 
			
		||||
import { Circle } from './ui/circle';
 | 
			
		||||
import { Container } from './ui/container';
 | 
			
		||||
import { Flex } from './ui/flex';
 | 
			
		||||
import { Text } from './ui/text';
 | 
			
		||||
 | 
			
		||||
export interface PaymentMethodProps {}
 | 
			
		||||
 | 
			
		||||
export const PaymentMethod: React.StatelessComponent<PaymentMethodProps> = () => (
 | 
			
		||||
    <Container padding="20px" width="100%">
 | 
			
		||||
        <Container marginBottom="10px">
 | 
			
		||||
            <Flex justify="space-between">
 | 
			
		||||
                <Text
 | 
			
		||||
                    letterSpacing="1px"
 | 
			
		||||
                    fontColor={ColorOption.primaryColor}
 | 
			
		||||
                    fontWeight={600}
 | 
			
		||||
                    textTransform="uppercase"
 | 
			
		||||
                    fontSize="14px"
 | 
			
		||||
                >
 | 
			
		||||
                    Payment Method
 | 
			
		||||
                </Text>
 | 
			
		||||
                <Flex>
 | 
			
		||||
                    <Circle color={ColorOption.green} diameter={8} />
 | 
			
		||||
                    <Container marginLeft="3px">
 | 
			
		||||
                        <Text fontColor={ColorOption.darkGrey} fontSize="12px">
 | 
			
		||||
                            MetaMask
 | 
			
		||||
                        </Text>
 | 
			
		||||
                    </Container>
 | 
			
		||||
                </Flex>
 | 
			
		||||
            </Flex>
 | 
			
		||||
        </Container>
 | 
			
		||||
        <PaymentMethodDropdown
 | 
			
		||||
            accountAddress="0xa1b2c3d4e5f6g7h8j9k10"
 | 
			
		||||
            accountEthBalanceInWei={new BigNumber(10500000000000000000)}
 | 
			
		||||
            network={Network.Mainnet}
 | 
			
		||||
        />
 | 
			
		||||
    </Container>
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										44
									
								
								packages/instant/src/components/payment_method_dropdown.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								packages/instant/src/components/payment_method_dropdown.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import copy from 'copy-to-clipboard';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
 | 
			
		||||
import { Network } from '../types';
 | 
			
		||||
import { etherscanUtil } from '../util/etherscan';
 | 
			
		||||
import { format } from '../util/format';
 | 
			
		||||
 | 
			
		||||
import { Dropdown, DropdownItemConfig } from './ui/dropdown';
 | 
			
		||||
 | 
			
		||||
export interface PaymentMethodDropdownProps {
 | 
			
		||||
    accountAddress: string;
 | 
			
		||||
    accountEthBalanceInWei?: BigNumber;
 | 
			
		||||
    network: Network;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class PaymentMethodDropdown extends React.Component<PaymentMethodDropdownProps> {
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const { accountAddress, accountEthBalanceInWei } = this.props;
 | 
			
		||||
        const value = format.ethAddress(accountAddress);
 | 
			
		||||
        const label = format.ethBaseAmount(accountEthBalanceInWei, 4, '') as string;
 | 
			
		||||
        return <Dropdown value={value} label={label} items={this._getDropdownItemConfigs()} />;
 | 
			
		||||
    }
 | 
			
		||||
    private readonly _getDropdownItemConfigs = (): DropdownItemConfig[] => {
 | 
			
		||||
        const viewOnEtherscan = {
 | 
			
		||||
            text: 'View on Etherscan',
 | 
			
		||||
            onClick: this._handleEtherscanClick,
 | 
			
		||||
        };
 | 
			
		||||
        const copyAddressToClipboard = {
 | 
			
		||||
            text: 'Copy address to clipboard',
 | 
			
		||||
            onClick: this._handleCopyToClipboardClick,
 | 
			
		||||
        };
 | 
			
		||||
        return [viewOnEtherscan, copyAddressToClipboard];
 | 
			
		||||
    };
 | 
			
		||||
    private readonly _handleEtherscanClick = (): void => {
 | 
			
		||||
        const { accountAddress, network } = this.props;
 | 
			
		||||
        const etherscanUrl = etherscanUtil.getEtherScanEthAddressIfExists(accountAddress, network);
 | 
			
		||||
        window.open(etherscanUrl, '_blank');
 | 
			
		||||
    };
 | 
			
		||||
    private readonly _handleCopyToClipboardClick = (): void => {
 | 
			
		||||
        const { accountAddress } = this.props;
 | 
			
		||||
        copy(accountAddress);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user