diff --git a/.gitignore b/.gitignore index 65ea75e..afec510 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,7 @@ expanded.rs # Maven with auto-import, exclude module files *.iml +# Python +__pycache__/ +*.sqlite diff --git a/python/notamon_viewer/app.py b/python/notamon_viewer/app.py index 2e67203..8f081e5 100644 --- a/python/notamon_viewer/app.py +++ b/python/notamon_viewer/app.py @@ -1,7 +1,9 @@ import flask import pbc_client +import base64 import dataclasses import requests_cache +from collections.abc import Iterator HTML_INDEX = """ @@ -63,6 +65,21 @@ class Notamon: nickname: str species_name: str +@dataclasses.dataclass(frozen=True) +class NotamonAttributes: + species_id: int + skin_id: int + effect_id: int + stat_hp: int + stat_attack: int + stat_defense: int + +@dataclasses.dataclass(frozen=True) +class AssetVariable: + variable_id: int + asset_id: int + opened: bytes | None + app = flask.Flask(__name__) @@ -74,18 +91,71 @@ TEST_NOTAMON = Notamon( species_name = 'Mudkip', ) -ADDRESS_NFTS = '' -ADDRESS_ASSETS = '' +ADDRESS_NFTS = '02b82d36784146bd29415dbaa623a5f1cf6e6e1108' +ADDRESS_ASSETS = '0338d039e3960426d0cfc590efbdbef70b049696a3' SESSION = requests_cache.CachedSession() -def determine_notamons(): + +def compress(b: bytes) -> bytes: + l = [] + for i in range(0, len(b)//8): + derp = 0 + for j in range(0, 8): + derp |= b[i*8+j] << j + del j + l.append(derp) + del i, derp + return bytes(l) + + +def decode_opened_variable(value: str) -> bytes: + return compress(base64.b64decode(value))[4:] + + +def get_asset_variables(client, address) -> Iterator[AssetVariable]: + asset_contract_state, _ = client.get_contract_state(ADDRESS_ASSETS) + + for variable in asset_contract_state['variables']: + print(variable) + + asset_id = int.from_bytes(base64.b64decode(variable['value']['information']['data'])) + opened = decode_opened_variable(variable['value']['openValue']['data']) if variable['value']['openValue'] else None + + yield AssetVariable( + variable_id = variable['key'], + asset_id = asset_id, + opened = opened, + ) + + +def to_base64_png(b: bytes) -> str: + return f'data:image/png;base64,{base64.b64encode(b)}' + + +def get_notamon_nfts(client: pbc_client.PbcClient): + asset_contract_state, _ = client.get_contract_state(ADDRESS_NFTS) + print(asset_contract_state) + + yield from [] + + + + +def select_notamons(): client = pbc_client.PbcClient(SESSION, pbc_client.HOSTNAME_TESTNET) - asset_contract_state = client.get_contract_state(ADDRESS_ASSETS) + + nfts = list(get_notamon_nfts(client)) + print(nfts) + + + print(client) + assets = list(get_asset_variables(client, ADDRESS_ASSETS)) + print(assets ) return [TEST_NOTAMON for i in range(100)] @app.route("/") def hello_world(): - return flask.render_template_string(HTML_INDEX, notamons = determine_notamons()) + return flask.render_template_string(HTML_INDEX, notamons = select_notamons()) diff --git a/rust/notamon-asset-contract/Cargo.toml b/rust/notamon-asset-contract/Cargo.toml index 67f236f..5c565c5 100644 --- a/rust/notamon-asset-contract/Cargo.toml +++ b/rust/notamon-asset-contract/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "zk-file-share" +name = "notamon-asset-contract" readme = "README.md" version.workspace = true description.workspace = true diff --git a/rust/notamon-nft/Cargo.toml b/rust/notamon-nft/Cargo.toml index fe07eb2..7328fe9 100644 --- a/rust/notamon-nft/Cargo.toml +++ b/rust/notamon-nft/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "nft-v2-contract" +name = "notamon-nft" readme = "README.md" version.workspace = true description.workspace = true diff --git a/rust/notamon-nft/src/lib.rs b/rust/notamon-nft/src/lib.rs index b14b612..417699e 100644 --- a/rust/notamon-nft/src/lib.rs +++ b/rust/notamon-nft/src/lib.rs @@ -31,9 +31,9 @@ struct OperatorApproval { /// ``` type TokenId = u128; -/// Unit +/// Unit2 #[derive(CreateTypeSpec, ReadWriteState)] -pub struct Unit {} +pub struct Unit2 {} /// State of the contract. #[state] @@ -57,7 +57,7 @@ pub struct NFTContractState { /// Containing approved operators of owners. Operators can transfer and change approvals on all tokens owned by owner. /// /// Required by MPC-721. - operator_approvals: AvlTreeMap, + operator_approvals: AvlTreeMap, /// Template which the uri's of the NFTs fit into. /// /// Required by MPC-721. @@ -220,6 +220,7 @@ pub fn initialize( name: String, symbol: String, uri_template: String, + asset_contract: Address, ) -> NFTContractState { NFTContractState { name, @@ -232,6 +233,7 @@ pub fn initialize( contract_owner: ctx.sender, notamon_attributes: AvlTreeMap::new(), cached_asset_unlocks: AvlTreeSet::new(), + asset_contract, } } @@ -303,7 +305,7 @@ pub fn set_approval_for_all( operator, }; if approved { - state.operator_approvals.insert(operator_approval, Unit {}); + state.operator_approvals.insert(operator_approval, Unit2 {}); } else { state.operator_approvals.remove(&operator_approval); } @@ -386,22 +388,22 @@ fn unlock_assets( NFTContractState, Vec, ) { - let asset_ids: Vec = notamon_attributes.asset_ids().into_iter().filter( - |id| state.cached_asset_unlocks.contains(id) + let ids_of_not_yet_unlocked_assets: Vec = notamon_attributes.asset_ids().into_iter().filter( + |id| !state.cached_asset_unlocks.contains(id) ) .collect(); - if asset_ids.is_empty() { + if ids_of_not_yet_unlocked_assets.is_empty() { return (state, vec![]); } - for id in asset_ids.clone() { + for id in ids_of_not_yet_unlocked_assets.clone() { state.cached_asset_unlocks.insert(id) } let mut event_group_builder = EventGroup::builder(); event_group_builder .call(state.asset_contract, Shortname::from_u32(0x07)) - .argument(asset_ids) + .argument(ids_of_not_yet_unlocked_assets) .done(); ( diff --git a/rust/upgradable-v1/Cargo.toml b/rust/upgradable-v1/Cargo.toml index ee5f09b..5697ffc 100644 --- a/rust/upgradable-v1/Cargo.toml +++ b/rust/upgradable-v1/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "upgradable-v1" +name = "todo-upgradable-v1" readme = "README.md" version.workspace = true description.workspace = true