Compare commits

...

32 Commits

Author SHA1 Message Date
semantic-release
1a42f227c7 0.5.5
Automatically generated by python-semantic-release
2023-03-24 14:52:53 +03:00
3cde79ef8f fix: lock erc20-demurrage-token 2023-03-24 14:52:27 +03:00
semantic-release
ab9f996174 0.5.4
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-07-05 08:26:41 +00:00
de78753675 fix: pass headers through KeyedWriterFactory
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-05 11:25:02 +03:00
semantic-release
7b7fd1e2bb 0.5.3
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-07-05 08:14:20 +00:00
4eda0fb5cc fix: add auth headers to HTTPWriter
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-05 11:12:54 +03:00
semantic-release
fa43080602 0.5.2
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-07-05 07:47:54 +00:00
15ae1143a5 fix: bump cic-types
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-05 10:46:29 +03:00
semantic-release
efbe04df6d 0.5.1
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-07-05 07:09:24 +00:00
22b3062c49 fix: upgrade cic-types to support meta auth
All checks were successful
continuous-integration/drone/push Build is passing
2022-07-05 10:07:40 +03:00
semantic-release
2f4680e1a7 0.5.0
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-07-04 10:38:55 +00:00
bfe7086178 feat: add meta-auth (#4)
All checks were successful
continuous-integration/drone/push Build is passing
Co-authored-by: William Luke <williamluke4@gmail.com>
Reviewed-on: #4
Co-authored-by: williamluke <williamluke4@gmail.com>
Co-committed-by: williamluke <williamluke4@gmail.com>
2022-07-04 10:37:40 +00:00
semantic-release
c3e5ee3199 0.4.1
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-06-14 08:05:32 +00:00
e36ea4bcfb fix: bump deps
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-14 10:50:52 +03:00
9ec3c33718 test: remove sink_account from giftable test
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-29 10:53:12 +03:00
semantic-release
fbd4ed6526 0.4.0
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-04-29 07:51:06 +00:00
b7acbdc4bc feat: add giftable generation
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-29 10:49:35 +03:00
semantic-release
3361f90ae1 0.3.4
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-04-27 07:26:57 +00:00
37188a60e8 fix: bump deps again
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-27 10:22:58 +03:00
semantic-release
fb1ebcf8cd 0.3.3
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-04-26 18:26:26 +00:00
38cfb18527 fix: it's ok if you already exsist
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-26 21:25:02 +03:00
c84517e3db fix: take the reins off
Some checks failed
continuous-integration/drone/push Build is failing
2022-04-26 21:20:35 +03:00
dcea763ce5 fix: bump deps 2022-04-26 17:21:42 +03:00
e55b82f529 fix(attachement): directory not getting created 2022-04-26 17:08:53 +03:00
semantic-release
02df3f792e 0.3.2
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-04-26 13:30:20 +00:00
d2e55fad0e fix: update deps
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-26 16:27:38 +03:00
semantic-release
edf312d969 0.3.1
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-04-26 12:03:27 +00:00
5f22220825 fix: throw if directory exsists
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-26 15:01:52 +03:00
semantic-release
067f354905 0.3.0
All checks were successful
continuous-integration/drone/push Build is passing
Automatically generated by python-semantic-release
2022-04-26 11:41:16 +00:00
f30076783d fix: tests
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-26 14:39:49 +03:00
60e8ecc41a fix: bump ci
Some checks failed
continuous-integration/drone/push Build is failing
2022-04-26 14:12:43 +03:00
3c4a86010d Merge pull request 'feat(wizard): add csv input flag' (#3) from feat/csv_input into master
Reviewed-on: #3
2022-04-26 11:07:00 +00:00
23 changed files with 2262 additions and 1630 deletions

View File

@ -59,7 +59,7 @@ confidence=
# #
# Kubeflow disables string-interpolation because we are starting to use f # Kubeflow disables string-interpolation because we are starting to use f
# style strings # style strings
disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,missing-docstring,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating,relative-import,invalid-name,bad-continuation,no-member,locally-disabled,fixme,import-error,too-many-locals,no-name-in-module,too-many-instance-attributes,no-self-use,logging-fstring-interpolation disable=old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,missing-docstring,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating,relative-import,invalid-name,bad-continuation,no-member,locally-disabled,fixme,import-error,too-many-locals,no-name-in-module,too-many-instance-attributes,no-self-use,logging-fstring-interpolation
[REPORTS] [REPORTS]

View File

@ -2,6 +2,65 @@
<!--next-version-placeholder--> <!--next-version-placeholder-->
## v0.5.5 (2023-03-24)
### Fix
* Lock erc20-demurrage-token ([`3cde79e`](https://git.grassecon.net/cicnet/cic-cli/commit/3cde79ef8fb77a6b03454e675568834e0ab4ba80))
## v0.5.4 (2022-07-05)
### Fix
* Pass headers through KeyedWriterFactory ([`de78753`](https://git.grassecon.net/cicnet/cic-cli/commit/de78753675242dd253359a5a5601d9062d81f0ee))
## v0.5.3 (2022-07-05)
### Fix
* Add auth headers to HTTPWriter ([`4eda0fb`](https://git.grassecon.net/cicnet/cic-cli/commit/4eda0fb5cc2c41a735619dc3e34f21c4e27fd112))
## v0.5.2 (2022-07-05)
### Fix
* Bump cic-types ([`15ae114`](https://git.grassecon.net/cicnet/cic-cli/commit/15ae1143a5230078219072d096741546ebcc3d07))
## v0.5.1 (2022-07-05)
### Fix
* Upgrade cic-types to support meta auth ([`22b3062`](https://git.grassecon.net/cicnet/cic-cli/commit/22b3062c4909400664bd2a50ca36d5ee737531a1))
## v0.5.0 (2022-07-04)
### Feature
* Add meta-auth ([#4](https://git.grassecon.net/cicnet/cic-cli/issues/4)) ([`bfe7086`](https://git.grassecon.net/cicnet/cic-cli/commit/bfe7086178f3fc2743dd68cc20c5459ca466ae8e))
## v0.4.1 (2022-06-14)
### Fix
* Bump deps ([`e36ea4b`](https://git.grassecon.net/cicnet/cic-cli/commit/e36ea4bcfb1c417d1adf2be9455cb20b23323414))
## v0.4.0 (2022-04-29)
### Feature
* Add giftable generation ([`b7acbdc`](https://git.grassecon.net/cicnet/cic-cli/commit/b7acbdc4bc5862752585fecfaee7d2fe70d8dbbe))
## v0.3.4 (2022-04-27)
### Fix
* Bump deps again ([`37188a6`](https://git.grassecon.net/cicnet/cic-cli/commit/37188a60e85d9545acfd950c1c160801c22d2b5b))
## v0.3.3 (2022-04-26)
### Fix
* It's ok if you already exsist ([`38cfb18`](https://git.grassecon.net/cicnet/cic-cli/commit/38cfb185270fb361ff5d9da9976745e1fecc40f8))
* Take the reins off ([`c84517e`](https://git.grassecon.net/cicnet/cic-cli/commit/c84517e3db264f541e6e5a8eef30703bf28d32d0))
* Bump deps ([`dcea763`](https://git.grassecon.net/cicnet/cic-cli/commit/dcea763ce5b3d542ed0a50586720fc3a45142e77))
* **attachement:** Directory not getting created ([`e55b82f`](https://git.grassecon.net/cicnet/cic-cli/commit/e55b82f5295397b3e4123297bc6b231ca251bc83))
## v0.3.2 (2022-04-26)
### Fix
* Update deps ([`d2e55fa`](https://git.grassecon.net/cicnet/cic-cli/commit/d2e55fad0efd13fa7a1de8ed8ab43e703a4aa046))
## v0.3.1 (2022-04-26)
### Fix
* Throw if directory exsists ([`5f22220`](https://git.grassecon.net/cicnet/cic-cli/commit/5f22220825f5c485550ca9a21a54598fbe3b3ba3))
## v0.3.0 (2022-04-26)
### Feature
* **wizard:** Add csv input flag ([`a9f97a9`](https://git.grassecon.net/cicnet/cic-cli/commit/a9f97a9a5c6908e4d51710e3b121764d2511c0ab))
### Fix
* Tests ([`f300767`](https://git.grassecon.net/cicnet/cic-cli/commit/f30076783d5fc93d91d29e9343d62af4c0fdffaa))
* Bump ci ([`60e8ecc`](https://git.grassecon.net/cicnet/cic-cli/commit/60e8ecc41a472dbea25c36d869259c8161145002))
## v0.2.3 (2022-03-22) ## v0.2.3 (2022-03-22)
### Fix ### Fix
* Remove this ([`92794a2`](https://git.grassecon.net/cicnet/cic-cli/commit/92794a2e3b2fc5ace63f519bbe5b23c542afc853)) * Remove this ([`92794a2`](https://git.grassecon.net/cicnet/cic-cli/commit/92794a2e3b2fc5ace63f519bbe5b23c542afc853))

View File

@ -1 +1 @@
__version__ = "0.2.3" __version__ = "0.5.5"

View File

@ -2,7 +2,7 @@ from __future__ import annotations
# standard import # standard import
import logging import logging
import os
from chainlib.cli.config import Config from chainlib.cli.config import Config
@ -66,13 +66,17 @@ def execute(
if wallet_keystore: if wallet_keystore:
config.add(wallet_keystore, "WALLET_KEY_FILE", exists_ok=True) config.add(wallet_keystore, "WALLET_KEY_FILE", exists_ok=True)
if not skip_gen: if skip_gen:
contract = load_contract(directory)
else:
if os.path.exists(directory):
raise Exception(f"Directory {directory} already exists")
if csv_file: if csv_file:
print(f"Generating from csv:{csv_file} to {directory}")
contract = load_contract_from_csv(config, directory, csv_file) contract = load_contract_from_csv(config, directory, csv_file)
else: else:
print("Using Interactive Mode")
contract = generate_contract(directory, [target], config, interactive=True) contract = generate_contract(directory, [target], config, interactive=True)
else:
contract = load_contract(directory)
print(contract) print(contract)

View File

@ -10,7 +10,7 @@ registry_address = 0xcf60ebc445b636a5ab787f9e8bc465a2a3ef8299
[meta] [meta]
url = http://localhost:63380 url = http://localhost:63380
http_origin = http_origin =
auth_token =
[rpc] [rpc]
provider = http://localhost:63545 provider = http://localhost:63545

View File

@ -10,6 +10,7 @@ registry_address = 0xcf60ebc445b636a5ab787f9e8bc465a2a3ef8299
[meta] [meta]
url = http://localhost:8000 url = http://localhost:8000
http_origin = http_origin =
auth_token =
[rpc] [rpc]
provider = http://localhost:8545 provider = http://localhost:8545

View File

@ -10,9 +10,10 @@ registry_address = 0xe3e3431BF25b06166513019Ed7B21598D27d05dC
[meta] [meta]
url = https://meta.sarafu.network url = https://meta.sarafu.network
http_origin = http_origin =
auth_token =
[rpc] [rpc]
provider = http://142.93.38.53:8545 provider = https://rpc.sarafu.network
[auth] [auth]
type = gnupg type = gnupg

View File

@ -5,23 +5,23 @@ proof_writer = cic.writers.KVWriter
ext_writer = cic.writers.KVWriter ext_writer = cic.writers.KVWriter
[cic] [cic]
registry_address = 0xcf60ebc445b636a5ab787f9e8bc465a2a3ef8299 registry_address = 0x47269C43e4aCcA5CFd09CB4778553B2F69963303
[meta] [meta]
url = https://meta.grassecon.net url = https://meta.sarafu.network
http_origin = http_origin =
auth_token =
[rpc] [rpc]
provider = https://rpc.grassecon.net provider = https://rpc.sarafu.network
[auth] [auth]
type = gnupg type = gnupg
keyfile_path = /home/will/grassroots/cic-internal-integration/apps/cic-ussd/tests/data/pgp/privatekeys_meta.asc keyfile_path =
passphrase = merman passphrase =
[wallet] [wallet]
key_file = /home/will/grassroots/cic-internal-integration/apps/contract-migration/keystore key_file =
passphrase = passphrase =
[chain] [chain]
spec = evm:byzantium:5050:bloxberg spec = evm:kitabu:6060:sarafu

View File

@ -23,8 +23,8 @@ class Attachment(Data):
self.path = path self.path = path
self.writer = writer self.writer = writer
self.attachment_path = os.path.join(self.path, "attachments") self.attachment_path = os.path.join(self.path, "attachments")
if interactive:
self.start() self.start()
if interactive:
input( input(
f"Please add attachment files to '{os.path.abspath(os.path.join(self.path,'attachments'))}' and then press ENTER to continue" f"Please add attachment files to '{os.path.abspath(os.path.join(self.path,'attachments'))}' and then press ENTER to continue"
) )
@ -45,7 +45,7 @@ class Attachment(Data):
def start(self): def start(self):
"""Initialize attachment settings from template.""" """Initialize attachment settings from template."""
super(Attachment, self).start() super(Attachment, self).start()
os.makedirs(self.attachment_path) os.makedirs(self.attachment_path, exist_ok=True)
def get(self, k): def get(self, k):
"""Get a single attachment by the sha256 hash of the content. """Get a single attachment by the sha256 hash of the content.

View File

@ -1,5 +1,5 @@
GITABLE_CONTRACT_URL = "https://gitlab.com/cicnet/eth-erc20/-/raw/master/python/giftable_erc20_token/data/GiftableToken" GITABLE_CONTRACT_URL = "https://gitlab.com/cicnet/eth-erc20/-/raw/master/python/giftable_erc20_token/data/GiftableToken"
DMR_CONTRACT_URL = "https://gitlab.com/cicnet/erc20-demurrage-token/-/raw/master/python/erc20_demurrage_token/data/DemurrageTokenSingleNocap" DMR_CONTRACT_URL = "https://gitlab.com/cicnet/erc20-demurrage-token/-/raw/v0.1.1/python/erc20_demurrage_token/data/DemurrageTokenSingleNocap"
CONTRACT_URLS = [ CONTRACT_URLS = [
{ {

View File

@ -4,10 +4,7 @@ import logging
import os import os
from typing import List from typing import List
# External imports
# external imports
from cic_types.ext.metadata import MetadataRequestsHandler
from cic_types.ext.metadata.signer import Signer as MetadataSigner
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from chainlib.cli.config import Config from chainlib.cli.config import Config
@ -20,8 +17,8 @@ from cic.contract.helpers import init_writers_from_config
from cic.contract.network import Network from cic.contract.network import Network
from cic.contract.processor import ContractProcessor from cic.contract.processor import ContractProcessor
from cic.writers import HTTPWriter, KeyedWriterFactory, MetadataWriter from cic.writers import HTTPWriter, KeyedWriterFactory, MetadataWriter
from cic_types.ext.metadata import MetadataRequestsHandler
from cic_types.ext.metadata.signer import Signer as MetadataSigner
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -74,16 +71,6 @@ def load_contract(directory) -> Contract:
def generate_contract( def generate_contract(
directory: str, targets: List[str], config, interactive=True directory: str, targets: List[str], config, interactive=True
) -> Contract: ) -> Contract:
if os.path.exists(directory):
contine = input(
f"Directory {directory} already exists, Would you like to delete it? (y/n): "
)
if contine.lower() != "y":
log.debug("Trying to load existing contract")
return load_contract(directory)
else:
print(f"Deleted {directory}")
os.system(f"rm -rf {directory}")
os.makedirs(directory) os.makedirs(directory)
log.info("Generating token") log.info("Generating token")
token = Token(directory, interactive=interactive) token = Token(directory, interactive=interactive)
@ -160,9 +147,12 @@ def deploy_contract(
output_writer_path_meta = output_directory output_writer_path_meta = output_directory
metadata_endpoint = config.get("META_URL") metadata_endpoint = config.get("META_URL")
metadata_auth_token = config.get("META_AUTH_TOKEN")
headers = {"Authorization": f"Basic {metadata_auth_token}"}
if metadata_endpoint is not None: if metadata_endpoint is not None:
MetadataRequestsHandler.base_url = metadata_endpoint MetadataRequestsHandler.base_url = metadata_endpoint
MetadataRequestsHandler.auth_token = metadata_auth_token
MetadataSigner.gpg_path = "/tmp" MetadataSigner.gpg_path = "/tmp"
MetadataSigner.key_file_path = config.get("AUTH_KEYFILE_PATH") MetadataSigner.key_file_path = config.get("AUTH_KEYFILE_PATH")
MetadataSigner.gpg_passphrase = config.get("AUTH_PASSPHRASE") MetadataSigner.gpg_passphrase = config.get("AUTH_PASSPHRASE")
@ -177,12 +167,12 @@ def deploy_contract(
) )
ca = Attachment( ca = Attachment(
path=contract_directory, path=contract_directory,
writer=writers["attachment"](path=output_writer_path_meta), writer=writers["attachment"](path=output_writer_path_meta, headers=headers),
) )
cp = Proof( cp = Proof(
path=contract_directory, path=contract_directory,
attachments=ca, attachments=ca,
writer=writers["proof"](path=output_writer_path_meta), writer=writers["proof"](path=output_writer_path_meta, headers=headers),
) )
cn = Network(path=contract_directory) cn = Network(path=contract_directory)

View File

@ -11,7 +11,7 @@ from cic.contract.components.attachment import Attachment
from cic.contract.components.meta import Meta from cic.contract.components.meta import Meta
from cic.contract.components.proof import Proof from cic.contract.components.proof import Proof
from cic.contract.components.token import Token from cic.contract.components.token import Token
from cic.contract.constants import DMR_CONTRACT_URL from cic.contract.constants import DMR_CONTRACT_URL, GITABLE_CONTRACT_URL
from cic.contract.contract import Contract from cic.contract.contract import Contract
from cic.contract.helpers import download_file from cic.contract.helpers import download_file
from cic.contract.network import Network from cic.contract.network import Network
@ -59,7 +59,6 @@ def load_contracts_from_csv(config, directory, csv_path: str) -> List[Contract]:
targets = ["eth"] targets = ["eth"]
os.makedirs(directory) os.makedirs(directory)
contract_rows = [] contract_rows = []
bin_path = os.path.abspath(download_file(DMR_CONTRACT_URL + ".bin"))
with open(csv_path, "rt", encoding="utf-8") as file: with open(csv_path, "rt", encoding="utf-8") as file:
csvreader = csv.reader(file, delimiter=",") csvreader = csv.reader(file, delimiter=",")
for idx, row in enumerate(csvreader): for idx, row in enumerate(csvreader):
@ -88,12 +87,9 @@ def load_contracts_from_csv(config, directory, csv_path: str) -> List[Contract]:
sink_account = contract_row[CSV_Column.sink_account] sink_account = contract_row[CSV_Column.sink_account]
description = contract_row[CSV_Column.description] description = contract_row[CSV_Column.description]
if token_type != "demurrage": if token_type == "demurrage":
raise Exception( bin_path = os.path.abspath(download_file(DMR_CONTRACT_URL + ".bin"))
f"Only demurrage tokens are supported at this time. {token_type} is not supported" log.info(f"Generating {token_type} contract for {issuer}")
)
log.info("Generating token")
token = Token( token = Token(
directory, directory,
name=voucher_name, name=voucher_name,
@ -104,6 +100,25 @@ def load_contracts_from_csv(config, directory, csv_path: str) -> List[Contract]:
extra_args_types=["uint256", "uint256", "address"], extra_args_types=["uint256", "uint256", "address"],
code=bin_path, code=bin_path,
) )
elif token_type == "giftable":
bin_path = os.path.abspath(download_file(GITABLE_CONTRACT_URL + ".bin"))
token = Token(
directory,
name=voucher_name,
symbol=symbol,
precision=precision,
supply=supply,
extra_args=[],
extra_args_types=[],
code=bin_path,
)
else:
raise Exception(
f"Only demurrage and gitable contracts currently supported at this time. {token_type} is not supported"
)
if token is None:
raise Exception(f"There was an issue building the contract")
token.start() token.start()
log.info("Generating proof") log.info("Generating proof")

View File

@ -84,6 +84,7 @@ class ContractProcessor:
if a is None: if a is None:
logg.debug(f'skipping missing task receiver "{task}"') logg.debug(f'skipping missing task receiver "{task}"')
continue continue
logg.debug(f'Processing "{ext}:{task}"')
v = a.process( v = a.process(
token_address=token_address, token_address=token_address,
token_symbol=token_symbol, token_symbol=token_symbol,

View File

@ -10,7 +10,7 @@ registry_address = 0xe3e3431BF25b06166513019Ed7B21598D27d05dC
[meta] [meta]
url = https://meta.sarafu.network url = https://meta.sarafu.network
http_origin = http_origin =
auth_token =
[auth] [auth]
type = gnupg type = gnupg
keyfile_path = keyfile_path =

View File

@ -90,7 +90,6 @@ def main():
except Exception as e: except Exception as e:
logg.exception(e) logg.exception(e)
sys.stderr.write("\033[;91m" + str(e) + "\033[;39m\n") sys.stderr.write("\033[;91m" + str(e) + "\033[;39m\n")
argparser.print_help()
sys.exit(1) sys.exit(1)

View File

@ -4,15 +4,15 @@ def object_to_str(obj, keys):
for key in keys: for key in keys:
value = eval("obj." + key) value = eval("obj." + key)
key = key.replace("()", "") key = key.replace("()", "")
if type(value) == str: if isinstance(value, str):
s += f"{key} = {value}\n" s += f"{key} = {value}\n"
elif type(value) == list: elif isinstance(value, list):
for idx, vv in enumerate(value): for idx, vv in enumerate(value):
if not vv: if not vv:
s += f"{key}[{idx}] = \n" s += f"{key}[{idx}] = \n"
continue continue
s += f"{key}[{idx}] = {vv}\n" s += f"{key}[{idx}] = {vv}\n"
elif type(value) == dict: elif isinstance(value, dict):
for vv_key in value.keys(): for vv_key in value.keys():
vv_value = value[vv_key] vv_value = value[vv_key]
if not vv_value: if not vv_value:

View File

@ -5,7 +5,7 @@ import logging
import os import os
import sys import sys
import urllib.request import urllib.request
from typing import Type, Union from typing import Dict, Type, Union
from cic_types.ext.metadata import MetadataPointer, MetadataRequestsHandler from cic_types.ext.metadata import MetadataPointer, MetadataRequestsHandler
@ -26,13 +26,14 @@ class StdoutWriter(OutputWriter):
class KVWriter(OutputWriter): class KVWriter(OutputWriter):
def __init__(self, *args, path=None, **kwargs): def __init__(self, path=None, *args, **kwargs):
try: try:
os.stat(path) os.stat(path)
except FileNotFoundError: except FileNotFoundError:
os.makedirs(path) os.makedirs(path)
self.path = path self.path = path
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def write(self, k, v): def write(self, k, v):
fp = os.path.join(self.path, str(k)) fp = os.path.join(self.path, str(k))
logg.debug(f"path write {fp} {str(v)}") logg.debug(f"path write {fp} {str(v)}")
@ -42,16 +43,17 @@ class KVWriter(OutputWriter):
class HTTPWriter(OutputWriter): class HTTPWriter(OutputWriter):
def __init__(self, *args, path=None, **kwargs): def __init__(self, path=None, headers: Dict[str, str] = None, *args, **kwargs):
super(HTTPWriter, self).__init__(*args, **kwargs) super(HTTPWriter, self).__init__(*args, **kwargs)
self.path = path self.path = path
self.headers = headers
def write(self, k, v): def write(self, k, v):
path = self.path path = self.path
if k is not None: if k is not None:
path = os.path.join(path, k) path = os.path.join(path, k)
logg.debug(f"http writer post {path} \n key: {k}, value: {v}") logg.debug(f"HTTPWriter POST {path} data: {v}, headers: {self.headers}")
rq = urllib.request.Request(path, method="POST", data=v) rq = urllib.request.Request(path, method="POST", data=v, headers=self.headers)
r = urllib.request.urlopen(rq) r = urllib.request.urlopen(rq)
logg.info(f"http writer submitted at {r.read()}") logg.info(f"http writer submitted at {r.read()}")
@ -83,13 +85,15 @@ class KeyedWriterFactory:
logg.debug(f"adding key {k} t keyed writer factory") logg.debug(f"adding key {k} t keyed writer factory")
self.x[k] = v self.x[k] = v
def new(self, *_args, path=None, **_kwargs): def new(self, path=None, headers: Dict[str, str] = None, *_args, **_kwargs):
writer_keyed = None writer_keyed = None
writer_immutable = None writer_immutable = None
if self.key_writer_constructor is not None: if self.key_writer_constructor is not None:
writer_keyed = self.key_writer_constructor(path, **self.x) writer_keyed = self.key_writer_constructor(path, **self.x)
if self.immutable_writer_constructor is not None: if self.immutable_writer_constructor is not None:
writer_immutable = self.immutable_writer_constructor(path, **self.x) writer_immutable = self.immutable_writer_constructor(
path, headers, **self.x
)
return KeyedWriter(writer_keyed, writer_immutable) return KeyedWriter(writer_keyed, writer_immutable)

3565
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "cic-cli" name = "cic-cli"
version = "0.2.3" version = "0.5.5"
description = "Generic cli tooling for the CIC token network" description = "Generic cli tooling for the CIC token network"
authors = [ authors = [
"Louis Holbrook <dev@holbrook.no>", "Louis Holbrook <dev@holbrook.no>",
@ -32,27 +32,30 @@ cic = 'cic.runnable.cic_cmd:main'
[[tool.poetry.source]] [[tool.poetry.source]]
name = "grassroots_" name = "grassroots_"
url = "https://pip.grassrootseconomics.net/" url = "https://pip.grassrootseconomics.net/"
default = true default = false
secondary = true
[[tool.poetry.source]] [[tool.poetry.source]]
name = "pypi_" name = "pypi_"
url = "https://pypi.org/simple/" url = "https://pypi.org/simple/"
secondary = true default = true
secondary = false
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.8" python = "^3.8"
funga-eth = "~0.5.5" funga-eth = "^0.6.0"
cic-types = "~0.2.1a8" cic-types = "^0.2.7"
confini = "~0.5.3" confini = "^0.6.0"
chainlib = "~0.0.17" chainlib = "~0.1.0"
cbor2 = "5.4.1" cbor2 = "~5.4.1"
chainlib-eth = { version = "~0.0.25", optional = true } chainlib-eth = { version = "~0.1.1", optional = true }
eth-token-index = { version = "~0.2.4", optional = true } eth-token-index = { version = "^0.3.0", optional = true }
eth-address-index = { version = "~0.2.4", optional = true } eth-address-index = { version = "~0.5.0", optional = true }
okota = { version = "~0.2.5", optional = true } okota = { version = "^0.4.0", optional = true }
cic_eth_registry = { version = "~0.6.6", optional = true } cic-eth-registry = { version = "^0.6.9", optional = true }
cic_contracts = { version = "~0.0.5", optional = true } cic-contracts = { version = "~0.1.0", optional = true }
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
@ -61,10 +64,10 @@ pytest-cov = "2.10.1"
python-semantic-release = "^7.25.2" python-semantic-release = "^7.25.2"
pylint = "^2.12.2" pylint = "^2.12.2"
black = { version = "^22.1.0", allow-prereleases = true } black = { version = "^22.1.0", allow-prereleases = true }
eth-erc20 = ">0.1.2a3,<0.2.0"
eth_tester = "0.5.0b3" eth_tester = "0.5.0b3"
py-evm = "0.3.0a20" py-evm = "0.3.0a20"
rlp = "2.0.1" rlp = "2.0.1"
mypy = "^0.961"
[tool.poetry.extras] [tool.poetry.extras]
eth = [ eth = [
@ -94,4 +97,3 @@ build_command = "pip install poetry && poetry build"
hvcs = "gitea" hvcs = "gitea"
hvcs_domain = "git.grassecon.net" hvcs_domain = "git.grassecon.net"
check_build_status = false check_build_status = false

View File

@ -4,15 +4,14 @@ import random
import tempfile import tempfile
import unittest import unittest
from cic.contract.components.attachment import Attachment # external imports
from cic.contract.components.proof import Proof from hexathon import add_0x
from cic.contract.processor import ContractProcessor
# local imports # local imports
from cic.writers import KVWriter from cic.writers import KVWriter
from cic.contract.components.attachment import Attachment
# external imports from cic.contract.components.proof import Proof
from hexathon import add_0x from cic.contract.processor import ContractProcessor
test_base_dir = os.path.dirname(os.path.realpath(__file__)) test_base_dir = os.path.dirname(os.path.realpath(__file__))
test_data_dir = os.path.join(test_base_dir, "testdata") test_data_dir = os.path.join(test_base_dir, "testdata")

View File

@ -1,12 +1,12 @@
import os import os
import tempfile import tempfile
import pytest
from cic.contract.csv import load_contract_from_csv from cic.contract.csv import load_contract_from_csv
from tests.base_cic import test_data_dir from tests.base_cic import test_data_dir
@pytest.mark.skip(reason="Public RPC is currently dead")
def test_csv_generate(): def test_csv_generate_demurrage():
outputs_dir = os.path.join(tempfile.mkdtemp(), "outputs") outputs_dir = os.path.join(tempfile.mkdtemp(), "outputs")
test_csv_path = os.path.join(test_data_dir, "voucher", "bondi.csv") test_csv_path = os.path.join(test_data_dir, "voucher", "bondi.csv")
contract = load_contract_from_csv( contract = load_contract_from_csv(
@ -72,3 +72,67 @@ def test_csv_generate():
assert contract.proof.namespace == "ge" assert contract.proof.namespace == "ge"
assert contract.proof.proofs == [] assert contract.proof.proofs == []
assert contract.proof.version() == 0 assert contract.proof.version() == 0
@pytest.mark.skip(reason="Public RPC is currently dead")
def test_csv_generate_giftable():
outputs_dir = os.path.join(tempfile.mkdtemp(), "outputs")
test_csv_path = os.path.join(test_data_dir, "voucher", "bondi_giftable.csv")
contract = load_contract_from_csv(
{
"WALLET_KEY_FILE": os.path.join(test_data_dir, "keystore", "ok"),
"WALLET_PASSPHRASE": "test",
"CHAIN_SPEC": "evm:kitabu:6060:sarafu",
"RPC_PROVIDER": "http://142.93.38.53:8545",
"CIC_REGISTRY_ADDRESS": "0xe3e3431BF25b06166513019Ed7B21598D27d05dC",
},
outputs_dir,
csv_path=test_csv_path,
)
# assert len(contracts) == 1
# contract = contracts[0]
# Token
assert contract.token.name == "Bondeni"
assert contract.token.extra_args == []
assert contract.token.extra_args_types == []
# assert contract.token.code == os.path.join(test_data_dir, "contracts", "Bondi.bin")
assert contract.token.precision == '6'
assert contract.token.supply == "5025"
assert contract.token.symbol == "BONDE"
# Meta
assert contract.meta.country_code == "KE"
assert contract.meta.location == "Mutitu Kilifi"
assert contract.meta.contact == {
"email": "info@grassecon.org",
"phone": "254797782065",
}
assert contract.meta.name == "Bondeni SHG"
# Network
assert contract.network.resources["eth"]["chain_spec"] == {
"arch": "evm",
"common_name": "sarafu",
"custom": [],
"extra": {},
"fork": "kitabu",
"network_id": 6060,
}
assert contract.network.resources["eth"]["contents"] == {
"address_declarator": {
"key_account": "cc4f82f5dacde395e1e0cfc4d62827c8b8b5688c",
"reference": "f055e83f713DbFF947e923749Af9802eaffFB5f9",
},
"token": {
"key_account": "cc4f82f5dacde395e1e0cfc4d62827c8b8b5688c",
"reference": None,
},
"token_index": {
"key_account": "cc4f82f5dacde395e1e0cfc4d62827c8b8b5688c",
"reference": "5A1EB529438D8b3cA943A45a48744f4c73d1f098",
},
}
assert contract.proof.description == "1 BONDE = 1 itumbe"
assert contract.proof.namespace == "ge"
assert contract.proof.proofs == []
assert contract.proof.version() == 0

View File

@ -14,7 +14,7 @@ from cic.keystore import KeystoreDirectory
# test imports # test imports
from tests.base_cic import test_base_dir from tests.base_cic import test_base_dir
logging = logging.getLogger() log = logging.getLogger(__name__)
script_dir = test_base_dir script_dir = test_base_dir

View File

@ -0,0 +1,2 @@
issuer,namespace,voucher_name,symbol,location,country_code,supply,precision,token_type,demurrage,period_minutes,phone_number,email_address,sink_account,description
Bondeni SHG,ge,Bondeni,BONDE,Mutitu Kilifi,KE,5025,6,giftable,,,254797782065,info@grassecon.org,,1 BONDE = 1 itumbe
1 issuer namespace voucher_name symbol location country_code supply precision token_type demurrage period_minutes phone_number email_address sink_account description
2 Bondeni SHG ge Bondeni BONDE Mutitu Kilifi KE 5025 6 giftable 254797782065 info@grassecon.org 1 BONDE = 1 itumbe