16 Commits

Author SHA1 Message Date
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
12 changed files with 791 additions and 420 deletions

View File

@@ -2,6 +2,33 @@
<!--next-version-placeholder--> <!--next-version-placeholder-->
## 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) ## v0.3.0 (2022-04-26)
### Feature ### Feature
* **wizard:** Add csv input flag ([`a9f97a9`](https://git.grassecon.net/cicnet/cic-cli/commit/a9f97a9a5c6908e4d51710e3b121764d2511c0ab)) * **wizard:** Add csv input flag ([`a9f97a9`](https://git.grassecon.net/cicnet/cic-cli/commit/a9f97a9a5c6908e4d51710e3b121764d2511c0ab))

View File

@@ -1 +1 @@
__version__ = "0.3.0" __version__ = "0.4.1"

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

@@ -12,7 +12,7 @@ url = https://meta.sarafu.network
http_origin = http_origin =
[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 =
[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,12 +23,12 @@ 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")
self.start()
if interactive: if interactive:
self.start()
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"
) )
self.load() self.load()
def load(self): def load(self):
"""Loads attachment data from settings.""" """Loads attachment data from settings."""
@@ -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

@@ -4,13 +4,8 @@ import logging
import os import os
from typing import List from typing import List
# 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
# Local Modules # Local Modules
from cic.contract.components.attachment import Attachment from cic.contract.components.attachment import Attachment
from cic.contract.components.meta import Meta from cic.contract.components.meta import Meta
@@ -20,8 +15,9 @@ 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
# external imports
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 +70,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)

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,22 +87,38 @@ 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}")
token = Token(
directory,
name=voucher_name,
symbol=symbol,
precision=precision,
supply=supply,
extra_args=[demurrage, period_minutes, sink_account],
extra_args_types=["uint256", "uint256", "address"],
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")
log.info("Generating token")
token = Token(
directory,
name=voucher_name,
symbol=symbol,
precision=precision,
supply=supply,
extra_args=[demurrage, period_minutes, sink_account],
extra_args_types=["uint256", "uint256", "address"],
code=bin_path,
)
token.start() token.start()
log.info("Generating proof") log.info("Generating proof")

979
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.3.0" version = "0.4.1"
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>",
@@ -41,18 +41,18 @@ secondary = true
[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.3"
confini = "~0.5.3" confini = "^0.6.0"
chainlib = "~0.0.17" chainlib = "~0.3.0"
cbor2 = "5.4.1" cbor2 = "~5.4.1"
chainlib-eth = { version = "~0.0.25", optional = true } chainlib-eth = { version = "~0.3.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.7.0", optional = true }
cic_contracts = { version = "~0.0.5", optional = true } cic-contracts = { version = "~0.2.0", optional = true }
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
@@ -61,9 +61,8 @@ 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.6.0b6"
eth_tester = "0.5.0b3" py-evm = "0.5.0a3"
py-evm = "0.3.0a20"
rlp = "2.0.1" rlp = "2.0.1"
[tool.poetry.extras] [tool.poetry.extras]
@@ -94,4 +93,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

@@ -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

@@ -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