commit 8a8458ac8bc048f897b154675a0092e70f0df664 Author: Blair Vanderlugt Date: Sun Jan 24 12:16:22 2021 -0800 init diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..15a15bb --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,7 @@ +include: + - local: 'ci_templates/.cic-base.yml' + +stages: + - build + - test + - release \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5e9d560 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# cic-internal-integration + +## Getting started + +start cluster +``` +docker-compose up +``` + +stop cluster +``` +docker-compose down +``` + +delete data +``` +docker-compose down -v +``` + +rebuild all the images +``` +docker-compose build --no-cache +``` \ No newline at end of file diff --git a/apps/cic-base-os/Dockerfile b/apps/cic-base-os/Dockerfile new file mode 100644 index 0000000..2af84ab --- /dev/null +++ b/apps/cic-base-os/Dockerfile @@ -0,0 +1,34 @@ +# The solc image messes up the alpine environment, so we have to go all over again +FROM python:3.8.6-slim-buster + +LABEL authors="Louis Holbrook 0826EDA1702D1E87C6E2875121D2E7BB88C2A746" +LABEL spdx-license-identifier="GPL-3.0-or-later" +LABEL description="Base layer for buiding development images for the cic component suite" + +RUN apt-get update && \ + apt-get install -y git gcc g++ libpq-dev && \ + apt-get install -y vim gawk jq telnet openssl iputils-ping curl wget gnupg socat bash procps make python2 postgresql-client + + +RUN echo installing nodejs tooling + +COPY ./dev/nvm.sh /root/ + +# Install nvm with node and npm +# https://stackoverflow.com/questions/25899912/how-to-install-nvm-in-docker +ENV NVM_DIR /root/.nvm +ENV NODE_VERSION 15.3.0 +ENV BANCOR_NODE_VERSION 10.16.0 + +RUN wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash \ + && . $NVM_DIR/nvm.sh \ + && nvm install $NODE_VERSION \ + && nvm alias default $NODE_VERSION \ + && nvm use $NODE_VERSION \ +# So many ridiculously stupid issues with node in docker that take oceans of absolutely wasted time to resolve +# owner of these files is "1001" by default - wtf + && chown -R root:root "$NVM_DIR/versions/node/v$NODE_VERSION" + +ENV NODE_PATH $NVM_DIR/versions/node//v$NODE_VERSION/lib/node_modules +ENV PATH $NVM_DIR/versions/node//v$NODE_VERSION/bin:$PATH + diff --git a/apps/cic-base-os/README.md b/apps/cic-base-os/README.md new file mode 100644 index 0000000..6551bf4 --- /dev/null +++ b/apps/cic-base-os/README.md @@ -0,0 +1 @@ +## this is an example base image if we wanted one for all the other apps. Its just OS level things \ No newline at end of file diff --git a/apps/contract-migration/Dockerfile b/apps/contract-migration/Dockerfile new file mode 100644 index 0000000..cb2ba6c --- /dev/null +++ b/apps/contract-migration/Dockerfile @@ -0,0 +1,175 @@ +#FROM ethereum/solc:0.6.12 +FROM ethereum/solc:0.8.0 + +# The solc image messes up the alpine environment, so we have to go all over again +FROM alpine +COPY --from=0 /usr/bin/solc /usr/bin/solc + +RUN apk update && \ + apk add make git + +WORKDIR /usr/src + +ARG cic_config_commit=2fa9fd511f6782a0a527d730edb52a3fe86f571b +ARG cic_config_url=https://gitlab.com/grassrootseconomics/cic-config.git/ +RUN echo Install confini schema files && \ + git clone --depth 1 $cic_config_url cic-config && \ + cd cic-config && \ + git fetch --depth 1 origin $cic_config_commit && \ + git checkout $cic_config_commit && \ + mkdir -vp /usr/local/etc/cic && \ + cp -v *.ini /usr/local/etc/cic/ +ENV CONFINI_DIR /usr/local/etc/cic + + +ARG cic_contracts_commit=698ef3a30fde8d7f2c498f1208fb0ff45d665501 +ARG cic_contracts_url=https://gitlab.com/grassrootseconomics/cic-contracts.git/ +RUN echo Install ABI collection for solidity interfaces used across all components && \ + git clone --depth 1 $cic_contracts_url cic-contracts && \ + cd cic-contracts && \ + git fetch --depth 1 origin $cic_contracts_commit && \ + git checkout $cic_contracts_commit && \ + make install + +#COPY ./Makefile ./cic-contracts/Makefile +#COPY ./*.sol ./cic-contracts/ + +#RUN cd cic-contracts && \ +# make -B && make install -B + +FROM python:3.8.6-slim-buster + +COPY --from=1 /usr/local/share/cic/ /usr/local/share/cic/ + +LABEL authors="Louis Holbrook 0826EDA1702D1E87C6E2875121D2E7BB88C2A746" +LABEL spdx-license-identifier="GPL-3.0-or-later" +LABEL description="Base layer for buiding development images for the cic component suite" + +RUN apt-get update && \ + apt-get install -y git gcc g++ libpq-dev && \ + apt-get install -y vim gawk jq telnet openssl iputils-ping curl wget gnupg socat bash procps make python2 postgresql-client + + +RUN echo installing nodejs tooling + +COPY ./dev/nvm.sh /root/ + +# Install nvm with node and npm +# https://stackoverflow.com/questions/25899912/how-to-install-nvm-in-docker +ENV NVM_DIR /root/.nvm +ENV NODE_VERSION 15.3.0 +ENV BANCOR_NODE_VERSION 10.16.0 + +RUN wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash \ + && . $NVM_DIR/nvm.sh \ + && nvm install $NODE_VERSION \ + && nvm alias default $NODE_VERSION \ + && nvm use $NODE_VERSION \ +# So many ridiculously stupid issues with node in docker that take oceans of absolutely wasted time to resolve +# owner of these files is "1001" by default - wtf + && chown -R root:root "$NVM_DIR/versions/node/v$NODE_VERSION" + +ENV NODE_PATH $NVM_DIR/versions/node//v$NODE_VERSION/lib/node_modules +ENV PATH $NVM_DIR/versions/node//v$NODE_VERSION/bin:$PATH + + +ARG pip_extra_index_url=https://pip.grassrootseconomics.net:8433 + +# This is a temporary solution for building the Bancor contracts using the bancor protocol repository truffle setup +# We should instead flatten the files ourselves and build them with solc in the first image layer in this file +ARG cic_bancor_commit=a04c7ae6882ea515938d852cc861d59a35070094 +ARG cic_bancor_url=https://gitlab.com/grassrootseconomics/cic-bancor.git/ +ARG cic_bancor_contracts_url=https://github.com/bancorprotocol/contracts-solidity +RUN echo Compile and install bancor protocol contracts && \ + git clone --depth 1 $cic_bancor_url cic-bancor && \ + cd cic-bancor && \ + git fetch --depth 1 origin $cic_bancor_commit && \ + git checkout $cic_bancor_commit && \ + # Apparently the git version here doesn't have set-url as a command. *sigh* + #if [ ! -z $cic_bancor_contracts_url ]; then + # git submodule set-url bancor $cic_bancor_contracts_url + #fi + git submodule init && \ + git submodule update +RUN cd root && \ + . $NVM_DIR/nvm.sh &&\ + nvm install $BANCOR_NODE_VERSION && \ + nvm use $BANCOR_NODE_VERSION && \ + cd - && \ + cd cic-bancor/bancor && \ + npm install --python=/usr/bin/python2 && \ + node_modules/truffle/build/cli.bundled.js compile && \ + mkdir -vp /usr/local/share/cic/bancor/solidity/build && \ + cp -vR solidity/build/contracts /usr/local/share/cic/bancor/solidity/build/ +RUN cd cic-bancor/python && \ + pip install --extra-index-url $pip_extra_index_url . + +ARG cryptocurrency_cli_tools_version=0.0.4 +# RUN pip install --extra-index-url $pip_extra_index_url cryptocurrency-cli-tools==$cryptocurrency_cli_tools_version + +ARG giftable_erc20_token_version=0.0.7b1 +# RUN pip install --extra-index-url $pip_extra_index_url giftable-erc20-token==$giftable_erc20_token_version + +ARG eth_accounts_index_version=0.0.10a2 +# RUN pip install --extra-index-url $pip_extra_index_url eth-accounts-index==$eth_accounts_index_version + +ARG erc20_approval_escrow_version=0.3.0a1 +# RUN pip install --extra-index-url $pip_extra_index_url erc20-approval-escrow==$erc20_approval_escrow_version + +ARG erc20_single_shot_faucet_version=0.2.0a1 +# RUN pip install --extra-index-url $pip_extra_index_url erc20-single-shot-faucet==$erc20_single_shot_faucet_version + +ARG eth_address_index_version==0.1.0a1 +# RUN pip install --extra-index-url $pip_extra_index_url eth-address-index==$eth_address_index_version + +# RUN echo Install cic specific python packages +ARG cic_registry_version=0.5.3a4 +# RUN pip install --extra-index-url $pip_extra_index_url cic-registry==$cic_registry_version + +# RUN pip install --extra-index-url $pip_extra_index_url crypto-dev-signer==0.4.13b9 +WORKDIR /root + +# RUN pip install --extra-index-url $pip_extra_index_url crypto-dev-signer==0.4.12 + +RUN pip install --extra-index-url $pip_extra_index_url \ + cryptocurrency-cli-tools==$cryptocurrency_cli_tools_version \ + giftable-erc20-token==$giftable_erc20_token_version \ + eth-accounts-index==$eth_accounts_index_version \ + erc20-approval-escrow==$erc20_approval_escrow_version \ + erc20-single-shot-faucet==$erc20_single_shot_faucet_version \ + cic-registry==$cic_registry_version \ + crypto-dev-signer==0.4.13b9 + + +COPY testdata/pgp testdata/pgp + +RUN mkdir -vp /tmp/cic/pgp +COPY testdata/pgp/* /tmp/cic/pgp/ + +# COPY .env_config_template .env_config_template +# COPY .env_dockercompose_template .env_dockercompose_template + +COPY reset.sh . +# COPY data.sh data.sh +COPY keystore keystore +COPY wait-for-it.sh . +RUN chmod +x reset.sh wait-for-it.sh + +LABEL version="4" + +# DEFAULTS ASSUME THE FOLLOWING MNEMONIC ON GANACHE-CLI +# history stumble mystery avoid embark arrive mom foil pledge keep grain dice +ENV DEV_ETH_ACCOUNT_RESERVE_OWNER="0xc14958CD9A605AB0d9A36850362AaD2b9D42DF97" +ENV DEV_ETH_ACCOUNT_RESERVE_MINTER="0xe3C4db5947409Aff0FF8D643047EA41515cA4B8e" +ENV DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER="0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C" +ENV DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_OWNER="0x1AB26f3AAaaa884B651E213508592F3Ec6BfCe74" +ENV DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER="0xACB0BC74E1686D62dE7DC6414C999EA60C09F0eA" +ENV DEV_ETH_RESERVE_AMOUNT="1000000000000000000000000" +ENV CIC_CHAIN_SPEC="Bloxberg:8995" +ENV CIC_DATA_DIR="/tmp/cic/config" + +# populated internally when running provisioning script (reset.sh) +# ENV DEV_ETH_RESERVE_ADDRESS +# ENV BANCOR_REGISTRY_ADDRESS +# ENV DEV_ETH_ACCOUNTS_INDEX_ADDRESS + diff --git a/apps/contract-migration/LICENSE.txt b/apps/contract-migration/LICENSE.txt new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/apps/contract-migration/LICENSE.txt @@ -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 +. diff --git a/apps/contract-migration/README.md b/apps/contract-migration/README.md new file mode 100644 index 0000000..a3bf699 --- /dev/null +++ b/apps/contract-migration/README.md @@ -0,0 +1,53 @@ +# Contract Migration + +Common docker artifacts and bootstrap scripts + +## How this repo works + +This repo builds contracts and deploys them to a chain + +First, bring up an eth evm provider +``` +docker-compose up eth +``` + +Now build this repo's image and run it against the 'eth' service (ganache, for example). You will need to bind to the docker-compose network (cic-network) and mount the special contract output folder that dependent services use to get deployed contract addresses. + +Here is how to do that in one shot: +``` +docker build -t registry.gitlab.com/grassrootseconomics/cic-docker-internal . && docker run --env ETH_PROVIDER=http://eth:8545 --net cic-network -v cic-docker-internal_contract-config:/tmp/cic/config --rm -it registry.gitlab.com/grassrootseconomics/cic-docker-internal reset.sh +``` + +Stop the containers and bring down the services with +``` +docker-compose down +``` + +If you want a fresh start to the dev environment then bring down the services and delete their associated volumes with + +``` +docker-compose down -v +``` + +A goal is to go through all of these containers and create a default non-root user a la: +https://vsupalov.com/docker-shared-permissions/ + +## Tips and Tricks + +Sometimes you just want to hold a container open in docker compose so you can exec into it and poke around. Replace "command" with + +``` + command: + - /bin/sh + - -c + - | + tail -f /dev/null +``` +then + +``` +docker exec -it [IMAGE_NANE] sh +``` + +--- + diff --git a/apps/contract-migration/config_template/bancor.ini b/apps/contract-migration/config_template/bancor.ini new file mode 100644 index 0000000..443924f --- /dev/null +++ b/apps/contract-migration/config_template/bancor.ini @@ -0,0 +1,2 @@ +[bancor] +dir = /usr/local/share/cic/bancor diff --git a/apps/contract-migration/config_template/celery.ini b/apps/contract-migration/config_template/celery.ini new file mode 100644 index 0000000..dac9a5f --- /dev/null +++ b/apps/contract-migration/config_template/celery.ini @@ -0,0 +1,3 @@ +[celery] +broker_url = redis://redis:6379 +result_url = redis://redis:6379 diff --git a/apps/contract-migration/config_template/cic.ini b/apps/contract-migration/config_template/cic.ini new file mode 100644 index 0000000..bf598b9 --- /dev/null +++ b/apps/contract-migration/config_template/cic.ini @@ -0,0 +1,7 @@ +[cic] +registry_address = +token_index_address = +accounts_index_address = +declarator_address = +approval_escrow_address = +chain_spec = Bloxberg:8996 diff --git a/apps/contract-migration/config_template/database.ini b/apps/contract-migration/config_template/database.ini new file mode 100644 index 0000000..db8227b --- /dev/null +++ b/apps/contract-migration/config_template/database.ini @@ -0,0 +1,8 @@ +[database] +user = postgres +password = tralala +name = +host = postgres +port = 5432 +engine = postgres +driver = psycopg2 diff --git a/apps/contract-migration/config_template/dev.ini b/apps/contract-migration/config_template/dev.ini new file mode 100644 index 0000000..a2c663e --- /dev/null +++ b/apps/contract-migration/config_template/dev.ini @@ -0,0 +1,33 @@ +[dev] +mnemonic = "history stumble mystery avoid embark arrive mom foil pledge keep grain dice" +eth_reserve_address = +eth_accounts_index_address = +# 10m * 10^18 (10^7 * 10^18) +eth_reserve_amount = 1000000000000000000000000 + +eth_account_contract_deployer=0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C +eth_account_gas_provider=0xFfe6E610d1Ea184AEE71c6B39828ecE921f04a7F +eth_account_gas_gifter=0xFfe6E610d1Ea184AEE71c6B39828ecE921f04a7F +eth_account_reserve_owner=0xc14958CD9A605AB0d9A36850362AaD2b9D42DF97 +eth_account_reserve_minter=0xe3C4db5947409Aff0FF8D643047EA41515cA4B8e +eth_account_accounts_index_owner=0x1AB26f3AAaaa884B651E213508592F3Ec6BfCe74 +eth_account_accounts_index_writer=0xACB0BC74E1686D62dE7DC6414C999EA60C09F0eA +eth_account_sarafu_owner=0x5567139c7a1C2977A391f51D8cA45B1D6700f5F6 +eth_account_sarafu_gifter=0x1149D55B3495CdC8FcfaF2816384AafaeFfaEa24 +eth_account_approval_escrow_owner=0x8754122F5718dC02Db5062c62fD4a63A5448623E +eth_account_single_shot_faucet_owner=0x34C85E47f45b0bea09F37c83e2fb02ECBC3a395d + +eth_sarafu_token_address = +eth_token_index_address = +eth_sarafu_faucet_address = +eth_erc20_approval_escrow_address = + +eth_sarafu_token_name=Sarafu +eth_sarafu_token_symbol=SRF +eth_sarafu_token_decimals=18 + +pgp_publickeys_active_file = publickeys.asc +pgp_publickeys_trusted_file = +pgp_publickeys_encrypt_file = + +faucet_amount = 1000000 diff --git a/apps/contract-migration/config_template/eth.ini b/apps/contract-migration/config_template/eth.ini new file mode 100644 index 0000000..5506851 --- /dev/null +++ b/apps/contract-migration/config_template/eth.ini @@ -0,0 +1,3 @@ +[eth] +provider = http://eth:8545 +abi_dir = /usr/local/share/cic/solidity/abi diff --git a/apps/contract-migration/config_template/meta.ini b/apps/contract-migration/config_template/meta.ini new file mode 100644 index 0000000..cbcc16a --- /dev/null +++ b/apps/contract-migration/config_template/meta.ini @@ -0,0 +1,2 @@ +[meta] +provider = http://cic-meta-server:80 diff --git a/apps/contract-migration/config_template/pgp.ini b/apps/contract-migration/config_template/pgp.ini new file mode 100644 index 0000000..fade0d5 --- /dev/null +++ b/apps/contract-migration/config_template/pgp.ini @@ -0,0 +1,4 @@ +[pgp] +exports_dir = /tmp/cic/pgp +privatekey_file = ge.priv.asc +passphrase = ge diff --git a/apps/contract-migration/config_template/signer.ini b/apps/contract-migration/config_template/signer.ini new file mode 100644 index 0000000..58ad0c0 --- /dev/null +++ b/apps/contract-migration/config_template/signer.ini @@ -0,0 +1,3 @@ +[signer] +socket_path = /tmp/cic/signer/jsonrpc.ipc +secret = deadbeef diff --git a/apps/contract-migration/config_template/syncer.ini b/apps/contract-migration/config_template/syncer.ini new file mode 100644 index 0000000..60c0c00 --- /dev/null +++ b/apps/contract-migration/config_template/syncer.ini @@ -0,0 +1,2 @@ +[syncer] +loop_interval = diff --git a/apps/contract-migration/config_template/tasks.ini b/apps/contract-migration/config_template/tasks.ini new file mode 100644 index 0000000..b49ecad --- /dev/null +++ b/apps/contract-migration/config_template/tasks.ini @@ -0,0 +1,5 @@ +[tasks] +africastalking = cic_notify.tasks.sms.africastalking +sms_db = cic_notify.tasks.sms.db +log = cic_notify.tasks.sms.log +transfer_callbacks=cic-ussd:cic_ussd.tasks.callback_handler.process_incoming_transfer_callback diff --git a/apps/contract-migration/dev/balance.py b/apps/contract-migration/dev/balance.py new file mode 100644 index 0000000..4fa6ba5 --- /dev/null +++ b/apps/contract-migration/dev/balance.py @@ -0,0 +1,58 @@ +#!python3 + +"""Gas transfer script + +.. moduleauthor:: Louis Holbrook +.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 + +""" + +# SPDX-License-Identifier: GPL-3.0-or-later + +# standard imports +import os +import json +import argparse +import logging + +# third-party imports +import web3 + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger() + +logging.getLogger('web3').setLevel(logging.WARNING) +logging.getLogger('urllib3').setLevel(logging.WARNING) + +default_abi_dir = os.environ.get('ETH_ABI_DIR', '/usr/share/local/cic/solidity/abi') +default_eth_provider = os.environ.get('ETH_PROVIDER', 'http://localhost:8545') + +argparser = argparse.ArgumentParser() +argparser.add_argument('-p', '--provider', dest='p', default=default_eth_provider, type=str, help='Web3 provider url (http only)') +argparser.add_argument('-t', '--token-address', dest='t', type=str, help='Token address. If not set, will return gas balance') +argparser.add_argument('--abi-dir', dest='abi_dir', type=str, default=default_abi_dir, help='Directory containing bytecode and abi (default {})'.format(default_abi_dir)) +argparser.add_argument('-v', action='store_true', help='Be verbose') +argparser.add_argument('account', type=str, help='Account address') +args = argparser.parse_args() + + +if args.v: + logg.setLevel(logging.DEBUG) + +def main(): + w3 = web3.Web3(web3.Web3.HTTPProvider(args.p)) + + balance = None + if args.t != None: + f = open(os.path.join(args.abi_dir, 'ERC20.json')) + abi = json.load(f) + f.close() + c = w3.eth.contract(abi=abi, address=args.t) + balance = c.functions.balanceOf(args.account).call() + else: + balance =w3.eth.getBalance(args.account) + + print(balance) + +if __name__ == '__main__': + main() diff --git a/apps/contract-migration/dev/create.py b/apps/contract-migration/dev/create.py new file mode 100644 index 0000000..11851ce --- /dev/null +++ b/apps/contract-migration/dev/create.py @@ -0,0 +1,47 @@ +#!/usr/bin/python +import sys +import os +import logging + +import celery +from cic_eth.api import Api +import confini +import argparse + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger('create_account_script') +logging.getLogger('confini').setLevel(logging.WARNING) +logging.getLogger('gnupg').setLevel(logging.WARNING) + +config_dir = os.environ.get('CONFINI_DIR', '/usr/local/etc/cic') + +argparser = argparse.ArgumentParser() +argparser.add_argument('--no-register', dest='no_register', action='store_true', help='Do not register new account in on-chain accounts index') +argparser.add_argument('-v', action='store_true', help='Be verbose') +argparser.add_argument('-vv', action='store_true', help='Be more verbose') +args = argparser.parse_args() + +if args.vv: + logg.setLevel(logging.DEBUG) +if args.v: + logg.setLevel(logging.INFO) + +config = confini.Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX')) +config.process() + +celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL')) + +api = Api(config.get('CIC_CHAIN_SPEC')) + +registration_account = None +#t = api.create_account(registration_account=registration_account) +if len(sys.argv) > 1: + registration_account = config.get('DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER', None) + +logg.debug('accounts index writer NOT USED {}'.format(registration_account)) + +register = not args.no_register +logg.debug('register {}'.format(register)) +t = api.create_account(register=register) + +print(t.get()) diff --git a/apps/contract-migration/dev/decode.py b/apps/contract-migration/dev/decode.py new file mode 100644 index 0000000..58b7766 --- /dev/null +++ b/apps/contract-migration/dev/decode.py @@ -0,0 +1,48 @@ +#!python3 + +"""Decode raw transaction + +.. moduleauthor:: Louis Holbrook +.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 + +""" + +# SPDX-License-Identifier: GPL-3.0-or-later + +# standard imports +import os +import json +import argparse +import logging + +# third-party imports +from cic_eth.eth.util import unpack_signed_raw_tx + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger() + +default_abi_dir = os.environ.get('ETH_ABI_DIR', '/usr/share/local/cic/solidity/abi') +default_eth_provider = os.environ.get('ETH_PROVIDER', 'http://localhost:8545') + +argparser = argparse.ArgumentParser() +argparser.add_argument('-v', action='store_true', help='Be verbose') +argparser.add_argument('-i', '--chain-id', dest='i', type=int, help='Numeric network id') +argparser.add_argument('tx', type=str, help='hex-encoded signed raw transaction') +args = argparser.parse_args() + + +if args.v: + logg.setLevel(logging.DEBUG) + +def main(): + tx_raw = args.tx + if tx_raw[:2] == '0x': + tx_raw = tx_raw[2:] + tx_raw_bytes = bytes.fromhex(tx_raw) + tx = unpack_signed_raw_tx(tx_raw_bytes, args.i) + for k in tx.keys(): + print('{}: {}'.format(k, tx[k])) + + +if __name__ == '__main__': + main() diff --git a/apps/contract-migration/dev/env.sh b/apps/contract-migration/dev/env.sh new file mode 100644 index 0000000..55fe450 --- /dev/null +++ b/apps/contract-migration/dev/env.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +cic_data_dir=${CIC_DATA_DIR:-/tmp/cic} +t=${1:-$(mktemp)} +prefix='' +if [ ! -z $2 ]; then + prefix="${2}_" +fi + +echo "#!/bin/bash" > $t +echo "set +a" >> $t +cat $cic_data_dir/.env | sed -e "s/^\([A-Z]\)/export ${prefix}\1/g" >> $t + +#if [ -f $cic_data_dir/.env ]; then +#cat $cic_data_dir/.env | sed -e "s/^\([A-Z]\)/export ${prefix}\1/g" >> $t +#fi +echo "export CONFINI_DIR=$(dirname $(realpath .))/config_template" >> $t +source $t +echo "export CELERY_BROKER_URL=redis://localhost:${HTTP_PORT_REDIS}" >> $t +echo "export CELERY_RESULT_URL=redis://localhost:${HTTP_PORT_REDIS}" >> $t +echo "export ETH_PROVIDER=http://localhost:${HTTP_PORT_ETH}" >> $t +echo "export META_PROVIDER=http://localhost:${HTTP_PORT_CIC_META}" >> $t +echo "set -a" >> $t +echo $t diff --git a/apps/contract-migration/dev/gas.py b/apps/contract-migration/dev/gas.py new file mode 100644 index 0000000..42c5cc4 --- /dev/null +++ b/apps/contract-migration/dev/gas.py @@ -0,0 +1,105 @@ +#!python3 + +"""Gas transfer script + +.. moduleauthor:: Louis Holbrook +.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 + +""" + +# SPDX-License-Identifier: GPL-3.0-or-later + +# standard imports +import os +import json +import argparse +import logging + +# third-party imports +import web3 +from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer +from crypto_dev_signer.keystore import DictKeystore +from crypto_dev_signer.eth.helper import EthTxExecutor + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger() + +logging.getLogger('web3').setLevel(logging.WARNING) +logging.getLogger('urllib3').setLevel(logging.WARNING) + +default_abi_dir = '/usr/share/local/cic/solidity/abi' +argparser = argparse.ArgumentParser() +argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)') +argparser.add_argument('-w', action='store_true', help='Wait for the last transaction to be confirmed') +argparser.add_argument('-ww', action='store_true', help='Wait for every transaction to be confirmed') +argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='Ethereum:1', help='Chain specification string') +argparser.add_argument('-a', '--signer-address', dest='a', type=str, help='Signing address') +argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing') +argparser.add_argument('-v', action='store_true', help='Be verbose') +argparser.add_argument('-vv', action='store_true', help='Be more verbose') +argparser.add_argument('recipient', type=str, help='Ethereum address of recipient') +argparser.add_argument('amount', type=int, help='Amount of tokens to mint and gift') +args = argparser.parse_args() + + +if args.vv: + logg.setLevel(logging.DEBUG) +elif args.v: + logg.setLevel(logging.INFO) + +block_last = args.w +block_all = args.ww + +w3 = web3.Web3(web3.Web3.HTTPProvider(args.p)) + +signer_address = None +keystore = DictKeystore() +if args.y != None: + logg.debug('loading keystore file {}'.format(args.y)) + signer_address = keystore.import_keystore_file(args.y) + logg.debug('now have key for signer address {}'.format(signer_address)) +signer = EIP155Signer(keystore) + +chain_pair = args.i.split(':') +chain_id = int(chain_pair[1]) + +helper = EthTxExecutor( + w3, + signer_address, + signer, + chain_id, + block=args.ww, + ) + + +def build_gas_transaction(recipient, value): + def builder(tx): + tx['to'] = recipient + tx['value'] = value + tx['data'] = '0x' + return tx + return builder + + +def main(): + recipient = args.recipient + value = args.amount + + logg.debug('sender {} balance before: {}'.format(signer_address, w3.eth.getBalance(signer_address))) + logg.debug('recipient {} balance before: {}'.format(recipient, w3.eth.getBalance(recipient))) + (tx_hash, rcpt) = helper.sign_and_send( + [ + build_gas_transaction(recipient, value), + ], + ) + logg.debug('sender {} balance after: {}'.format(signer_address, w3.eth.getBalance(signer_address))) + logg.debug('recipient {} balance after: {}'.format(recipient, w3.eth.getBalance(recipient))) + + if block_last: + helper.wait_for() + + print(tx_hash) + + +if __name__ == '__main__': + main() diff --git a/apps/contract-migration/dev/js/register_users.js b/apps/contract-migration/dev/js/register_users.js new file mode 100644 index 0000000..60b0f3a --- /dev/null +++ b/apps/contract-migration/dev/js/register_users.js @@ -0,0 +1,101 @@ +const fs = require('fs'); +const path = require('path'); +const cic = require('cic-client-meta'); +const http = require('http'); +const confini = require('confini'); + +console.debug('sorry this script doesnt read cli flags, set all in env vars'); + +let config_data_dir = process.env.CONFINI_DIR; +if (config_data_dir === undefined) { + config_data_dir = '/usr/local/etc/cic'; +} +const config = new confini.Config(config_data_dir, process.env.CONFINI_ENV_PREFIX); +config.process(); +Object.keys(config.store).forEach((k) => { + console.debug(k, config.get(k)); +}); + +// flatten file list from directories recursively +// cheekily though gratefully stolen from https://coderrocketfuel.com/article/recursively-list-all-the-files-in-a-directory-using-node-js +const getAllFiles = function(dirPath, arrayOfFiles) { + files = fs.readdirSync(dirPath) + + arrayOfFiles = arrayOfFiles || [] + + files.forEach(function(file) { + if (fs.statSync(dirPath + "/" + file).isDirectory()) { + arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles) + } else { + arrayOfFiles.push(path.join(dirPath, "/", file)) + } + }) + + return arrayOfFiles +} + +async function sendit(uid, envelope) { + const d = envelope.toJSON(); + + const opts = { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': d.length, + 'X-CIC-AUTOMERGE': 'client', + + }, + }; + let url = config.get('META_PROVIDER'); //['archiveUrl']; + url = url.replace(new RegExp('^(.+://[^/]+)/*$'), '$1/'); + const req = http.request(url + uid, opts, (res) => { + res.on('data', process.stdout.write); + res.on('end', () => { + console.log('result', res.statusCode, res.headers); + }); + }); + + req.write(d); + req.end(); +} + +function doit(keystore) { + dataDir = 'data'; + if (process.argv.length > 2) { + dataDir = process.argv[2]; + } + console.log('argv', process.argv); + console.log('datadir', path.join(dataDir, 'person')); + getAllFiles(path.join(dataDir, 'person')).forEach((filename) => { + console.debug('person file', filename); + const signer = new cic.PGPSigner(keystore); + const parts = filename.split('.'); + const uid = path.basename(parts[0]); + + const d = fs.readFileSync(filename, 'utf-8'); + const o = JSON.parse(d); + + const s = new cic.Syncable(uid, o); + console.log(s); + s.setSigner(signer); + s.onwrap = (env) => { + console.log('env', env); + //console.log('sign', s.m.signature.digest); + sendit(uid, env); + }; + s.sign(); + }); +} + +pk = fs.readFileSync(path.join(config.get('PGP_EXPORTS_DIR'), config.get('PGP_PRIVATEKEY_FILE'))); +pubk = fs.readFileSync(path.join(config.get('PGP_EXPORTS_DIR'), config.get('DEV_PGP_PUBLICKEYS_ACTIVE_FILE'))); + +new cic.PGPKeyStore( + process.env['PGP_PASSPHRASE'], + pk, + pubk, + undefined, + undefined, + doit, +); + diff --git a/apps/contract-migration/dev/keys.sh b/apps/contract-migration/dev/keys.sh new file mode 100644 index 0000000..6424258 --- /dev/null +++ b/apps/contract-migration/dev/keys.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +mkdir -vp .tmp +echo -n '' > .tmp/.env_accounts +account_labels=( + DEV_ETH_ACCOUNT_BANCOR_DEPLOYER + DEV_ETH_ACCOUNT_GAS_PROVIDER + DEV_ETH_ACCOUNT_RESERVE_OWNER + DEV_ETH_ACCOUNT_RESERVE_MINTER + DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_OWNER + DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER + DEV_ETH_ACCOUNT_SARAFU_OWNER + DEV_ETH_ACCOUNT_SARAFU_GIFTER + DEV_ETH_ACCOUNT_APPROVAL_ESCROW_OWNER + DEV_ETH_ACCOUNT_SINGLE_SHOT_FAUCET_OWNER +) +bip39gen -n ${#account_labels[@]} "$DEV_MNEMONIC" +i=0 +for a in `bip39gen -n ${#account_labels[@]} "$DEV_MNEMONIC" | jq -r .address[]`; do + exportline=${account_labels[$i]}=$a + export $exportline + echo $exportline >> .tmp/.env_accounts + echo exportline $exportline + i=$(($i+1)) +done + diff --git a/apps/contract-migration/dev/nvm.sh b/apps/contract-migration/dev/nvm.sh new file mode 100644 index 0000000..60419b7 --- /dev/null +++ b/apps/contract-migration/dev/nvm.sh @@ -0,0 +1,4 @@ +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh" +[ -s "$NVM_DIR/bash_completion" ] && source "$NVM_DIR/bash_completion" + diff --git a/apps/contract-migration/dev/python/scripts/setup.py b/apps/contract-migration/dev/python/scripts/setup.py new file mode 100644 index 0000000..bd1da75 --- /dev/null +++ b/apps/contract-migration/dev/python/scripts/setup.py @@ -0,0 +1,4 @@ +from setuptools import setup + +setup( + ) diff --git a/apps/contract-migration/dev/python/scripts/tx_driver.py b/apps/contract-migration/dev/python/scripts/tx_driver.py new file mode 100644 index 0000000..c2a79ae --- /dev/null +++ b/apps/contract-migration/dev/python/scripts/tx_driver.py @@ -0,0 +1,150 @@ +# standard imports +import os +import logging +import argparse +import re +import json +import signal +import random +import time + +# third-party imports +import confini +import web3 +from cic_registry.chain import ChainSpec +from cic_registry.chain import ChainRegistry +from cic_registry import CICRegistry +from eth_token_index import TokenUniqueSymbolIndex as TokenIndex +from eth_accounts_index import AccountRegistry + +from cic_eth.api import Api + + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger() +logging.getLogger('websockets.protocol').setLevel(logging.CRITICAL) +logging.getLogger('web3.RequestManager').setLevel(logging.CRITICAL) +logging.getLogger('web3.providers.WebsocketProvider').setLevel(logging.CRITICAL) +logging.getLogger('web3.providers.HTTPProvider').setLevel(logging.CRITICAL) + +default_data_dir = '/usr/local/share/cic/solidity/abi' + +argparser = argparse.ArgumentParser() +argparser.add_argument('-c', type=str, default='./config', help='config file') +argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='chain spec') +argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration') +argparser.add_argument('--abi-dir', dest='abi_dir', type=str, default=default_data_dir, help='Directory containing bytecode and abi (default: {})'.format(default_data_dir)) +argparser.add_argument('-v', action='store_true', help='be verbose') +argparser.add_argument('-vv', action='store_true', help='be more verbose') +argparser.add_argument('--wait-max', dest='wait_max', default=2.0, type=float, help='maximum time in decimal seconds to wait between transactions') +argparser.add_argument('--account-index-address', dest='account_index', type=str, help='Contract address of accounts index') +argparser.add_argument('--token-index-address', dest='token_index', type=str, help='Contract address of token index') +argparser.add_argument('--approval-escrow-address', dest='approval_escrow', type=str, help='Contract address for transfer approvals') +argparser.add_argument('--declarator-address', dest='declarator', type=str, help='Address of declarations contract to perform lookup against') +argparser.add_argument('-a', '--accounts-index-writer', dest='a', type=str, help='Address of account with access to add to accounts index') + +args = argparser.parse_args() + +if args.vv: + logging.getLogger().setLevel(logging.DEBUG) +elif args.v: + logging.getLogger().setLevel(logging.INFO) + +config = confini.Config(args.c, args.env_prefix) +config.process() +args_override = { + 'ETH_ABI_DIR': getattr(args, 'abi_dir'), + 'CIC_CHAIN_SPEC': getattr(args, 'i'), + 'DEV_ETH_ACCOUNTS_INDEX_ADDRESS': getattr(args, 'account_index'), + 'DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER': getattr(args, 'a'), + 'DEV_ETH_ERC20_APPROVAL_ESCROW_ADDRESS': getattr(args, 'approval_escrow'), + 'DEV_ETH_TOKEN_INDEX_ADDRESS': getattr(args, 'token_index'), + } +config.dict_override(args_override, 'cli flag') +config.validate() +config.censor('PASSWORD', 'DATABASE') +config.censor('PASSWORD', 'SSL') +logg.debug('config:\n{}'.format(config)) + +re_websocket = r'^wss?:' +re_http = r'^https?:' +blockchain_provider = None +if re.match(re_websocket, config.get('ETH_PROVIDER')): + blockchain_provider = web3.Web3.WebsocketProvider(config.get('ETH_PROVIDER')) +elif re.match(re_http, config.get('ETH_PROVIDER')): + blockchain_provider = web3.Web3.HTTPProvider(config.get('ETH_PROVIDER')) +w3 = web3.Web3(blockchain_provider) + + +chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC')) +CICRegistry.init(w3, config.get('CIC_REGISTRY_ADDRESS'), chain_spec) +CICRegistry.add_path(config.get('ETH_ABI_DIR')) + +chain_registry = ChainRegistry(chain_spec) +CICRegistry.add_chain_registry(chain_registry, True) + +run = True + +def inthandler(name, frame): + logg.warning('got {}, stopping'.format(name)) + global run + run = False + +signal.signal(signal.SIGTERM, inthandler) +signal.signal(signal.SIGINT, inthandler) + +api = Api(str(chain_spec)) + +f = open(os.path.join(config.get('ETH_ABI_DIR'), 'ERC20.json')) +erc20_abi = json.load(f) +f.close() + +def get_tokens(): + tokens = [] + token_index = TokenIndex(w3, config.get('CIC_TOKEN_INDEX_ADDRESS')) + token_count = token_index.count() + for i in range(token_count): + tokens.append(token_index.get_index(i)) + logg.debug('tokens {}'.format(tokens)) + return tokens + +def get_addresses(): + address_index = AccountRegistry(w3, config.get('CIC_ACCOUNTS_INDEX_ADDRESS')) + address_count = address_index.count() + addresses = address_index.last(address_count-1) + logg.debug('addresses {} {}'.format(address_count, addresses)) + return addresses + +random.seed() + +while run: + n = random.randint(0, 255) + + # some of the time do other things than transfers + if n & 0xf8 == 0xf8: + t = api.create_account() + logg.info('create account {}'.format(t)) + + else: + tokens = get_tokens() + addresses = get_addresses() + address_pair = random.choices(addresses, k=2) + sender = address_pair[0] + recipient = address_pair[1] + token = random.choice(tokens) + + c = w3.eth.contract(abi=erc20_abi, address=token) + sender_balance = c.functions.balanceOf(sender).call() + token_symbol = c.functions.symbol().call() + amount = int(random.random() * (sender_balance / 2)) + + n = random.randint(0, 255) + + if n & 0xc0 == 0xc0: + t = api.transfer_request(sender, recipient, config.get('CIC_APPROVAL_ESCROW_ADDRESS'), amount, token_symbol) + logg.info('transfer REQUEST {} {} from {} to {} => {}'.format(amount, token_symbol, sender, recipient, t)) + else: + t = api.transfer(sender, recipient, amount, token_symbol) + logg.info('transfer {} {} from {} to {} => {}'.format(amount, token_symbol, sender, recipient, t)) + + time.sleep(random.random() * args.wait_max) diff --git a/apps/contract-migration/dev/python/scripts/tx_seed.py b/apps/contract-migration/dev/python/scripts/tx_seed.py new file mode 100644 index 0000000..aacb9fa --- /dev/null +++ b/apps/contract-migration/dev/python/scripts/tx_seed.py @@ -0,0 +1,51 @@ +#!/usr/bin/python + +import csv +import logging +import argparse +import os +import re + +import web3 +import confini + +from cic_registry import CICRegistry +from cic_eth.api import Api + +logging.basicConfig(level=logging.INFO) +logg = logging.getLogger() + +confini_default_dir = os.environ.get('CONFINI_DIR', '/usr/local/etc/cic') + + +argparser = argparse.ArgumentParser() +argparser.add_argument('-c', type=str, default=confini_default_dir, help='config data dir') +argparser.add_argument('-a', '--token-gifter-address', dest='a', type=str, help='Token gifter address') +argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='chain spec') +argparser.add_argument('-s', '--token-symbol', dest='s', type=str, help='Token symbol') +argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration') +argparser.add_argument('-v', action='store_true', help='be verbose') +argparser.add_argument('-vv', action='store_true', help='be more verbose') +args = argparser.parse_args() + +if args.vv: + logging.getLogger().setLevel(logging.DEBUG) +elif args.v: + logging.getLogger().setLevel(logging.INFO) + +config = confini.Config(args.c, args.env_prefix) +config.process() +args_override = { + 'CIC_CHAIN_SPEC': getattr(args, 'i'), + } +cic_eth_api = Api(config.get('CIC_CHAIN_SPEC')) + +token_gifter_address = args.a + +if __name__ == '__main__': + f = open('./data/amounts', 'r') + cr = csv.reader(f) + for r in cr: + logg.info('sending {} {} from {} to {}'.format(r[1], args.s, token_gifter_address, r[0])) + cic_eth_api.transfer(token_gifter_address, r[0], int(r[1]), args.s) + f.close() diff --git a/apps/contract-migration/dev/python/scripts/users.py b/apps/contract-migration/dev/python/scripts/users.py new file mode 100644 index 0000000..035806b --- /dev/null +++ b/apps/contract-migration/dev/python/scripts/users.py @@ -0,0 +1,212 @@ +#!/usr/bin/python + +import json +import time +import datetime +import random +import logging +import os +import base64 +import hashlib +import sys + +import vobject + +import celery +import web3 +from faker import Faker +import cic_registry +import confini +from cic_eth.api import Api + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +fake = Faker(['sl', 'en_US', 'no', 'de', 'ro']) + +#f = open('cic.conf', 'r') +#config = json.load(f) +#f.close() +# + +config_dir = os.environ.get('CONFINI_DIR', '/usr/local/etc/cic') + +config = confini.Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX')) +config.process() +logg.info('loaded config\n{}'.format(config)) + + +w3s = None +w3s = web3.Web3(web3.Web3.IPCProvider(config.get('SIGNER_SOCKET_PATH'))) +#w3s = web3.Web3(web3.Web3.IPCProvider(config['signer']['provider'])) +#w3 = web3.Web3(web3.Web3.WebsocketProvider(config['eth']['provider'])) + +dt_now = datetime.datetime.utcnow() +dt_then = dt_now - datetime.timedelta(weeks=150) +ts_now = int(dt_now.timestamp()) +ts_then = int(dt_then.timestamp()) + +celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL')) + +api = Api(config.get('CIC_CHAIN_SPEC')) + +gift_max = 10000 +gift_factor = (10**9) + +categories = [ + "food/water", + "fuel/energy", + "education", + "health", + "shop", + "environment", + "transport", + "farming/labor", + "savingsgroup", + ] + +phone_idx = [] + + +def genPhoneIndex(phone): + h = hashlib.new('sha256') + h.update(phone.encode('utf-8')) + h.update(b'cic.msisdn') + return h.digest().hex() + + +def genId(addr, typ): + h = hashlib.new('sha256') + h.update(bytes.fromhex(addr[2:])) + h.update(typ.encode('utf-8')) + return h.digest().hex() + + +def genDate(): + + logg.info(ts_then) + ts = random.randint(ts_then, ts_now) + return datetime.datetime.fromtimestamp(ts).timestamp() + + +def genPhone(): + return fake.msisdn() + + +def genPersonal(phone): + fn = fake.first_name() + ln = fake.last_name() + e = fake.email() + + v = vobject.vCard() + first_name = fake.first_name() + last_name = fake.last_name() + v.add('n') + v.n.value = vobject.vcard.Name(family=last_name, given=first_name) + v.add('fn') + v.fn.value = '{} {}'.format(first_name, last_name) + v.add('tel') + v.tel.typ_param = 'CELL' + v.tel.value = phone + v.add('email') + v.email.value = fake.email() + + vcard_serialized = v.serialize() + vcard_base64 = base64.b64encode(vcard_serialized.encode('utf-8')) + + return vcard_base64.decode('utf-8') + + +def genCats(): + i = random.randint(0, 3) + return random.choices(categories, k=i) + + +def genAmount(): + return random.randint(0, gift_max) * gift_factor + + +def gen(): + old_blockchain_address = '0x' + os.urandom(20).hex() + accounts_index_account = config.get('DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER') + if not accounts_index_account: + accounts_index_account = None + logg.debug('accounts indexwriter {}'.format(accounts_index_account)) + t = api.create_account() + new_blockchain_address = t.get() + gender = random.choice(['female', 'male', 'other']) + phone = genPhone() + v = genPersonal(phone) + o = { + 'date_registered': genDate(), + 'vcard': v, + 'gender': gender, + 'key': { + 'ethereum': [ + old_blockchain_address, + new_blockchain_address, + ], + }, + 'location': { + 'latitude': str(fake.latitude()), + 'longitude': str(fake.longitude()), + 'external': { # add osm lookup + } + }, + 'selling': genCats(), + } + uid = genId(new_blockchain_address, 'cic.person') + + #logg.info('gifting {} to {}'.format(amount, new_blockchain_address)) + + return (uid, phone, o) + + +def prepareLocalFilePath(datadir, address): + parts = [ + address[:2], + address[2:4], + ] + dirs = '{}/{}/{}'.format( + datadir, + parts[0], + parts[1], + ) + os.makedirs(dirs, exist_ok=True) + return dirs + + +if __name__ == '__main__': + + os.makedirs('data/person', exist_ok=True) + os.makedirs('data/phone', exist_ok=True) + + fa = open('./data/amounts', 'w') + fb = open('./data/addresses', 'w') + + #for i in range(10): + for i in range(int(sys.argv[1])): + + (uid, phone, o) = gen() + eth = o['key']['ethereum'][1] + + print(o) + + d = prepareLocalFilePath('./data/person', uid) + f = open('{}/{}'.format(d, uid), 'w') + json.dump(o, f) + f.close() + + pidx = genPhoneIndex(phone) + d = prepareLocalFilePath('./data/phone', uid) + f = open('{}/{}'.format(d, pidx), 'w') + f.write(eth) + f.close() + + amount = genAmount() + fa.write('{},{}\n'.format(eth,amount)) + fb.write('{}\n'.format(eth)) + logg.debug('pidx {}, uid {}, eth {}, amount {}'.format(pidx, uid, eth, amount)) + + fb.close() + fa.close() diff --git a/apps/contract-migration/dev/python/setup.cfg b/apps/contract-migration/dev/python/setup.cfg new file mode 100644 index 0000000..a62eb41 --- /dev/null +++ b/apps/contract-migration/dev/python/setup.cfg @@ -0,0 +1,40 @@ +[metadata] +name = cic-dev-fake +version = 0.0.1 +description = Fake data generator tools +author = Louis Holbrook +author_email = dev@holbrook.no +url = https://gitlab.com/nolash/simple-multisig +keywords = + ethereum +classifiers = + Programming Language :: Python :: 3 + Operating System :: OS Independent + Development Status :: 3 - Alpha + Environment :: No Input/Output (Daemon) + Intended Audience :: Developers + License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) + Topic :: Internet + #Topic :: Blockchain :: EVM +license = GPL3 +licence_files = + LICENSE + +[options] +python_requires = >= 3.6 +install_requires = + web3==5.12.2 + vobject==0.9.6.1 + faker==4.17.1 +tests_require = + eth-tester==0.5.0b2 + py-evm==0.3.0a20 +scripts = + scripts/users.py + scripts/tx_generator.py + scripts/tx_seed.py + +[options.extras_require] +testing = + eth-tester==0.5.0b2 + py-evm==0.3.0a20 diff --git a/apps/contract-migration/dev/python/setup.py b/apps/contract-migration/dev/python/setup.py new file mode 100644 index 0000000..bd1da75 --- /dev/null +++ b/apps/contract-migration/dev/python/setup.py @@ -0,0 +1,4 @@ +from setuptools import setup + +setup( + ) diff --git a/apps/contract-migration/dev/requirements.txt b/apps/contract-migration/dev/requirements.txt new file mode 100644 index 0000000..72c938f --- /dev/null +++ b/apps/contract-migration/dev/requirements.txt @@ -0,0 +1,10 @@ +cryptocurrency-cli-tools~=0.0.4 +giftable-erc20-token~=0.0.7b1 +eth-accounts-index~=0.0.10a2 +erc20-single-shot-faucet~=0.2.0a1 +erc20-approval-escrow~=0.3.0a1 +cic-eth==0.10.0a5 +vobject==0.9.6.1 +faker==4.17.1 +eth-address-index~=0.1.0a1 +crypto-dev-signer~=0.4.13b9 diff --git a/apps/contract-migration/dev/sarafu_declaration.json b/apps/contract-migration/dev/sarafu_declaration.json new file mode 100644 index 0000000..ff0745d --- /dev/null +++ b/apps/contract-migration/dev/sarafu_declaration.json @@ -0,0 +1,18 @@ +{ + "objectType": "ERC20", + "content": { + { + "tokenlists": { + "logoURI": "data:image/svg+xml;base64,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", + "tags": [ + "cic", + "bancor" + ] + }, + "logo": { + "sha256": "6d36122bf05c4ebe483a1be281b5b524e4d2d6df4607fe31e80ccdc430ea981d", + "bzz": "7fa223e40ebdc1691253775abdf96d2289e6fc8ef8f0775e318071744b691e87" + } + } + } +} diff --git a/apps/contract-migration/dev/sarafu_logo.png b/apps/contract-migration/dev/sarafu_logo.png new file mode 100644 index 0000000..5b9c746 Binary files /dev/null and b/apps/contract-migration/dev/sarafu_logo.png differ diff --git a/apps/contract-migration/dev/setup.sh b/apps/contract-migration/dev/setup.sh new file mode 100644 index 0000000..2c65a8a --- /dev/null +++ b/apps/contract-migration/dev/setup.sh @@ -0,0 +1,138 @@ +#!/bin/bash + +# Debug flag +#debug='-v' +keystore_file=../keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c + +debug='' +abi_dir=${ETH_ABI_DIR:-/usr/local/share/cic/solidity/abi} + +# Determine token amount +token_amount=${DEV_ETH_RESERVE_AMOUNT:0:-1} + +# Determine gas amount +#gas_amount=20000000000000000000 +gas_amount=2000000000000000000 + +export DATABASE_NAME=$DATABASE_NAME_CIC_ETH +export DATABASE_PORT=$HTTP_PORT_POSTGRES +export DATABASE_HOST=localhost + +set -e +set -a + +old_gas_provider=$DEV_ETH_ACCOUNT_GAS_PROVIDER +DEV_ETH_ACCOUNT_GAS_GIFTER=`python ./create.py --no-register` +echo DEV_ETH_ACCOUNT_GAS_GIFTER=$DEV_ETH_ACCOUNT_GAS_GIFTER +export DEV_ETH_ACCOUNT_GAS_GIFTER=$DEV_ETH_ACCOUNT_GAS_GIFTER +cic-eth-tag GAS_GIFTER $DEV_ETH_ACCOUNT_GAS_GIFTER + +DEV_ETH_ACCOUNT_SARAFU_GIFTER=`python ./create.py --no-register` +echo DEV_ETH_ACCOUNT_SARAFU_GIFTER=$DEV_ETH_ACCOUNT_SARAFU_GIFTER +export DEV_ETH_ACCOUNT_SARAFU_GIFTER=$DEV_ETH_ACCOUNT_SARAFU_GIFTER +cic-eth-tag SARAFU_GIFTER $DEV_ETH_ACCOUNT_SARAFU_GIFTER + + +DEV_ETH_ACCOUNT_APPROVAL_ESCROW_OWNER=`python ./create.py --no-register` +echo DEV_ETH_ACCOUNT_APPROVAL_ESCROW_OWNER=$DEV_ETH_ACCOUNT_APPROVAL_ESCROW_OWNER +export DEV_ETH_ACCOUNT_APPROVAL_ESCROW_OWNER=$DEV_ETH_ACCOUNT_APPROVAL_ESCROW_OWNER +cic-eth-tag TRANSFER_APPROVAL_OWNER $DEV_ETH_ACCOUNT_APPROVAL_ESCROW_OWNER + + +DEV_ETH_ACCOUNT_SINGLE_SHOT_FAUCET_OWNER=`python ./create.py --no-register` +echo DEV_ETH_ACCOUNT_SINGLE_SHOT_FAUCET_OWNER=$DEV_ETH_ACCOUNT_SINGLE_SHOT_FAUCET_OWNER +export DEV_ETH_ACCOUNT_SINGLE_SHOT_FAUCET_OWNER=$DEV_ETH_ACCOUNT_SINGLE_SHOT_FAUCET_OWNER +cic-eth-tag FAUCET_OWNER $DEV_ETH_ACCOUNT_SINGLE_SHOT_FAUCET_OWNER + + +DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER=`python ./create.py --no-register` +echo DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER=$DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER +export DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER=$DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER +cic-eth-tag ACCOUNTS_INDEX_WRITER $DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER + + +# Transfer gas to custodial gas provider adddress +#echo $old_gas_provider +>&2 echo gift gas to gas gifter +>&2 echo "python gas.py -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w $debug $DEV_ETH_ACCOUNT_GAS_GIFTER $gas_amount" +>&2 python gas.py -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w $debug $DEV_ETH_ACCOUNT_GAS_GIFTER $gas_amount + +>&2 echo gift gas to sarafu token owner +>&2 echo "python gas.py -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w $debug $DEV_ETH_ACCOUNT_SARAFU_OWNER $gas_amount" +>&2 python gas.py -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w $debug $DEV_ETH_ACCOUNT_SARAFU_OWNER $gas_amount + +>&2 echo gift gas to account index owner +>&2 echo "python gas.py -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w $debug $DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_OWNER $gas_amount" +>&2 python gas.py -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w $debug $DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_OWNER $gas_amount + + +# Send reserve to token creator +>&2 giftable-token-gift -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -a $DEV_ETH_RESERVE_ADDRESS --recipient $DEV_ETH_ACCOUNT_SARAFU_OWNER -w $debug $token_amount + + +# Create token +#DEV_ETH_SARAFU_TOKEN_ADDRESS=`cic-bancor-token -p $ETH_PROVIDER -r $CIC_REGISTRY_ADDRESS -z $DEV_ETH_RESERVE_ADDRESS -o $DEV_ETH_ACCOUNT_SARAFU_OWNER -n $DEV_ETH_SARAFU_TOKEN_NAME -s $DEV_ETH_SARAFU_TOKEN_SYMBOL -d $DEV_ETH_SARAFU_TOKEN_DECIMALS -i $CIC_CHAIN_SPEC $debug $token_amount` +DEV_ETH_SARAFU_TOKEN_ADDRESS=$DEV_ETH_RESERVE_ADDRESS +echo DEV_ETH_SARAFU_TOKEN_ADDRESS=$DEV_ETH_SARAFU_TOKEN_ADDRESS +export DEV_ETH_SARAFU_TOKEN_ADDRESS=$DEV_ETH_SARAFU_TOKEN_ADDRESS + + +# Transfer tokens to gifter address +>&2 python transfer.py -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER --token-address $DEV_ETH_SARAFU_TOKEN_ADDRESS --abi-dir $abi_dir -w $debug $DEV_ETH_ACCOUNT_SARAFU_GIFTER ${token_amount:0:-1} + +# Deploy transfer approval contract +CIC_APPROVAL_ESCROW_ADDRESS=`erc20-approval-escrow-deploy -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER --approver $DEV_ETH_ACCOUNT_APPROVAL_ESCROW_OWNER -w $debug` +echo CIC_APPROVAL_ESCROW_ADDRESS=$CIC_APPROVAL_ESCROW_ADDRESS +export CIC_APPROVAL_ESCROW_ADDRESS=$CIC_APPROVAL_ESCROW_ADDRESS + +# Register transfer approval contract +>&2 cic-registry-set -y $keystore_file -r $CIC_REGISTRY_ADDRESS -k TransferApproval -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w $debug $CIC_APPROVAL_ESCROW_ADDRESS + +# Deploy one-time token faucet for newly created token +DEV_ETH_SARAFU_FAUCET_ADDRESS=`erc20-single-shot-faucet-deploy -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER --token-address $DEV_ETH_SARAFU_TOKEN_ADDRESS --editor $DEV_ETH_ACCOUNT_SINGLE_SHOT_FAUCET_OWNER --set-amount 1048576 -w $debug` +echo DEV_ETH_SARAFU_FAUCET_ADDRESS=$DEV_ETH_SARAFU_FAUCET_ADDRESS +export DEV_ETH_SARAFU_FAUCET_ADDRESS=$DEV_ETH_SARAFU_FAUCET_ADDRESS + +# Transfer tokens to faucet contract +>&2 python transfer.py -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER --token-address $DEV_ETH_SARAFU_TOKEN_ADDRESS --abi-dir $abi_dir -w $debug $DEV_ETH_SARAFU_FAUCET_ADDRESS ${token_amount:0:-1} + +# Registry faucet entry +>&2 cic-registry-set -y $keystore_file -r $CIC_REGISTRY_ADDRESS -k Faucet -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w $debug $DEV_ETH_SARAFU_FAUCET_ADDRESS + +# Deploy token endorser registry +#DEV_ETH_TOKEN_ENDORSER_ADDRESS=`eth-token-endorser-deploy -p $ETH_PROVIDER -o $DEV_ETH_ACCOUNT_SARAFU_OWNER $debug` +#echo DEV_ETH_TOKEN_ENDORSER_ADDRESS=$DEV_ETH_TOKEN_ENDORSER_ADDRESS +#export DEV_ETH_TOKEN_ENDORSER_ADDRESS=$DEV_ETH_TOKEN_ENDORSER_ADDRESS +#ENDORSEMENT_MSG=`echo -n 'very cool token' | sha256sum | awk '{print $1;}'` +#>&2 eth-token-endorser-add -p $ETH_PROVIDER -a $DEV_ETH_TOKEN_ENDORSER_ADDRESS -t $DEV_ETH_SARAFU_TOKEN_ADDRESS -o $DEV_ETH_ACCOUNT_SARAFU_OWNER $debug $ENDORSEMENT_MSG +CIC_TOKEN_INDEX_ADDRESS=`eth-token-index-deploy -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w $debug` +echo CIC_TOKEN_INDEX_ADDRESS=$CIC_TOKEN_INDEX_ADDRESS +export CIC_TOKEN_INDEX_ADDRESS=$CIC_TOKEN_INDEX_ADDRESS +>&2 eth-token-index-add -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -r $CIC_TOKEN_INDEX_ADDRESS -w $debug $DEV_ETH_SARAFU_TOKEN_ADDRESS + +# Register token registry +>&2 cic-registry-set -y $keystore_file -r $CIC_REGISTRY_ADDRESS -k TokenRegistry -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER $CIC_TOKEN_INDEX_ADDRESS + +# Deploy address declarator registry +declarator_description=0x546869732069732074686520434943206e6574776f726b000000000000000000 +CIC_DECLARATOR_ADDRESS=`eth-address-declarator-deploy -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w $debug $declarator_description` +echo CIC_DECLARATOR_ADDRESS=$CIC_DECLARATOR_ADDRESS +export CIC_DECLARATOR_ADDRESS=$CIC_DECLARATOR_ADDRESS +token_description_one=`sha256sum sarafu_declaration.json | awk '{ print $1; }'` +token_description_two=0x54686973206973207468652053617261667520746f6b656e0000000000000000 +>&2 eth-address-declarator-add -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -r $CIC_DECLARATOR_ADDRESS -w $debug $DEV_ETH_SARAFU_TOKEN_ADDRESS $token_description_one +>&2 eth-address-declarator-add -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -r $CIC_DECLARATOR_ADDRESS -w $debug $DEV_ETH_SARAFU_TOKEN_ADDRESS $token_description_two + + +# Register address declarator +>&2 cic-registry-set -y $keystore_file -r $CIC_REGISTRY_ADDRESS -k AddressDeclarator -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER $CIC_DECLARATOR_ADDRESS + +# We're done with the registry at this point, seal it off +>&2 cic-registry-seal -y $keystore_file -i $CIC_CHAIN_SPEC -r $CIC_REGISTRY_ADDRESS -p $ETH_PROVIDER + + +# Add accounts index writer with key from keystore +>&2 eth-accounts-index-add -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -r $CIC_ACCOUNTS_INDEX_ADDRESS --writer $DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER -w $debug + +set +a +set +e diff --git a/apps/contract-migration/dev/tests/create.py b/apps/contract-migration/dev/tests/create.py new file mode 100644 index 0000000..7b5f020 --- /dev/null +++ b/apps/contract-migration/dev/tests/create.py @@ -0,0 +1,31 @@ +#!python3 + +# Author: Louis Holbrook 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 +# SPDX-License-Identifier: GPL-3.0-or-later +# File-version: 1 +# Description: Smoke test for cic-eth create account api + +# standard imports +import os +import logging + +# third-party imports +import celery +import confini + +# platform imports +from cic_eth import Api + +script_dir = os.path.dirname(__file__) + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +config_dir = os.environ.get('CONFINI_DIR', '/usr/local/etc/cic/') + +config = confini.Config(config_dir) +config.process() + +a = Api() +t = a.create_account() +logg.debug('create account task uuid {}'.format(t)) diff --git a/apps/contract-migration/dev/transfer.py b/apps/contract-migration/dev/transfer.py new file mode 100644 index 0000000..c8ef8fd --- /dev/null +++ b/apps/contract-migration/dev/transfer.py @@ -0,0 +1,105 @@ +#!python3 + +"""Token transfer script + +.. moduleauthor:: Louis Holbrook +.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 + +""" + +# SPDX-License-Identifier: GPL-3.0-or-later + +# standard imports +import os +import json +import argparse +import logging + +# third-party imports +import web3 +from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer +from crypto_dev_signer.keystore import DictKeystore +from crypto_dev_signer.eth.helper import EthTxExecutor + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger() + +logging.getLogger('web3').setLevel(logging.WARNING) +logging.getLogger('urllib3').setLevel(logging.WARNING) + +default_abi_dir = '/usr/share/local/cic/solidity/abi' +argparser = argparse.ArgumentParser() +argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)') +argparser.add_argument('-w', action='store_true', help='Wait for the last transaction to be confirmed') +argparser.add_argument('-ww', action='store_true', help='Wait for every transaction to be confirmed') +argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='Ethereum:1', help='Chain specification string') +argparser.add_argument('--token-address', required='True', dest='t', type=str, help='Token address') +argparser.add_argument('-a', '--sender-address', dest='s', type=str, help='Sender account address') +argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing') +argparser.add_argument('--abi-dir', dest='abi_dir', type=str, default=default_abi_dir, help='Directory containing bytecode and abi (default {})'.format(default_abi_dir)) +argparser.add_argument('-v', action='store_true', help='Be verbose') +argparser.add_argument('-vv', action='store_true', help='Be more verbose') +argparser.add_argument('recipient', type=str, help='Recipient account address') +argparser.add_argument('amount', type=int, help='Amount of tokens to mint and gift') +args = argparser.parse_args() + + +if args.vv: + logg.setLevel(logging.DEBUG) +elif args.v: + logg.setLevel(logging.INFO) + +block_last = args.w +block_all = args.ww + +w3 = web3.Web3(web3.Web3.HTTPProvider(args.p)) + +signer_address = None +keystore = DictKeystore() +if args.y != None: + logg.debug('loading keystore file {}'.format(args.y)) + signer_address = keystore.import_keystore_file(args.y) + logg.debug('now have key for signer address {}'.format(signer_address)) +signer = EIP155Signer(keystore) + +chain_pair = args.i.split(':') +chain_id = int(chain_pair[1]) + +helper = EthTxExecutor( + w3, + signer_address, + signer, + chain_id, + block=args.ww, + ) + + +def main(): + # TODO: Add pure ERC20 abi to collection + f = open(os.path.join(args.abi_dir, 'ERC20.json'), 'r') + abi = json.load(f) + f.close() + + c = w3.eth.contract(abi=abi, address=args.t) + + recipient = args.recipient + value = args.amount + + logg.debug('sender {} balance before: {}'.format(signer_address, c.functions.balanceOf(signer_address).call())) + logg.debug('recipient {} balance before: {}'.format(recipient, c.functions.balanceOf(recipient).call())) + (tx_hash, rcpt) = helper.sign_and_send( + [ + c.functions.transfer(recipient, value).buildTransaction, + ], + ) + logg.debug('sender {} balance after: {}'.format(signer_address, c.functions.balanceOf(signer_address).call())) + logg.debug('recipient {} balance after: {}'.format(recipient, c.functions.balanceOf(recipient).call())) + + if block_last: + helper.wait_for() + + print(tx_hash) + + +if __name__ == '__main__': + main() diff --git a/apps/contract-migration/doc/cluster.dot b/apps/contract-migration/doc/cluster.dot new file mode 100644 index 0000000..6301fbc --- /dev/null +++ b/apps/contract-migration/doc/cluster.dot @@ -0,0 +1,110 @@ +digraph { + overlap="false"; + blockchain [ label="bloxberg", shape="doublecircle" ]; + db [ label="postgres", shape="cylinder" ]; + kv [ label="redis", shape="cylinder" ]; + + subgraph client { + cic_staff_gui [ label="cic-staff-gui", shape="box" ]; + AT [ shape="box" ]; + } + + subgraph cic_eth { + { + cic_eth_mq [ label="celery cic-eth queue", shape="ellipse" ]; + + cic_eth_server [ label="cic-eth-server", shape="box" ]; + cic_eth_tasker [ label="cic-eth-tasker", shape="box" ]; + cic_eth_manager_head [ label="cic-eth-manager-head", shape="box" ]; + cic_eth_manager_history [ label="cic-eth-manager-history", shape="box" ]; + cic_eth_dispatcher [ label="cic-eth-dispatcher", shape="box" ]; + cic_eth_retrier [ label="cic-eth-retrier", shape="box" ]; + + cic_eth_server_api_transferrequest [ label="/transferrequest", shape="ellipse" ]; + + cic_eth_celery_api_transfer [ label="transfer", shape="ellipse" ]; + cic_eth_celery_api_convert [ label="convert", shape="ellipse" ]; + cic_eth_celery_api_createaccount [ label="createaccount", shape="ellipse" ]; + cic_eth_celery_api_balance [ label="balance", shape="ellipse" ]; + } + } + + subgraph cic_ussd { + { + cic_ussd_mq [ label="celery cic-ussd queue", shape="ellipse" ]; + cic_ussd_tasker [ label="cic-ussd-tasker", shape="box" ]; + cic_ussd_server [ label="cic-ussd-server", shape="box" ]; + cic_ussd_server_api_ussd [ label="/ussd", shape="ellipse" ]; + cic_ussd_server_api_pin [ label="/pin", shape="ellipse" ]; + } + } + + subgraph files { + { + api_files [ label="/", shape="ellipse" ]; + cic_meta_server [ label="cic-meta-server", shape="box" ]; + swarm [ label="swarm", shape="box" ]; + ipfs [ label="ipfs", shape="box" ]; + } + } + + subgraph cic_notify { + cic_notify_mq [ label="celery cic-notify queue", shape="ellipse" ]; + } + + subgraph cic_cache { + { + cic_cache_tracker [ label="cic-cache-tracker", shape="box" ]; + cic_cache_server [ label="cic-cache-server", shape="box" ]; + cic_cache_server_api_tx [ label="/tx", shape="ellipse" ]; + } + } + + + kv -> cic_eth_mq; + cic_eth_mq -> kv; + + kv -> cic_ussd_mq; + cic_ussd_mq -> kv; + + cic_staff_gui -> cic_eth_server_api_transferrequest -> cic_eth_server -> cic_eth_mq; + + cic_eth_mq -> cic_eth_tasker -> db; + + db -> cic_eth_dispatcher -> blockchain; + db -> cic_eth_retrier -> blockchain; + + blockchain -> cic_eth_manager_head -> db; + cic_eth_manager_head -> cic_eth_mq; + cic_eth_manager_head -> cic_ussd_mq; + + blockchain -> cic_eth_manager_history -> db; + cic_eth_manager_history -> cic_eth_mq; + cic_eth_manager_history -> cic_ussd_mq; + + cic_ussd_server -> cic_eth_celery_api_transfer -> cic_eth_mq; + cic_ussd_server -> cic_eth_celery_api_balance -> cic_eth_mq; + cic_ussd_server -> cic_eth_celery_api_convert -> cic_eth_mq; + cic_ussd_server -> cic_eth_celery_api_createaccount -> cic_eth_mq; + cic_ussd_server -> db; + cic_ussd_server -> kv; + cic_ussd_server -> api_files; + cic_ussd_tasker -> db; + + cic_ussd_mq -> cic_ussd_tasker -> cic_notify_mq; + + cic_staff_gui -> cic_ussd_server_api_pin -> cic_ussd_server; + AT -> cic_ussd_server_api_ussd -> cic_ussd_server; + +// comment + blockchain -> cic_cache_tracker -> db; + cic_staff_gui -> cic_cache_server_api_tx -> cic_cache_server -> db; + + cic_ussd_tasker -> cic_notify_mq; + + cic_staff_gui -> api_files; + api_files -> swarm; + api_files -> ipfs; + api_files -> cic_meta_server -> db; + +} diff --git a/apps/contract-migration/keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c b/apps/contract-migration/keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c new file mode 100644 index 0000000..2b843ec --- /dev/null +++ b/apps/contract-migration/keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c @@ -0,0 +1 @@ +{"address":"eb3907ecad74a0013c259d5874ae7f22dcbcc95c","crypto":{"cipher":"aes-128-ctr","ciphertext":"b0f70a8af4071faff2267374e2423cbc7a71012096fd2215866d8de7445cc215","cipherparams":{"iv":"9ac89383a7793226446dcb7e1b45cdf3"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"299f7b5df1d08a0a7b7f9c9eb44fe4798683b78da3513fcf9603fd913ab3336f"},"mac":"6f4ed36c11345a9a48353cd2f93f1f92958c96df15f3112a192bc994250e8d03"},"id":"61a9dd88-24a9-495c-9a51-152bd1bfaa5b","version":3} \ No newline at end of file diff --git a/apps/contract-migration/reset.sh b/apps/contract-migration/reset.sh new file mode 100644 index 0000000..4ccbfcc --- /dev/null +++ b/apps/contract-migration/reset.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +keystore_file=$(realpath ./keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c) + +echo "environment:" +printenv +echo \n + +# This is a grassroots team convention for building the Bancor contracts using the bancor protocol repository truffle setup +# Running this in docker-internal dev container (built from Docker folder in this repo) will write a +# source-able env file to CIC_DATA_DIR. Services dependent on these contracts can mount this file OR +# define these parameters at runtime +# pushd /usr/src + +#!/bin/sh + +# Abort on any error (including if wait-for-it fails). +set -e + +# Wait for the backend to be up, if we know where it is. +if [[ -n "${ETH_PROVIDER}" ]]; then + echo "waiting for ${ETH_PROVIDER}..." + ./wait-for-it.sh "${ETH_PROVIDER_HOST}:${ETH_PROVIDER_PORT}" + + #DEV_ETH_RESERVE_ADDRESS=`giftable-token-deploy -p $ETH_PROVIDER -o $DEV_ETH_ACCOUNT_RESERVE_OWNER -m $DEV_ETH_ACCOUNT_RESERVE_MINTER $DEV_ETH_RESERVE_AMOUNT` + DEV_ETH_RESERVE_ADDRESS=`giftable-token-deploy -p $ETH_PROVIDER -y $keystore_file -i $CIC_CHAIN_SPEC --minter $DEV_ETH_ACCOUNT_RESERVE_MINTER -v -w --name "Sarafu" --symbol "SRF" $DEV_ETH_RESERVE_AMOUNT` + + #BANCOR_REGISTRY_ADDRESS=`cic-bancor-deploy --bancor-dir /usr/local/share/cic/bancor -z $DEV_ETH_RESERVE_ADDRESS -p $ETH_PROVIDER -o $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER` + + CIC_ACCOUNTS_INDEX_ADDRESS=`eth-accounts-index-deploy -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -y $keystore_file --writer $DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER -vv -w` + + CIC_REGISTRY_ADDRESS=`cic-registry-deploy -i $CIC_CHAIN_SPEC -y $keystore_file -k CICRegistry -k BancorRegistry -k AccountRegistry -k TokenRegistry -k AddressDeclarator -k Faucet -k TransferApproval -p $ETH_PROVIDER -vv -w` + cic-registry-set -y $keystore_file -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -k CICRegistry -p $ETH_PROVIDER $CIC_REGISTRY_ADDRESS -vv + #cic-registry-set -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -k BancorRegistry -p $ETH_PROVIDER $BANCOR_REGISTRY_ADDRESS -vv + cic-registry-set -y $keystore_file -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -k AccountRegistry -p $ETH_PROVIDER $CIC_ACCOUNTS_INDEX_ADDRESS -vv +else + echo "\$ETH_PROVIDER not set!" + exit 1 +fi + +mkdir -p $CIC_DATA_DIR + +# this is consumed in downstream services to set environment variables +cat << EOF > $CIC_DATA_DIR/.env +export DEV_ETH_RESERVE_ADDRESS=$DEV_ETH_RESERVE_ADDRESS +export DEV_ETH_RESERVE_AMOUNT=$DEV_ETH_RESERVE_AMOUNT +export DEV_ETH_ACCOUNTS_INDEX_ADDRESS=$DEV_ETH_ACCOUNTS_INDEX_ADDRESS +export BANCOR_REGISTRY_ADDRESS=$BANCOR_REGISTRY_ADDRESS +export CIC_REGISTRY_ADDRESS=$CIC_REGISTRY_ADDRESS + +EOF + +# popd + +exec "$@" diff --git a/apps/contract-migration/testdata/pgp/alice.priv.asc b/apps/contract-migration/testdata/pgp/alice.priv.asc new file mode 100644 index 0000000..eeb212b --- /dev/null +++ b/apps/contract-migration/testdata/pgp/alice.priv.asc @@ -0,0 +1,83 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +=zMNq +-----END PGP PRIVATE KEY BLOCK----- diff --git a/apps/contract-migration/testdata/pgp/alice.pub.asc b/apps/contract-migration/testdata/pgp/alice.pub.asc new file mode 100644 index 0000000..f237925 --- /dev/null +++ b/apps/contract-migration/testdata/pgp/alice.pub.asc @@ -0,0 +1,41 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +xgjhMwawpFV3APdc0dOIvUdZAFQ= +=BKz+ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/apps/contract-migration/testdata/pgp/bob.priv.asc b/apps/contract-migration/testdata/pgp/bob.priv.asc new file mode 100644 index 0000000..e440ba1 --- /dev/null +++ b/apps/contract-migration/testdata/pgp/bob.priv.asc @@ -0,0 +1,83 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +=qmcx +-----END PGP PRIVATE KEY BLOCK----- diff --git a/apps/contract-migration/testdata/pgp/bob.pub.asc b/apps/contract-migration/testdata/pgp/bob.pub.asc new file mode 100644 index 0000000..8c0744c --- /dev/null +++ b/apps/contract-migration/testdata/pgp/bob.pub.asc @@ -0,0 +1,41 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +n0OSM7kpK5v6VPdtByaN6w== +=EmWr +-----END PGP PUBLIC KEY BLOCK----- diff --git a/apps/contract-migration/testdata/pgp/ge.priv.asc b/apps/contract-migration/testdata/pgp/ge.priv.asc new file mode 100644 index 0000000..d46d40d --- /dev/null +++ b/apps/contract-migration/testdata/pgp/ge.priv.asc @@ -0,0 +1,83 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +=B12U +-----END PGP PRIVATE KEY BLOCK----- diff --git a/apps/contract-migration/testdata/pgp/ge.pub.asc b/apps/contract-migration/testdata/pgp/ge.pub.asc new file mode 100644 index 0000000..72782a1 --- /dev/null +++ b/apps/contract-migration/testdata/pgp/ge.pub.asc @@ -0,0 +1,41 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +32d1dwRCBUARSk9jwmwsycaIC9eupit1mLY= +=vg+T +-----END PGP PUBLIC KEY BLOCK----- diff --git a/apps/contract-migration/testdata/pgp/publickeys.asc b/apps/contract-migration/testdata/pgp/publickeys.asc new file mode 100644 index 0000000..b30ad7f --- /dev/null +++ b/apps/contract-migration/testdata/pgp/publickeys.asc @@ -0,0 +1,114 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +7qTmw0n71OJB0zWJVnQd8yPzx5ARKgWKQ+IVfzIqBezm2EVHqtO9+du7slEJD0xk +Du/O9JkCZt4nwB5Nz2uKxzqG7Th84QolJ7OYDbZlfMfCPj2j4jGhBjULtcYWC3XF +lL+6gIQwtfIEkSjSG1JPt9Zjeh8urPzJvkQZ68VDjAXDgFxZBLHGat42cAHJHgRF +OGlbDl1mVgglRKrszCqQF48cFtS+7AKquIR8jROXP9ZySJZ8qCxQ5xDv1y7Ql/K2 +eZJKyVCoW/7MrJsyzGLtuBrSPTek9R/ir8qyqvPNMW/Oit9i47lRXfPxNuc4yWkw +3o+O3I6Y5iEWoGVUwgrGV4hEaaIYJpnIhMuzcZ5MExRiZwp7oHHPJEBUzXWAA6/l +I1K5w2V1x7ppTQDBMgI6p4abhbFn/z2h+SMxABEBAAG0HEFsaWNlIENyeXB0IDxh +bGljZUBhY21lLm9yZz6JAdQEEwEIAD4WIQSyyqioEFbhGRV+rnhK64QdamhpJwUC +X8DRGQIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRBK64Qdamhp +J3DyDACqCHGZpbWaRtcC9A7REd8qNBvcVZsvd8kUcEqSv0dCXTEnfSIE99+qoenA +rMdNowrLUfQc+XKBjmWLc69u2C3Hhhw5bEu0QIojIkLKttgPWjeIpezyIILnYNud +SPhTJBklH2LwaXIBUicYI7DLu9S+uZeXU+AHxchyedDfuopRs3qNOGRfqVjZlzp+ +BvDN8X3i/uO3mLgdTi+Cd7rbyrI354PGdMI7Y+uO23bDKolhoJqJ0oSvqSdiPOEW +z8LKDUeRzqmiaX1DQSd06Fcjnp52hbpvzYBOshh9WPDQXoyNRTGJGcAtJwZFGr6u +uuxZEAyGmucicDU7ojKDJEetk8fYqt47jQ31a2xvxQWTwkthPjFwhbsrgiEmd/dn +1Wn9DcdbFyFhK/aZqTclBx7NEQ4RDilWaTibMpl5HzZ3BxeTSMpvAXzfkv7JR186 +gcaN4v3S1rlQPDZEZ3rsJKntaPCJlP+DXEDMg8lGesb7oD6oY6TGokUoxpY7uoem +A0Qfm8O5AY0EX8DRGQEMAN7P3NQSOQsG6xxbNpYGh2l62bMqhL61yy3HjLPJK59e +kMaO2NcV1fyPb+wFHK0HWIsbQ7Ouf6bXYMBVSSELjDCkCuBHpGiuHZg1329aev/d +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 +wmwsycaIC9eupit1mLY= +=1aEW +-----END PGP PUBLIC KEY BLOCK----- diff --git a/apps/contract-migration/testdata/ssl/client.crt b/apps/contract-migration/testdata/ssl/client.crt new file mode 100644 index 0000000..d7a77bf --- /dev/null +++ b/apps/contract-migration/testdata/ssl/client.crt @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE4DCCAsgCAQMwDQYJKoZIhvcNAQELBQAwgaExCzAJBgNVBAYTAktZMQ8wDQYD +VQQIDAZLaWxpZmkxEDAOBgNVBAcMB01uYXJhbmkxHTAbBgNVBAoMFEdyYXNzcm9v +dHMgRWNvbm9taWNzMQswCQYDVQQLDAJIUTEgMB4GA1UEAwwXZ3Jhc3Nyb290c2Vj +b25vbWljcy5vcmcxITAfBgkqhkiG9w0BCQEWEndpbGxAZ3Jhc3NlY29uLm9yZzAe +Fw0yMDAzMjgwMDE3MzRaFw0yMjEyMjQwMDE3MzRaMIHJMQswCQYDVQQGEwJNTjEU +MBIGA1UECgwLVGhlIE1vbmdvbHMxGzAZBgNVBAMMEnd3dy51bGFhbmJhYXRhci5t +bjEVMBMGA1UEKQwMS2h1YmxhaSBLaGFuMR8wHQYJKoZIhvcNAQkBFhBmb29Ac2Vj +aG9zdC5pbmZvMRAwDgYDVQQqDAdLaHVibGFpMQ0wCwYDVQQEDARLaGFuMRQwEgYD +VQQHDAtVbGFhbmJhYXRhcjEYMBYGA1UECAwPVGhlIFdob2xlIFdvcmxkMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtT1IP3Ls0ha5cX5RiMnyjPzjGjvS +GrWhDU579+qQ4T4k9ONq8fxNv95ZdxkccUyXZVR24pq+ALxmV65soCAGNJHb00lE +XWY3mQ9Jd10pC8UQPqfQ4Ez/J0Q+oIwpTdUCQStIe8QHz6sh8AVmPrTKWphjD5Up +PuWjFz4qs6h46hzNDoc90HPr4rqnxzBIo4Phs4a8/46FWvphufybKgorz+B5uWeB +Uzi3fOOKNAk8UmZK8fWB8DMIm8NFcOZV7METJmMBH1v5sY6zQWNBOHJmin02VkCW +rie16Ll+vfWp1jQEh442qgBFk0NiZBoGWJamYa7RmwH5d4LPGLiDUVgsnwIDAQAB +MA0GCSqGSIb3DQEBCwUAA4ICAQBy0DIHBXVDPy4dTrmjcr78ytxy26p+8kjlzTQF +w9a9F+CPsRNV4KAmXJKUlyBTPiVocVhhSmj2Mz9OtI9FFWkSleKzxUtWlDEjIwGj +PRqWKhj/Y8LJsgdcUGCBtraBMCD5D1xyNx3n+zwhNp+HNB4ThVlV0iGCoOOq7XZu +4QHwkuy0ILcXt3NU6tWNXXsP544BxsCFHgyu+Ks+JkJzSFzGe+ybEMblXyHJZtOC +uyCLQN2Uo44Mtdo728p00mRGSFlouFfQWMu/7lQPNYouQ7XiLXy+mNeNN0CYUjpg +a7wfPExMljJEkgYyWT4JMuTB5RTsjQqw41aGtfy021L7yCZnVR2GG3pmeRQtqe4r ++V+WHV3YOkW5vObd5RE3ykntFkbrZNodBzxp6qKF4qsfqQH6WJFVXh0b36VmOdSa +qWxidz+SeCI379nemy93bcusQxRDXc+j5hbpW2pTtz2uxN5Y86DWEdSjpmiu6ExT +eBUyoK/5Zes/oZ3R9vj0V9jhpGN1/FahkXfkjZcuwXXFXuwk8rODU9DKGOEqFPKI +P/MZSVkfNvkBhiNozBXx1X/vJ2QoQKqE9zPfXlmvZkLiUaMjqd+h3qRe0vqXlQU+ +ZH8NrKTi5xS/2VGtz4ksGlQp7GMZ0XFWL23BGhUfQVRLKMPCqta+GTuJUo3r5HVL +YiI4dw== +-----END CERTIFICATE----- diff --git a/apps/contract-migration/testdata/ssl/client.key b/apps/contract-migration/testdata/ssl/client.key new file mode 100644 index 0000000..43ca172 --- /dev/null +++ b/apps/contract-migration/testdata/ssl/client.key @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,A748148F1C16F6129F04A346A324170A + +k5K2EMTBDsaa9LqsnWnDV2Ocd14fZ6lXsNBoPZR1axrOV+zNZtDDIQwFP0FHmTN6 +KrxDuDvPjkhoebMiLkRyWc6d4fslWQnr3vASi8gONYGT3pXKbuPNEMSXJeRfxvzC +CAcSh9rItcVxKv7m8+vuUWUy8m6TGBLRpDwiYf/9KTjGaPO2fnDBLHPlBuHVEmQW +xa0MOknleWnMucGMAtNdsiOVULgyljnoexgbES0VAosegnCKaRA5mRt47V0XUFDl +cFxXsHlZ4Wo4R9BowkWhpxX+IBVBmr1Rbmhkl8Z/k3SWfmAd2PNqHckl4oZsG0NN +kfi/x5RvMFXGwfW0q5XK/4oK1KbxV7UTn/lozkyvixSWDrN+2jETNCJyL//oXUcS +ZTr1+qic92fAAonx1JkX1QwQlNTb0ogmgpJzvAKqGqlNpSL3D0xySNTsSM0fEeZV +1qEnWTp1WpoyxG1CeiV0MDN9wkh9aV+KYm0FFo8PEqG6L1jsVNJKMtySeCXmWETK +S6iUBwiNf8atQwERfWx0wqSwHtJs9+zqUasskqYWJcO9T3TGqdc8UBaeVGAGdWFF +soGsBqrVyU8TEAuK6UReJyFQtHqXbm7kFIJ8J6fgc/QG4Dhy4laBKpR5Lg1W3fCa +g+o4OvkWr0Mvu0/y528qL0cqb3JoxvAtsZ8cHiiy1g3AiSr9ehlvtVboyg1ViP5d +cZZyU0NaeEUYOIULeBap4LNUBPQUSN5lw15C7N/reI8uuTNp8u8/6ITXKH3tknJr +n6Jhd6uFuYNImRhHgQ5rKgai5+Nhc6RqdO5K05fVMt8wIng5RkShQzQEZtaynWyg +3VbmJrKXjYesMxYFuKYP4efEVH/9tUeHiqlgVBF2N2Ntd4vKYied3mllthAo8BVC +0S0A+cZ2K65MKSoh/FHxxqfXo3AF6dL58DC+9jnzhKNgErVSTti0/Ps6pxrloNuN +ILUVeUQNhVlZu7KpJHININCnicohj8wAJDVZo7bb3iZfRGDIAFfgKuEALk+CRd0H +D6PukualFGd9w+KDLmUVdpkUTq9+UaZcJMXqGAN1ihIz44Xvk4QgFRN+9Szz4HbL +j5rTNqRmXjWjPahk90D/cOQuuE81GsVdiLnFzEacAlDGoGgV+Wcr/lQ06H099Hz1 +v9hSwXoI+EbeQTjoqenQV62V7wuOiAKg3SpekGsYAsuuPElCBwYGTzWvotf9BBFe +LxhfVTCXD1cOQo3pgC8nHBwQSJ6TEXMrR52lgIkOZq/EPhPAYyO5A6ab2tKD1Zah +7qlkDDov7f4eTJrXfPnOu/tl3voN+VOxVbxFqsJuMPRCDc/DI18mOi+4yeUFK22W +pOCa+Etv7tGa3KlOuU/VWQfGTsICC8ejCIBgwmcbJ5HndEtzrPQv0ESziIcy/ybr +zkmlKJ7n7MZLNx/if5Ly9rxg+Y1al5JkOWpIqGKIhP075M2H9Kcg08TqHY6YoG5w +eJuudcyosGggxo/oTCCPrHNnPSvaauaZRynF02AQ1hle83V7T1Sy0jbtoGRXM7Hq +7AyQDLAcCregAkUuCMF/pktcJLQ2rY738RzNyaR3OiaTgKjko553QkciLP28qwZh +-----END RSA PRIVATE KEY----- diff --git a/apps/contract-migration/testdata/ssl/ge.crt b/apps/contract-migration/testdata/ssl/ge.crt new file mode 100644 index 0000000..3bd23e1 --- /dev/null +++ b/apps/contract-migration/testdata/ssl/ge.crt @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- diff --git a/apps/contract-migration/wait-for-it.sh b/apps/contract-migration/wait-for-it.sh new file mode 100644 index 0000000..3974640 --- /dev/null +++ b/apps/contract-migration/wait-for-it.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env bash +# Use this script to test if a given TCP host/port are available + +WAITFORIT_cmdname=${0##*/} + +echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } + +usage() +{ + cat << USAGE >&2 +Usage: + $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args] + -h HOST | --host=HOST Host or IP under test + -p PORT | --port=PORT TCP port under test + Alternatively, you specify the host and port as host:port + -s | --strict Only execute subcommand if the test succeeds + -q | --quiet Don't output any status messages + -t TIMEOUT | --timeout=TIMEOUT + Timeout in seconds, zero for no timeout + -- COMMAND ARGS Execute command with args after the test finishes +USAGE + exit 1 +} + +wait_for() +{ + if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then + echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" + else + echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout" + fi + WAITFORIT_start_ts=$(date +%s) + while : + do + if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then + nc -z $WAITFORIT_HOST $WAITFORIT_PORT + WAITFORIT_result=$? + else + (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 + WAITFORIT_result=$? + fi + if [[ $WAITFORIT_result -eq 0 ]]; then + WAITFORIT_end_ts=$(date +%s) + echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds" + break + fi + sleep 1 + done + return $WAITFORIT_result +} + +wait_for_wrapper() +{ + # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 + if [[ $WAITFORIT_QUIET -eq 1 ]]; then + timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & + else + timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & + fi + WAITFORIT_PID=$! + trap "kill -INT -$WAITFORIT_PID" INT + wait $WAITFORIT_PID + WAITFORIT_RESULT=$? + if [[ $WAITFORIT_RESULT -ne 0 ]]; then + echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" + fi + return $WAITFORIT_RESULT +} + +# process arguments +while [[ $# -gt 0 ]] +do + case "$1" in + *:* ) + WAITFORIT_hostport=(${1//:/ }) + WAITFORIT_HOST=${WAITFORIT_hostport[0]} + WAITFORIT_PORT=${WAITFORIT_hostport[1]} + shift 1 + ;; + --child) + WAITFORIT_CHILD=1 + shift 1 + ;; + -q | --quiet) + WAITFORIT_QUIET=1 + shift 1 + ;; + -s | --strict) + WAITFORIT_STRICT=1 + shift 1 + ;; + -h) + WAITFORIT_HOST="$2" + if [[ $WAITFORIT_HOST == "" ]]; then break; fi + shift 2 + ;; + --host=*) + WAITFORIT_HOST="${1#*=}" + shift 1 + ;; + -p) + WAITFORIT_PORT="$2" + if [[ $WAITFORIT_PORT == "" ]]; then break; fi + shift 2 + ;; + --port=*) + WAITFORIT_PORT="${1#*=}" + shift 1 + ;; + -t) + WAITFORIT_TIMEOUT="$2" + if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi + shift 2 + ;; + --timeout=*) + WAITFORIT_TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + WAITFORIT_CLI=("$@") + break + ;; + --help) + usage + ;; + *) + echoerr "Unknown argument: $1" + usage + ;; + esac +done + +if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then + echoerr "Error: you need to provide a host and port to test." + usage +fi + +WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15} +WAITFORIT_STRICT=${WAITFORIT_STRICT:-0} +WAITFORIT_CHILD=${WAITFORIT_CHILD:-0} +WAITFORIT_QUIET=${WAITFORIT_QUIET:-0} + +# Check to see if timeout is from busybox? +WAITFORIT_TIMEOUT_PATH=$(type -p timeout) +WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH) + +WAITFORIT_BUSYTIMEFLAG="" +if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then + WAITFORIT_ISBUSY=1 + # Check if busybox timeout uses -t flag + # (recent Alpine versions don't support -t anymore) + if timeout &>/dev/stdout | grep -q -e '-t '; then + WAITFORIT_BUSYTIMEFLAG="-t" + fi +else + WAITFORIT_ISBUSY=0 +fi + +if [[ $WAITFORIT_CHILD -gt 0 ]]; then + wait_for + WAITFORIT_RESULT=$? + exit $WAITFORIT_RESULT +else + if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then + wait_for_wrapper + WAITFORIT_RESULT=$? + else + wait_for + WAITFORIT_RESULT=$? + fi +fi + +if [[ $WAITFORIT_CLI != "" ]]; then + if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then + echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess" + exit $WAITFORIT_RESULT + fi + exec "${WAITFORIT_CLI[@]}" +else + exit $WAITFORIT_RESULT +fi \ No newline at end of file diff --git a/ci_templates/.cic-base.yml b/ci_templates/.cic-base.yml new file mode 100644 index 0000000..8f4b7cd --- /dev/null +++ b/ci_templates/.cic-base.yml @@ -0,0 +1,22 @@ +.py-build + stage: build + image: docker:19.03.13 + variables: + # docker host + DOCKER_HOST: tcp://docker:2376 + # container, thanks to volume mount from config.toml + DOCKER_TLS_CERTDIR: "/certs" + # These are usually specified by the entrypoint, however the + # Kubernetes executor doesn't run entrypoints + # https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4125 + DOCKER_TLS_VERIFY: 1 + DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client" + services: + - docker:19.03.13-dind + before_script: + - docker info + - cd $CONTEXT + script: + - docker build -t $CI_PROJECT_PATH_SLUG:$CI_COMMIT_SHORT_SHA . + + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c9cec43 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,384 @@ +version: "3" + +volumes: + ganache-db: {} + postgres-db: {} + contract-config: {} + bee-data: {} + +networks: + default: + name: cic-network + +services: + eth: + image: trufflesuite/ganache-cli + ports: + - ${HTTP_PORT_ETH:-8545} + - ${WS_PORT_ETH:-8546} + # Note! -e switch doesnt work, whatever you put there, it will be 100 + command: "-i 8995 -e 100 -l 9000000 -m '${DEV_MNEMONIC:-\"history stumble mystery avoid embark arrive mom foil pledge keep grain dice\"}' -v --db /tmp/cic/ganache/ganache.db --noVMErrorsOnRPCResponse" + volumes: + - ganache-db:/tmp/cic/ganache + + # See contents of /initdb/create_db.sql for app user, password and databases + postgres: + image: postgres:12.5-alpine + environment: + POSTGRES_HOST_AUTH_METHOD: trust # for postgres user access w/o password. Obvioulsy not safe but allows easy elevated debugging. + PGDATA: /tmp/cic/postgres + ports: + - ${HTTP_PORT_POSTGRES:-5432} + volumes: + - ./scripts/initdb/create_db.sql:/docker-entrypoint-initdb.d/1-create_all_db.sql # init db scripts will run in order at container start + - postgres-db:/tmp/cic/postgres + + redis: + image: redis:6.0.9-alpine + ports: + - ${HTTP_PORT_REDIS:-6379} + command: "--loglevel verbose" + + bee: + image: ethersphere/bee:0.4.1 + container_name: bee + environment: + BEE_NETWORK_ID: ${BEE_NETWORK_ID:-313} + BEE_PASSWORD: $BEE_PASSWORD + ports: + - 1633 + - 1635 + command: "start --swap-enable=false --standalone" + volumes: + - bee-data:/tmp/cic/bee + + contract-migration: + build: apps/contract-migration + environment: + # ETH_PROVIDER should be broken out into host/port but cic-eth expects this + ETH_PROVIDER: http://eth:8545 + # And these two are for wait-for-it (could parse this) + ETH_PROVIDER_HOST: eth + ETH_PROVIDER_PORT: 8545 + command: ["./reset.sh"] + depends_on: + - eth + volumes: + - contract-config:/tmp/cic/config + + cic-cache-tracker: + # image: registry.gitlab.com/grassrootseconomics/cic-cache:master-latest + build: apps/cic-cache + environment: + CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS # supplied at contract-config after contract provisioning + ETH_PROVIDER: ${ETH_PROVIDER:-http://eth:8545} + BANCOR_DIR: ${BANCOR_DIR:-/usr/local/share/cic/bancor} + DATABASE_USER: ${DATABASE_USER:-grassroots} + DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala} # this is is set at initdb see: postgres/initdb/create_db.sql + DATABASE_HOST: ${DATABASE_HOST:-postgres} + DATABASE_PORT: ${DATABASE_PORT:-5432} + DATABASE_NAME: ${DATABASE_NAME_CIC_CACHE:-cic_cache} + DATABASE_ENGINE: ${DATABASE_ENGINE:-postgres} + DATABASE_DRIVER: ${DATABASE_DRIVER:-psycopg2} + ETH_ABI_DIR: ${ETH_ABI_DIR:-/usr/local/share/cic/solidity/abi} + deploy: + restart_policy: + condition: on-failure + depends_on: + - postgres + - eth + command: + - /bin/sh + - -c + - | + if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi + /usr/local/bin/cic-cache-tracker -vv + volumes: + - contract-config:/tmp/cic/config/:ro + # entrypoint: ["/usr/local/bin/cic-cache-tracker", "-vv"] + # command: "/usr/local/bin/cic-cache-tracker -vv" + +# cic-cache-server: +# image: grassrootseconomics:cic-cache-uwsgi +# environment: +# DATABASE_USER: $DATABASE_USER +# DATABASE_HOST: $DATABASE_HOST +# DATABASE_PORT: $DATABASE_PORT +# DATABASE_PASSWORD: $DATABASE_PASSWORD +# DATABASE_NAME: $DATABASE_NAME_CIC_CACHE +# PGPASSWORD: $DATABASE_PASSWORD +# SERVER_PORT: 80 +# ports: +# - ${HTTP_PORT_CIC_CACHE}:80 +# depends_on: +# - postgres +# deploy: +# restart_policy: +# condition: on-failure +# command: "/root/start_uwsgi.sh" + +# cic-eth-tasker: +# image: grassrootseconomics:cic-eth-service +# environment: +# ETH_PROVIDER: $ETH_PROVIDER +# ETH_ABI_DIR: $ETH_ABI_DIR +# ETH_GAS_PROVIDER_ADDRESS: $DEV_ETH_ACCOUNT_GAS_PROVIDER +# DATABASE_USER: $DATABASE_USER +# DATABASE_HOST: $DATABASE_HOST +# DATABASE_PASSWORD: $DATABASE_PASSWORD +# DATABASE_NAME: $DATABASE_NAME_CIC_ETH +# DATABASE_PORT: $DATABASE_PORT +# DATABASE_ENGINE: $DATABASE_ENGINE +# DATABASE_DRIVER: $DATABASE_DRIVER +# PGPASSWORD: $DATABASE_PASSWORD +# CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS +# CIC_CHAIN_SPEC: $CIC_CHAIN_SPEC +# BANCOR_DIR: $BANCOR_DIR +# CELERY_BROKER_URL: $CELERY_BROKER_URL +# CELERY_RESULT_URL: $CELERY_RESULT_URL +# SIGNER_SOCKET_PATH: $SIGNER_SOCKET_PATH +# SIGNER_SECRET: $SIGNER_SECRET +# ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER: $DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER +# depends_on: +# - eth +# - postgres +# - redis +# deploy: +# restart_policy: +# condition: on-failure +# volumes: +# - ${LOCAL_VOLUME_DIR:-/tmp/cic}/signer:/tmp/cic/signer +# command: "/root/start_tasker.sh -q cic-eth -vv" + +# cic-eth-manager-head: +# image: grassrootseconomics:cic-eth-service +# environment: +# ETH_PROVIDER: $ETH_PROVIDER +# DATABASE_USER: $DATABASE_USER +# DATABASE_HOST: $DATABASE_HOST +# DATABASE_PORT: $DATABASE_PORT +# DATABASE_PASSWORD: $DATABASE_PASSWORD +# DATABASE_NAME: $DATABASE_NAME_CIC_ETH +# DATABASE_ENGINE: $DATABASE_ENGINE +# DATABASE_DRIVER: $DATABASE_DRIVER +# CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS +# CIC_CHAIN_SPEC: $CIC_CHAIN_SPEC +# BANCOR_DIR: $BANCOR_DIR +# CELERY_BROKER_URL: $CELERY_BROKER_URL +# CELERY_RESULT_URL: $CELERY_RESULT_URL +# TASKS_TRANSFER_CALLBACKS: $TASKS_TRANSFER_CALLBACKS +# depends_on: +# - eth +# - postgres +# - redis +# deploy: +# restart_policy: +# condition: on-failure +# command: "/root/start_manager.sh head -vv" + +# cic-eth-manager-history: +# image: grassrootseconomics:cic-eth-service +# environment: +# ETH_PROVIDER: $ETH_PROVIDER +# DATABASE_USER: $DATABASE_USER +# DATABASE_HOST: $DATABASE_HOST +# DATABASE_PORT: $DATABASE_PORT +# DATABASE_PASSWORD: $DATABASE_PASSWORD +# DATABASE_NAME: $DATABASE_NAME_CIC_ETH +# DATABASE_ENGINE: $DATABASE_ENGINE +# DATABASE_DRIVER: $DATABASE_DRIVER +# CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS +# CIC_CHAIN_SPEC: $CIC_CHAIN_SPEC +# BANCOR_DIR: $BANCOR_DIR +# CELERY_BROKER_URL: $CELERY_BROKER_URL +# CELERY_RESULT_URL: $CELERY_RESULT_URL +# depends_on: +# - eth +# - postgres +# - redis +# #deploy: +# #restart_policy: +# # condition: on-failure +# command: "/root/start_manager.sh history -vv" + +# cic-eth-dispatcher: +# image: grassrootseconomics:cic-eth-service +# environment: +# ETH_PROVIDER: $ETH_PROVIDER +# DATABASE_USER: $DATABASE_USER +# DATABASE_HOST: $DATABASE_HOST +# DATABASE_PORT: $DATABASE_PORT +# DATABASE_PASSWORD: $DATABASE_PASSWORD +# DATABASE_NAME: $DATABASE_NAME_CIC_ETH +# DATABASE_ENGINE: $DATABASE_ENGINE +# DATABASE_DRIVER: $DATABASE_DRIVER +# CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS +# CIC_CHAIN_SPEC: $CIC_CHAIN_SPEC +# BANCOR_DIR: $BANCOR_DIR +# CELERY_BROKER_URL: $CELERY_BROKER_URL +# CELERY_RESULT_URL: $CELERY_RESULT_URL +# depends_on: +# - eth +# - postgres +# - redis +# deploy: +# restart_policy: +# condition: on-failure +# command: "/root/start_dispatcher.sh -q cic-eth -vv" + + +# cic-eth-retrier: +# image: grassrootseconomics:cic-eth-service +# environment: +# ETH_PROVIDER: $ETH_PROVIDER +# DATABASE_USER: $DATABASE_USER +# DATABASE_HOST: $DATABASE_HOST +# DATABASE_PORT: $DATABASE_PORT +# DATABASE_PASSWORD: $DATABASE_PASSWORD +# DATABASE_NAME: $DATABASE_NAME_CIC_ETH +# DATABASE_ENGINE: $DATABASE_ENGINE +# DATABASE_DRIVER: $DATABASE_DRIVER +# CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS +# CIC_CHAIN_SPEC: $CIC_CHAIN_SPEC +# BANCOR_DIR: $BANCOR_DIR +# CELERY_BROKER_URL: $CELERY_BROKER_URL +# CELERY_RESULT_URL: $CELERY_RESULT_URL +# depends_on: +# - eth +# - postgres +# - redis +# deploy: +# restart_policy: +# condition: on-failure +# command: "/root/start_retry.sh -q cic-eth -vv" + + +# cic-eth-server: +# image: grassrootseconomics:cic-eth-service +# environment: +# # ETH_PROVIDER: $ETH_PROVIDER +# # DATABASE_USER: $DATABASE_USER +# # DATABASE_HOST: $DATABASE_HOST +# # DATABASE_PORT: $DATABASE_PORT +# # DATABASE_PASSWORD: $DATABASE_PASSWORD +# # DATABASE_NAME: $DATABASE_NAME_CIC_ETH +# # DATABASE_ENGINE: $DATABASE_ENGINE +# # DATABASE_DRIVER: $DATABASE_DRIVER +# # CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS +# CIC_CHAIN_SPEC: $CIC_CHAIN_SPEC +# # BANCOR_DIR: $BANCOR_DIR +# CELERY_BROKER_URL: $CELERY_BROKER_URL +# CELERY_RESULT_URL: $CELERY_RESULT_URL +# SERVER_PORT: 80 +# ports: +# - ${HTTP_PORT_CIC_ETH}:80 +# depends_on: +# # - eth +# # - postgres +# - redis +# deploy: +# restart_policy: +# condition: on-failure +# #command: "/bin/bash-c uwsgi --wsgi-file /usr/src/cic-eth/cic_eth/runnable/server_agent.py --http :80 --pyargv '-vv'" +# #command: "uwsgi" +# entrypoint: +# - "/usr/local/bin/uwsgi" +# - "--wsgi-file" +# - "/usr/src/cic-eth/cic_eth/runnable/server_agent.py" +# - "--http" +# - ":80" +# command: "--pyargv -vv" + + + +# cic-notify-tasker: +# image: grassrootseconomics:cic-notify-service +# environment: +# DATABASE_USER: $DATABASE_USER +# DATABASE_HOST: $DATABASE_HOST +# DATABASE_PORT: $DATABASE_PORT +# DATABASE_PASSWORD: $DATABASE_PASSWORD +# DATABASE_NAME: $DATABASE_NAME_CIC_NOTIFY +# DATABASE_ENGINE: $DATABASE_ENGINE +# DATABASE_DRIVER: $DATABASE_DRIVER +# PGPASSWORD: $DATABASE_PASSWORD +# CELERY_BROKER_URL: $CELERY_BROKER_URL +# CELERY_RESULT_URL: $CELERY_RESULT_URL +# TASKS_AFRICASTALKING: $TASKS_AFRICASTALKING +# TASKS_SMS_DB: $TASKS_SMS_DB +# TASKS_LOG: $TASKS_LOG +# depends_on: +# - postgres +# - redis +# deploy: +# restart_policy: +# condition: on-failure +# command: "/root/start_tasker.sh -q cic-notify" + + +# cic-meta-server: +# image: grassrootseconomics:cic-meta-server +# environment: +# DATABASE_USER: $DATABASE_USER +# DATABASE_HOST: $DATABASE_HOST +# DATABASE_PORT: $DATABASE_PORT +# DATABASE_PASSWORD: $DATABASE_PASSWORD +# DATABASE_NAME: $DATABASE_NAME_CIC_META +# DATABASE_ENGINE: $DATABASE_ENGINE +# DATABASE_DRIVER: $DATABASE_DRIVER +# DATABASE_SCHEMA_SQL_PATH: $DATABASE_SCHEMA_SQL_PATH_CIC_META +# SERVER_PORT: 80 +# PGP_PASSPHRASE: $PGP_PASSPHRASE +# PGP_EXPORTS_DIR: $PGP_EXPORTS_DIR +# PGP_PRIVATEKEY_FILE: $PGP_PRIVATEKEY_FILE +# ports: +# - ${HTTP_PORT_CIC_META}:80 +# depends_on: +# - postgres +# deploy: +# restart_policy: +# condition: on-failure +# volumes: +# - ${LOCAL_VOLUME_DIR:-/tmp/cic}/pgp:/tmp/cic/pgp +# command: "/root/start_server.sh -vv" + +# cic-ussd-server: +# image: grassrootseconomics:cic-ussd +# environment: +# DATABASE_USER: $DATABASE_USER +# DATABASE_HOST: $DATABASE_HOST +# DATABASE_PORT: $DATABASE_PORT +# DATABASE_PASSWORD: $DATABASE_PASSWORD +# DATABASE_NAME: $DATABASE_NAME_CIC_USSD +# DATABASE_ENGINE: $DATABASE_ENGINE +# DATABASE_DRIVER: $DATABASE_DRIVER +# SERVER_PORT: 80 +# ports: +# - ${HTTP_PORT_CIC_USSD}:80 +# depends_on: +# - postgres +# - redis +# deploy: +# restart_policy: +# condition: on-failure +# command: "/root/start_uwsgi.sh" + +# cic-ussd-tasker: +# image: grassrootseconomics:cic-ussd +# environment: +# DATABASE_USER: $DATABASE_USER +# DATABASE_HOST: $DATABASE_HOST +# DATABASE_PORT: $DATABASE_PORT +# DATABASE_PASSWORD: $DATABASE_PASSWORD +# DATABASE_NAME: $DATABASE_NAME_CIC_USSD +# DATABASE_ENGINE: $DATABASE_ENGINE +# DATABASE_DRIVER: $DATABASE_DRIVER +# CELERY_BROKER_URL: $CELERY_BROKER_URL +# CELERY_RESULT_URL: $CELERY_RESULT_URL +# depends_on: +# - postgres +# - redis +# deploy: +# restart_policy: +# condition: on-failure +# command: "/root/start_tasker.sh -q cic-ussd" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5bd5740 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,44 @@ +africastalking==1.2.3 +alembic==1.4.2 +bcrypt==3.2.0 +celery==4.4.7 +confini==0.3.6a1 +crypto-dev-signer==0.4.13b10 +cryptography==3.2.1 +ecuth==0.4.5a1 +eth-accounts-index==0.0.10a5 +eth-address-index==0.1.0a5 +eth-tester==0.5.0b3 +erc20-approval-escrow==0.3.0a3 +erc20-single-shot-faucet==0.2.0a4 +faker==4.17.1 +http-hoba-auth==0.2.0 +moolb==0.1.0 +phonenumbers==8.12.12 +psycopg2==2.8.6 +py-eth==0.1.1 +py-evm==0.3.0a20 +pytest==6.0.1 +pytest-alembic==0.2.5 +pytest-celery==0.0.0a1 +pytest-cov==2.10.1 +pytest-mock==3.3.1 +pytest-redis==2.0.0 +python-i18n==0.3.9 +PyYAML==5.3.1 +redis==3.5.3 +requests==2.24.0 +semver==2.13.0 +SQLAlchemy==1.3.20 +sqlparse==0.4.1 +tinydb==4.2.0 +transitions==0.8.4 +uWSGI==2.0.19.1 +vobject==0.9.6.1 +web3==5.12.2 +websockets==8.1 +yaml-acl==0.0.1 +semver==2.13.0 +rlp==2.0.1 +cryptocurrency-cli-tools==0.0.4 +giftable-erc20-token==0.0.7b5 diff --git a/scripts/initdb/create_db.sql b/scripts/initdb/create_db.sql new file mode 100644 index 0000000..4a802f4 --- /dev/null +++ b/scripts/initdb/create_db.sql @@ -0,0 +1,9 @@ +CREATE USER grassroots WITH PASSWORD 'tralala' CREATEDB; +CREATE DATABASE "cic-cache"; +CREATE DATABASE "cic-eth"; +CREATE DATABASE "cic-notify"; +CREATE DATABASE "cic-meta"; +CREATE DATABASE "cic-signer"; +GRANT ALL PRIVILEGES +ON DATABASE "cic-cache", "cic-eth", "cic-notify", "cic-meta", "cic-signer" +TO grassroots;