diff --git a/bridge-monitor/.env.example b/bridge-monitor/.env.example
new file mode 100644
index 00000000..5645f127
--- /dev/null
+++ b/bridge-monitor/.env.example
@@ -0,0 +1,10 @@
+HOME_RPC_URL=https://sokol.poa.network
+FOREIGN_RPC_URL=https://kovan.infura.io/mew
+HOME_BRIDGE_ADDRESS=0xABb4C1399DcC28FBa3Beb76CAE2b50Be3e087353
+FOREIGN_BRIDGE_ADDRESS=0xE405F6872cE38a7a4Ff63DcF946236D458c2ca3a
+HOME_DEPLOYMENT_BLOCK=0
+FOREIGN_DEPLOYMENT_BLOCK=0
+GAS_PRICE_SPEED_TYPE=standard
+GAS_LIMIT=300000
+GAS_PRICE_FALLBACK=21
+LEFT_TX_THRESHOLD=100
diff --git a/bridge-monitor/.eslintrc b/bridge-monitor/.eslintrc
new file mode 100644
index 00000000..9cde6f18
--- /dev/null
+++ b/bridge-monitor/.eslintrc
@@ -0,0 +1,21 @@
+{
+ "plugins": ["node", "prettier"],
+ "extends": [
+ "plugin:node/recommended",
+ "airbnb-base",
+ "plugin:prettier/recommended"
+ ],
+ "rules": {
+ "prettier/prettier": "error",
+ "arrow-body-style": "off",
+ "no-await-in-loop": "off",
+ "no-console": "off",
+ "no-else-return": "off",
+ "no-plusplus": "off",
+ "no-restricted-syntax": "off",
+ "no-shadow": "off",
+ "prefer-template": "off",
+ "no-use-before-define": "off",
+ "no-underscore-dangle": "off"
+ }
+}
diff --git a/bridge-monitor/.gitignore b/bridge-monitor/.gitignore
new file mode 100644
index 00000000..9214e871
--- /dev/null
+++ b/bridge-monitor/.gitignore
@@ -0,0 +1,7 @@
+.env
+node_modules
+responses/*
+!responses/.gitkeep
+*.err
+*.out
+.idea
diff --git a/bridge-monitor/.prettierrc b/bridge-monitor/.prettierrc
new file mode 100644
index 00000000..75a894a2
--- /dev/null
+++ b/bridge-monitor/.prettierrc
@@ -0,0 +1,5 @@
+{
+ "semi": false,
+ "singleQuote": true,
+ "printWidth": 100
+}
diff --git a/bridge-monitor/LICENSE b/bridge-monitor/LICENSE
new file mode 100644
index 00000000..20d40b6b
--- /dev/null
+++ b/bridge-monitor/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
\ No newline at end of file
diff --git a/bridge-monitor/README.md b/bridge-monitor/README.md
new file mode 100644
index 00000000..a05ac3f5
--- /dev/null
+++ b/bridge-monitor/README.md
@@ -0,0 +1,155 @@
+# Bridge Monitor
+Deployed version:
+https://bridge-monitoring.poa.net/
+
+This tools allows you to spin up node.js server to monitor for 2 contracts on
+Home and Foreign Eth networks to check for balance difference.
+On Home network it checks for `HOME_BRIDGE_ADDRESS` balance.
+On Foreign network it checks for the `ERC20 token` total supply for the `FOREIGN_BRIDGE_ADDRESS`.
+
+Example of an API
+
+* `GET /` - check contract balances & tx numbers
+
+```json
+
+{
+ "home": {
+ "balance": "3710077.6896438415780044",
+ "deposits": 481,
+ "withdrawals": 221
+ },
+ "foreign": {
+ "totalSupply": "3710077.6896438415780044",
+ "deposits": 481,
+ "withdrawals": 221
+ },
+ "balanceDiff": 0,
+ "lastChecked": 1529511982,
+ "depositsDiff": 0,
+ "withdrawalDiff": 0
+}
+```
+
+* `GET /validators` - check validators balances
+```json
+{
+ "home": {
+ "validators": {
+ "0x35DC13c72A9C09C8AEEBD0490C7228C43Ccc38Cd": {
+ "balance": "19.994900374",
+ "leftTx": 66649667913333,
+ "gasPrice": 1
+ },
+ "0x5D44BC8642947685F45004c936245B969F9709a6": {
+ "balance": "19.993736069",
+ "leftTx": 66645786896666,
+ "gasPrice": 1
+ },
+ "0x284877074B986A78F01D7Eb1f34B6043b1719002": {
+ "balance": "19.995139875",
+ "leftTx": 66650466250000,
+ "gasPrice": 1
+ }
+ },
+ "requiredSignatures": 2
+ },
+ "foreign": {
+ "validators": {
+ "0x35DC13c72A9C09C8AEEBD0490C7228C43Ccc38Cd": {
+ "balance": "19.084023268196",
+ "leftTx": 28915,
+ "gasPrice": 2.2
+ },
+ "0x5D44BC8642947685F45004c936245B969F9709a6": {
+ "balance": "19.086724777075",
+ "leftTx": 28919,
+ "gasPrice": 2.2
+ },
+ "0x284877074B986A78F01D7Eb1f34B6043b1719002": {
+ "balance": "19.050074813935",
+ "leftTx": 28863,
+ "gasPrice": 2.2
+ }
+ },
+ "requiredSignatures": 2
+ },
+ "requiredSignaturesMatch": true,
+ "validatorsMatch": true,
+ "lastChecked": 1529512164
+}
+```
+
+* `GET /eventsStats` - check unprocessed events
+```json
+{
+ "onlyInHomeDeposits": [],
+ "onlyInForeignDeposits": [],
+ "onlyInHomeWithdrawals": [],
+ "onlyInForeignWithdrawals": [],
+ "lastChecked": 1529512436
+}
+```
+
+* `GET /stuckTransfers` - check stucked transfers that wasnot called by transferAndCall
+```json
+{
+
+ "stuckTransfers": [
+ {
+ "address": "0x6758B7d441a9739b98552B373703d8d3d14f9e62",
+ "blockNumber": 5964312,
+ "transactionHash": "0x74413ba79509a292d5d0d6edd364b3617c83a57b13d603de9deb6c8e6b6c6daf",
+ ...
+ "returnValues": {
+ "0": "0x8D4bbc1B533aB9e3a743210870b6e3c4c0f7E935",
+ "1": "0xd819E948b14cA6AAD2b7Ffd333cCDf732b129EeD",
+ "2": "10000000000000000000000",
+ "from": "0x8D4bbc1B533aB9e3a743210870b6e3c4c0f7E935",
+ "to": "0xd819E948b14cA6AAD2b7Ffd333cCDf732b129EeD",
+ "value": "10000000000000000000000"
+ },
+ ...
+ }
+ ],
+ "total": 2,
+ "lastChecked": 1535058662
+}
+```
+
+# How to run
+Create .env file (see `.env.example` for parameters reference)
+```bash
+HOME_RPC_URL=https://sokol.poa.network
+FOREIGN_RPC_URL=https://kovan.infura.io/mew
+HOME_BRIDGE_ADDRESS=0xABb4C1399DcC28FBa3Beb76CAE2b50Be3e087353
+FOREIGN_BRIDGE_ADDRESS=0xE405F6872cE38a7a4Ff63DcF946236D458c2ca3a
+GAS_PRICE_SPEED_TYPE=standard
+GAS_LIMIT=300000
+GAS_PRICE_FALLBACK=21
+LEFT_TX_THRESHOLD=100
+```
+
+```bash
+npm i
+# check balances of contracts and validators
+node checkWorker.js
+# check unprocessed events
+node checkWorker2.js
+# check stuck transfers called by transfer, not transferAndCall
+# only applicable for bridge-rust-v1-native-to-erc
+node checkWorker3.js
+# run web interface
+node index.js
+```
+
+To enabled debug logging, set `DEBUG=1` env variable.
+
+You can create cron job to run workers (see `crontab.example` for reference):
+```bash
+#crontab -e
+*/4 * * * * cd $HOME/bridge-monitor; node checkWorker.js >>cronWorker.out 2>>cronWorker.err
+*/5 * * * * cd $HOME/bridge-monitor; node checkWorker2.js >>cronWorker2.out 2>>cronWorker2.err
+```
+
+You can run web interface via [pm2](https://www.npmjs.com/package/pm2) or similar supervisor program.
diff --git a/bridge-monitor/abis/BridgeValidators.abi.json b/bridge-monitor/abis/BridgeValidators.abi.json
new file mode 100644
index 00000000..a37bd3e9
--- /dev/null
+++ b/bridge-monitor/abis/BridgeValidators.abi.json
@@ -0,0 +1,296 @@
+[
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorCount",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeValidatorsInterfacesVersion",
+ "outputs": [
+ {
+ "name": "major",
+ "type": "uint64"
+ },
+ {
+ "name": "minor",
+ "type": "uint64"
+ },
+ {
+ "name": "patch",
+ "type": "uint64"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isInitialized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorList",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_requiredSignatures",
+ "type": "uint256"
+ }
+ ],
+ "name": "setRequiredSignatures",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredSignatures",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_address",
+ "type": "address"
+ }
+ ],
+ "name": "getNextValidator",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "deployedAtBlock",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "F_ADDR",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_validator",
+ "type": "address"
+ }
+ ],
+ "name": "isValidator",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "validator",
+ "type": "address"
+ }
+ ],
+ "name": "ValidatorAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "validator",
+ "type": "address"
+ }
+ ],
+ "name": "ValidatorRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "requiredSignatures",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequiredSignaturesChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_requiredSignatures",
+ "type": "uint256"
+ },
+ {
+ "name": "_initialValidators",
+ "type": "address[]"
+ },
+ {
+ "name": "_owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validator",
+ "type": "address"
+ }
+ ],
+ "name": "addValidator",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validator",
+ "type": "address"
+ }
+ ],
+ "name": "removeValidator",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/ERC20.abi.json b/bridge-monitor/abis/ERC20.abi.json
new file mode 100644
index 00000000..49cac883
--- /dev/null
+++ b/bridge-monitor/abis/ERC20.abi.json
@@ -0,0 +1,175 @@
+[
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "who",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/ERC677.abi.json b/bridge-monitor/abis/ERC677.abi.json
new file mode 100644
index 00000000..df7161d9
--- /dev/null
+++ b/bridge-monitor/abis/ERC677.abi.json
@@ -0,0 +1,229 @@
+[
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "who",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "",
+ "type": "address"
+ },
+ {
+ "name": "",
+ "type": "uint256"
+ },
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "transferAndCall",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/ERC677BridgeToken.abi.json b/bridge-monitor/abis/ERC677BridgeToken.abi.json
new file mode 100644
index 00000000..8ba51f9e
--- /dev/null
+++ b/bridge-monitor/abis/ERC677BridgeToken.abi.json
@@ -0,0 +1,597 @@
+[
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "mintingFinished",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_spender",
+ "type": "address"
+ },
+ {
+ "name": "_value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "name": "_value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "mint",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_value",
+ "type": "uint256"
+ }
+ ],
+ "name": "burn",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_spender",
+ "type": "address"
+ },
+ {
+ "name": "_subtractedValue",
+ "type": "uint256"
+ }
+ ],
+ "name": "decreaseApproval",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_owner",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "bridgeContract",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_spender",
+ "type": "address"
+ },
+ {
+ "name": "_addedValue",
+ "type": "uint256"
+ }
+ ],
+ "name": "increaseApproval",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_owner",
+ "type": "address"
+ },
+ {
+ "name": "_spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "name": "_name",
+ "type": "string"
+ },
+ {
+ "name": "_symbol",
+ "type": "string"
+ },
+ {
+ "name": "_decimals",
+ "type": "uint8"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "ContractFallbackCallFailed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Mint",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "MintFinished",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "previousOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipRenounced",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "burner",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Burn",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_bridgeContract",
+ "type": "address"
+ }
+ ],
+ "name": "setBridgeContract",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "name": "_value",
+ "type": "uint256"
+ },
+ {
+ "name": "_data",
+ "type": "bytes"
+ }
+ ],
+ "name": "transferAndCall",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getTokenInterfacesVersion",
+ "outputs": [
+ {
+ "name": "major",
+ "type": "uint64"
+ },
+ {
+ "name": "minor",
+ "type": "uint64"
+ },
+ {
+ "name": "patch",
+ "type": "uint64"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "name": "_value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [],
+ "name": "finishMinting",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ }
+ ],
+ "name": "claimTokens",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/ForeignBridgeErc677ToErc677.abi.json b/bridge-monitor/abis/ForeignBridgeErc677ToErc677.abi.json
new file mode 100644
index 00000000..43735aec
--- /dev/null
+++ b/bridge-monitor/abis/ForeignBridgeErc677ToErc677.abi.json
@@ -0,0 +1,699 @@
+[
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "erc677token",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_txHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "relayedMessages",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "vs",
+ "type": "uint8[]"
+ },
+ {
+ "name": "rs",
+ "type": "bytes32[]"
+ },
+ {
+ "name": "ss",
+ "type": "bytes32[]"
+ },
+ {
+ "name": "message",
+ "type": "bytes"
+ }
+ ],
+ "name": "executeSignatures",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_day",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalSpentPerDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isInitialized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "setExecutionDailyLimit",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getCurrentDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredBlockConfirmations",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeMode",
+ "outputs": [
+ {
+ "name": "_data",
+ "type": "bytes4"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "executionDailyLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_day",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalExecutedPerDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "dailyLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ }
+ ],
+ "name": "claimTokens",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withinExecutionLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "executionMaxPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredSignatures",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorContract",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "deployedAtBlock",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeInterfacesVersion",
+ "outputs": [
+ {
+ "name": "major",
+ "type": "uint64"
+ },
+ {
+ "name": "minor",
+ "type": "uint64"
+ },
+ {
+ "name": "patch",
+ "type": "uint64"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMinPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "name": "_value",
+ "type": "uint256"
+ },
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "onTokenTransfer",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_blockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setRequiredBlockConfirmations",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "setDailyLimit",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "setGasPrice",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "upgradeabilityAdmin",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "minPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withinLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setExecutionMaxPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "maxPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "gasPrice",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserRequestForAffirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RelayedMessage",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "GasPriceChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "requiredBlockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequiredBlockConfirmationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "newLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "DailyLimitChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "newLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "ExecutionDailyLimitChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validatorContract",
+ "type": "address"
+ },
+ {
+ "name": "_erc20token",
+ "type": "address"
+ },
+ {
+ "name": "_requiredBlockConfirmations",
+ "type": "uint256"
+ },
+ {
+ "name": "_gasPrice",
+ "type": "uint256"
+ },
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ },
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_homeDailyLimit",
+ "type": "uint256"
+ },
+ {
+ "name": "_homeMaxPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "erc20token",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/ForeignBridgeErcToErc.abi.json b/bridge-monitor/abis/ForeignBridgeErcToErc.abi.json
new file mode 100644
index 00000000..d0679046
--- /dev/null
+++ b/bridge-monitor/abis/ForeignBridgeErcToErc.abi.json
@@ -0,0 +1,448 @@
+[
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_txHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "relayedMessages",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "vs",
+ "type": "uint8[]"
+ },
+ {
+ "name": "rs",
+ "type": "bytes32[]"
+ },
+ {
+ "name": "ss",
+ "type": "bytes32[]"
+ },
+ {
+ "name": "message",
+ "type": "bytes"
+ }
+ ],
+ "name": "executeSignatures",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_day",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalSpentPerDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isInitialized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getCurrentDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredBlockConfirmations",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "dailyLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredSignatures",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorContract",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "deployedAtBlock",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeInterfacesVersion",
+ "outputs": [
+ {
+ "name": "major",
+ "type": "uint64"
+ },
+ {
+ "name": "minor",
+ "type": "uint64"
+ },
+ {
+ "name": "patch",
+ "type": "uint64"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMinPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_blockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setRequiredBlockConfirmations",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "setDailyLimit",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "setGasPrice",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "minPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withinLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "maxPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "gasPrice",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RelayedMessage",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "GasPriceChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "requiredBlockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequiredBlockConfirmationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "newLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "DailyLimitChanged",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validatorContract",
+ "type": "address"
+ },
+ {
+ "name": "_erc20token",
+ "type": "address"
+ },
+ {
+ "name": "_requiredBlockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeMode",
+ "outputs": [
+ {
+ "name": "_data",
+ "type": "bytes4"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ }
+ ],
+ "name": "claimTokens",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "erc20token",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/ForeignBridgeErcToNative.abi.json b/bridge-monitor/abis/ForeignBridgeErcToNative.abi.json
new file mode 100644
index 00000000..45fc322c
--- /dev/null
+++ b/bridge-monitor/abis/ForeignBridgeErcToNative.abi.json
@@ -0,0 +1,452 @@
+[
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_txHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "relayedMessages",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "vs",
+ "type": "uint8[]"
+ },
+ {
+ "name": "rs",
+ "type": "bytes32[]"
+ },
+ {
+ "name": "ss",
+ "type": "bytes32[]"
+ },
+ {
+ "name": "message",
+ "type": "bytes"
+ }
+ ],
+ "name": "executeSignatures",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_day",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalSpentPerDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isInitialized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getCurrentDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredBlockConfirmations",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "dailyLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredSignatures",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorContract",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "deployedAtBlock",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeInterfacesVersion",
+ "outputs": [
+ {
+ "name": "major",
+ "type": "uint64"
+ },
+ {
+ "name": "minor",
+ "type": "uint64"
+ },
+ {
+ "name": "patch",
+ "type": "uint64"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMinPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_blockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setRequiredBlockConfirmations",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "setDailyLimit",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "setGasPrice",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "minPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withinLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "maxPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "gasPrice",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RelayedMessage",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "GasPriceChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "requiredBlockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequiredBlockConfirmationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "newLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "DailyLimitChanged",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validatorContract",
+ "type": "address"
+ },
+ {
+ "name": "_erc20token",
+ "type": "address"
+ },
+ {
+ "name": "_requiredBlockConfirmations",
+ "type": "uint256"
+ },
+ {
+ "name": "_gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeMode",
+ "outputs": [
+ {
+ "name": "_data",
+ "type": "bytes4"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ }
+ ],
+ "name": "claimTokens",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "erc20token",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/ForeignBridgeNativeToErc.abi.json b/bridge-monitor/abis/ForeignBridgeNativeToErc.abi.json
new file mode 100644
index 00000000..67e720a1
--- /dev/null
+++ b/bridge-monitor/abis/ForeignBridgeNativeToErc.abi.json
@@ -0,0 +1,526 @@
+[
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "erc677token",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_txHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "relayedMessages",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "vs",
+ "type": "uint8[]"
+ },
+ {
+ "name": "rs",
+ "type": "bytes32[]"
+ },
+ {
+ "name": "ss",
+ "type": "bytes32[]"
+ },
+ {
+ "name": "message",
+ "type": "bytes"
+ }
+ ],
+ "name": "executeSignatures",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_day",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalSpentPerDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isInitialized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getCurrentDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredBlockConfirmations",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "dailyLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ }
+ ],
+ "name": "claimTokens",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredSignatures",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorContract",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "deployedAtBlock",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeInterfacesVersion",
+ "outputs": [
+ {
+ "name": "major",
+ "type": "uint64"
+ },
+ {
+ "name": "minor",
+ "type": "uint64"
+ },
+ {
+ "name": "patch",
+ "type": "uint64"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMinPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "name": "_value",
+ "type": "uint256"
+ },
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "onTokenTransfer",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_blockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setRequiredBlockConfirmations",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "setDailyLimit",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "setGasPrice",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "minPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withinLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "maxPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "gasPrice",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserRequestForAffirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RelayedMessage",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "GasPriceChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "requiredBlockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequiredBlockConfirmationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "newLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "DailyLimitChanged",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validatorContract",
+ "type": "address"
+ },
+ {
+ "name": "_erc677token",
+ "type": "address"
+ },
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ },
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_foreignGasPrice",
+ "type": "uint256"
+ },
+ {
+ "name": "_requiredBlockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeMode",
+ "outputs": [
+ {
+ "name": "_data",
+ "type": "bytes4"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ }
+ ],
+ "name": "claimTokensFromErc677",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/HomeBridgeErcToErc.abi.json b/bridge-monitor/abis/HomeBridgeErcToErc.abi.json
new file mode 100644
index 00000000..6f39d5be
--- /dev/null
+++ b/bridge-monitor/abis/HomeBridgeErcToErc.abi.json
@@ -0,0 +1,715 @@
+[
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_message",
+ "type": "bytes32"
+ }
+ ],
+ "name": "numMessagesSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_hash",
+ "type": "bytes32"
+ },
+ {
+ "name": "_index",
+ "type": "uint256"
+ }
+ ],
+ "name": "signature",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "erc677token",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_day",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalSpentPerDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isInitialized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getCurrentDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredBlockConfirmations",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredMessageLength",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_hash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "message",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "signature",
+ "type": "bytes"
+ },
+ {
+ "name": "message",
+ "type": "bytes"
+ }
+ ],
+ "name": "submitSignature",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "dailyLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ }
+ ],
+ "name": "claimTokens",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_withdrawal",
+ "type": "bytes32"
+ }
+ ],
+ "name": "numAffirmationsSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_withdrawal",
+ "type": "bytes32"
+ }
+ ],
+ "name": "affirmationsSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredSignatures",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_message",
+ "type": "bytes32"
+ }
+ ],
+ "name": "messagesSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorContract",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "executeAffirmation",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "deployedAtBlock",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeInterfacesVersion",
+ "outputs": [
+ {
+ "name": "major",
+ "type": "uint64"
+ },
+ {
+ "name": "minor",
+ "type": "uint64"
+ },
+ {
+ "name": "patch",
+ "type": "uint64"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMinPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "name": "_value",
+ "type": "uint256"
+ },
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "name": "onTokenTransfer",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_blockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setRequiredBlockConfirmations",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "setDailyLimit",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "setGasPrice",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "minPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withinLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "maxPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "gasPrice",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_number",
+ "type": "uint256"
+ }
+ ],
+ "name": "isAlreadyProcessed",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "fallback"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserRequestForSignature",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AffirmationCompleted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "signer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "messageHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "SignedForUserRequest",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "signer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "SignedForAffirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "authorityResponsibleForRelay",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "messageHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "name": "NumberOfCollectedSignatures",
+ "type": "uint256"
+ }
+ ],
+ "name": "CollectedSignatures",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "GasPriceChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "requiredBlockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequiredBlockConfirmationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "newLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "DailyLimitChanged",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validatorContract",
+ "type": "address"
+ },
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ },
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_homeGasPrice",
+ "type": "uint256"
+ },
+ {
+ "name": "_requiredBlockConfirmations",
+ "type": "uint256"
+ },
+ {
+ "name": "_erc677token",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeMode",
+ "outputs": [
+ {
+ "name": "_data",
+ "type": "bytes4"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/HomeBridgeErcToNative.abi.json b/bridge-monitor/abis/HomeBridgeErcToNative.abi.json
new file mode 100644
index 00000000..53eefd44
--- /dev/null
+++ b/bridge-monitor/abis/HomeBridgeErcToNative.abi.json
@@ -0,0 +1,716 @@
+[
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_message",
+ "type": "bytes32"
+ }
+ ],
+ "name": "numMessagesSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_hash",
+ "type": "bytes32"
+ },
+ {
+ "name": "_index",
+ "type": "uint256"
+ }
+ ],
+ "name": "signature",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_day",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalSpentPerDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isInitialized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getCurrentDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredBlockConfirmations",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredMessageLength",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_hash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "message",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "signature",
+ "type": "bytes"
+ },
+ {
+ "name": "message",
+ "type": "bytes"
+ }
+ ],
+ "name": "submitSignature",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "dailyLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ }
+ ],
+ "name": "claimTokens",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_withdrawal",
+ "type": "bytes32"
+ }
+ ],
+ "name": "numAffirmationsSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_withdrawal",
+ "type": "bytes32"
+ }
+ ],
+ "name": "affirmationsSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredSignatures",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_message",
+ "type": "bytes32"
+ }
+ ],
+ "name": "messagesSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorContract",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "executeAffirmation",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "deployedAtBlock",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeInterfacesVersion",
+ "outputs": [
+ {
+ "name": "major",
+ "type": "uint64"
+ },
+ {
+ "name": "minor",
+ "type": "uint64"
+ },
+ {
+ "name": "patch",
+ "type": "uint64"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMinPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_blockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setRequiredBlockConfirmations",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "setDailyLimit",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "setGasPrice",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "minPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withinLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "maxPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "gasPrice",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_number",
+ "type": "uint256"
+ }
+ ],
+ "name": "isAlreadyProcessed",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "payable": true,
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserRequestForSignature",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AffirmationCompleted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "signer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "messageHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "SignedForUserRequest",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "signer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "SignedForAffirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "authorityResponsibleForRelay",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "messageHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "name": "NumberOfCollectedSignatures",
+ "type": "uint256"
+ }
+ ],
+ "name": "CollectedSignatures",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "GasPriceChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "requiredBlockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequiredBlockConfirmationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "newLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "DailyLimitChanged",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validatorContract",
+ "type": "address"
+ },
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ },
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_homeGasPrice",
+ "type": "uint256"
+ },
+ {
+ "name": "_requiredBlockConfirmations",
+ "type": "uint256"
+ },
+ {
+ "name": "_blockReward",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeMode",
+ "outputs": [
+ {
+ "name": "_data",
+ "type": "bytes4"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "blockRewardContract",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "totalBurntCoins",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_blockReward",
+ "type": "address"
+ }
+ ],
+ "name": "setBlockRewardContract",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/HomeBridgeNativeToErc.abi.json b/bridge-monitor/abis/HomeBridgeNativeToErc.abi.json
new file mode 100644
index 00000000..0e7006b2
--- /dev/null
+++ b/bridge-monitor/abis/HomeBridgeNativeToErc.abi.json
@@ -0,0 +1,670 @@
+[
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_message",
+ "type": "bytes32"
+ }
+ ],
+ "name": "numMessagesSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_hash",
+ "type": "bytes32"
+ },
+ {
+ "name": "_index",
+ "type": "uint256"
+ }
+ ],
+ "name": "signature",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_day",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalSpentPerDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isInitialized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getCurrentDay",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredBlockConfirmations",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredMessageLength",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_hash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "message",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "signature",
+ "type": "bytes"
+ },
+ {
+ "name": "message",
+ "type": "bytes"
+ }
+ ],
+ "name": "submitSignature",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "dailyLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ }
+ ],
+ "name": "claimTokens",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_withdrawal",
+ "type": "bytes32"
+ }
+ ],
+ "name": "numAffirmationsSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_withdrawal",
+ "type": "bytes32"
+ }
+ ],
+ "name": "affirmationsSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredSignatures",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_message",
+ "type": "bytes32"
+ }
+ ],
+ "name": "messagesSigned",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorContract",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "executeAffirmation",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "deployedAtBlock",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeInterfacesVersion",
+ "outputs": [
+ {
+ "name": "major",
+ "type": "uint64"
+ },
+ {
+ "name": "minor",
+ "type": "uint64"
+ },
+ {
+ "name": "patch",
+ "type": "uint64"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMinPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_blockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "setRequiredBlockConfirmations",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "setDailyLimit",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "setGasPrice",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxPerTx",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "minPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withinLimit",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "maxPerTx",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "gasPrice",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_number",
+ "type": "uint256"
+ }
+ ],
+ "name": "isAlreadyProcessed",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "payable": true,
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserRequestForSignature",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "recipient",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AffirmationCompleted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "signer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "messageHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "SignedForUserRequest",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "signer",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "transactionHash",
+ "type": "bytes32"
+ }
+ ],
+ "name": "SignedForAffirmation",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "authorityResponsibleForRelay",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "messageHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "name": "NumberOfCollectedSignatures",
+ "type": "uint256"
+ }
+ ],
+ "name": "CollectedSignatures",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "gasPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "GasPriceChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "requiredBlockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequiredBlockConfirmationChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "newLimit",
+ "type": "uint256"
+ }
+ ],
+ "name": "DailyLimitChanged",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validatorContract",
+ "type": "address"
+ },
+ {
+ "name": "_dailyLimit",
+ "type": "uint256"
+ },
+ {
+ "name": "_maxPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_minPerTx",
+ "type": "uint256"
+ },
+ {
+ "name": "_homeGasPrice",
+ "type": "uint256"
+ },
+ {
+ "name": "_requiredBlockConfirmations",
+ "type": "uint256"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeMode",
+ "outputs": [
+ {
+ "name": "_data",
+ "type": "bytes4"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/IBlockReward.abi.json b/bridge-monitor/abis/IBlockReward.abi.json
new file mode 100644
index 00000000..aecd62ee
--- /dev/null
+++ b/bridge-monitor/abis/IBlockReward.abi.json
@@ -0,0 +1,34 @@
+[
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "name": "_receiver",
+ "type": "address"
+ }
+ ],
+ "name": "addExtraReceiver",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "mintedTotally",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/abis/RewardableValidators.abi.json b/bridge-monitor/abis/RewardableValidators.abi.json
new file mode 100644
index 00000000..f437c17e
--- /dev/null
+++ b/bridge-monitor/abis/RewardableValidators.abi.json
@@ -0,0 +1,328 @@
+[
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorCount",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getBridgeValidatorsInterfacesVersion",
+ "outputs": [
+ {
+ "name": "major",
+ "type": "uint64"
+ },
+ {
+ "name": "minor",
+ "type": "uint64"
+ },
+ {
+ "name": "patch",
+ "type": "uint64"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "pure",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "isInitialized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_requiredSignatures",
+ "type": "uint256"
+ }
+ ],
+ "name": "setRequiredSignatures",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "requiredSignatures",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_address",
+ "type": "address"
+ }
+ ],
+ "name": "getNextValidator",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "deployedAtBlock",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "F_ADDR",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_validator",
+ "type": "address"
+ }
+ ],
+ "name": "isValidator",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "reward",
+ "type": "address"
+ }
+ ],
+ "name": "ValidatorAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "validator",
+ "type": "address"
+ }
+ ],
+ "name": "ValidatorRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "requiredSignatures",
+ "type": "uint256"
+ }
+ ],
+ "name": "RequiredSignaturesChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_requiredSignatures",
+ "type": "uint256"
+ },
+ {
+ "name": "_initialValidators",
+ "type": "address[]"
+ },
+ {
+ "name": "_initialRewards",
+ "type": "address[]"
+ },
+ {
+ "name": "_owner",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validator",
+ "type": "address"
+ },
+ {
+ "name": "_reward",
+ "type": "address"
+ }
+ ],
+ "name": "addValidator",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_validator",
+ "type": "address"
+ }
+ ],
+ "name": "removeValidator",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "validatorList",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_validator",
+ "type": "address"
+ }
+ ],
+ "name": "getValidatorRewardAddress",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
diff --git a/bridge-monitor/alerts.js b/bridge-monitor/alerts.js
new file mode 100644
index 00000000..013a317a
--- /dev/null
+++ b/bridge-monitor/alerts.js
@@ -0,0 +1,204 @@
+require('dotenv').config()
+const Web3 = require('web3')
+const logger = require('./logger')('alerts')
+const eventsInfo = require('./utils/events')
+const { getBlockNumber } = require('./utils/contract')
+
+const { HOME_RPC_URL, FOREIGN_RPC_URL } = process.env
+
+const homeProvider = new Web3.providers.HttpProvider(HOME_RPC_URL)
+const web3Home = new Web3(homeProvider)
+
+const foreignProvider = new Web3.providers.HttpProvider(FOREIGN_RPC_URL)
+const web3Foreign = new Web3(foreignProvider)
+
+async function main() {
+ try {
+ const {
+ foreignDeposits,
+ homeDeposits,
+ homeWithdrawals,
+ foreignWithdrawals
+ } = await eventsInfo()
+
+ const xSignatures = foreignDeposits.filter(findDifferences(homeDeposits))
+ const xAffirmations = homeWithdrawals.filter(findDifferences(foreignWithdrawals))
+
+ logger.debug('building misbehavior blocks')
+ const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
+
+ const baseRange = [false, false, false, false, false]
+ const xSignaturesMisbehavior = buildRangesObject(
+ xSignatures.map(findMisbehaviorRange(foreignBlockNumber)).reduce(mergeRanges, baseRange)
+ )
+ const xAffirmationsMisbehavior = buildRangesObject(
+ xAffirmations.map(findMisbehaviorRange(homeBlockNumber)).reduce(mergeRanges, baseRange)
+ )
+
+ logger.debug('extracting most recent transactionHash')
+ const { transactionHash: xSignaturesMostRecentTxHash = '' } =
+ xSignatures.sort(sortEvents).reverse()[0] || {}
+ const { transactionHash: xAffirmationsMostRecentTxHash = '' } =
+ xAffirmations.sort(sortEvents).reverse()[0] || {}
+
+ logger.debug('building transaction objects')
+ const foreignValidators = await Promise.all(
+ xSignatures.map(event => findTxSender(web3Foreign)(event))
+ )
+ const homeValidators = await Promise.all(
+ xAffirmations.map(event => findTxSender(web3Home)(event))
+ )
+
+ const xSignaturesTxs = xSignatures
+ .map(normalizeEventInformation)
+ .reduce(buildTxList(foreignValidators), {})
+ const xAffirmationsTxs = xAffirmations
+ .map(normalizeEventInformation)
+ .reduce(buildTxList(homeValidators), {})
+
+ logger.debug('Done')
+
+ return {
+ executeSignatures: {
+ misbehavior: xSignaturesMisbehavior,
+ mostRecentTxHash: xSignaturesMostRecentTxHash,
+ transactions: xSignaturesTxs
+ },
+ executeAffirmations: {
+ misbehavior: xAffirmationsMisbehavior,
+ mostRecentTxHash: xAffirmationsMostRecentTxHash,
+ transactions: xAffirmationsTxs
+ },
+ lastChecked: Math.floor(Date.now() / 1000)
+ }
+ } catch (e) {
+ logger.error(e)
+ throw e
+ }
+}
+
+/**
+ * Finds the location for the blockNumber in a specific range starting from currentBlockNumber
+ * @param {BN} currentBlockNumber
+ * @returns {function({blockNumber?: *}): boolean[]}
+ */
+const findMisbehaviorRange = currentBlockNumber => ({ blockNumber }) => {
+ const minus60 = currentBlockNumber.sub(Web3.utils.toBN(60))
+ const minus180 = currentBlockNumber.sub(Web3.utils.toBN(180))
+ const minus720 = currentBlockNumber.sub(Web3.utils.toBN(720))
+ const minus17280 = currentBlockNumber.sub(Web3.utils.toBN(17280))
+
+ return [
+ minus60.lte(blockNumber),
+ minus180.lte(blockNumber) && minus60.gt(blockNumber),
+ minus720.lte(blockNumber) && minus180.gt(blockNumber),
+ minus17280.lte(blockNumber) && minus720.gt(blockNumber),
+ minus17280.gt(blockNumber)
+ ]
+}
+
+/**
+ * Merges range arrays into one single array
+ * @param {Array} acc
+ * @param {Array} range
+ * @returns {Array}
+ */
+const mergeRanges = (acc, range) => acc.map((item, index) => item || range[index])
+
+/**
+ * Converts an array of boolean into the object representation of the ranges
+ * @param {Array} range
+ * @returns {{
+ * last60blocks: *,
+ * last60to180blocks: *,
+ * last180to720blocks: *,
+ * last720to17280blocks: *,
+ * last17280blocks: *
+ * }}
+ */
+const buildRangesObject = range => ({
+ last60blocks: range[0],
+ last60to180blocks: range[1],
+ last180to720blocks: range[2],
+ last720to17280blocks: range[3],
+ before17280blocks: range[4]
+})
+
+/**
+ * Sorts events by blockNumber from oldest to newest
+ * @param {Object} prev
+ * @param {Object} next
+ * @returns {number}
+ */
+const sortEvents = ({ blockNumber: prev }, { blockNumber: next }) => prev - next
+
+/**
+ * Retrieves the transaction object and returns the 'from' key from it using the provided web3 instance
+ * @param {Object} web3
+ * @returns {function({transactionHash?: *}): Transaction.from}
+ */
+const findTxSender = web3 => async ({ transactionHash }) => {
+ const { from } = await web3.eth.getTransaction(transactionHash)
+ return from
+}
+
+/**
+ * Builds a list of transactions information using the txHash as key
+ * _validatorsList_ is a correlative list of validators addresses for each event processed
+ * @param {Array} validatorsList
+ * @returns {{acc[event.txHash]: {
+ * value: string,
+ * block: number,
+ * referenceTx: string,
+ * recipient: string,
+ * validator: string
+ * }}}
+ */
+const buildTxList = validatorsList => (acc, event, index) => {
+ acc[event.txHash] = {
+ value: event.value,
+ block: event.blockNumber,
+ referenceTx: event.referenceTx,
+ recipient: event.recipient,
+ validator: validatorsList[index]
+ }
+ return acc
+}
+
+/**
+ * Finds a missing destDeposit in src list if there's any
+ * @param {Array} src
+ * @returns {function(*=): boolean}
+ */
+const findDifferences = src => dest => {
+ const b = normalizeEventInformation(dest)
+
+ return (
+ src
+ .map(normalizeEventInformation)
+ .filter(
+ a => a.referenceTx === b.referenceTx && a.recipient === b.recipient && a.value === b.value
+ ).length === 0
+ )
+}
+
+/**
+ * Normalizes the different event objects to facilitate data processing
+ * @param {Object} event
+ * @returns {{
+ * txHash: string,
+ * blockNumber: number,
+ * referenceTx: string,
+ * recipient: string | *,
+ * value: *
+ * }}
+ */
+const normalizeEventInformation = event => ({
+ txHash: event.transactionHash,
+ blockNumber: event.blockNumber,
+ referenceTx: event.returnValues.transactionHash || event.transactionHash,
+ recipient: event.returnValues.recipient || event.returnValues.from,
+ value: event.returnValues.value
+})
+
+module.exports = main
diff --git a/bridge-monitor/checkWorker.js b/bridge-monitor/checkWorker.js
new file mode 100644
index 00000000..4a71b6b1
--- /dev/null
+++ b/bridge-monitor/checkWorker.js
@@ -0,0 +1,49 @@
+const fs = require('fs')
+const path = require('path')
+const Web3 = require('web3')
+const logger = require('./logger')('checkWorker')
+const { decodeBridgeMode } = require('./utils/bridgeMode')
+const getBalances = require('./getBalances')
+const getShortEventStats = require('./getShortEventStats')
+const validators = require('./validators')
+
+const { HOME_BRIDGE_ADDRESS, HOME_RPC_URL } = process.env
+const homeProvider = new Web3.providers.HttpProvider(HOME_RPC_URL)
+const web3Home = new Web3(homeProvider)
+
+const HOME_ERC_TO_ERC_ABI = require('./abis/HomeBridgeErcToErc.abi')
+
+async function checkWorker() {
+ try {
+ const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, HOME_BRIDGE_ADDRESS)
+ const bridgeModeHash = await homeBridge.methods.getBridgeMode().call()
+ const bridgeMode = decodeBridgeMode(bridgeModeHash)
+ logger.debug('Bridge mode:', bridgeMode)
+ logger.debug('calling getBalances()')
+ const balances = await getBalances(bridgeMode)
+ logger.debug('calling getShortEventStats()')
+ const events = await getShortEventStats(bridgeMode)
+ const home = Object.assign({}, balances.home, events.home)
+ const foreign = Object.assign({}, balances.foreign, events.foreign)
+ const status = Object.assign({}, balances, events, { home }, { foreign })
+ if (!status) throw new Error('status is empty: ' + JSON.stringify(status))
+ fs.writeFileSync(
+ path.join(__dirname, '/responses/getBalances.json'),
+ JSON.stringify(status, null, 4)
+ )
+
+ logger.debug('calling validators()')
+ const vBalances = await validators(bridgeMode)
+ if (!vBalances) throw new Error('vBalances is empty: ' + JSON.stringify(vBalances))
+ fs.writeFileSync(
+ path.join(__dirname, '/responses/validators.json'),
+ JSON.stringify(vBalances, null, 4)
+ )
+ logger.debug('Done')
+ return status
+ } catch (e) {
+ logger.error(e)
+ throw e
+ }
+}
+checkWorker()
diff --git a/bridge-monitor/checkWorker2.js b/bridge-monitor/checkWorker2.js
new file mode 100644
index 00000000..eaf16a35
--- /dev/null
+++ b/bridge-monitor/checkWorker2.js
@@ -0,0 +1,30 @@
+const fs = require('fs')
+const path = require('path')
+const logger = require('./logger')('checkWorker2')
+const eventsStats = require('./eventsStats')
+const alerts = require('./alerts')
+
+async function checkWorker2() {
+ try {
+ logger.debug('calling eventsStats()')
+ const evStats = await eventsStats()
+ if (!evStats) throw new Error('evStats is empty: ' + JSON.stringify(evStats))
+ fs.writeFileSync(
+ path.join(__dirname, '/responses/eventsStats.json'),
+ JSON.stringify(evStats, null, 4)
+ )
+ logger.debug('calling alerts()')
+ const _alerts = await alerts()
+ if (!_alerts) throw new Error('alerts is empty: ' + JSON.stringify(_alerts))
+ fs.writeFileSync(
+ path.join(__dirname, '/responses/alerts.json'),
+ JSON.stringify(_alerts, null, 4)
+ )
+ logger.debug('Done x2')
+ return evStats
+ } catch (e) {
+ logger.error('checkWorker2.js', e)
+ throw e
+ }
+}
+checkWorker2()
diff --git a/bridge-monitor/checkWorker3.js b/bridge-monitor/checkWorker3.js
new file mode 100644
index 00000000..4b003351
--- /dev/null
+++ b/bridge-monitor/checkWorker3.js
@@ -0,0 +1,23 @@
+const fs = require('fs')
+const path = require('path')
+const logger = require('./logger')('checkWorker3')
+const stuckTransfers = require('./stuckTransfers')
+
+async function checkWorker3() {
+ try {
+ logger.debug('calling stuckTransfers()')
+ const transfers = await stuckTransfers()
+ // console.log(transfers)
+ if (!transfers) throw new Error('transfers is empty: ' + JSON.stringify(transfers))
+ fs.writeFileSync(
+ path.join(__dirname, '/responses/stuckTransfers.json'),
+ JSON.stringify(transfers, null, 4)
+ )
+ logger.debug('Done')
+ return transfers
+ } catch (e) {
+ logger.error('checkWorker3.js', e)
+ throw e
+ }
+}
+checkWorker3()
diff --git a/bridge-monitor/crontab.example b/bridge-monitor/crontab.example
new file mode 100644
index 00000000..0fa1787d
--- /dev/null
+++ b/bridge-monitor/crontab.example
@@ -0,0 +1,2 @@
+*/4 * * * * cd $HOME/bridge-monitor; node checkWorker.js >>cronWorker.out 2>>cronWorker.err
+*/5 * * * * cd $HOME/bridge-monitor; node checkWorker2.js >>cronWorker2.out 2>>cronWorker2.err
diff --git a/bridge-monitor/eventsStats.js b/bridge-monitor/eventsStats.js
new file mode 100644
index 00000000..4b936830
--- /dev/null
+++ b/bridge-monitor/eventsStats.js
@@ -0,0 +1,95 @@
+require('dotenv').config()
+const logger = require('./logger')('eventsStats')
+const eventsInfo = require('./utils/events')
+
+function compareDepositsHome(foreign) {
+ return homeDeposit => {
+ return (
+ foreign.filter(foreignDeposit => {
+ return (
+ foreignDeposit.returnValues.transactionHash === homeDeposit.transactionHash &&
+ foreignDeposit.returnValues.recipient === homeDeposit.returnValues.recipient &&
+ foreignDeposit.returnValues.value === homeDeposit.returnValues.value
+ )
+ }).length === 0
+ )
+ }
+}
+function compareDepositsForeign(home) {
+ return foreignDeposit => {
+ return (
+ home.filter(homeDeposit => {
+ return (
+ homeDeposit.transactionHash === foreignDeposit.returnValues.transactionHash &&
+ homeDeposit.returnValues.recipient === foreignDeposit.returnValues.recipient &&
+ homeDeposit.returnValues.value === foreignDeposit.returnValues.value
+ )
+ }).length === 0
+ )
+ }
+}
+
+function compareTransferHome(foreign) {
+ return homeDeposit => {
+ return (
+ foreign.filter(foreignDeposit => {
+ return (
+ homeDeposit.returnValues.transactionHash === foreignDeposit.transactionHash &&
+ homeDeposit.returnValues.recipient === foreignDeposit.returnValues.from &&
+ homeDeposit.returnValues.value === foreignDeposit.returnValues.value
+ )
+ }).length === 0
+ )
+ }
+}
+function compareTransferForeign(home) {
+ return foreignDeposit => {
+ return (
+ home.filter(homeDeposit => {
+ return (
+ foreignDeposit.transactionHash === homeDeposit.returnValues.transactionHash &&
+ foreignDeposit.returnValues.from === homeDeposit.returnValues.recipient &&
+ foreignDeposit.returnValues.value === homeDeposit.returnValues.value
+ )
+ }).length === 0
+ )
+ }
+}
+
+async function main() {
+ try {
+ const {
+ foreignDeposits,
+ homeDeposits,
+ homeWithdrawals,
+ foreignWithdrawals,
+ isExternalErc20
+ } = await eventsInfo()
+
+ const onlyInHomeDeposits = homeDeposits.filter(compareDepositsHome(foreignDeposits))
+ const onlyInForeignDeposits = foreignDeposits
+ .concat([])
+ .filter(compareDepositsForeign(homeDeposits))
+
+ const onlyInHomeWithdrawals = isExternalErc20
+ ? homeWithdrawals.filter(compareTransferHome(foreignWithdrawals))
+ : homeWithdrawals.filter(compareDepositsForeign(foreignWithdrawals))
+ const onlyInForeignWithdrawals = isExternalErc20
+ ? foreignWithdrawals.filter(compareTransferForeign(homeWithdrawals))
+ : foreignWithdrawals.filter(compareDepositsHome(homeWithdrawals))
+
+ logger.debug('Done')
+ return {
+ onlyInHomeDeposits,
+ onlyInForeignDeposits,
+ onlyInHomeWithdrawals,
+ onlyInForeignWithdrawals,
+ lastChecked: Math.floor(Date.now() / 1000)
+ }
+ } catch (e) {
+ logger.error(e)
+ throw e
+ }
+}
+
+module.exports = main
diff --git a/bridge-monitor/getBalances.js b/bridge-monitor/getBalances.js
new file mode 100644
index 00000000..32241ba3
--- /dev/null
+++ b/bridge-monitor/getBalances.js
@@ -0,0 +1,131 @@
+require('dotenv').config()
+const BN = require('bignumber.js')
+const Web3 = require('web3')
+const logger = require('./logger')('getBalances')
+const { BRIDGE_MODES } = require('./utils/bridgeMode')
+
+const Web3Utils = Web3.utils
+
+const { HOME_RPC_URL, FOREIGN_RPC_URL, HOME_BRIDGE_ADDRESS, FOREIGN_BRIDGE_ADDRESS } = process.env
+
+const homeProvider = new Web3.providers.HttpProvider(HOME_RPC_URL)
+const web3Home = new Web3(homeProvider)
+
+const foreignProvider = new Web3.providers.HttpProvider(FOREIGN_RPC_URL)
+const web3Foreign = new Web3(foreignProvider)
+
+const ERC20_ABI = require('./abis/ERC20.abi')
+const ERC677_ABI = require('./abis/ERC677.abi')
+const HOME_ERC_TO_ERC_ABI = require('./abis/HomeBridgeErcToErc.abi')
+const HOME_ERC_TO_NATIVE_ABI = require('./abis/HomeBridgeErcToNative.abi')
+const BLOCK_REWARD_ABI = require('./abis/IBlockReward.abi')
+const FOREIGN_ERC_TO_ERC_ABI = require('./abis/ForeignBridgeErcToErc.abi')
+const FOREIGN_ERC_TO_NATIVE_ABI = require('./abis/ForeignBridgeErcToNative.abi')
+const FOREIGN_NATIVE_TO_ERC_ABI = require('./abis/ForeignBridgeNativeToErc.abi')
+
+async function main(bridgeMode) {
+ try {
+ if (bridgeMode === BRIDGE_MODES.ERC_TO_ERC) {
+ const foreignBridge = new web3Foreign.eth.Contract(
+ FOREIGN_ERC_TO_ERC_ABI,
+ FOREIGN_BRIDGE_ADDRESS
+ )
+ const erc20Address = await foreignBridge.methods.erc20token().call()
+ const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
+ logger.debug('calling erc20Contract.methods.balanceOf')
+ const foreignErc20Balance = await erc20Contract.methods
+ .balanceOf(FOREIGN_BRIDGE_ADDRESS)
+ .call()
+ const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, HOME_BRIDGE_ADDRESS)
+ logger.debug('calling homeBridge.methods.erc677token')
+ const tokenAddress = await homeBridge.methods.erc677token().call()
+ const tokenContract = new web3Home.eth.Contract(ERC677_ABI, tokenAddress)
+ logger.debug('calling tokenContract.methods.totalSupply()')
+ const totalSupply = await tokenContract.methods.totalSupply().call()
+ const foreignBalanceBN = new BN(foreignErc20Balance)
+ const foreignTotalSupplyBN = new BN(totalSupply)
+ const diff = foreignBalanceBN.minus(foreignTotalSupplyBN).toString(10)
+ logger.debug('Done')
+ return {
+ home: {
+ totalSupply: Web3Utils.fromWei(totalSupply)
+ },
+ foreign: {
+ erc20Balance: Web3Utils.fromWei(foreignErc20Balance)
+ },
+ balanceDiff: Number(Web3Utils.fromWei(diff)),
+ lastChecked: Math.floor(Date.now() / 1000)
+ }
+ } else if (bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC) {
+ logger.debug('calling web3Home.eth.getBalance')
+ const foreignBridge = new web3Foreign.eth.Contract(
+ FOREIGN_NATIVE_TO_ERC_ABI,
+ FOREIGN_BRIDGE_ADDRESS
+ )
+ const erc20Address = await foreignBridge.methods.erc677token().call()
+ const homeBalance = await web3Home.eth.getBalance(HOME_BRIDGE_ADDRESS)
+ const tokenContract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
+ logger.debug('calling tokenContract.methods.totalSupply()')
+ const totalSupply = await tokenContract.methods.totalSupply().call()
+ const homeBalanceBN = new BN(homeBalance)
+ const foreignTotalSupplyBN = new BN(totalSupply)
+ const diff = homeBalanceBN.minus(foreignTotalSupplyBN).toString(10)
+ logger.debug('Done')
+ return {
+ home: {
+ balance: Web3Utils.fromWei(homeBalance)
+ },
+ foreign: {
+ totalSupply: Web3Utils.fromWei(totalSupply)
+ },
+ balanceDiff: Number(Web3Utils.fromWei(diff)),
+ lastChecked: Math.floor(Date.now() / 1000)
+ }
+ } else if (bridgeMode === BRIDGE_MODES.ERC_TO_NATIVE) {
+ const foreignBridge = new web3Foreign.eth.Contract(
+ FOREIGN_ERC_TO_NATIVE_ABI,
+ FOREIGN_BRIDGE_ADDRESS
+ )
+ const erc20Address = await foreignBridge.methods.erc20token().call()
+ const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
+ logger.debug('calling erc20Contract.methods.balanceOf')
+ const foreignErc20Balance = await erc20Contract.methods
+ .balanceOf(FOREIGN_BRIDGE_ADDRESS)
+ .call()
+
+ const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_NATIVE_ABI, HOME_BRIDGE_ADDRESS)
+ logger.debug('calling homeBridge.methods.blockRewardContract')
+ const blockRewardAddress = await homeBridge.methods.blockRewardContract().call()
+ const blockRewardContract = new web3Home.eth.Contract(BLOCK_REWARD_ABI, blockRewardAddress)
+ logger.debug('calling blockReward.methods.mintedTotally')
+ const mintedCoins = await blockRewardContract.methods.mintedTotally().call()
+ logger.debug('calling homeBridge.methods.totalBurntCoins')
+ const burntCoins = await homeBridge.methods.totalBurntCoins().call()
+
+ const mintedCoinsBN = new BN(mintedCoins)
+ const burntCoinsBN = new BN(burntCoins)
+ const totalSupplyBN = mintedCoinsBN.minus(burntCoinsBN)
+ const foreignErc20BalanceBN = new BN(foreignErc20Balance)
+
+ const diff = foreignErc20BalanceBN.minus(totalSupplyBN).toFixed()
+ logger.debug('Done')
+ return {
+ home: {
+ totalSupply: Web3Utils.fromWei(totalSupplyBN.toFixed())
+ },
+ foreign: {
+ erc20Balance: Web3Utils.fromWei(foreignErc20Balance)
+ },
+ balanceDiff: Number(Web3Utils.fromWei(diff)),
+ lastChecked: Math.floor(Date.now() / 1000)
+ }
+ } else {
+ throw new Error(`Unrecognized bridge mode: '${bridgeMode}'`)
+ }
+ } catch (e) {
+ logger.error(e)
+ throw e
+ }
+}
+
+module.exports = main
diff --git a/bridge-monitor/getShortEventStats.js b/bridge-monitor/getShortEventStats.js
new file mode 100644
index 00000000..fac0edf1
--- /dev/null
+++ b/bridge-monitor/getShortEventStats.js
@@ -0,0 +1,97 @@
+require('dotenv').config()
+const Web3 = require('web3')
+const { toBN } = require('web3').utils
+const logger = require('./logger')('getShortEventStats.js')
+const { getBridgeABIs, BRIDGE_MODES, ERC_TYPES } = require('./utils/bridgeMode')
+
+const { HOME_RPC_URL, FOREIGN_RPC_URL, HOME_BRIDGE_ADDRESS, FOREIGN_BRIDGE_ADDRESS } = process.env
+const HOME_DEPLOYMENT_BLOCK = toBN(Number(process.env.HOME_DEPLOYMENT_BLOCK) || 0)
+const FOREIGN_DEPLOYMENT_BLOCK = toBN(Number(process.env.FOREIGN_DEPLOYMENT_BLOCK) || 0)
+
+const homeProvider = new Web3.providers.HttpProvider(HOME_RPC_URL)
+const web3Home = new Web3(homeProvider)
+
+const foreignProvider = new Web3.providers.HttpProvider(FOREIGN_RPC_URL)
+const web3Foreign = new Web3(foreignProvider)
+
+const ERC20_ABI = require('./abis/ERC20.abi')
+const { getTokenType } = require('./utils/ercUtils')
+const { getPastEvents, getBlockNumber } = require('./utils/contract')
+
+async function main(bridgeMode) {
+ try {
+ const { HOME_ABI, FOREIGN_ABI } = getBridgeABIs(bridgeMode)
+ const homeBridge = new web3Home.eth.Contract(HOME_ABI, HOME_BRIDGE_ADDRESS)
+ const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ABI, FOREIGN_BRIDGE_ADDRESS)
+ const erc20MethodName = bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC ? 'erc677token' : 'erc20token'
+ const erc20Address = await foreignBridge.methods[erc20MethodName]().call()
+ const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
+ const tokenType = await getTokenType(foreignBridge, FOREIGN_BRIDGE_ADDRESS)
+
+ logger.debug('getting last block numbers')
+ const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
+ logger.debug("calling homeBridge.getPastEvents('UserRequestForSignature')")
+ const homeDeposits = await getPastEvents({
+ contract: homeBridge,
+ event: 'UserRequestForSignature',
+ fromBlock: HOME_DEPLOYMENT_BLOCK,
+ toBlock: homeBlockNumber,
+ options: {}
+ })
+
+ logger.debug("calling foreignBridge.getPastEvents('RelayedMessage')")
+ const foreignDeposits = await getPastEvents({
+ contract: foreignBridge,
+ event: 'RelayedMessage',
+ fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
+ toBlock: foreignBlockNumber,
+ options: {}
+ })
+
+ logger.debug("calling homeBridge.getPastEvents('AffirmationCompleted')")
+ const homeWithdrawals = await getPastEvents({
+ contract: homeBridge,
+ event: 'AffirmationCompleted',
+ fromBlock: HOME_DEPLOYMENT_BLOCK,
+ toBlock: homeBlockNumber,
+ options: {}
+ })
+
+ logger.debug("calling foreignBridge.getPastEvents('UserRequestForAffirmation')")
+ const foreignWithdrawals =
+ tokenType === ERC_TYPES.ERC20
+ ? await getPastEvents({
+ contract: erc20Contract,
+ event: 'Transfer',
+ fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
+ toBlock: foreignBlockNumber,
+ options: {
+ filter: { to: FOREIGN_BRIDGE_ADDRESS }
+ }
+ })
+ : await getPastEvents({
+ contract: foreignBridge,
+ event: 'UserRequestForAffirmation',
+ fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
+ toBlock: foreignBlockNumber,
+ options: {}
+ })
+ logger.debug('Done')
+ return {
+ depositsDiff: homeDeposits.length - foreignDeposits.length,
+ withdrawalDiff: homeWithdrawals.length - foreignWithdrawals.length,
+ home: {
+ deposits: homeDeposits.length,
+ withdrawals: homeWithdrawals.length
+ },
+ foreign: {
+ deposits: foreignDeposits.length,
+ withdrawals: foreignWithdrawals.length
+ }
+ }
+ } catch (e) {
+ logger.error(e)
+ throw e
+ }
+}
+module.exports = main
diff --git a/bridge-monitor/index.js b/bridge-monitor/index.js
new file mode 100644
index 00000000..45db3c60
--- /dev/null
+++ b/bridge-monitor/index.js
@@ -0,0 +1,103 @@
+require('dotenv').config()
+const express = require('express')
+const fs = require('fs')
+
+const app = express()
+
+const LEFT_TX_THRESHOLD = Number(process.env.LEFT_TX_THRESHOLD) || 100
+console.log('LEFT_TX_THRESHOLD = ' + LEFT_TX_THRESHOLD)
+
+async function readFile(path) {
+ try {
+ const content = await fs.readFileSync(path)
+ const json = JSON.parse(content)
+ const timeDiff = Math.floor(Date.now() / 1000) - json.lastChecked
+ return Object.assign({}, json, { timeDiff })
+ } catch (e) {
+ console.error(e)
+ return {
+ error: 'please check your worker'
+ }
+ }
+}
+
+app.get('/', async (req, res, next) => {
+ try {
+ const results = await readFile('./responses/getBalances.json')
+ res.json(results)
+ } catch (e) {
+ // this will eventually be handled by your error handling middleware
+ next(e)
+ }
+})
+
+app.get('/validators', async (req, res, next) => {
+ try {
+ const results = await readFile('./responses/validators.json')
+ results.homeOk = true
+ results.foreignOk = true
+ for (const hv in results.home.validators) {
+ if (results.home.validators[hv].leftTx < LEFT_TX_THRESHOLD) {
+ results.homeOk = false
+ break
+ }
+ }
+ for (const hv in results.foreign.validators) {
+ if (results.foreign.validators[hv].leftTx < LEFT_TX_THRESHOLD) {
+ results.foreignOk = false
+ break
+ }
+ }
+ results.ok = results.homeOk && results.foreignOk
+ res.json(results)
+ } catch (e) {
+ // this will eventually be handled by your error handling middleware
+ next(e)
+ }
+})
+
+// responses/eventsStats.json
+app.get('/eventsStats', async (req, res, next) => {
+ try {
+ const results = await readFile('./responses/eventsStats.json')
+ results.ok =
+ results.onlyInHomeDeposits.length === 0 &&
+ results.onlyInForeignDeposits.length === 0 &&
+ results.onlyInHomeWithdrawals.length === 0 &&
+ results.onlyInForeignWithdrawals.length === 0
+ res.json(results)
+ } catch (e) {
+ // this will eventually be handled by your error handling middleware
+ next(e)
+ }
+})
+
+app.get('/alerts', async (req, res, next) => {
+ try {
+ const results = await readFile('./responses/alerts.json')
+ results.ok =
+ !results.executeAffirmations.mostRecentTxHash && !results.executeSignatures.mostRecentTxHash
+ res.json(results)
+ } catch (e) {
+ next(e)
+ }
+})
+
+// responses/stuckTransfers.json
+// Only applicable for bridge-rust-v1-native-to-erc
+/*
+app.get('/stuckTransfers', async (req, res, next) => {
+ try {
+ const results = await readFile('./responses/stuckTransfers.json')
+ results.ok = results.total.length === 0
+ res.json(results)
+ } catch (e) {
+ // this will eventually be handled by your error handling middleware
+ next(e)
+ }
+})
+*/
+
+const port = process.env.PORT || 3000
+app.set('port', port)
+app.listen(port, () => console.log('Monitoring app listening on port 3000!'))
diff --git a/bridge-monitor/logger.js b/bridge-monitor/logger.js
new file mode 100644
index 00000000..0b74a979
--- /dev/null
+++ b/bridge-monitor/logger.js
@@ -0,0 +1,34 @@
+module.exports = function logger(name) {
+ let lastlog = 0
+
+ function log(...args) {
+ const now = new Date()
+ console.log(
+ now.toISOString(),
+ `(+${lastlog ? now.getTime() - lastlog : 0}ms)`,
+ `[${name}]`,
+ ...args
+ )
+ lastlog = now.getTime()
+ }
+
+ function error(...args) {
+ const now = new Date()
+ console.error(now.toISOString(), `[${name}]`, ...args)
+ }
+
+ let dbg
+ if (process.env.DEBUG) {
+ dbg = (...args) => {
+ log(...args)
+ }
+ } else {
+ dbg = () => {}
+ }
+
+ return {
+ log,
+ error,
+ debug: dbg
+ }
+}
diff --git a/bridge-monitor/package-lock.json b/bridge-monitor/package-lock.json
new file mode 100644
index 00000000..cbc5727c
--- /dev/null
+++ b/bridge-monitor/package-lock.json
@@ -0,0 +1,3809 @@
+{
+ "name": "bridge-monitoring",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
+ "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.0.0"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
+ "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.0",
+ "esutils": "^2.0.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "accepts": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
+ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
+ "requires": {
+ "mime-types": "~2.1.18",
+ "negotiator": "0.6.1"
+ }
+ },
+ "acorn": {
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
+ "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz",
+ "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==",
+ "dev": true,
+ "requires": {
+ "acorn": "^5.0.3"
+ }
+ },
+ "ajv": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+ "requires": {
+ "co": "^4.6.0",
+ "fast-deep-equal": "^1.0.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.3.0"
+ }
+ },
+ "ajv-keywords": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
+ "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+ "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.1"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
+ },
+ "asn1.js": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+ "requires": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "async-limiter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+ "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
+ "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w=="
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "base64-js": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz",
+ "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w=="
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "optional": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "bignumber.js": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-6.0.0.tgz",
+ "integrity": "sha512-x247jIuy60/+FtMRvscqfxtVHQf8AGx2hm9c6btkgC0x/hp9yt+teISNhvF8WlwRkCc5yF2fDECH8SIMe8j+GA=="
+ },
+ "bl": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
+ "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
+ "requires": {
+ "readable-stream": "^2.3.5",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "block-stream": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+ "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+ "requires": {
+ "inherits": "~2.0.0"
+ }
+ },
+ "bluebird": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+ "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
+ },
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ },
+ "body-parser": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
+ "requires": {
+ "bytes": "3.0.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.1",
+ "http-errors": "~1.6.2",
+ "iconv-lite": "0.4.19",
+ "on-finished": "~2.3.0",
+ "qs": "6.5.1",
+ "raw-body": "2.3.2",
+ "type-is": "~1.6.15"
+ }
+ },
+ "boom": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+ "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+ "requires": {
+ "hoek": "4.x.x"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
+ },
+ "browserify-aes": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "requires": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+ "requires": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "browserify-des": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz",
+ "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==",
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+ "requires": {
+ "bn.js": "^4.1.0",
+ "randombytes": "^2.0.1"
+ }
+ },
+ "browserify-sha3": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz",
+ "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=",
+ "requires": {
+ "js-sha3": "^0.3.1"
+ }
+ },
+ "browserify-sign": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+ "requires": {
+ "bn.js": "^4.1.1",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.2",
+ "elliptic": "^6.0.0",
+ "inherits": "^2.0.1",
+ "parse-asn1": "^5.0.0"
+ }
+ },
+ "buffer": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz",
+ "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==",
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
+ },
+ "buffer-to-arraybuffer": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
+ "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo="
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+ "dev": true
+ },
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+ },
+ "caller-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+ "dev": true,
+ "requires": {
+ "callsites": "^0.2.0"
+ }
+ },
+ "callsites": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "circular-json": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^2.0.0"
+ }
+ },
+ "cli-width": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+ "dev": true
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
+ "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
+ "requires": {
+ "graceful-readlink": ">= 1.0.0"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "contains-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+ "dev": true
+ },
+ "content-disposition": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+ "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "cors": {
+ "version": "2.8.4",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz",
+ "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=",
+ "requires": {
+ "object-assign": "^4",
+ "vary": "^1"
+ }
+ },
+ "create-ecdh": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.1.tgz",
+ "integrity": "sha512-iZvCCg8XqHQZ1ioNBTzXS/cQSkqkqcPs8xSX4upNB+DAk9Ht3uzQf2J32uAHNCne8LDmKr29AgZrEs4oIrwLuQ==",
+ "requires": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.0.0"
+ }
+ },
+ "create-hash": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "requires": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "cryptiles": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+ "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+ "requires": {
+ "boom": "5.x.x"
+ },
+ "dependencies": {
+ "boom": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
+ "requires": {
+ "hoek": "4.x.x"
+ }
+ }
+ }
+ },
+ "crypto-browserify": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+ "requires": {
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
+ },
+ "decompress": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz",
+ "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=",
+ "requires": {
+ "decompress-tar": "^4.0.0",
+ "decompress-tarbz2": "^4.0.0",
+ "decompress-targz": "^4.0.0",
+ "decompress-unzip": "^4.0.1",
+ "graceful-fs": "^4.1.10",
+ "make-dir": "^1.0.0",
+ "pify": "^2.3.0",
+ "strip-dirs": "^2.0.0"
+ }
+ },
+ "decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "decompress-tar": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
+ "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
+ "requires": {
+ "file-type": "^5.2.0",
+ "is-stream": "^1.1.0",
+ "tar-stream": "^1.5.2"
+ }
+ },
+ "decompress-tarbz2": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
+ "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
+ "requires": {
+ "decompress-tar": "^4.1.0",
+ "file-type": "^6.1.0",
+ "is-stream": "^1.1.0",
+ "seek-bzip": "^1.0.5",
+ "unbzip2-stream": "^1.0.9"
+ },
+ "dependencies": {
+ "file-type": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
+ "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg=="
+ }
+ }
+ },
+ "decompress-targz": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
+ "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
+ "requires": {
+ "decompress-tar": "^4.1.1",
+ "file-type": "^5.2.0",
+ "is-stream": "^1.1.0"
+ }
+ },
+ "decompress-unzip": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
+ "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
+ "requires": {
+ "file-type": "^3.8.0",
+ "get-stream": "^2.2.0",
+ "pify": "^2.3.0",
+ "yauzl": "^2.4.2"
+ },
+ "dependencies": {
+ "file-type": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+ "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
+ },
+ "get-stream": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
+ "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
+ "requires": {
+ "object-assign": "^4.0.1",
+ "pinkie-promise": "^2.0.0"
+ }
+ }
+ }
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "del": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+ "dev": true,
+ "requires": {
+ "globby": "^5.0.0",
+ "is-path-cwd": "^1.0.0",
+ "is-path-in-cwd": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "rimraf": "^2.2.8"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "des.js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+ "requires": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "diffie-hellman": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+ "requires": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "dom-walk": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
+ "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg="
+ },
+ "dotenv": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz",
+ "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow=="
+ },
+ "duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "optional": true,
+ "requires": {
+ "jsbn": "~0.1.0"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "elliptic": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
+ "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
+ "requires": {
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
+ }
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+ },
+ "end-of-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+ "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
+ "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.1.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.1",
+ "is-callable": "^1.1.3",
+ "is-regex": "^1.0.4"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
+ "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.1",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.1"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "eslint": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.6.0.tgz",
+ "integrity": "sha512-/eVYs9VVVboX286mBK7bbKnO1yamUy2UCRjiY6MryhQL2PaaXCExsCQ2aO83OeYRhU2eCU/FMFP+tVMoOrzNrA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.5.3",
+ "chalk": "^2.1.0",
+ "cross-spawn": "^6.0.5",
+ "debug": "^3.1.0",
+ "doctrine": "^2.1.0",
+ "eslint-scope": "^4.0.0",
+ "eslint-utils": "^1.3.1",
+ "eslint-visitor-keys": "^1.0.0",
+ "espree": "^4.0.0",
+ "esquery": "^1.0.1",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^2.0.0",
+ "functional-red-black-tree": "^1.0.1",
+ "glob": "^7.1.2",
+ "globals": "^11.7.0",
+ "ignore": "^4.0.6",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^6.1.0",
+ "is-resolvable": "^1.1.0",
+ "js-yaml": "^3.12.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.5",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.2",
+ "path-is-inside": "^1.0.2",
+ "pluralize": "^7.0.0",
+ "progress": "^2.0.0",
+ "regexpp": "^2.0.0",
+ "require-uncached": "^1.0.3",
+ "semver": "^5.5.1",
+ "strip-ansi": "^4.0.0",
+ "strip-json-comments": "^2.0.1",
+ "table": "^4.0.3",
+ "text-table": "^0.2.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz",
+ "integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "debug": {
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz",
+ "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-config-airbnb": {
+ "version": "17.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz",
+ "integrity": "sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw==",
+ "dev": true,
+ "requires": {
+ "eslint-config-airbnb-base": "^13.1.0",
+ "object.assign": "^4.1.0",
+ "object.entries": "^1.0.4"
+ }
+ },
+ "eslint-config-airbnb-base": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz",
+ "integrity": "sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==",
+ "dev": true,
+ "requires": {
+ "eslint-restricted-globals": "^0.1.1",
+ "object.assign": "^4.1.0",
+ "object.entries": "^1.0.4"
+ }
+ },
+ "eslint-config-prettier": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-3.1.0.tgz",
+ "integrity": "sha512-QYGfmzuc4q4J6XIhlp8vRKdI/fI0tQfQPy1dME3UOLprE+v4ssH/3W9LM2Q7h5qBcy5m0ehCrBDU2YF8q6OY8w==",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^6.0.0"
+ }
+ },
+ "eslint-import-resolver-node": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
+ "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.9",
+ "resolve": "^1.5.0"
+ }
+ },
+ "eslint-module-utils": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz",
+ "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.8",
+ "pkg-dir": "^1.0.0"
+ }
+ },
+ "eslint-plugin-es": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.3.1.tgz",
+ "integrity": "sha512-9XcVyZiQRVeFjqHw8qHNDAZcQLqaHlOGGpeYqzYh8S4JYCWTCO3yzyen8yVmA5PratfzTRWDwCOFphtDEG+w/w==",
+ "dev": true,
+ "requires": {
+ "eslint-utils": "^1.3.0",
+ "regexpp": "^2.0.0"
+ }
+ },
+ "eslint-plugin-import": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz",
+ "integrity": "sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g==",
+ "dev": true,
+ "requires": {
+ "contains-path": "^0.1.0",
+ "debug": "^2.6.8",
+ "doctrine": "1.5.0",
+ "eslint-import-resolver-node": "^0.3.1",
+ "eslint-module-utils": "^2.2.0",
+ "has": "^1.0.1",
+ "lodash": "^4.17.4",
+ "minimatch": "^3.0.3",
+ "read-pkg-up": "^2.0.0",
+ "resolve": "^1.6.0"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ }
+ }
+ }
+ },
+ "eslint-plugin-node": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz",
+ "integrity": "sha512-lfVw3TEqThwq0j2Ba/Ckn2ABdwmL5dkOgAux1rvOk6CO7A6yGyPI2+zIxN6FyNkp1X1X/BSvKOceD6mBWSj4Yw==",
+ "dev": true,
+ "requires": {
+ "eslint-plugin-es": "^1.3.1",
+ "eslint-utils": "^1.3.1",
+ "ignore": "^4.0.2",
+ "minimatch": "^3.0.4",
+ "resolve": "^1.8.1",
+ "semver": "^5.5.0"
+ }
+ },
+ "eslint-plugin-prettier": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.2.tgz",
+ "integrity": "sha512-tGek5clmW5swrAx1mdPYM8oThrBE83ePh7LeseZHBWfHVGrHPhKn7Y5zgRMbU/9D5Td9K4CEmUPjGxA7iw98Og==",
+ "dev": true,
+ "requires": {
+ "fast-diff": "^1.1.1",
+ "jest-docblock": "^21.0.0"
+ }
+ },
+ "eslint-restricted-globals": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz",
+ "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=",
+ "dev": true
+ },
+ "eslint-scope": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz",
+ "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz",
+ "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==",
+ "dev": true
+ },
+ "eslint-visitor-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+ "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+ "dev": true
+ },
+ "espree": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz",
+ "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==",
+ "dev": true,
+ "requires": {
+ "acorn": "^5.6.0",
+ "acorn-jsx": "^4.1.1"
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.0.0"
+ }
+ },
+ "esrecurse": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.1.0"
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "eth-lib": {
+ "version": "0.1.27",
+ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz",
+ "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==",
+ "requires": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "keccakjs": "^0.2.1",
+ "nano-json-stream-parser": "^0.1.2",
+ "servify": "^0.1.12",
+ "ws": "^3.0.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "ethjs-unit": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
+ "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "number-to-bn": "1.7.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ }
+ }
+ },
+ "eventemitter3": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz",
+ "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA="
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "requires": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "express": {
+ "version": "4.16.3",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
+ "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
+ "requires": {
+ "accepts": "~1.3.5",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.18.2",
+ "content-disposition": "0.5.2",
+ "content-type": "~1.0.4",
+ "cookie": "0.3.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.1.1",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.3",
+ "qs": "6.5.1",
+ "range-parser": "~1.2.0",
+ "safe-buffer": "5.1.1",
+ "send": "0.16.2",
+ "serve-static": "1.13.2",
+ "setprototypeof": "1.1.0",
+ "statuses": "~1.4.0",
+ "type-is": "~1.6.16",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
+ },
+ "external-editor": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
+ "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+ "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
+ },
+ "fast-diff": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
+ "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "fd-slicer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+ "requires": {
+ "pend": "~1.2.0"
+ }
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^1.2.1",
+ "object-assign": "^4.0.1"
+ }
+ },
+ "file-type": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+ "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY="
+ },
+ "finalhandler": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
+ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
+ "statuses": "~1.4.0",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
+ }
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "dev": true,
+ "requires": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "flat-cache": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+ "dev": true,
+ "requires": {
+ "circular-json": "^0.3.1",
+ "del": "^2.0.2",
+ "graceful-fs": "^4.1.2",
+ "write": "^0.2.1"
+ }
+ },
+ "for-each": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz",
+ "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=",
+ "requires": {
+ "is-function": "~1.0.0"
+ }
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "fs-extra": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz",
+ "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0"
+ }
+ },
+ "fs-promise": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz",
+ "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=",
+ "requires": {
+ "any-promise": "^1.3.0",
+ "fs-extra": "^2.0.0",
+ "mz": "^2.6.0",
+ "thenify-all": "^1.6.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "fstream": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+ "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "inherits": "~2.0.0",
+ "mkdirp": ">=0.5 0",
+ "rimraf": "2"
+ }
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+ "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "global": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
+ "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
+ "requires": {
+ "min-document": "^2.19.0",
+ "process": "~0.5.1"
+ }
+ },
+ "globals": {
+ "version": "11.7.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz",
+ "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==",
+ "dev": true
+ },
+ "globby": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+ "dev": true,
+ "requires": {
+ "array-union": "^1.0.1",
+ "arrify": "^1.0.0",
+ "glob": "^7.0.3",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "got": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+ "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+ "requires": {
+ "decompress-response": "^3.2.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^3.0.0",
+ "is-plain-obj": "^1.1.0",
+ "is-retry-allowed": "^1.0.0",
+ "is-stream": "^1.0.0",
+ "isurl": "^1.0.0-alpha5",
+ "lowercase-keys": "^1.0.0",
+ "p-cancelable": "^0.3.0",
+ "p-timeout": "^1.1.1",
+ "safe-buffer": "^5.0.1",
+ "timed-out": "^4.0.0",
+ "url-parse-lax": "^1.0.0",
+ "url-to-options": "^1.0.1"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ },
+ "graceful-readlink": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+ "requires": {
+ "ajv": "^5.1.0",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "has-symbol-support-x": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
+ "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw=="
+ },
+ "has-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+ "dev": true
+ },
+ "has-to-string-tag-x": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+ "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+ "requires": {
+ "has-symbol-support-x": "^1.4.1"
+ }
+ },
+ "hash-base": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "hash.js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
+ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "hawk": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+ "requires": {
+ "boom": "4.x.x",
+ "cryptiles": "3.x.x",
+ "hoek": "4.x.x",
+ "sntp": "2.x.x"
+ }
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "requires": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "hoek": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
+ "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA=="
+ },
+ "hosted-git-info": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+ "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ }
+ },
+ "http-https": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
+ "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs="
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+ },
+ "ieee754": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz",
+ "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg=="
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "inquirer": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz",
+ "integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^3.0.0",
+ "chalk": "^2.0.0",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^3.0.0",
+ "figures": "^2.0.0",
+ "lodash": "^4.17.10",
+ "mute-stream": "0.0.7",
+ "run-async": "^2.2.0",
+ "rxjs": "^6.1.0",
+ "string-width": "^2.1.0",
+ "strip-ansi": "^4.0.0",
+ "through": "^2.3.6"
+ }
+ },
+ "ipaddr.js": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz",
+ "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs="
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-builtin-module": {
+ "version": "1.0.0",
+ "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+ "dev": true,
+ "requires": {
+ "builtin-modules": "^1.0.0"
+ }
+ },
+ "is-callable": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
+ "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
+ "dev": true
+ },
+ "is-date-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "is-function": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
+ "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU="
+ },
+ "is-hex-prefixed": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz",
+ "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ="
+ },
+ "is-natural-number": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
+ "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg="
+ },
+ "is-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+ "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA="
+ },
+ "is-path-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+ "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+ "dev": true
+ },
+ "is-path-in-cwd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
+ "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
+ "dev": true,
+ "requires": {
+ "is-path-inside": "^1.0.0"
+ }
+ },
+ "is-path-inside": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+ "dev": true,
+ "requires": {
+ "path-is-inside": "^1.0.1"
+ }
+ },
+ "is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
+ },
+ "is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.1"
+ }
+ },
+ "is-resolvable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+ "dev": true
+ },
+ "is-retry-allowed": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
+ "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ="
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+ },
+ "is-symbol": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
+ "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.0"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "isurl": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+ "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+ "requires": {
+ "has-to-string-tag-x": "^1.2.0",
+ "is-object": "^1.0.1"
+ }
+ },
+ "jest-docblock": {
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz",
+ "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==",
+ "dev": true
+ },
+ "js-sha3": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz",
+ "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM="
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
+ "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "optional": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+ },
+ "json-schema-traverse": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "keccakjs": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz",
+ "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=",
+ "requires": {
+ "browserify-sha3": "^0.0.1",
+ "sha3": "^1.1.0"
+ }
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "load-json-file": {
+ "version": "2.0.0",
+ "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "dependencies": {
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ }
+ }
+ },
+ "lodash": {
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+ "dev": true
+ },
+ "lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
+ },
+ "make-dir": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz",
+ "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==",
+ "requires": {
+ "pify": "^3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
+ }
+ }
+ },
+ "md5.js": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
+ "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "requires": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ }
+ },
+ "mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
+ },
+ "mime-db": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
+ },
+ "mime-types": {
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+ "requires": {
+ "mime-db": "~1.33.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true
+ },
+ "mimic-response": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
+ "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4="
+ },
+ "min-document": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+ "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+ "requires": {
+ "dom-walk": "^0.1.0"
+ }
+ },
+ "minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "mkdirp-promise": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
+ "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
+ "requires": {
+ "mkdirp": "*"
+ }
+ },
+ "mock-fs": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.4.2.tgz",
+ "integrity": "sha512-dF+yxZSojSiI8AXGoxj5qdFWpucndc54Ug+TwlpHFaV7j22MGG+OML2+FVa6xAZtjb/OFFQhOC37Jegx2GbEwA=="
+ },
+ "mout": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz",
+ "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "mute-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+ "dev": true
+ },
+ "mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "requires": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "nan": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
+ "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA=="
+ },
+ "nano-json-stream-parser": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
+ "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18="
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "node-fetch": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
+ "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U="
+ },
+ "normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "is-builtin-module": "^1.0.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "number-to-bn": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
+ "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "strip-hex-prefix": "1.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ }
+ }
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "object-keys": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
+ "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
+ "dev": true
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ }
+ },
+ "object.entries": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.0.4.tgz",
+ "integrity": "sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8=",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.6.1",
+ "function-bind": "^1.1.0",
+ "has": "^1.0.1"
+ }
+ },
+ "oboe": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz",
+ "integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=",
+ "requires": {
+ "http-https": "^1.0.0"
+ }
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.4",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "wordwrap": "~1.0.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "p-cancelable": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+ "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw=="
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-timeout": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+ "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+ "requires": {
+ "p-finally": "^1.0.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true
+ },
+ "parse-asn1": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
+ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
+ "requires": {
+ "asn1.js": "^4.0.0",
+ "browserify-aes": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3"
+ }
+ },
+ "parse-headers": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz",
+ "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=",
+ "requires": {
+ "for-each": "^0.3.2",
+ "trim": "0.0.1"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "dev": true,
+ "requires": {
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "requires": {
+ "pify": "^2.0.0"
+ }
+ },
+ "pbkdf2": {
+ "version": "3.0.14",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
+ "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
+ "requires": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "pkg-dir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz",
+ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
+ "dev": true,
+ "requires": {
+ "find-up": "^1.0.0"
+ }
+ },
+ "pluralize": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+ "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
+ },
+ "prettier": {
+ "version": "1.14.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.14.3.tgz",
+ "integrity": "sha512-qZDVnCrnpsRJJq5nSsiHCE3BYMED2OtsI+cmzIzF1QIfqm5ALf8tEJcO27zV1gKNKRPdhjO0dNWnrzssDQ1tFg==",
+ "dev": true
+ },
+ "process": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+ "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
+ },
+ "progress": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+ "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
+ "dev": true
+ },
+ "proxy-addr": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
+ "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.6.0"
+ }
+ },
+ "public-encrypt": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
+ "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==",
+ "requires": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1"
+ }
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ },
+ "qs": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
+ },
+ "query-string": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+ "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+ "requires": {
+ "decode-uri-component": "^0.2.0",
+ "object-assign": "^4.1.0",
+ "strict-uri-encode": "^1.0.0"
+ }
+ },
+ "randombytes": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "requires": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "randomhex": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz",
+ "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU="
+ },
+ "range-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
+ },
+ "raw-body": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+ "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+ "requires": {
+ "bytes": "3.0.0",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
+ },
+ "http-errors": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "requires": {
+ "depd": "1.1.1",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.0.3",
+ "statuses": ">= 1.3.1 < 2"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
+ }
+ }
+ },
+ "read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^2.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^2.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^2.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "regexpp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz",
+ "integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==",
+ "dev": true
+ },
+ "request": {
+ "version": "2.85.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz",
+ "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==",
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.6.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.5",
+ "extend": "~3.0.1",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.1",
+ "har-validator": "~5.0.3",
+ "hawk": "~6.0.2",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.17",
+ "oauth-sign": "~0.8.2",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.1",
+ "safe-buffer": "^5.1.1",
+ "stringstream": "~0.0.5",
+ "tough-cookie": "~2.3.3",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.1.0"
+ }
+ },
+ "require-uncached": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+ "dev": true,
+ "requires": {
+ "caller-path": "^0.1.0",
+ "resolve-from": "^1.0.0"
+ }
+ },
+ "resolve": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
+ "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.5"
+ }
+ },
+ "resolve-from": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+ "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "requires": {
+ "glob": "^7.0.5"
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
+ "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
+ "requires": {
+ "hash-base": "^2.0.0",
+ "inherits": "^2.0.1"
+ },
+ "dependencies": {
+ "hash-base": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
+ "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
+ "requires": {
+ "inherits": "^2.0.1"
+ }
+ }
+ }
+ },
+ "run-async": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+ "dev": true,
+ "requires": {
+ "is-promise": "^2.1.0"
+ }
+ },
+ "rxjs": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.2.tgz",
+ "integrity": "sha512-hV7criqbR0pe7EeL3O66UYVg92IR0XsA97+9y+BWTePK9SKmEI5Qd3Zj6uPnGkNzXsBywBQWTvujPl+1Kn9Zjw==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "scrypt": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz",
+ "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=",
+ "requires": {
+ "nan": "^2.0.8"
+ }
+ },
+ "scrypt.js": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz",
+ "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=",
+ "requires": {
+ "scrypt": "^6.0.2",
+ "scryptsy": "^1.2.1"
+ }
+ },
+ "scryptsy": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz",
+ "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=",
+ "requires": {
+ "pbkdf2": "^3.0.3"
+ }
+ },
+ "seek-bzip": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz",
+ "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=",
+ "requires": {
+ "commander": "~2.8.1"
+ }
+ },
+ "semver": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz",
+ "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==",
+ "dev": true
+ },
+ "send": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
+ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.6.2",
+ "mime": "1.4.1",
+ "ms": "2.0.0",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.0",
+ "statuses": "~1.4.0"
+ },
+ "dependencies": {
+ "statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
+ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.2",
+ "send": "0.16.2"
+ }
+ },
+ "servify": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
+ "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
+ "requires": {
+ "body-parser": "^1.16.0",
+ "cors": "^2.8.1",
+ "express": "^4.14.0",
+ "request": "^2.79.0",
+ "xhr": "^2.3.3"
+ }
+ },
+ "setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+ },
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
+ },
+ "sha.js": {
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "sha3": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.0.tgz",
+ "integrity": "sha1-aYnxtwpJhwWHajc+LGKs6WqpOZo=",
+ "requires": {
+ "nan": "^2.0.5"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "simple-concat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
+ "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
+ },
+ "simple-get": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz",
+ "integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==",
+ "requires": {
+ "decompress-response": "^3.3.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "slice-ansi": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
+ "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0"
+ }
+ },
+ "sntp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
+ "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
+ "requires": {
+ "hoek": "4.x.x"
+ }
+ },
+ "spdx-correct": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
+ "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
+ "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz",
+ "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
+ "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+ },
+ "strict-uri-encode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "strip-dirs": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
+ "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==",
+ "requires": {
+ "is-natural-number": "^4.0.1"
+ }
+ },
+ "strip-hex-prefix": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
+ "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+ "requires": {
+ "is-hex-prefixed": "1.0.0"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "swarm-js": {
+ "version": "0.1.37",
+ "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz",
+ "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==",
+ "requires": {
+ "bluebird": "^3.5.0",
+ "buffer": "^5.0.5",
+ "decompress": "^4.0.0",
+ "eth-lib": "^0.1.26",
+ "fs-extra": "^2.1.2",
+ "fs-promise": "^2.0.0",
+ "got": "^7.1.0",
+ "mime-types": "^2.1.16",
+ "mkdirp-promise": "^5.0.1",
+ "mock-fs": "^4.1.0",
+ "setimmediate": "^1.0.5",
+ "tar.gz": "^1.0.5",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "table": {
+ "version": "4.0.3",
+ "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz",
+ "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.0.1",
+ "ajv-keywords": "^3.0.0",
+ "chalk": "^2.1.0",
+ "lodash": "^4.17.4",
+ "slice-ansi": "1.0.0",
+ "string-width": "^2.1.1"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz",
+ "integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ }
+ }
+ },
+ "tar": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+ "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+ "requires": {
+ "block-stream": "*",
+ "fstream": "^1.0.2",
+ "inherits": "2"
+ }
+ },
+ "tar-stream": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz",
+ "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==",
+ "requires": {
+ "bl": "^1.0.0",
+ "end-of-stream": "^1.0.0",
+ "readable-stream": "^2.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "tar.gz": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz",
+ "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==",
+ "requires": {
+ "bluebird": "^2.9.34",
+ "commander": "^2.8.1",
+ "fstream": "^1.0.8",
+ "mout": "^0.11.0",
+ "tar": "^2.1.1"
+ },
+ "dependencies": {
+ "bluebird": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
+ "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE="
+ }
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "thenify": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz",
+ "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=",
+ "requires": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
+ "requires": {
+ "thenify": ">= 3.1.0 < 4"
+ }
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
+ },
+ "timed-out": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
+ "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
+ "requires": {
+ "punycode": "^1.4.1"
+ }
+ },
+ "trim": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
+ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0="
+ },
+ "tslib": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
+ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "optional": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-is": {
+ "version": "1.6.16",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.18"
+ }
+ },
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "requires": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "ultron": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
+ },
+ "unbzip2-stream": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz",
+ "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==",
+ "requires": {
+ "buffer": "^3.0.1",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "base64-js": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
+ "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg="
+ },
+ "buffer": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz",
+ "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=",
+ "requires": {
+ "base64-js": "0.0.8",
+ "ieee754": "^1.1.4",
+ "isarray": "^1.0.0"
+ }
+ }
+ }
+ },
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ }
+ }
+ },
+ "url-parse-lax": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+ "requires": {
+ "prepend-http": "^1.0.1"
+ }
+ },
+ "url-set-query": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
+ "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk="
+ },
+ "url-to-options": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+ "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k="
+ },
+ "utf8": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz",
+ "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g="
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
+ "uuid": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
+ "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA=="
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "web3": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.34.tgz",
+ "integrity": "sha1-NH5WG3hAmMtVYzFfSQR5odkfKrE=",
+ "requires": {
+ "web3-bzz": "1.0.0-beta.34",
+ "web3-core": "1.0.0-beta.34",
+ "web3-eth": "1.0.0-beta.34",
+ "web3-eth-personal": "1.0.0-beta.34",
+ "web3-net": "1.0.0-beta.34",
+ "web3-shh": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-bzz": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.0.0-beta.34.tgz",
+ "integrity": "sha1-Bo03d3q2Xlxg+OyLmlDP5FJ3kpw=",
+ "requires": {
+ "got": "7.1.0",
+ "swarm-js": "0.1.37",
+ "underscore": "1.8.3"
+ }
+ },
+ "web3-core": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.34.tgz",
+ "integrity": "sha1-EhvoVV6fsA0sXQXd0zgdDJ5GmH4=",
+ "requires": {
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-core-requestmanager": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-core-helpers": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.34.tgz",
+ "integrity": "sha1-sWjaANPhnhVrwVriAyA91N/uLQM=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-eth-iban": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-core-method": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.34.tgz",
+ "integrity": "sha1-7BY8iixJD6AqfsFVWfpzB/x8xt0=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-promievent": "1.0.0-beta.34",
+ "web3-core-subscriptions": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-core-promievent": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.34.tgz",
+ "integrity": "sha1-pPT6Z4S7KT6CxglgrltWqUzQPtw=",
+ "requires": {
+ "any-promise": "1.3.0",
+ "eventemitter3": "1.1.1"
+ }
+ },
+ "web3-core-requestmanager": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.34.tgz",
+ "integrity": "sha1-Afj2zyrmtvC3DDi64e90G1urIVw=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-providers-http": "1.0.0-beta.34",
+ "web3-providers-ipc": "1.0.0-beta.34",
+ "web3-providers-ws": "1.0.0-beta.34"
+ }
+ },
+ "web3-core-subscriptions": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.34.tgz",
+ "integrity": "sha1-n+0UQDPyIcPPIQYDAv/a9e8t4t4=",
+ "requires": {
+ "eventemitter3": "1.1.1",
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34"
+ }
+ },
+ "web3-eth": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.0.0-beta.34.tgz",
+ "integrity": "sha1-dAhgAIUMb+b1Ne9Jg31tS7YRMmg=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-core-subscriptions": "1.0.0-beta.34",
+ "web3-eth-abi": "1.0.0-beta.34",
+ "web3-eth-accounts": "1.0.0-beta.34",
+ "web3-eth-contract": "1.0.0-beta.34",
+ "web3-eth-iban": "1.0.0-beta.34",
+ "web3-eth-personal": "1.0.0-beta.34",
+ "web3-net": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-eth-abi": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.34.tgz",
+ "integrity": "sha1-A0Uz46ovfln/MXk+rqaFwO1a9no=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ }
+ }
+ },
+ "web3-eth-accounts": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.34.tgz",
+ "integrity": "sha1-4JFC7uzHl6w0WbdemyOUbTaV8zM=",
+ "requires": {
+ "any-promise": "1.3.0",
+ "crypto-browserify": "3.12.0",
+ "eth-lib": "0.2.7",
+ "scrypt.js": "0.2.0",
+ "underscore": "1.8.3",
+ "uuid": "2.0.1",
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "eth-lib": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+ "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+ "requires": {
+ "bn.js": "^4.11.6",
+ "elliptic": "^6.4.0",
+ "xhr-request-promise": "^0.1.2"
+ }
+ },
+ "uuid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+ "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w="
+ }
+ }
+ },
+ "web3-eth-contract": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.34.tgz",
+ "integrity": "sha1-nbs4+udkOoCEJ6IBgEcOx0FckeY=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-core-promievent": "1.0.0-beta.34",
+ "web3-core-subscriptions": "1.0.0-beta.34",
+ "web3-eth-abi": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-eth-iban": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.34.tgz",
+ "integrity": "sha1-mvRYYFhnzPdOqXmq8yazi6alugw=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "web3-utils": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ }
+ }
+ },
+ "web3-eth-personal": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.34.tgz",
+ "integrity": "sha1-mvuhZzQuveVCC81YlcP2w0OI8gU=",
+ "requires": {
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-net": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-net": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.34.tgz",
+ "integrity": "sha1-QnzqL0MYgUScjjjVIykPFz+f9j0=",
+ "requires": {
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-providers-http": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.0.0-beta.34.tgz",
+ "integrity": "sha1-5WG1K7tDdmKCAH1AKFv+NVDCfno=",
+ "requires": {
+ "web3-core-helpers": "1.0.0-beta.34",
+ "xhr2": "0.1.4"
+ }
+ },
+ "web3-providers-ipc": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.34.tgz",
+ "integrity": "sha1-obd/GjBtc2SanAOQUuQMtxMo0Ao=",
+ "requires": {
+ "oboe": "2.1.3",
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34"
+ }
+ },
+ "web3-providers-ws": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.34.tgz",
+ "integrity": "sha1-fecPG4Py3jZHZ3IVa+z+9uNRbrM=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "websocket": "git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c"
+ }
+ },
+ "web3-shh": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.0.0-beta.34.tgz",
+ "integrity": "sha1-l1Bh1x6uxCzO5Xb3vY9w8DhEr+A=",
+ "requires": {
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-core-subscriptions": "1.0.0-beta.34",
+ "web3-net": "1.0.0-beta.34"
+ }
+ },
+ "web3-utils": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.34.tgz",
+ "integrity": "sha1-lBH8OarvOcpOBhafdiKX2f8CCXA=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "eth-lib": "0.1.27",
+ "ethjs-unit": "0.1.6",
+ "number-to-bn": "1.7.0",
+ "randomhex": "0.1.5",
+ "underscore": "1.8.3",
+ "utf8": "2.1.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ }
+ }
+ },
+ "websocket": {
+ "version": "git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c",
+ "from": "websocket@git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c",
+ "requires": {
+ "debug": "^2.2.0",
+ "nan": "^2.3.3",
+ "typedarray-to-buffer": "^3.1.2",
+ "yaeti": "^0.0.6"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "write": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "ws": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+ "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+ "requires": {
+ "async-limiter": "~1.0.0",
+ "safe-buffer": "~5.1.0",
+ "ultron": "~1.1.0"
+ }
+ },
+ "xhr": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.1.tgz",
+ "integrity": "sha512-pAIU5vBr9Hiy5cpFIbPnwf0C18ZF86DBsZKrlsf87N5De/JbA6RJ83UP/cv+aljl4S40iRVMqP4pr4sF9Dnj0A==",
+ "requires": {
+ "global": "~4.3.0",
+ "is-function": "^1.0.1",
+ "parse-headers": "^2.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "xhr-request": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
+ "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
+ "requires": {
+ "buffer-to-arraybuffer": "^0.0.5",
+ "object-assign": "^4.1.1",
+ "query-string": "^5.0.1",
+ "simple-get": "^2.7.0",
+ "timed-out": "^4.0.1",
+ "url-set-query": "^1.0.0",
+ "xhr": "^2.0.4"
+ }
+ },
+ "xhr-request-promise": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz",
+ "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=",
+ "requires": {
+ "xhr-request": "^1.0.1"
+ }
+ },
+ "xhr2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz",
+ "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8="
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
+ },
+ "yaeti": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
+ "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc="
+ },
+ "yauzl": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz",
+ "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=",
+ "requires": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.0.1"
+ }
+ }
+ }
+}
diff --git a/bridge-monitor/package.json b/bridge-monitor/package.json
new file mode 100644
index 00000000..f822d5b3
--- /dev/null
+++ b/bridge-monitor/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "bridge-monitoring",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "start": "node index.js",
+ "lint": "eslint .",
+ "lint:fix": "eslint . --fix"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "bignumber.js": "^6.0.0",
+ "dotenv": "^5.0.1",
+ "express": "^4.16.3",
+ "node-fetch": "^2.1.2",
+ "web3": "1.0.0-beta.34"
+ },
+ "engines": {
+ "node": ">=8.9"
+ },
+ "devDependencies": {
+ "eslint": "^5.6.0",
+ "eslint-config-airbnb": "^17.1.0",
+ "eslint-config-prettier": "^3.1.0",
+ "eslint-plugin-import": "^2.14.0",
+ "eslint-plugin-node": "^7.0.1",
+ "eslint-plugin-prettier": "^2.6.2",
+ "prettier": "^1.14.3"
+ }
+}
diff --git a/bridge-monitor/responses/.gitkeep b/bridge-monitor/responses/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/bridge-monitor/stuckTransfers.js b/bridge-monitor/stuckTransfers.js
new file mode 100644
index 00000000..15033fe9
--- /dev/null
+++ b/bridge-monitor/stuckTransfers.js
@@ -0,0 +1,109 @@
+require('dotenv').config()
+const Web3 = require('web3')
+const logger = require('./logger')('stuckTransfers.js')
+
+const { FOREIGN_RPC_URL, FOREIGN_BRIDGE_ADDRESS, ERC20_ADDRESS } = process.env
+const FOREIGN_DEPLOYMENT_BLOCK = Number(process.env.FOREIGN_DEPLOYMENT_BLOCK) || 0
+
+const foreignProvider = new Web3.providers.HttpProvider(FOREIGN_RPC_URL)
+const web3Foreign = new Web3(foreignProvider)
+
+const ABITransferWithoutData = [
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: true,
+ name: 'from',
+ type: 'address'
+ },
+ {
+ indexed: true,
+ name: 'to',
+ type: 'address'
+ },
+ {
+ indexed: false,
+ name: 'value',
+ type: 'uint256'
+ }
+ ],
+ name: 'Transfer',
+ type: 'event'
+ }
+]
+
+const ABIWithData = [
+ {
+ anonymous: false,
+ inputs: [
+ {
+ indexed: true,
+ name: 'from',
+ type: 'address'
+ },
+ {
+ indexed: true,
+ name: 'to',
+ type: 'address'
+ },
+ {
+ indexed: false,
+ name: 'value',
+ type: 'uint256'
+ },
+ {
+ indexed: false,
+ name: 'data',
+ type: 'bytes'
+ }
+ ],
+ name: 'Transfer',
+ type: 'event'
+ }
+]
+
+function compareTransfers(transfersNormal) {
+ return withData => {
+ return (
+ transfersNormal.filter(normal => {
+ return normal.transactionHash === withData.transactionHash
+ }).length === 0
+ )
+ }
+}
+
+async function main() {
+ try {
+ // TODO: ERC20_ADDRESS is no longer an env constant. It has to be extracted from the ForeignBridge Contract.
+ const tokenContract = new web3Foreign.eth.Contract(ABITransferWithoutData, ERC20_ADDRESS)
+ const tokenContractWithData = new web3Foreign.eth.Contract(ABIWithData, ERC20_ADDRESS)
+ logger.debug('calling tokenContract.getPastEvents Transfer')
+ const transfersNormal = await tokenContract.getPastEvents('Transfer', {
+ filter: {
+ to: FOREIGN_BRIDGE_ADDRESS
+ },
+ fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
+ toBlock: 'latest'
+ })
+ logger.debug('calling tokenContractWithData.getPastEvents Transfer')
+ const transfersWithData = await tokenContractWithData.getPastEvents('Transfer', {
+ filter: {
+ to: FOREIGN_BRIDGE_ADDRESS
+ },
+ fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
+ toBlock: 'latest'
+ })
+ const stuckTransfers = transfersNormal.filter(compareTransfers(transfersWithData))
+ logger.debug('Done')
+ return {
+ stuckTransfers,
+ total: stuckTransfers.length,
+ lastChecked: Math.floor(Date.now() / 1000)
+ }
+ } catch (e) {
+ logger.error(e)
+ throw e
+ }
+}
+module.exports = main
diff --git a/bridge-monitor/test-srv.js b/bridge-monitor/test-srv.js
new file mode 100644
index 00000000..5d543792
--- /dev/null
+++ b/bridge-monitor/test-srv.js
@@ -0,0 +1,13 @@
+const express = require('express')
+
+const app = express()
+
+app.all('/', (req, res) => {
+ setTimeout(() => {
+ res.status(504)
+ res.end()
+ }, 2000)
+})
+
+const PORT = process.env.PORT || 4000
+app.listen(PORT, () => console.log('Listening on port ' + PORT))
diff --git a/bridge-monitor/utils/bridgeMode.js b/bridge-monitor/utils/bridgeMode.js
new file mode 100644
index 00000000..02536d23
--- /dev/null
+++ b/bridge-monitor/utils/bridgeMode.js
@@ -0,0 +1,56 @@
+const HOME_NATIVE_TO_ERC_ABI = require('../abis/HomeBridgeNativeToErc.abi')
+const FOREIGN_NATIVE_TO_ERC_ABI = require('../abis/ForeignBridgeNativeToErc.abi')
+const HOME_ERC_TO_ERC_ABI = require('../abis/HomeBridgeErcToErc.abi')
+const FOREIGN_ERC_TO_ERC_ABI = require('../abis/ForeignBridgeErc677ToErc677.abi')
+const HOME_ERC_TO_NATIVE_ABI = require('../abis/HomeBridgeErcToNative.abi')
+const FOREIGN_ERC_TO_NATIVE_ABI = require('../abis/ForeignBridgeErcToNative.abi')
+
+const BRIDGE_MODES = {
+ NATIVE_TO_ERC: 'NATIVE_TO_ERC',
+ ERC_TO_ERC: 'ERC_TO_ERC',
+ ERC_TO_NATIVE: 'ERC_TO_NATIVE'
+}
+
+const ERC_TYPES = {
+ ERC20: 'ERC20',
+ ERC677: 'ERC677'
+}
+
+function getBridgeABIs(bridgeMode) {
+ let HOME_ABI = null
+ let FOREIGN_ABI = null
+ if (bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC) {
+ HOME_ABI = HOME_NATIVE_TO_ERC_ABI
+ FOREIGN_ABI = FOREIGN_NATIVE_TO_ERC_ABI
+ } else if (bridgeMode === BRIDGE_MODES.ERC_TO_ERC) {
+ HOME_ABI = HOME_ERC_TO_ERC_ABI
+ FOREIGN_ABI = FOREIGN_ERC_TO_ERC_ABI
+ } else if (bridgeMode === BRIDGE_MODES.ERC_TO_NATIVE) {
+ HOME_ABI = HOME_ERC_TO_NATIVE_ABI
+ FOREIGN_ABI = FOREIGN_ERC_TO_NATIVE_ABI
+ } else {
+ throw new Error(`Unrecognized bridge mode: ${bridgeMode}`)
+ }
+
+ return { HOME_ABI, FOREIGN_ABI }
+}
+
+function decodeBridgeMode(bridgeModeHash) {
+ switch (bridgeModeHash) {
+ case '0x92a8d7fe':
+ return BRIDGE_MODES.NATIVE_TO_ERC
+ case '0xba4690f5':
+ return BRIDGE_MODES.ERC_TO_ERC
+ case '0x18762d46':
+ return BRIDGE_MODES.ERC_TO_NATIVE
+ default:
+ throw new Error(`Unrecognized bridge mode hash: '${bridgeModeHash}'`)
+ }
+}
+
+module.exports = {
+ decodeBridgeMode,
+ getBridgeABIs,
+ BRIDGE_MODES,
+ ERC_TYPES
+}
diff --git a/bridge-monitor/utils/contract.js b/bridge-monitor/utils/contract.js
new file mode 100644
index 00000000..c682f179
--- /dev/null
+++ b/bridge-monitor/utils/contract.js
@@ -0,0 +1,50 @@
+const { toBN } = require('web3').utils
+
+const ONE = toBN(1)
+const TWO = toBN(2)
+
+async function getPastEvents({ contract, event, fromBlock, toBlock, options }) {
+ let events
+ try {
+ events = await contract.getPastEvents(event, {
+ ...options,
+ fromBlock,
+ toBlock
+ })
+ } catch (e) {
+ if (e.message.includes('query returned more than 1000 results')) {
+ const middle = fromBlock.add(toBlock).divRound(TWO)
+ const middlePlusOne = middle.add(ONE)
+
+ const firstHalfEvents = await getPastEvents({
+ contract,
+ event,
+ fromBlock,
+ toBlock: middle,
+ options
+ })
+ const secondHalfEvents = await getPastEvents({
+ contract,
+ event,
+ fromBlock: middlePlusOne,
+ toBlock,
+ options
+ })
+ events = [...firstHalfEvents, ...secondHalfEvents]
+ } else {
+ throw new Error(e)
+ }
+ }
+ return events
+}
+
+const getBlockNumberCall = web3 => web3.eth.getBlockNumber()
+
+async function getBlockNumber(web3Home, web3Foreign) {
+ return (await Promise.all([web3Home, web3Foreign].map(getBlockNumberCall))).map(toBN)
+}
+
+module.exports = {
+ getPastEvents,
+ getBlockNumber
+}
diff --git a/bridge-monitor/utils/ercUtils.js b/bridge-monitor/utils/ercUtils.js
new file mode 100644
index 00000000..f6a2d695
--- /dev/null
+++ b/bridge-monitor/utils/ercUtils.js
@@ -0,0 +1,18 @@
+const { ERC_TYPES } = require('./bridgeMode')
+
+const getTokenType = async (contract, bridgeAddress) => {
+ try {
+ const bridgeContract = await contract.methods.bridgeContract().call()
+ if (bridgeContract === bridgeAddress) {
+ return ERC_TYPES.ERC677
+ } else {
+ return ERC_TYPES.ERC20
+ }
+ } catch (e) {
+ return ERC_TYPES.ERC20
+ }
+}
+
+module.exports = {
+ getTokenType
+}
diff --git a/bridge-monitor/utils/events.js b/bridge-monitor/utils/events.js
new file mode 100644
index 00000000..238ea8ac
--- /dev/null
+++ b/bridge-monitor/utils/events.js
@@ -0,0 +1,98 @@
+require('dotenv').config()
+const Web3 = require('web3')
+const { toBN } = require('web3').utils
+const logger = require('../logger')('eventsUtils')
+const { BRIDGE_MODES, decodeBridgeMode, getBridgeABIs, ERC_TYPES } = require('./bridgeMode')
+const { getTokenType } = require('./ercUtils')
+
+const { HOME_RPC_URL, FOREIGN_RPC_URL, HOME_BRIDGE_ADDRESS, FOREIGN_BRIDGE_ADDRESS } = process.env
+const HOME_DEPLOYMENT_BLOCK = toBN(Number(process.env.HOME_DEPLOYMENT_BLOCK) || 0)
+const FOREIGN_DEPLOYMENT_BLOCK = toBN(Number(process.env.FOREIGN_DEPLOYMENT_BLOCK) || 0)
+
+const homeProvider = new Web3.providers.HttpProvider(HOME_RPC_URL)
+const web3Home = new Web3(homeProvider)
+
+const foreignProvider = new Web3.providers.HttpProvider(FOREIGN_RPC_URL)
+const web3Foreign = new Web3(foreignProvider)
+
+const HOME_ERC_TO_ERC_ABI = require('../abis/HomeBridgeErcToErc.abi')
+const ERC20_ABI = require('../abis/ERC20.abi')
+const { getPastEvents, getBlockNumber } = require('./contract')
+
+async function main() {
+ try {
+ const homeErcBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, HOME_BRIDGE_ADDRESS)
+ const bridgeModeHash = await homeErcBridge.methods.getBridgeMode().call()
+ const bridgeMode = decodeBridgeMode(bridgeModeHash)
+ const { HOME_ABI, FOREIGN_ABI } = getBridgeABIs(bridgeMode)
+ const homeBridge = new web3Home.eth.Contract(HOME_ABI, HOME_BRIDGE_ADDRESS)
+ const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ABI, FOREIGN_BRIDGE_ADDRESS)
+ const tokenType = await getTokenType(foreignBridge, FOREIGN_BRIDGE_ADDRESS)
+ const isExternalErc20 = tokenType === ERC_TYPES.ERC20
+ const erc20MethodName = bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC ? 'erc677token' : 'erc20token'
+ const erc20Address = await foreignBridge.methods[erc20MethodName]().call()
+ const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
+
+ logger.debug('getting last block numbers')
+ const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
+
+ logger.debug("calling homeBridge.getPastEvents('UserRequestForSignature')")
+ const homeDeposits = await getPastEvents({
+ contract: homeBridge,
+ event: 'UserRequestForSignature',
+ fromBlock: HOME_DEPLOYMENT_BLOCK,
+ toBlock: homeBlockNumber,
+ options: {}
+ })
+
+ logger.debug("calling foreignBridge.getPastEvents('RelayedMessage')")
+ const foreignDeposits = await getPastEvents({
+ contract: foreignBridge,
+ event: 'RelayedMessage',
+ fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
+ toBlock: foreignBlockNumber,
+ options: {}
+ })
+
+ logger.debug("calling homeBridge.getPastEvents('AffirmationCompleted')")
+ const homeWithdrawals = await getPastEvents({
+ contract: homeBridge,
+ event: 'AffirmationCompleted',
+ fromBlock: HOME_DEPLOYMENT_BLOCK,
+ toBlock: homeBlockNumber,
+ options: {}
+ })
+
+ logger.debug("calling foreignBridge.getPastEvents('UserRequestForAffirmation')")
+ const foreignWithdrawals = isExternalErc20
+ ? await getPastEvents({
+ contract: erc20Contract,
+ event: 'Transfer',
+ fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
+ toBlock: foreignBlockNumber,
+ options: {
+ filter: { to: FOREIGN_BRIDGE_ADDRESS }
+ }
+ })
+ : await getPastEvents({
+ contract: foreignBridge,
+ event: 'UserRequestForAffirmation',
+ fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
+ toBlock: foreignBlockNumber,
+ options: {}
+ })
+ logger.debug('Done')
+ return {
+ homeDeposits,
+ foreignDeposits,
+ homeWithdrawals,
+ foreignWithdrawals,
+ isExternalErc20
+ }
+ } catch (e) {
+ logger.error(e)
+ throw e
+ }
+}
+
+module.exports = main
diff --git a/bridge-monitor/utils/validatorUtils.js b/bridge-monitor/utils/validatorUtils.js
new file mode 100644
index 00000000..facb36e1
--- /dev/null
+++ b/bridge-monitor/utils/validatorUtils.js
@@ -0,0 +1,79 @@
+/* eslint no-param-reassign: ["error", { "props": false }] */
+
+const bridgeValidatorsAbi = require('../abis/BridgeValidators.abi')
+const logger = require('../logger')('validatorsUtils')
+const { getPastEvents } = require('./contract')
+
+const parseValidatorEvent = event => {
+ if (
+ event.event === undefined &&
+ event.raw &&
+ event.raw.topics &&
+ (event.raw.topics[0] === '0xe366c1c0452ed8eec96861e9e54141ebff23c9ec89fe27b996b45f5ec3884987' ||
+ event.raw.topics[0] === '0x8064a302796c89446a96d63470b5b036212da26bd2debe5bec73e0170a9a5e83')
+ ) {
+ const rawAddress = event.raw.topics.length > 1 ? event.raw.topics[1] : event.raw.data
+ const address = '0x' + rawAddress.slice(26)
+ event.event = 'ValidatorAdded'
+ event.returnValues.validator = address
+ } else if (
+ event.event === undefined &&
+ event.raw &&
+ event.raw.topics &&
+ event.raw.topics[0] === '0xe1434e25d6611e0db941968fdc97811c982ac1602e951637d206f5fdda9dd8f1'
+ ) {
+ const rawAddress = event.raw.data === '0x' ? event.raw.topics[1] : event.raw.data
+ const address = '0x' + rawAddress.slice(26)
+ event.event = 'ValidatorRemoved'
+ event.returnValues.validator = address
+ }
+}
+
+const processValidatorsEvents = events => {
+ const validatorList = new Set()
+ events.forEach(event => {
+ parseValidatorEvent(event)
+
+ if (event.event === 'ValidatorAdded') {
+ validatorList.add(event.returnValues.validator)
+ } else if (event.event === 'ValidatorRemoved') {
+ validatorList.delete(event.returnValues.validator)
+ }
+ })
+
+ return Array.from(validatorList)
+}
+
+const validatorList = async contract => {
+ try {
+ return await contract.methods.validatorList().call()
+ } catch (e) {
+ return []
+ }
+}
+
+const getValidatorList = async (address, eth, fromBlock, toBlock) => {
+ logger.debug('getting validatorList')
+ const validatorsContract = new eth.Contract(bridgeValidatorsAbi, address)
+ const validators = await validatorList(validatorsContract)
+
+ if (validators.length) {
+ return validators
+ }
+
+ logger.debug('getting validatorsEvents')
+ const contract = new eth.Contract([], address)
+ const validatorsEvents = await getPastEvents({
+ contract,
+ event: 'allEvents',
+ fromBlock,
+ toBlock,
+ options: {}
+ })
+
+ return processValidatorsEvents(validatorsEvents)
+}
+
+module.exports = {
+ getValidatorList
+}
diff --git a/bridge-monitor/validators.js b/bridge-monitor/validators.js
new file mode 100644
index 00000000..2e6229c0
--- /dev/null
+++ b/bridge-monitor/validators.js
@@ -0,0 +1,156 @@
+require('dotenv').config()
+const Web3 = require('web3')
+const fetch = require('node-fetch')
+const logger = require('./logger')('validators')
+const { getBridgeABIs } = require('./utils/bridgeMode')
+const { getValidatorList } = require('./utils/validatorUtils')
+const { getBlockNumber } = require('./utils/contract')
+
+const {
+ HOME_RPC_URL,
+ FOREIGN_RPC_URL,
+ HOME_BRIDGE_ADDRESS,
+ FOREIGN_BRIDGE_ADDRESS,
+ GAS_PRICE_SPEED_TYPE,
+ GAS_LIMIT,
+ GAS_PRICE_FALLBACK
+} = process.env
+const HOME_DEPLOYMENT_BLOCK = Number(process.env.HOME_DEPLOYMENT_BLOCK) || 0
+const FOREIGN_DEPLOYMENT_BLOCK = Number(process.env.FOREIGN_DEPLOYMENT_BLOCK) || 0
+
+const Web3Utils = Web3.utils
+
+const homeProvider = new Web3.providers.HttpProvider(HOME_RPC_URL)
+const web3Home = new Web3(homeProvider)
+
+const foreignProvider = new Web3.providers.HttpProvider(FOREIGN_RPC_URL)
+const web3Foreign = new Web3(foreignProvider)
+
+const BRIDGE_VALIDATORS_ABI = require('./abis/BridgeValidators.abi')
+
+const asyncForEach = async (array, callback) => {
+ for (let index = 0; index < array.length; index++) {
+ await callback(array[index], index, array)
+ }
+}
+
+async function getGasPrices(type) {
+ try {
+ const response = await fetch('https://gasprice.poa.network/')
+ const json = await response.json()
+ logger.log('Fetched gasprice: ' + json[type])
+ return json[type]
+ } catch (e) {
+ logger.error('Gas Price API is not available', e)
+ return GAS_PRICE_FALLBACK
+ }
+}
+
+async function main(bridgeMode) {
+ try {
+ const { HOME_ABI, FOREIGN_ABI } = getBridgeABIs(bridgeMode)
+ const homeBridge = new web3Home.eth.Contract(HOME_ABI, HOME_BRIDGE_ADDRESS)
+ const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ABI, FOREIGN_BRIDGE_ADDRESS)
+ const homeValidatorsAddress = await homeBridge.methods.validatorContract().call()
+ const homeBridgeValidators = new web3Home.eth.Contract(
+ BRIDGE_VALIDATORS_ABI,
+ homeValidatorsAddress
+ )
+
+ logger.debug('getting last block numbers')
+ const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
+
+ logger.debug('calling foreignBridge.methods.validatorContract().call()')
+ const foreignValidatorsAddress = await foreignBridge.methods.validatorContract().call()
+ const foreignBridgeValidators = new web3Foreign.eth.Contract(
+ BRIDGE_VALIDATORS_ABI,
+ foreignValidatorsAddress
+ )
+
+ logger.debug('calling foreignBridgeValidators getValidatorList()')
+ const foreignValidators = await getValidatorList(
+ foreignValidatorsAddress,
+ web3Foreign.eth,
+ FOREIGN_DEPLOYMENT_BLOCK,
+ foreignBlockNumber
+ )
+
+ logger.debug('calling homeBridgeValidators getValidatorList()')
+ const homeValidators = await getValidatorList(
+ homeValidatorsAddress,
+ web3Home.eth,
+ HOME_DEPLOYMENT_BLOCK,
+ homeBlockNumber
+ )
+
+ const homeBalances = {}
+ logger.debug('calling asyncForEach homeValidators homeBalances')
+ await asyncForEach(homeValidators, async v => {
+ homeBalances[v] = Web3Utils.fromWei(await web3Home.eth.getBalance(v))
+ })
+ const foreignVBalances = {}
+ const homeVBalances = {}
+ logger.debug('calling getGasPrices')
+ const gasPriceInGwei = await getGasPrices(GAS_PRICE_SPEED_TYPE)
+ const gasPrice = new Web3Utils.BN(Web3Utils.toWei(gasPriceInGwei.toString(10), 'gwei'))
+ const txCost = gasPrice.mul(new Web3Utils.BN(GAS_LIMIT))
+ let validatorsMatch = true
+ logger.debug('calling asyncForEach foreignValidators foreignVBalances')
+ await asyncForEach(foreignValidators, async v => {
+ const balance = await web3Foreign.eth.getBalance(v)
+ const leftTx = new Web3Utils.BN(balance).div(txCost).toString(10)
+ foreignVBalances[v] = {
+ balance: Web3Utils.fromWei(balance),
+ leftTx: Number(leftTx),
+ gasPrice: gasPriceInGwei
+ }
+ if (!homeValidators.includes(v)) {
+ validatorsMatch = false
+ foreignVBalances[v].onlyOnForeign = true
+ }
+ })
+ logger.debug('calling asyncForEach homeValidators homeVBalances')
+ await asyncForEach(homeValidators, async v => {
+ const gasPrice = new Web3Utils.BN(1)
+ const txCost = gasPrice.mul(new Web3Utils.BN(GAS_LIMIT))
+ const balance = await web3Home.eth.getBalance(v)
+ const leftTx = new Web3Utils.BN(balance).div(txCost).toString(10)
+ homeVBalances[v] = {
+ balance: Web3Utils.fromWei(balance),
+ leftTx: Number(leftTx),
+ gasPrice: Number(gasPrice.toString(10))
+ }
+ if (!foreignValidators.includes(v)) {
+ validatorsMatch = false
+ homeVBalances[v].onlyOnHome = true
+ }
+ })
+ logger.debug('calling homeBridgeValidators.methods.requiredSignatures().call()')
+ const reqSigHome = await homeBridgeValidators.methods.requiredSignatures().call()
+ logger.debug('calling foreignBridgeValidators.methods.requiredSignatures().call()')
+ const reqSigForeign = await foreignBridgeValidators.methods.requiredSignatures().call()
+ logger.debug('Done')
+ return {
+ home: {
+ validators: {
+ ...homeVBalances
+ },
+ requiredSignatures: Number(reqSigHome)
+ },
+ foreign: {
+ validators: {
+ ...foreignVBalances
+ },
+ requiredSignatures: Number(reqSigForeign)
+ },
+ requiredSignaturesMatch: reqSigHome === reqSigForeign,
+ validatorsMatch,
+ lastChecked: Math.floor(Date.now() / 1000)
+ }
+ } catch (e) {
+ logger.error(e)
+ throw e
+ }
+}
+
+module.exports = main