diff --git a/ree-cookie-canister/Cargo.lock b/ree-cookie-canister/Cargo.lock index 93b4a7e..8eb3848 100644 --- a/ree-cookie-canister/Cargo.lock +++ b/ree-cookie-canister/Cargo.lock @@ -13,20 +13,20 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -37,9 +37,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" [[package]] name = "arc-swap" @@ -72,24 +72,24 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ - "event-listener 5.4.0", + "event-listener 5.4.1", "event-listener-strategy", "pin-project-lite", ] [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backoff" @@ -113,16 +113,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "instant", "rand 0.8.5", ] [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -130,7 +130,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -169,9 +169,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.7.3" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bech32" @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "bitcoin" -version = "0.32.5" +version = "0.32.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" +checksum = "0fda569d741b895131a88ee5589a467e73e9c4718e958ac9308e4f7dc44b6945" dependencies = [ "base58ck", "base64 0.21.7", @@ -268,9 +268,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29" [[package]] name = "block-buffer" @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byteorder" @@ -323,9 +323,9 @@ dependencies = [ [[package]] name = "candid" -version = "0.10.13" +version = "0.10.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253bab4a9be502c82332b60cbeee6202ad0692834efeec95fae9f29db33d692" +checksum = "eaac522d18020d5fbc8320ecb12a9b13b2137ae31133da2d42fa256a825507c4" dependencies = [ "anyhow", "binread", @@ -346,30 +346,30 @@ dependencies = [ [[package]] name = "candid_derive" -version = "0.6.6" +version = "0.10.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3de398570c386726e7a59d9887b68763c481477f9a043fb998a2e09d428df1a9" +checksum = "8a1b4fddbd462182050989068d53604a91a3d0f117c3c8316c6818023df00add" dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] name = "cc" -version = "1.2.16" +version = "1.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "3ee0f8803222ba5a7e2777dd72ca451868909b1ac410621b676adf07280e9b5f" dependencies = [ "shlex", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cfg_aliases" @@ -403,9 +403,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] @@ -451,17 +451,52 @@ dependencies = [ "zeroize", ] +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.106", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.106", +] + [[package]] name = "data-encoding" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "der" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", "pem-rfc7468", @@ -470,9 +505,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -506,7 +541,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] @@ -572,9 +607,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "5.4.0" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -583,11 +618,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "event-listener 5.4.0", + "event-listener 5.4.1", "pin-project-lite", ] @@ -646,7 +681,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] @@ -691,22 +726,22 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "js-sys", @@ -749,11 +784,20 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] [[package]] name = "hex-conservative" @@ -840,11 +884,10 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.5" +version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "futures-util", "http", "hyper", "hyper-util", @@ -858,18 +901,23 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" dependencies = [ + "base64 0.22.1", "bytes", "futures-channel", + "futures-core", "futures-util", "http", "http-body", "hyper", + "ipnet", + "libc", + "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.0", "tokio", "tower-service", "tracing", @@ -913,10 +961,10 @@ dependencies = [ "serde_bytes", "serde_cbor", "serde_repr", - "sha2 0.10.8", + "sha2 0.10.9", "simple_asn1", "stop-token", - "thiserror 2.0.12", + "thiserror 2.0.15", "time", "tokio", "tower-service", @@ -926,99 +974,110 @@ dependencies = [ [[package]] name = "ic-canister-log" version = "0.2.0" -source = "git+https://github.com/dfinity/ic?tag=release-2024-01-18_23-01#a7862784e8da4a97a1d608fd5b3db365de41a2d7" +source = "git+https://github.com/dfinity/ic?tag=release-2025-08-14_03-27-base#1db8f933fdadc81a90e7db2389b081e21263a9b6" dependencies = [ "serde", ] [[package]] -name = "ic-canisters-http-types" -version = "0.9.0" -source = "git+https://github.com/dfinity/ic?tag=release-2024-03-06_23-01%2Bp2p#fff20526e154f8b8d24373efd9b50f588d147e91" +name = "ic-cdk" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db9cc3e0e86ee12504c749fa33793014f1f4d6956a8a70e4db595169c5f6ac26" dependencies = [ "candid", + "ic-cdk-executor", + "ic-cdk-macros", + "ic-error-types", + "ic-management-canister-types", + "ic0", "serde", "serde_bytes", + "slotmap", + "thiserror 2.0.15", ] [[package]] -name = "ic-cdk" -version = "0.12.3" +name = "ic-cdk-executor" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c64e04d117461946f34785f8d327dc050a7e47abec6ffad93143dda5d755f1" +checksum = "15948808e3e7b50749fe50838df77fccaf048c8af2c26884ff5c8f787c29787a" dependencies = [ - "candid", - "ic-cdk-executor", - "ic-cdk-macros 0.8.4", - "ic0 0.21.1", - "serde", - "serde_bytes", + "slotmap", ] [[package]] -name = "ic-cdk" -version = "0.17.1" +name = "ic-cdk-macros" +version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122efbcb0af5280d408a75a57b7dc6e9d92893bf6ed9cc98fe4dcff51f18b67c" +checksum = "b190cace2b141a5801252115bdc27397d47f086c928af3e917ce1da81b17e3cd" dependencies = [ "candid", - "ic-cdk-macros 0.17.1", - "ic0 0.23.0", + "darling", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "ic-certification" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb40d73f9f8273dc6569a68859003bbd467c9dc6d53c6fd7d174742f857209d" +dependencies = [ + "hex", "serde", "serde_bytes", + "sha2 0.10.9", ] [[package]] -name = "ic-cdk-executor" -version = "0.1.0" +name = "ic-error-types" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "903057edd3d4ff4b3fe44a64eaee1ceb73f579ba29e3ded372b63d291d7c16c2" +checksum = "bbeeb3d91aa179d6496d7293becdacedfc413c825cac79fd54ea1906f003ee55" +dependencies = [ + "serde", + "strum", + "strum_macros", +] [[package]] -name = "ic-cdk-macros" -version = "0.8.4" +name = "ic-http-types" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5a618e4020cea88e933d8d2f8c7f86d570ec06213506a80d4f2c520a9bba512" +checksum = "207166ed1477b107f56c3d98f6c9ea771ed84be407567bc7099db907d98490a3" dependencies = [ "candid", - "proc-macro2", - "quote", "serde", - "serde_tokenstream 0.1.7", - "syn 1.0.109", + "serde_bytes", ] [[package]] -name = "ic-cdk-macros" -version = "0.17.1" +name = "ic-management-canister-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c792bf0d1621c893ccf2bcdeac4ee70121103a03030a1827031a6b3c60488944" +checksum = "95f3af3543f6d0cbdecd2dcdfd4737ada2bd42d935cc787eec22090c96492c76" dependencies = [ "candid", - "proc-macro2", - "quote", "serde", - "serde_tokenstream 0.2.2", - "syn 2.0.100", + "serde_bytes", ] [[package]] -name = "ic-certification" -version = "3.0.3" +name = "ic-stable-structures" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb40d73f9f8273dc6569a68859003bbd467c9dc6d53c6fd7d174742f857209d" +checksum = "4d30d4cf17aff1024e13133897048bcba580e063c9000571ab766ca37e2996f4" dependencies = [ - "hex", - "serde", - "serde_bytes", - "sha2 0.10.8", + "ic_principal", ] [[package]] name = "ic-stable-structures" -version = "0.6.8" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f5684f577e0146738cd11afed789109c4f51ba963c75823c48c1501dc53278" +checksum = "e54aeb082293c69def5ab34c70593ba85ff000386f7d0eacdf73514daaeca031" dependencies = [ "ic_principal", ] @@ -1037,8 +1096,8 @@ dependencies = [ "serde_bytes", "serde_cbor", "serde_repr", - "sha2 0.10.8", - "thiserror 2.0.12", + "sha2 0.10.9", + "thiserror 2.0.15", ] [[package]] @@ -1052,20 +1111,14 @@ dependencies = [ "lazy_static", "pairing", "rand 0.8.5", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] name = "ic0" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a54b5297861c651551676e8c43df805dad175cc33bc97dbd992edbbb85dcbcdf" - -[[package]] -name = "ic0" -version = "0.23.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de254dd67bbd58073e23dc1c8553ba12fa1dc610a19de94ad2bbcd0460c067f" +checksum = "8877193e1921b5fd16accb0305eb46016868cd1935b05c05eca0ec007b943272" [[package]] name = "ic_bls12_381" @@ -1090,65 +1143,72 @@ dependencies = [ "crc32fast", "data-encoding", "serde", - "sha2 0.10.8", + "sha2 0.10.9", "thiserror 1.0.69", ] [[package]] -name = "icrc-ledger-client" -version = "0.1.2" -source = "git+https://github.com/dfinity/ic?tag=release-2024-01-18_23-01#a7862784e8da4a97a1d608fd5b3db365de41a2d7" +name = "icrc-cbor" +version = "0.1.0" +source = "git+https://github.com/dfinity/ic?tag=release-2025-08-14_03-27-base#1db8f933fdadc81a90e7db2389b081e21263a9b6" dependencies = [ - "async-trait", "candid", - "icrc-ledger-types", - "serde", + "minicbor", + "num-bigint", + "num-traits", ] [[package]] -name = "icrc-ledger-client-cdk" -version = "0.1.2" -source = "git+https://github.com/dfinity/ic?tag=release-2024-01-18_23-01#a7862784e8da4a97a1d608fd5b3db365de41a2d7" +name = "icrc-ledger-client" +version = "0.1.3" +source = "git+https://github.com/dfinity/ic?tag=release-2025-08-14_03-27-base#1db8f933fdadc81a90e7db2389b081e21263a9b6" dependencies = [ "async-trait", "candid", - "ic-cdk 0.12.3", - "icrc-ledger-client", + "icrc-ledger-types", ] [[package]] name = "icrc-ledger-types" -version = "0.1.4" -source = "git+https://github.com/dfinity/ic?tag=release-2024-01-18_23-01#a7862784e8da4a97a1d608fd5b3db365de41a2d7" +version = "0.1.10" +source = "git+https://github.com/dfinity/ic?tag=release-2025-08-14_03-27-base#1db8f933fdadc81a90e7db2389b081e21263a9b6" dependencies = [ "base32", "candid", "crc32fast", "hex", + "ic-stable-structures 0.6.9", + "icrc-cbor", + "itertools 0.12.1", + "minicbor", "num-bigint", "num-traits", "serde", "serde_bytes", - "sha2 0.10.8", + "sha2 0.10.9", + "strum", + "strum_macros", + "time", ] [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -1157,31 +1217,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -1189,66 +1229,59 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] [[package]] -name = "icu_provider_macros" -version = "1.5.0" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" @@ -1263,9 +1296,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -1280,12 +1313,42 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-uring" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + [[package]] name = "ipnet" version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.14.0" @@ -1321,7 +1384,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.8", + "sha2 0.10.9", "signature", ] @@ -1339,21 +1402,27 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -1365,36 +1434,56 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] -name = "mime" -version = "0.3.17" +name = "minicbor" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "d7005aaf257a59ff4de471a9d5538ec868a21586534fff7f85dd97d4043a6139" +dependencies = [ + "minicbor-derive", +] + +[[package]] +name = "minicbor-derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1154809406efdb7982841adb6311b3d095b46f78342dd646736122fe6b19e267" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] [[package]] name = "mio" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", ] [[package]] @@ -1430,6 +1519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1443,9 +1533,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "opaque-debug" @@ -1462,7 +1552,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -1482,9 +1572,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -1492,15 +1582,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1556,6 +1646,15 @@ dependencies = [ "spki", ] +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -1568,14 +1667,14 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.24", + "zerocopy", ] [[package]] name = "pretty" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55c4d17d994b637e2f4daf6e5dc5d660d209d5642377d675d7a1c3ab69fa579" +checksum = "ac98773b7109bc75f475ab5a134c9b64b87e59d776d31098d8f346922396a477" dependencies = [ "arrayvec 0.5.2", "typed-arena", @@ -1593,27 +1692,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] [[package]] name = "psm" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58e5423e24c18cc840e1c98370b3993c6649cd1678b4d24318bcf0a083cbe88" +checksum = "6e944464ec8536cd1beb0bbfd96987eb5e3b72f2ecdafdc5c769a37f1fa2ae1f" dependencies = [ "cc", ] [[package]] name = "quinn" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" +checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" dependencies = [ "bytes", "cfg_aliases", @@ -1622,8 +1721,8 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2", - "thiserror 2.0.12", + "socket2 0.5.10", + "thiserror 2.0.15", "tokio", "tracing", "web-time", @@ -1631,19 +1730,20 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.10" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" +checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" dependencies = [ "bytes", - "getrandom 0.3.2", - "rand 0.9.0", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.2", "ring", "rustc-hash", "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.12", + "thiserror 2.0.15", "tinyvec", "tracing", "web-time", @@ -1651,14 +1751,14 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" +checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2", + "socket2 0.5.10", "tracing", "windows-sys 0.59.0", ] @@ -1674,9 +1774,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" @@ -1691,13 +1791,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy 0.8.24", ] [[package]] @@ -1726,7 +1825,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] @@ -1735,27 +1834,27 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.3", ] [[package]] name = "rangemap" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" +checksum = "f93e7e49bb0bf967717f7bd674458b3d6b0c5f48ec7e3038166026a69fc22223" [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ "bitflags", ] [[package]] name = "ree-cookie" -version = "0.1.1" +version = "0.2.6" dependencies = [ "anyhow", "bincode", @@ -1764,14 +1863,14 @@ dependencies = [ "hex", "ic-agent", "ic-canister-log", - "ic-canisters-http-types", - "ic-cdk 0.17.1", - "ic-cdk-macros 0.17.1", - "ic-stable-structures", - "icrc-ledger-client-cdk", + "ic-cdk", + "ic-cdk-macros", + "ic-http-types", + "ic-stable-structures 0.7.0", + "icrc-ledger-client", "icrc-ledger-types", - "itertools", - "ree-types", + "itertools 0.14.0", + "ree-exchange-sdk", "serde", "serde_bytes", "serde_derive", @@ -1781,10 +1880,35 @@ dependencies = [ "tokio", ] +[[package]] +name = "ree-exchange-sdk" +version = "0.10.0" +source = "git+https://github.com/octopus-network/ree-exchange-sdk.git?rev=9dedff405c1afccc31cb5551bc29616110483e48#9dedff405c1afccc31cb5551bc29616110483e48" +dependencies = [ + "bincode", + "candid", + "ic-cdk", + "ic-stable-structures 0.7.0", + "ree-exchange-sdk-macro", + "ree-types", + "serde", + "serde_bytes", +] + +[[package]] +name = "ree-exchange-sdk-macro" +version = "0.10.0" +source = "git+https://github.com/octopus-network/ree-exchange-sdk.git?rev=9dedff405c1afccc31cb5551bc29616110483e48#9dedff405c1afccc31cb5551bc29616110483e48" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "ree-types" -version = "0.5.0" -source = "git+https://github.com/octopus-network/ree-types.git?rev=3d0fb503384082bdeaf368305c4229801ee9ebd3#3d0fb503384082bdeaf368305c4229801ee9ebd3" +version = "0.10.0" +source = "git+https://github.com/octopus-network/ree-exchange-sdk.git?rev=9dedff405c1afccc31cb5551bc29616110483e48#9dedff405c1afccc31cb5551bc29616110483e48" dependencies = [ "anyhow", "bincode", @@ -1792,8 +1916,8 @@ dependencies = [ "candid", "generic-array", "hex", - "ic-cdk 0.17.1", - "ic-stable-structures", + "ic-cdk", + "ic-stable-structures 0.7.0", "serde", "serde_bytes", "thiserror 1.0.69", @@ -1801,9 +1925,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.15" +version = "0.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ "base64 0.22.1", "bytes", @@ -1816,16 +1940,12 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "ipnet", "js-sys", "log", - "mime", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", "rustls", - "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", @@ -1835,6 +1955,7 @@ dependencies = [ "tokio-rustls", "tokio-util", "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", @@ -1842,7 +1963,6 @@ dependencies = [ "wasm-streams", "web-sys", "webpki-roots", - "windows-registry", ] [[package]] @@ -1863,7 +1983,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -1871,9 +1991,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" @@ -1883,9 +2003,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustls" -version = "0.23.25" +version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ "once_cell", "ring", @@ -1895,29 +2015,21 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ "web-time", + "zeroize", ] [[package]] name = "rustls-webpki" -version = "0.103.0" +version = "0.103.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" dependencies = [ "ring", "rustls-pki-types", @@ -1926,9 +2038,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -2012,14 +2124,14 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" dependencies = [ "itoa", "memchr", @@ -2035,30 +2147,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", -] - -[[package]] -name = "serde_tokenstream" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "797ba1d80299b264f3aac68ab5d12e5825a561749db4df7cd7c8083900c5d4e9" -dependencies = [ - "proc-macro2", - "serde", - "syn 1.0.109", -] - -[[package]] -name = "serde_tokenstream" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64060d864397305347a78851c51588fd283767e7e7589829e8121d65512340f1" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] @@ -2088,9 +2177,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -2105,9 +2194,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] @@ -2130,35 +2219,51 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint", "num-traits", - "thiserror 2.0.12", + "thiserror 2.0.15", "time", ] [[package]] name = "slab" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ - "autocfg", + "version_check", ] [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "spki" version = "0.7.3" @@ -2177,9 +2282,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stacker" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9156ebd5870ef293bfb43f91c7a74528d363ec0d424afe24160ed5a4343d08a" +checksum = "cddb07e32ddb770749da91081d8d0ac3a16f1a569a18b20348cd371f5dead06b" dependencies = [ "cc", "cfg-if", @@ -2200,6 +2305,34 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.106", +] + [[package]] name = "subtle" version = "2.6.1" @@ -2225,9 +2358,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -2245,13 +2378,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] @@ -2265,11 +2398,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "80d76d3f064b981389ecb4b6b7f45a0bf9fdac1d5b9204c7bd6714fecc302850" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.15", ] [[package]] @@ -2280,18 +2413,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "44d29feb33e986b6ea906bd9c3559a856983f92371b3eaa5e83782a351623de0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] @@ -2327,9 +2460,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -2352,20 +2485,22 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.1" +version = "1.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "slab", + "socket2 0.6.0", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2376,7 +2511,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] @@ -2391,9 +2526,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.14" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", @@ -2417,6 +2552,24 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -2441,9 +2594,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", ] @@ -2495,12 +2648,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -2524,9 +2671,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -2559,7 +2706,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", "wasm-bindgen-shared", ] @@ -2594,7 +2741,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2643,55 +2790,20 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.8" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" dependencies = [ "rustls-pki-types", ] -[[package]] -name = "windows-link" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" - -[[package]] -name = "windows-registry" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" -dependencies = [ - "windows-result", - "windows-strings", - "windows-targets 0.53.0", -] - -[[package]] -name = "windows-result" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -2700,7 +2812,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -2709,30 +2821,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -2741,96 +2837,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - [[package]] name = "wit-bindgen-rt" version = "0.39.0" @@ -2840,23 +2888,17 @@ dependencies = [ "bitflags", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -2866,54 +2908,34 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy" -version = "0.8.24" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ - "zerocopy-derive 0.8.24", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "syn 2.0.106", ] [[package]] @@ -2933,7 +2955,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", "synstructure", ] @@ -2943,11 +2965,22 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ "yoke", "zerofrom", @@ -2956,11 +2989,11 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.106", ] diff --git a/ree-cookie-canister/Cargo.toml b/ree-cookie-canister/Cargo.toml index 6eb835b..cf34b88 100644 --- a/ree-cookie-canister/Cargo.toml +++ b/ree-cookie-canister/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ree-cookie" -version = "0.1.1" +version = "0.2.6" edition = "2021" [workspace] @@ -12,13 +12,15 @@ crate-type = ["cdylib"] [dependencies] candid = "0.10" -ic-cdk = "0.17" -ic-cdk-macros = "0.17" -ic-stable-structures = "0.6" -ic-canisters-http-types = { git = "https://github.com/dfinity/ic", tag = "release-2024-03-06_23-01+p2p" } -ic-canister-log = { git = "https://github.com/dfinity/ic", tag = "release-2024-01-18_23-01" } -icrc-ledger-client-cdk = { git = "https://github.com/dfinity/ic", tag = "release-2024-01-18_23-01" } -icrc-ledger-types = { git = "https://github.com/dfinity/ic", tag = "release-2024-01-18_23-01" } +ic-cdk = "0.18.4" +ic-cdk-macros = "0.18.4" +ic-stable-structures = "0.7" +# ic-canisters-http-types = { git = "https://github.com/dfinity/ic", tag = "release-2025-08-14_03-27-base" } +ic-http-types = "0.1.0" +ic-canister-log = { git = "https://github.com/dfinity/ic", tag = "release-2025-08-14_03-27-base" } +# icp-ledger = { git = "https://github.com/dfinity/ic", tag = "release-2025-08-14_03-27-base" } +icrc-ledger-client = { git = "https://github.com/dfinity/ic", tag = "release-2025-08-14_03-27-base" } +icrc-ledger-types = { git = "https://github.com/dfinity/ic", tag = "release-2025-08-14_03-27-base" } anyhow = "1" thiserror = "1" @@ -30,18 +32,15 @@ serde_json = "1.0" cfg-if = "1.0" time = "0.3" -# ree-types = { git = "https://github.com/octopus-network/ree-types.git", rev = "a48b38f16efdb1e9703e6e9c45af681ae2b61f59" } -# ree-types = "0.3" -# ree-types = { git = "https://github.com/octopus-network/ree-types.git", rev = "1bc6810a7aac2576c32bdca26b6dd399b1a307eb" } -# ree-types = { git = "https://github.com/octopus-network/ree-types.git", rev = "6d98cd59310a86d951105cbf4cf2a4feed2e2057" } -ree-types = { git = "https://github.com/octopus-network/ree-types.git", rev = "3d0fb503384082bdeaf368305c4229801ee9ebd3" } +# ree-exchange-sdk = { git = "https://github.com/octopus-network/ree-exchange-sdk.git", rev="b5bb7181449d3535de27239a6c0a03fbcf29e418" } +ree-exchange-sdk = { git = "https://github.com/octopus-network/ree-exchange-sdk.git", rev="9dedff405c1afccc31cb5551bc29616110483e48" } + bincode = "1.3.3" itertools = "0.14.0" [dev-dependencies] tokio = { version = "1", features = ["full"] } ic-agent = "0.39" -# ree-orchestrator = { git="https://github.com/octopus-network/ree-orchestrator.git", branch="main" } [features] default = ["testnet"] diff --git a/ree-cookie-canister/fomo10k.did b/ree-cookie-canister/fomo10k.did new file mode 100644 index 0000000..e69de29 diff --git a/ree-cookie-canister/ree_cookie.did b/ree-cookie-canister/ree_cookie.did index 6415d79..8beef79 100644 --- a/ree-cookie-canister/ree_cookie.did +++ b/ree-cookie-canister/ree_cookie.did @@ -3,6 +3,12 @@ type AddLiquidityInfo = record { rune_amount_for_add_liquidity : nat; }; type CoinBalance = record { id : text; value : nat }; +type CookiePoolState = record { + txid : text; + utxo : Utxo; + user_action : UserAction; + nonce : nat64; +}; type CreateGameArgs = record { rune_premine_amount : nat; create_address : text; @@ -23,7 +29,6 @@ type ExchangeError = variant { RuneNotFound : text; CookieBalanceInsufficient : nat; GameEnd; - ReorgError : ReorgError; GamerAlreadyExist : text; DuplicateBlock : record { nat32; text }; PoolStateExpired : nat64; @@ -36,7 +41,7 @@ type ExchangeError = variant { InvalidRuneId; InvalidPool; InvalidPsbt : text; - GameNotFound : nat64; + GameNotFound : text; PoolAlreadyExists; GamerCoolingDown : record { text; nat64 }; InvalidTxid : text; @@ -56,9 +61,8 @@ type ExchangeError = variant { PoolAddressMismatch : record { actual : text; expected : text }; }; type ExchangeState = record { - txid_game_map : vec record { text; nat64 }; - orchestrator : principal; - games : vec record { nat64; Game }; + txid_game_map : vec record { text; text }; + games : vec record { text; Game }; }; type ExecuteTxArgs = record { zero_confirmed_tx_queue_length : nat32; @@ -72,17 +76,22 @@ type Game = record { claimed_cookies : nat; rune_premine_amount : nat; creator_address : text; - pool : opt Pool; rune_info : opt RuneInfo; gamers : vec record { text; Gamer }; claim_amount_per_click : nat; - game_id : nat64; + game_id : text; game_status : GameStatus; game_name : text; etch_rune_commit_tx : text; + pool_address : opt text; claim_cooling_down : nat64; gamer_register_fee : nat64; }; +type GameAndPool = record { + game : Game; + pool_state : opt CookiePoolState; + pool_metadata : opt Metadata; +}; type GameStatus = variant { WaitAddedLiquidity; Playing; Withdrawing; Etching }; type Gamer = record { is_withdrawn : bool; @@ -108,6 +117,12 @@ type IntentionSet = record { initiator_address : text; intentions : vec Intention; }; +type Metadata = record { + key : text; + name : text; + key_derivation_path : vec blob; + address : text; +}; type NewBlockInfo = record { block_hash : text; confirmed_txids : vec text; @@ -115,16 +130,6 @@ type NewBlockInfo = record { block_height : nat32; }; type OutputCoin = record { to : text; coin : CoinBalance }; -type Pool = record { - states : vec PoolState; - name : text; - pubkey : text; - key_derivation_path : text; - attributes : text; - address : text; - nonce : nat64; - pending_transaction_counts : nat64; -}; type PoolBasic = record { name : text; address : text }; type PoolInfo = record { key : text; @@ -137,12 +142,6 @@ type PoolInfo = record { nonce : nat64; utxos : vec Utxo; }; -type PoolState = record { - id : text; - utxo : Utxo; - user_action : UserAction; - nonce : nat64; -}; type RejectionCode = variant { NoError; CanisterError; @@ -152,23 +151,16 @@ type RejectionCode = variant { SysFatal; CanisterReject; }; -type ReorgError = variant { - DuplicateBlock : record { height : nat32; hash : text }; - BlockNotFoundInState : record { height : nat32 }; - Unrecoverable; - Recoverable : record { height : nat32; depth : nat32 }; -}; type Result = variant { Ok : nat; Err : ExchangeError }; -type Result_1 = variant { Ok : nat64; Err : text }; -type Result_2 = variant { Ok : text; Err : text }; -type Result_3 = variant { Ok; Err : text }; -type RollbackTxArgs = record { txid : text }; +type Result_1 = variant { Ok : text; Err : text }; +type Result_2 = variant { Ok; Err : text }; +type RollbackTxArgs = record { txid : text; reason_code : text }; type RuneInfo = record { rune_name : text; rune_id : text }; type UserAction = variant { - Withdraw : text; + Withdraw : record { text; text }; AddLiquidity; Init; - Register : text; + Register : record { text; text }; }; type Utxo = record { coins : vec CoinBalance; @@ -176,20 +168,21 @@ type Utxo = record { txid : text; vout : nat32; }; -service : (principal) -> { - claim : (nat64) -> (Result); +service : () -> { + claim : (text) -> (Result); create_game : (CreateGameArgs) -> (Result_1); - etch_rune : (nat64, text) -> (Result_2); - execute_tx : (ExecuteTxArgs) -> (Result_2); - finalize_etch : (nat64) -> (Result_2); + etch_rune : (text, text) -> (Result_1); + execute_tx : (ExecuteTxArgs) -> (Result_1); + finalize_etch : (text) -> (Result_1); + game_address : (text) -> (Result_1); get_exchange_state : () -> (ExchangeState) query; - get_game_info : (nat64) -> (opt Game) query; - get_game_pool_address : (nat64) -> (text); - get_games_info : () -> (vec Game) query; + get_game_info : (text) -> (opt GameAndPool) query; + get_game_pool_address : (text) -> (text); + get_games_info : () -> (vec GameAndPool) query; get_pool_info : (GetPoolInfoArgs) -> (opt PoolInfo) query; get_pool_list : () -> (vec PoolBasic) query; - new_block : (NewBlockInfo) -> (Result_3); - query_add_liquidity_info : (nat64) -> (AddLiquidityInfo) query; - reset_blocks : () -> (); - rollback_tx : (RollbackTxArgs) -> (Result_3); + new_block : (NewBlockInfo) -> (Result_2); + query_add_liquidity_info : (text) -> (AddLiquidityInfo) query; + rollback_tx : (RollbackTxArgs) -> (Result_2); + test : () -> (); } diff --git a/ree-cookie-canister/src/canister.rs b/ree-cookie-canister/src/canister.rs index 2c56750..19c097e 100644 --- a/ree-cookie-canister/src/canister.rs +++ b/ree-cookie-canister/src/canister.rs @@ -1,41 +1,40 @@ -use std::{collections::HashMap, str::FromStr}; +use std::str::FromStr; pub use crate::log::*; use crate::{ + exchange::{ + self, + exchange::{ + AddressPrincipalMap, CookiePools, State, __CustomStorageAccess, mutate_state, + read_state, + }, + CookiePoolState, + }, external::{ etch_canister::{etching, get_etching_request, EtchingArgs, EtchingStatus}, internal_identity::get_principal, rune_indexer::get_etching, }, - game:: - game::{CreateGameArgs, Game, RuneInfo} - , + game::game::{CreateGameArgs, Game, GameAndPool, RuneInfo}, log, - memory::{mutate_state, read_state, set_state, ADDRESS_PRINCIPLE_MAP, BLOCKS, TX_RECORDS}, - pool::Pool, state::ExchangeState, - utils::{request_address, AddLiquidityInfo}, + utils::AddLiquidityInfo, AddressStr, ExchangeError, GameId, DUST_BTC_VALUE, }; -use candid::Principal; use ic_cdk::{init, post_upgrade, query, update}; -use ree_types::{ - bitcoin::{Network, Psbt}, - exchange_interfaces::{ - ExecuteTxArgs, ExecuteTxResponse, GetPoolInfoArgs, GetPoolInfoResponse, GetPoolListResponse, NewBlockArgs, NewBlockResponse, - PoolBasic, PoolInfo, RollbackTxArgs, RollbackTxResponse, - }, - psbt::ree_pool_sign, - CoinBalance, CoinBalances, CoinId, Intention, Txid, Utxo, +use ic_stable_structures::Storable; +use itertools::Itertools; +use ree_exchange_sdk::{ + prelude::schnorr::request_p2tr_address, + types::{CoinBalance, CoinBalances, CoinId, Txid, Utxo}, + Metadata, PoolStorageAccess, }; #[init] -fn init( - orchestrator: Principal, -) { - set_state(ExchangeState::init( - orchestrator, - )); +fn init() { + State::with_mut(|s| { + s.set(Some(ExchangeState::default())); + }); } #[update] @@ -43,21 +42,24 @@ pub async fn create_game(create_game_args: CreateGameArgs) -> Result create_game_args.claim_amount_per_click, + assert!( + create_game_args.rune_premine_amount > create_game_args.claim_amount_per_click, "Total cookie amount must be greater than cookie amount per claim" ); - assert!(create_game_args.rune_premine_amount % 10 == 0, + assert!( + create_game_args.rune_premine_amount % 10 == 0, "Total cookie amount must be divisible by 10" ); assert!( - (create_game_args.rune_premine_amount * 4/5) % create_game_args.claim_amount_per_click == 0, + (create_game_args.rune_premine_amount * 4 / 5) % create_game_args.claim_amount_per_click + == 0, "Total cookie amount must be divisible by cookie amount per claim" ); let game_id = mutate_state(|s| { - let game_id = s.games.len(); - let game = Game::new(create_game_args, ic_cdk::caller(), game_id); - s.games.insert(game_id, game); + let game_id = s.games.len().to_string(); + let game = Game::new(create_game_args, ic_cdk::caller(), game_id.clone()); + s.games.insert(game_id.clone(), game); game_id }); @@ -66,16 +68,23 @@ pub async fn create_game(create_game_args: CreateGameArgs) -> Result AddressStr { + let pool_opt = exchange::exchange::CookiePools::get(&game_id); let game = read_state(|es| es.games.get(&game_id).expect("Game Not Found").clone()); - if let Some(pool) = game.pool { - return pool.address.clone(); + if let Some(pool) = pool_opt { + return pool.metadata().address.to_string(); } else { let key_path = game.key_path(); - let (_pubkey, _tweaked_pubkey, address) = request_address(key_path) - .await - .expect("Failed to request address"); - return address.to_string(); + // let (_pubkey, _tweaked_pubkey, address) = request_address(key_path) + // .await + // .expect("Failed to request address"); + let (_pubkey, _tweaked_pubkey, pool_address) = request_p2tr_address( + vec![key_path.to_bytes().to_vec()], + ree_exchange_sdk::Network::Testnet4, + ) + .await + .expect("Failed to request address"); + return pool_address.to_string(); } } @@ -85,20 +94,60 @@ fn get_exchange_state() -> ExchangeState { } #[query] -fn get_games_info() -> Vec { - read_state(|es| es.games.values().cloned().collect()) +fn get_games_info() -> Vec { + let games = read_state(|es| es.games.values().cloned().collect_vec()); + + let mut game_and_pool_list = vec![]; + for game in games { + let pool_address_opt = game.pool_address.clone(); + + let pool = pool_address_opt + .map(|pool_address| { + exchange::exchange::CookiePools::get(&pool_address) + .map(|p| (p.metadata().clone(), p.last_state().unwrap().clone())) + }) + .unwrap_or(None); + + // let pool = exchange::exchange::CookiePools::get(&game.game_id) + // .map(|p| (p.metadata().clone(), p.last_state().unwrap().clone())); + + game_and_pool_list.push(GameAndPool { + game, + pool_metadata: pool.clone().map(|p| p.0), + pool_state: pool.map(|p| p.1), + }); + } + + game_and_pool_list } #[query] -fn get_game_info(game_id: GameId) -> Option { - read_state(|s| s.games.get(&game_id).cloned()) +fn get_game_info(game_id: GameId) -> Option { + let game_opt = read_state(|s| s.games.get(&game_id).cloned()); + if game_opt.is_none() { + return None; + } + let game = game_opt.unwrap(); + let pool_address_opt = game.pool_address.clone(); + let pool = pool_address_opt + .map(|pool_address| { + exchange::exchange::CookiePools::get(&pool_address) + .map(|p| (p.metadata().clone(), p.last_state().unwrap().clone())) + }) + .unwrap_or(None); + + Some(GameAndPool { + game, + pool_metadata: pool.clone().map(|p| p.0), + pool_state: pool.map(|p| p.1), + }) } #[update] pub fn claim(game_id: GameId) -> Result { let principal = ic_cdk::caller(); - let address = crate::memory::ADDRESS_PRINCIPLE_MAP.with_borrow(|m| { + let address = AddressPrincipalMap::with(|m| { m.get(&principal) .ok_or(ExchangeError::GamerNotFound(principal.to_text().clone())) })?; @@ -111,6 +160,26 @@ pub fn claim(game_id: GameId) -> Result { }) } +#[update] +async fn game_address(game_id: GameId) -> Result { + let game = read_state(|s| { + s.games + .get(&game_id) + .cloned() + .ok_or_else(|| format!("Game with ID {} not found", game_id)) + })?; + let key_path = game.key_path(); + + let (_pubkey, _tweaked_pubkey, pool_address) = request_p2tr_address( + vec![key_path.to_bytes().to_vec()], + ree_exchange_sdk::Network::Testnet4, + ) + .await + .expect("Failed to request address"); + + Ok(pool_address.to_string()) +} + #[update] async fn etch_rune(game_id: GameId, rune_name: String) -> std::result::Result { let game = read_state(|s| { @@ -127,9 +196,12 @@ async fn etch_rune(game_id: GameId, rune_name: String) -> std::result::Result Result { assert!(result.confirmations >= 1, "Etching not confirmed yet"); let key_path = game.key_path(); - let (pubkey, _tweaked_pubkey, pool_address) = request_address(key_path.clone()) - .await - .expect("Failed to request address"); + let (pubkey, _tweaked_pubkey, pool_address) = request_p2tr_address( + vec![key_path.to_bytes().to_vec()], + ree_exchange_sdk::Network::Testnet4, + ) + .await + .expect("Failed to request address"); + + let mut coin_balances = CoinBalances::new(); + coin_balances.add_coin(&CoinBalance { + id: CoinId::btc(), + value: DUST_BTC_VALUE as u128, + }); + coin_balances.add_coin(&CoinBalance { + id: CoinId::from_str(result.rune_id.as_str()) + .expect("Failed to parse rune ID from etching result"), + value: info.etching_args.premine.expect("Premine amount not found") as u128, + }); + + exchange::exchange::new_pool_by_utxo( + key_path.clone(), + key_path, + pubkey, + pool_address.to_string(), + Utxo { + txid: Txid::from_str(&reveal_tx_id).expect("Failed to parse reveal tx id"), + vout: 1, + coins: coin_balances, + sats: DUST_BTC_VALUE, + }, + ); mutate_state(|es| { let game = es.games.get_mut(&game_id).expect("Game not found"); @@ -203,30 +302,8 @@ pub async fn finalize_etch(game_id: GameId) -> Result { old_rune_info.rune_id = CoinId::from_str(result.rune_id.as_str()) .expect("Failed to parse rune ID from etching result"); game.rune_info = Some(old_rune_info); + game.pool_address = Some(pool_address.to_string()); - let mut coin_balances = CoinBalances::new(); - coin_balances.add_coin(&CoinBalance { - id: CoinId::btc(), - value: DUST_BTC_VALUE as u128, - }); - coin_balances.add_coin(&CoinBalance { - id: CoinId::from_str(result.rune_id.as_str()) - .expect("Failed to parse rune ID from etching result"), - value: info.etching_args.premine.expect("Premine amount not found") as u128, - }); - game.pool = Some(Pool::init( - key_path.clone(), - key_path, - pubkey, - pool_address.to_string(), - result.rune_id, - Utxo { - txid: Txid::from_str(&reveal_tx_id).expect("Failed to parse reveal tx id"), - vout: 1, - coins: coin_balances, - sats: DUST_BTC_VALUE, - }, - )); game.game_status = game.game_status.finish_etching(); }); @@ -245,431 +322,30 @@ pub fn query_add_liquidity_info(game_id: GameId) -> AddLiquidityInfo { }) } -/// REE API -#[query] -pub fn get_pool_info(args: GetPoolInfoArgs) -> GetPoolInfoResponse { - let pool_address = args.pool_address; - - read_state(|es| { - let mut aim_pool = None; - for (_id, game) in &es.games { - if let Some(pool) = &game.pool { - if pool.address.eq(&pool_address) { - aim_pool = Some(pool.clone()); - break; - } - } - } - - if let Some(pool) = aim_pool { - return pool.last_state().map(|last_state| PoolInfo { - key: pool.pubkey.clone(), - key_derivation_path: vec![pool.key_derivation_path.clone().into_bytes()], - name: pool.name.clone(), - address: pool.address.clone(), - nonce: last_state.nonce, - coin_reserved: last_state.utxo.coins.iter().map(|cb| cb.clone()).collect(), - btc_reserved: last_state.btc_balance(), - utxos: vec![last_state.utxo], - attributes: "".to_string(), - }); - } else { - return None; - } - }) -} - -#[query] -pub fn get_pool_list() -> GetPoolListResponse { - - read_state(|es| { - let mut pool_list = vec![]; - for (_, game) in &es.games { - if let Some(pool) = &game.pool { - pool_list.push(PoolBasic { - name: pool.name.clone(), - address: pool.address.clone(), - }); - } - } - - return pool_list; - }) -} - #[query(hidden = true)] -fn http_request( - req: ic_canisters_http_types::HttpRequest, -) -> ic_canisters_http_types::HttpResponse { +fn http_request(req: ic_http_types::HttpRequest) -> ic_http_types::HttpResponse { if ic_cdk::api::data_certificate().is_none() { ic_cdk::trap("update call rejected"); } if req.path() == "/logs" { log::do_reply(req) } else { - ic_canisters_http_types::HttpResponseBuilder::not_found().build() + ic_http_types::HttpResponseBuilder::not_found().build() } } -#[update(guard = "ensure_orchestrator")] -async fn execute_tx(args: ExecuteTxArgs) -> ExecuteTxResponse { - let r = internal_execute_tx(args).await; - - if r.is_err() { - log!(ERROR, "execute_tx error: {:?}", r); - } else { - log!(INFO, "execute_tx success, txid: {:?}", r.clone().unwrap()); - } - - r -} - -pub(crate) async fn internal_execute_tx(args: ExecuteTxArgs) -> ExecuteTxResponse { - let ExecuteTxArgs { - psbt_hex, - txid, - intention_set, - intention_index, - zero_confirmed_tx_queue_length: _zero_confirmed_tx_queue_length, - } = args; - let raw = hex::decode(&psbt_hex).map_err(|_| "invalid psbt".to_string())?; - let mut psbt = Psbt::deserialize(raw.as_slice()).map_err(|_| "invalid psbt".to_string())?; - let intention = intention_set.intentions[intention_index as usize].clone(); - let initiator = intention_set.initiator_address.clone(); - let Intention { - exchange_id: _, - action, - action_params, - pool_address, - nonce, - pool_utxo_spent, - pool_utxo_received, - input_coins, - output_coins, - } = intention; - let action_params_json_value = - serde_json::from_str::(action_params.as_str()) - .map_err(|_| "invalid action params".to_string())?; - - let game = read_state(|es| { - let game_id = action_params_json_value - .get("game_id") - .and_then(|v| v.as_u64().map(|e| e as usize)) - .ok_or("invalid game id".to_string())?; - - es.games - .get(&game_id) - .cloned() - .ok_or("Game not found".to_string()) - })?; - - match action.as_str() { - "register" => { - let (new_state, (key_derivation_path, utxo)) = game - .validate_register( - txid, - nonce, - pool_utxo_spent, - pool_utxo_received, - input_coins, - output_coins, - initiator.clone(), - ) - .map_err(|e| e.to_string())?; - ree_pool_sign( - &mut psbt, - vec![&utxo], - "key_1", - vec![key_derivation_path.into_bytes()], - ) - .await - .map_err(|e| e.to_string())?; - - let principal_of_initiator = get_principal(initiator.clone()).await?; - - mutate_state(|es| { - let game_id = game.game_id; - let game = es.games.get_mut(&game_id).ok_or("Game not found").unwrap(); - game.register_new_gamer(initiator.clone()) - .expect("Failed to register gamer"); - game.pool.as_mut().unwrap().commit(new_state); - }); - - ADDRESS_PRINCIPLE_MAP.with_borrow_mut(|m| { - m.insert(principal_of_initiator, initiator.clone()); - }); - } - "add_liquidity" => { - // let rich_swap_address = read_state(|s| s.richswap_pool_address.clone()); - let (new_state, (key_derivation_path, utxo)) = game - .validate_add_liquidity( - txid, - nonce, - pool_utxo_spent, - pool_utxo_received, - input_coins, - output_coins, - ) - .map_err(|e| e.to_string())?; - - log!(INFO, "psbt: {:?}", serde_json::to_string_pretty(&psbt)); - - ree_pool_sign( - &mut psbt, - vec![&utxo], - "key_1", - vec![key_derivation_path.into_bytes()], - ) - .await - .map_err(|e| e.to_string())?; - log!(INFO, "psbt: {:?}", serde_json::to_string_pretty(&psbt)); - - mutate_state(|es| { - // let game_id = serde_json::from_str::(action_params.as_str()) - // .map_err(|_| "invalid game id".to_string()) - // .unwrap(); - let game_id = game.game_id; - let game = es.games.get_mut(&game_id).ok_or("Game not found").unwrap(); - game.pool.as_mut().unwrap().commit(new_state); - game.game_status = game.game_status.finish_add_liquidity(); - }); - } - "withdraw" => { - let (new_state, (key_derivation_path, utxo)) = game - .validate_withdraw( - txid, - nonce, - pool_utxo_spent, - pool_utxo_received, - input_coins, - output_coins, - initiator.clone(), - ) - .map_err(|e| e.to_string())?; - - ree_pool_sign( - &mut psbt, - vec![&utxo], - "key_1", - vec![key_derivation_path.into_bytes()], - ) - .await - .map_err(|e| e.to_string())?; - log!(INFO, "psbt: {:?}", serde_json::to_string_pretty(&psbt)); - - mutate_state(|es| { - let game_id = game.game_id; - let game = es.games.get_mut(&game_id).ok_or("Game not found").unwrap(); - game.pool.as_mut().unwrap().commit(new_state); - game.withdraw(initiator.clone()) - .expect("Failed to withdraw"); - }); - } - _ => { - return Err("invalid method".to_string()); - } - } - - // Record the transaction as unconfirmed and track which pools it affects - TX_RECORDS.with_borrow_mut(|m| { - ic_cdk::println!("new unconfirmed txid: {} in pool: {} ", txid, pool_address); - let mut record = m.get(&(txid.clone(), false)).unwrap_or_default(); - if !record.pools.contains(&pool_address) { - record.pools.push(pool_address.clone()); - } - m.insert((txid.clone(), false), record); - }); - - Ok(psbt.serialize_hex()) -} - -/// REE API -#[update(guard = "ensure_orchestrator")] -pub fn new_block(args: NewBlockArgs) -> NewBlockResponse { - match crate::reorg::detect_reorg(Network::Testnet4, args.clone()) { - Ok(_) => {} - Err(crate::reorg::ReorgError::DuplicateBlock { height, hash }) => { - ic_cdk::println!( - "Duplicate block detected at height {} with hash {}", - height, - hash - ); - } - Err(crate::reorg::ReorgError::Unrecoverable) => { - return Err("Unrecoverable reorg detected".to_string()); - } - Err(crate::reorg::ReorgError::BlockNotFoundInState { height }) => { - return Err(format!("Block not found in state at height {}", height)); - } - Err(crate::reorg::ReorgError::Recoverable { height, depth }) => { - crate::reorg::handle_reorg(height, depth); - } - } - - let NewBlockArgs { - block_height, - block_hash: _, - block_timestamp: _, - confirmed_txids, - } = args.clone(); - - // Store the new block information - BLOCKS.with_borrow_mut(|m| { - m.insert(block_height, args); - ic_cdk::println!("new block {} inserted into blocks", block_height,); - }); - - // Mark transactions as confirmed - for txid in confirmed_txids { - TX_RECORDS.with_borrow_mut(|m| { - if let Some(record) = m.get(&(txid.clone(), false)) { - m.insert((txid.clone(), true), record.clone()); - ic_cdk::println!("confirm txid: {} with pools: {:?}", txid, record.pools); - } - }); - } - // Calculate the height below which blocks are considered fully confirmed (beyond reorg risk) - let confirmed_height = - block_height - crate::reorg::get_max_recoverable_reorg_depth(Network::Testnet4) + 1; - - // let exchange_pool_address = - // read_state(|s| s.address.clone()).ok_or("pool address not init".to_string())?; - - let all_pool_of_game_map: HashMap = read_state(|es| { - es.games - .iter() - .filter_map(|(game_id, game)| { - game.pool - .clone() - .and_then(|pool| Some((pool.address.clone(), *game_id))) - }) - .collect() - }); - - // Finalize transactions in confirmed blocks - BLOCKS.with_borrow(|m| { - m.iter() - .take_while(|(height, _)| *height <= confirmed_height) - .for_each(|(height, block_info)| { - ic_cdk::println!("finalizing txs in block: {}", height); - block_info.confirmed_txids.into_iter().for_each(|txid| { - TX_RECORDS.with_borrow_mut(|m| { - if let Some(record) = m.get(&(txid.clone(), true)) { - record.pools.iter().for_each(|pool_addr| { - if let Some(game_id) = all_pool_of_game_map.get(pool_addr) { - mutate_state(|es| { - es.games - .get_mut(game_id) - .expect("Game not found") - .finalize_tx(txid.clone()) - .expect("Failed to finalize tx") - }); - } - }); - } - }) - }) - }) - }); - - // Clean up old block data that's no longer needed - BLOCKS.with_borrow_mut(|m| { - let heights_to_remove: Vec = m - .iter() - .take_while(|(height, _)| *height <= confirmed_height) - .map(|(height, _)| height) - .collect(); - for height in heights_to_remove { - ic_cdk::println!("removing block: {}", height); - m.remove(&height); - } - }); - - Ok(()) -} - -/// REE API -#[update(guard = "ensure_orchestrator")] -pub fn rollback_tx(args: RollbackTxArgs) -> RollbackTxResponse { - // read_state(|s| - // s.key.clone().ok_or("key not init".to_string())? - // .eq(&args.pool_key) - // .then(|| ()) - // .ok_or("key not match".to_string()) - // )?; - - // mutate_state(|es| es.rollback(args.txid)).map_err(|e| e.to_string()) - - // let cookie_pool = - // read_state(|s| s.address.clone()).ok_or("pool address not init".to_string())?; - - let all_pool_of_game_map: HashMap = read_state(|es| { - es.games - .iter() - .filter_map(|(game_id, game)| { - game.pool - .clone() - .and_then(|pool| Some((pool.address.clone(), *game_id))) - }) - .collect() - }); - - TX_RECORDS.with_borrow(|m| { - let maybe_unconfirmed_record = m.get(&(args.txid.clone(), false)); - let maybe_confirmed_record = m.get(&(args.txid.clone(), true)); - let record = maybe_confirmed_record.or(maybe_unconfirmed_record).unwrap(); - ic_cdk::println!( - "rollback txid: {} with pools: {:?}", - args.txid, - record.pools - ); - - // Roll back each affected pool to its state before this transaction - record.pools.iter().for_each(|pool_address| { - if let Some(game_id) = all_pool_of_game_map.get(pool_address) { - mutate_state(|es| { - es.games - .get_mut(&game_id) - .expect("Game not found") - .rollback_tx(args.txid.clone()) - .expect("Failed to rollback tx"); - }); - } - - // if pool_address.eq(&cookie_pool) { - // // Rollback the state of the pool - // mutate_state(|s| s.rollback(args.txid)).unwrap(); - // } - }); - }); - - Ok(()) -} - -#[update(guard = "is_controller")] -pub fn reset_blocks() { - BLOCKS.with_borrow_mut(|b| { - b.clear_new(); - }); -} - -fn is_controller() -> std::result::Result<(), String> { - ic_cdk::api::is_controller(&ic_cdk::caller()) - .then(|| ()) - .ok_or("Access denied".to_string()) -} - -fn ensure_orchestrator() -> std::result::Result<(), String> { - read_state(|s| { - s.orchestrator - .eq(&ic_cdk::caller()) - .then(|| ()) - .ok_or("Access denied".to_string()) - }) -} - #[post_upgrade] fn post_upgrade() { + mutate_state(|es| { + es.games.get_mut(&"0".to_string()).map(|game| { + game.etch_rune_commit_tx = + "343658c5f1937d38f9db2fe65d43a3cd7a96054b31387b148d511be3e6a9292b".to_string(); + game.rune_info = Some(RuneInfo { + rune_id: CoinId::btc(), + rune_name: "TEST•COOKIE•VWG".to_string(), + }); + }) + }); log!( INFO, @@ -677,6 +353,3 @@ fn post_upgrade() { env!("CARGO_PKG_VERSION") ); } - -// Enable Candid export -ic_cdk::export_candid!(); diff --git a/ree-cookie-canister/src/errors.rs b/ree-cookie-canister/src/errors.rs index 080948c..2dc63a9 100644 --- a/ree-cookie-canister/src/errors.rs +++ b/ree-cookie-canister/src/errors.rs @@ -66,7 +66,7 @@ pub enum ExchangeError { #[error("Cookie balance({0}) insufficient")] CookieBalanceInsufficient(u128), #[error("Game Not Found: {0}")] - GameNotFound(usize), + GameNotFound(String), #[error("Game Not End")] GameNotEnd, #[error("Game End")] @@ -86,9 +86,6 @@ pub enum ExchangeError { #[error("Invalid block, height: {0}, depth: {1}")] Recoverable(u32, u32), - #[error("Reorg error: {0}")] - ReorgError(#[from] reorg::ReorgError), - #[error("Pool address mismatch, expected: {expected}, actual: {actual}")] PoolAddressMismatch { expected: AddressStr, diff --git a/ree-cookie-canister/src/exchange.rs b/ree-cookie-canister/src/exchange.rs new file mode 100644 index 0000000..bfd804e --- /dev/null +++ b/ree-cookie-canister/src/exchange.rs @@ -0,0 +1,352 @@ +use std::borrow::Cow; + +use candid::CandidType; +use ic_stable_structures::{storable::Bound, Storable}; +use ree_exchange_sdk::prelude::*; +use ree_exchange_sdk::{ + types::{CoinBalance, Txid, Utxo}, + StateInfo, StateView, +}; +use serde::{Deserialize, Serialize}; + +use crate::{AddressStr, GameId}; + +#[derive(Deserialize, Serialize, Clone, Debug, CandidType, PartialEq, Eq)] +pub enum UserAction { + Init, + AddLiquidity, + Register(GameId, AddressStr), + Withdraw(GameId, AddressStr), +} + +#[derive(CandidType, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct CookiePoolState { + pub txid: Txid, + pub nonce: u64, + pub utxo: Utxo, + pub user_action: UserAction, +} + +impl Storable for CookiePoolState { + const BOUND: Bound = Bound::Unbounded; + fn to_bytes(&self) -> std::borrow::Cow<[u8]> { + Cow::Owned(bincode::serialize(self).unwrap()) + } + + fn from_bytes(bytes: std::borrow::Cow<[u8]>) -> Self { + bincode::deserialize(bytes.as_ref()).unwrap() + } + + fn into_bytes(self) -> Vec { + let mut bytes = vec![]; + bincode::serialize_into(&mut bytes, &self).unwrap(); + bytes + } +} + +impl StateView for CookiePoolState { + fn inspect_state(&self) -> StateInfo { + let mut coin_reserved: Vec = vec![]; // Placeholder, as CoinBalance is not defined in the provided context + self.utxo.coins.iter().for_each(|c| { + coin_reserved.push(c.clone()); + }); + + StateInfo { + txid: self.txid, + nonce: self.nonce, + coin_reserved: coin_reserved, + btc_reserved: self.utxo.sats, + utxos: vec![self.utxo.clone()], + attributes: "{}".to_string(), + } + } +} + +#[exchange] +pub mod exchange { + + use candid::Principal; + use ree_exchange_sdk::{ + store::{StableBTreeMap, StableCell}, + types::{bitcoin, Intention, Pubkey}, + }; + + use crate::{external::internal_identity::get_principal, state::ExchangeState}; + + use super::*; + + #[storage(0)] + pub type State = StableCell; + + #[storage(1)] + pub type AddressPrincipalMap = StableBTreeMap; + + #[pools] + pub struct CookiePools; + + impl Pools for CookiePools { + type State = CookiePoolState; + + const POOL_MEMORY: u8 = 100; + + const BLOCK_MEMORY: u8 = 101; + + const TRANSACTION_MEMORY: u8 = 102; + + fn network() -> Network { + Network::Testnet4 + } + + // This is optional + fn finalize_threshold() -> u32 { + 60 + } + } + + pub fn new_pool_by_utxo( + pool_name: String, + key_path: String, + pubkey: Pubkey, + address: AddressStr, + // attributes: String, + utxo: Utxo, + ) { + let mut pool = Pool::new(Metadata { + key: pubkey, + key_derivation_path: vec![key_path.clone().into_bytes()], + name: pool_name.clone(), + address: address.to_string(), + }); + pool.states_mut().push(CookiePoolState { + txid: utxo.txid.clone(), + nonce: 0, + utxo: utxo, + user_action: UserAction::Init, + }); + CookiePools::insert(pool); + } + + pub fn mutate_pool( + pool_address: &AddressStr, + f: impl FnOnce(&mut Pool) -> std::result::Result<(), String>, + ) -> std::result::Result<(), String> { + let mut pool = CookiePools::get(pool_address) + .ok_or_else(|| format!("Pool with address {} not found", pool_address))?; + f(&mut pool)?; + CookiePools::insert(pool); + Ok(()) + } + + #[hook] + impl Hook for CookiePools { + fn on_tx_rollbacked( + _address: String, + _txid: Txid, + _reason: String, + rollbacked_states: Vec, + ) { + for e in rollbacked_states { + match e.user_action { + UserAction::Register(game_id, address) => { + // State::with_mut(|es| { + // let game = es.games.get_mut(&game_id).unwrap(); + // game.gamers.remove(&address); + // }); + mutate_state(|es| { + let game = es.games.get_mut(&game_id).unwrap(); + game.gamers.remove(&address); + }); + } + UserAction::Withdraw(game_id, address) => { + mutate_state(|es| { + let game = es.games.get_mut(&game_id).unwrap(); + game.gamers + .get_mut(&address) + .map(|g| g.is_withdrawn = false); + }); + } + _ => {} + } + } + } + } + + #[action] + pub async fn register(_psbt: &bitcoin::Psbt, args: ActionArgs) -> ActionResult { + let Intention { + exchange_id: _, + action: _, + action_params, + pool_address, + nonce, + pool_utxo_spent, + pool_utxo_received, + input_coins, + output_coins, + } = args.intention; + let action_params_json_value = + serde_json::from_str::(action_params.as_str()) + .map_err(|_| "invalid action params".to_string())?; + let game = read_state(|es| { + let game_id = action_params_json_value + .get("game_id") + .map(|v| v.to_string()) + .ok_or("invalid game id".to_string())?; + + es.games + .get(&game_id) + .cloned() + .ok_or("Game not found".to_string()) + })?; + let (new_state, (_key_derivation_path, _utxo)) = game + .validate_register( + pool_address.clone(), + args.txid.clone(), + nonce, + pool_utxo_spent, + pool_utxo_received, + input_coins, + output_coins, + args.initiator_address.clone(), + ) + .map_err(|e| e.to_string())?; + + let initiator = args.initiator_address.clone(); + let principal_of_initiator = get_principal(initiator.clone()).await?; + mutate_state(|es| { + let game_id = game.game_id; + let game = es.games.get_mut(&game_id).ok_or("Game not found").unwrap(); + game.register_new_gamer(initiator.clone()) + .expect("Failed to register gamer"); + }); + AddressPrincipalMap::with_mut(|m| { + m.insert(principal_of_initiator, initiator.clone()); + }); + Ok(new_state) + } + + #[action] + pub async fn add_liquidity( + _psbt: &bitcoin::Psbt, + args: ActionArgs, + ) -> ActionResult { + let Intention { + exchange_id: _, + action: _, + action_params, + pool_address, + nonce, + pool_utxo_spent, + pool_utxo_received, + input_coins, + output_coins, + } = args.intention; + let action_params_json_value = + serde_json::from_str::(action_params.as_str()) + .map_err(|_| "invalid action params".to_string())?; + let game = read_state(|es| { + let game_id = action_params_json_value + .get("game_id") + .map(|v| v.to_string()) + .ok_or("invalid game id".to_string())?; + + es.games + .get(&game_id) + .cloned() + .ok_or("Game not found".to_string()) + })?; + let (new_state, (_key_derivation_path, _utxo)) = game + .validate_add_liquidity( + pool_address.clone(), + args.txid.clone(), + nonce, + pool_utxo_spent, + pool_utxo_received, + input_coins, + output_coins, + ) + .map_err(|e| e.to_string())?; + + mutate_state(|es| { + let game_id = game.game_id; + let game = es.games.get_mut(&game_id).ok_or("Game not found").unwrap(); + game.game_status = game.game_status.finish_add_liquidity(); + }); + + Ok(new_state) + } + + #[action] + pub async fn withdraw(_psbt: &bitcoin::Psbt, args: ActionArgs) -> ActionResult { + let Intention { + exchange_id: _, + action: _, + action_params, + pool_address, + nonce, + pool_utxo_spent, + pool_utxo_received, + input_coins, + output_coins, + } = args.intention; + let action_params_json_value = + serde_json::from_str::(action_params.as_str()) + .map_err(|_| "invalid action params".to_string())?; + let game = read_state(|es| { + let game_id = action_params_json_value + .get("game_id") + .map(|v| v.to_string()) + .ok_or("invalid game id".to_string())?; + + es.games + .get(&game_id) + .cloned() + .ok_or("Game not found".to_string()) + })?; + let (new_state, (_key_derivation_path, _utxo)) = game + .validate_withdraw( + pool_address.clone(), + args.txid.clone(), + nonce, + pool_utxo_spent, + pool_utxo_received, + input_coins, + output_coins, + args.initiator_address.clone(), + ) + .map_err(|e| e.to_string())?; + + mutate_state(|es| { + let game_id = game.game_id; + let game = es.games.get_mut(&game_id).ok_or("Game not found").unwrap(); + game.withdraw(args.initiator_address.clone()) + .expect("Failed to withdraw"); + }); + + Ok(new_state) + } + + pub fn mutate_state(f: F) -> R + where + F: FnOnce(&mut ExchangeState) -> R, + { + State::with_mut(|es| { + let mut a = es.get().clone().expect("Failed to get state"); + let r = f(&mut a); + es.set(Some(a)); + r + }) + } + + pub fn read_state(f: F) -> R + where + F: FnOnce(&ExchangeState) -> R, + { + State::with(|es| { + es.get() + .as_ref() + .map(|s| f(&s)) + .expect("Failed to get state") + }) + } +} diff --git a/ree-cookie-canister/src/external/etch_canister.rs b/ree-cookie-canister/src/external/etch_canister.rs index 4afbd95..85d85eb 100644 --- a/ree-cookie-canister/src/external/etch_canister.rs +++ b/ree-cookie-canister/src/external/etch_canister.rs @@ -1,8 +1,7 @@ use candid::{CandidType, Nat, Principal}; -use icrc_ledger_client_cdk::{CdkRuntime, ICRC1Client}; use icrc_ledger_types::{ icrc1::account::Account, - icrc2::approve::ApproveArgs, + icrc2::approve::{ApproveArgs, ApproveError}, }; use serde::{Deserialize, Serialize}; @@ -56,45 +55,62 @@ pub enum EtchingStatus { Final, } -pub async fn get_etching_request(commit_tx: String)-> Option { +pub async fn get_etching_request(commit_tx: String) -> Option { let etching_principal = Principal::from_text(ETCH_CANISTER_ID).ok()?; - let (info,): (Option,) = ic_cdk::api::call::call( - etching_principal, - "get_etching_request", - (commit_tx,), - ) - .await - .ok()?; + let (info,): (Option,) = + ic_cdk::api::call::call(etching_principal, "get_etching_request", (commit_tx,)) + .await + .ok()?; info } pub async fn etching(args: EtchingArgs) -> Result { - let client = ICRC1Client { - runtime: CdkRuntime, - ledger_canister_id: Principal::from_text(ICP_LEDGER_CANISTER_ID).unwrap(), - }; - - let etching_principal = Principal::from_text(ETCH_CANISTER_ID).map_err(|e| format!("Invalid etching canister ID: {}", e))?; + let etching_principal = Principal::from_text(ETCH_CANISTER_ID) + .map_err(|e| format!("Invalid etching canister ID: {}", e))?; - client - .approve(ApproveArgs { - from_subaccount: None, - spender: Account { - owner: etching_principal, - subaccount: None, - }, - amount: Nat::from(100_000_000_u64), - expected_allowance: None, - expires_at: None, - fee: None, - memo: None, - created_at_time: None, - }) - .await - .map_err(|e| format!("Failed to approve etching canister: {:?}", e)) - .map_err(|e| e)? + let approve_args = ApproveArgs { + from_subaccount: None, + spender: Account { + owner: etching_principal, + subaccount: None, + }, + amount: Nat::from(100_000_000_u64), // 1 ICP + expected_allowance: None, + expires_at: None, + fee: None, + memo: None, + created_at_time: None, + }; + let result: (Result,) = ic_cdk::api::call::call( + Principal::from_text(ICP_LEDGER_CANISTER_ID).unwrap(), + "icrc2_approve", + (approve_args,), + ) + .await + .map_err(|e| format!("Failed to approve etching canister: {:?}", e))?; + result + .0 .map_err(|e| format!("Failed to approve etching canister: {:?}", e))?; + // client + // .approve(ApproveArgs { + // from_subaccount: None, + // spender: Account { + // owner: etching_principal, + // subaccount: None, + // }, + // amount: Nat::from(100_000_000_u64), + // expected_allowance: None, + // expires_at: None, + // fee: None, + // memo: None, + // created_at_time: None, + // }) + // .await + // .map_err(|e| format!("Failed to approve etching canister: {:?}", e)) + // .map_err(|e| e)? + // .map_err(|e| format!("Failed to approve etching canister: {:?}", e))?; + let r: (Result,) = ic_cdk::api::call::call(etching_principal, "etching", (args,)) .await diff --git a/ree-cookie-canister/src/external/internal_identity.rs b/ree-cookie-canister/src/external/internal_identity.rs index b4ab192..be8d10e 100644 --- a/ree-cookie-canister/src/external/internal_identity.rs +++ b/ree-cookie-canister/src/external/internal_identity.rs @@ -5,10 +5,10 @@ use serde_bytes::ByteBuf; use crate::SIWB_TESTNET_CANISTER; pub async fn get_principal(address: String) -> Result { - // let ii_canister = read_state(|s| s.ii_canister.clone()); let siwb_principal = Principal::from_text(SIWB_TESTNET_CANISTER) .map_err(|e| format!("Failed to parse SIWB_TESTNET_CANISTER principal: {}", e))?; - let result: CallResult<(Result,)> = ic_cdk::call(siwb_principal, "get_principal", (address,)).await; + let result: CallResult<(Result,)> = + ic_cdk::call(siwb_principal, "get_principal", (address,)).await; let success_result = result .map_err(|e| format!("Failed to call get_principal: {:?}", e))? .0 @@ -18,9 +18,11 @@ pub async fn get_principal(address: String) -> Result { .map_err(|e| format!("Failed to convert ByteBuf to Principal: {}", e)) } - #[test] pub fn test() { - let principal = Principal::from_slice(&vec![225, 209, 222, 36, 248, 96, 118, 238, 2, 172, 201, 226, 207, 83, 78, 83, 28, 133, 229, 192, 29, 162, 40, 195, 199, 202, 155, 62, 2]); + let principal = Principal::from_slice(&vec![ + 225, 209, 222, 36, 248, 96, 118, 238, 2, 172, 201, 226, 207, 83, 78, 83, 28, 133, 229, 192, + 29, 162, 40, 195, 199, 202, 155, 62, 2, + ]); dbg!(&principal.to_text()); -} \ No newline at end of file +} diff --git a/ree-cookie-canister/src/external/management.rs b/ree-cookie-canister/src/external/management.rs deleted file mode 100644 index 34c5ef7..0000000 --- a/ree-cookie-canister/src/external/management.rs +++ /dev/null @@ -1,96 +0,0 @@ -use crate::*; -use ic_cdk::api::management_canister::{ - main::CanisterId, - schnorr::{self, SchnorrAlgorithm, SchnorrKeyId, SchnorrPublicKeyArgument}, -}; -use serde_bytes::ByteBuf; - -const MGMT_CANISTER_ID: &str = "aaaaa-aa"; - -fn mgmt_canister_id() -> CanisterId { - CanisterId::from_text(MGMT_CANISTER_ID).unwrap() -} - -pub(crate) async fn request_schnorr_key(key_name: impl ToString, path: Vec) -> Result { - let arg = SchnorrPublicKeyArgument { - canister_id: None, - derivation_path: vec![path], - key_id: SchnorrKeyId { - algorithm: SchnorrAlgorithm::Bip340secp256k1, - name: key_name.to_string(), - }, - }; - let res = schnorr::schnorr_public_key(arg) - .await - .map_err(|(_, _)| ExchangeError::ChainKeyError)?; - let mut raw = res.0.public_key.to_vec(); - raw[0] = 0x00; - let pubkey = Pubkey::from_raw(raw).expect("management api error: invalid pubkey"); - Ok(pubkey) -} - -#[derive(Eq, PartialEq, Debug, CandidType, Serialize)] -pub enum SignWithSchnorrAux { - #[serde(rename = "bip341")] - Bip341(SignWithBip341Aux), -} - -#[derive(Eq, PartialEq, Debug, CandidType, Serialize)] -pub struct SignWithBip341Aux { - pub merkle_root_hash: ByteBuf, -} - -#[derive(CandidType, Deserialize, Debug)] -struct ManagementCanisterSignatureReply { - pub signature: Vec, -} - -#[derive(CandidType, Serialize, Debug)] -struct ManagementCanisterSignatureRequest { - pub message: Vec, - pub aux: Option, - pub derivation_path: Vec>, - pub key_id: SchnorrKeyId, -} - -pub async fn schnorr_sign( - message: Vec, - derive_path: Vec, - key_id: impl ToString, - merkle_root: Option>, -) -> std::result::Result, String> { - let merkle_root_hash = merkle_root - .map(|bytes| { - if bytes.len() == 32 || bytes.is_empty() { - Ok(ByteBuf::from(bytes)) - } else { - Err(format!( - "merkle tree root bytes must be 0 or 32 bytes long but got {}", - bytes.len() - )) - } - }) - .transpose()? - .unwrap_or_default(); - let aux = Some(SignWithSchnorrAux::Bip341(SignWithBip341Aux { - merkle_root_hash, - })); - let request = ManagementCanisterSignatureRequest { - message, - derivation_path: vec![derive_path], - key_id: SchnorrKeyId { - algorithm: SchnorrAlgorithm::Bip340secp256k1, - name: key_id.to_string(), - }, - aux, - }; - let (reply,): (ManagementCanisterSignatureReply,) = ic_cdk::api::call::call_with_payment( - mgmt_canister_id(), - "sign_with_schnorr", - (request,), - 26_153_846_153, - ) - .await - .map_err(|e| format!("sign_with_schnorr failed {e:?}"))?; - Ok(reply.signature) -} diff --git a/ree-cookie-canister/src/external/mod.rs b/ree-cookie-canister/src/external/mod.rs index 48ff643..9008a47 100644 --- a/ree-cookie-canister/src/external/mod.rs +++ b/ree-cookie-canister/src/external/mod.rs @@ -1,4 +1,3 @@ +pub mod etch_canister; pub mod internal_identity; -pub mod management; pub mod rune_indexer; -pub mod etch_canister; diff --git a/ree-cookie-canister/src/external/rune_indexer.rs b/ree-cookie-canister/src/external/rune_indexer.rs index 51dae33..184d3a0 100644 --- a/ree-cookie-canister/src/external/rune_indexer.rs +++ b/ree-cookie-canister/src/external/rune_indexer.rs @@ -79,17 +79,11 @@ impl Service { } } - -pub async fn get_etching(txid: String)->Option{ +pub async fn get_etching(txid: String) -> Option { let rune_indexer_principal = Principal::from_text(RUNE_INDEXER_CANISTER).ok()?; - let (result,): (Option,) = ic_cdk::api::call::call( - rune_indexer_principal, - "get_etching", - (txid,), - ) - .await - .ok()?; + let (result,): (Option,) = + ic_cdk::api::call::call(rune_indexer_principal, "get_etching", (txid,)) + .await + .ok()?; result - - -} \ No newline at end of file +} diff --git a/ree-cookie-canister/src/game/game.rs b/ree-cookie-canister/src/game/game.rs index bc58df5..e51068f 100644 --- a/ree-cookie-canister/src/game/game.rs +++ b/ree-cookie-canister/src/game/game.rs @@ -1,13 +1,17 @@ use std::borrow::Cow; use std::collections::HashMap; -use crate::pool::{Pool, PoolState, UserAction}; +use crate::exchange::exchange::CookiePools; +use crate::exchange::{CookiePoolState, UserAction}; + use crate::*; use crate::{utils::get_chain_second_timestamp, AddressStr, ExchangeError, Seconds}; +use errors::*; use ic_cdk::api::management_canister::bitcoin::Satoshi; use ic_stable_structures::storable::Bound; use ic_stable_structures::Storable; -use ree_types::{CoinId, InputCoin, OutputCoin}; +use ree_exchange_sdk::prelude::PoolStorageAccess; +use ree_exchange_sdk::types::{CoinId, InputCoin, OutputCoin}; use serde::{Deserialize, Serialize}; use super::gamer::Gamer; @@ -22,8 +26,7 @@ pub struct Game { pub game_status: GameStatus, pub creator: Principal, pub creator_address: AddressStr, - // pub pool_manager: PoolManager, - pub pool: Option, + pub pool_address: Option, pub rune_premine_amount: u128, pub rune_info: Option, pub claimed_cookies: u128, @@ -32,6 +35,12 @@ pub struct Game { pub etch_rune_commit_tx: String, } +#[derive(CandidType, Deserialize, Serialize, Clone)] +pub struct GameAndPool { + pub game: Game, + pub pool_metadata: Option, + pub pool_state: Option, +} #[derive(CandidType, Deserialize, Serialize, Clone)] pub struct RuneInfo { @@ -48,6 +57,12 @@ impl Storable for Game { bincode::deserialize(bytes.as_ref()).unwrap() } + fn into_bytes(self) -> Vec { + let mut bytes = vec![]; + bincode::serialize_into(&mut bytes, &self).unwrap(); + bytes + } + const BOUND: Bound = Bound::Unbounded; } @@ -62,8 +77,7 @@ impl Game { game_status: GameStatus::Etching, creator: creator, creator_address: args.create_address.clone(), - pool: None, - // pool_manager: PoolManager::new(game_id.to_string()), + pool_address: None, rune_info: None, rune_premine_amount: args.rune_premine_amount, claimed_cookies: 0, @@ -130,11 +144,6 @@ impl Game { pub fn claim(&mut self, gamer_id: AddressStr) -> Result { self.able_claim(gamer_id.clone())?; - // let mut gamer = GAMER.with_borrow(|g| { - // g.get(&gamer_id) - // .ok_or(ExchangeError::GamerNotFound(gamer_id.clone())) - // })?; - let gamer = self .gamers .get_mut(&gamer_id) @@ -166,63 +175,35 @@ impl Game { if !gamer.is_withdrawn { gamer.is_withdrawn = true; - // gamer.withdrawn_at = Some(get_chain_ms_timestamp()); - // gamer.withdrawn_txid = Some(txid); - let cookies = gamer.cookies; - - Ok(cookies) + Ok(gamer.cookies) } else { Err(ExchangeError::GamerWithdrawRepeatedly(gamer_id)) } } - - pub fn finalize_tx(&mut self, txid: Txid) -> Result<()> { - self.pool.as_mut().unwrap().finalize(txid)?; - - Ok(()) - } - - pub fn rollback_tx(&mut self, txid: Txid) -> Result<()> { - let rollback_state = self.pool.as_mut().unwrap().rollback(txid)?; - for state in rollback_state { - match state.user_action { - UserAction::Register(address) => { - self.gamers.remove(&address); - } - UserAction::Withdraw(address) => { - self.gamers - .get_mut(&address) - .ok_or(ExchangeError::GamerNotFound(address.clone()))? - .is_withdrawn = false; - } - _ => {} - } - } - Ok(()) - } } impl Game { pub fn validate_add_liquidity( &self, + pool_address: AddressStr, txid: Txid, nonce: u64, pool_utxo_spent: Vec, pool_utxo_received: Vec, input_coins: Vec, output_coins: Vec, - ) -> Result<(PoolState, (String, Utxo))> { + ) -> Result<(CookiePoolState, (Vec>, Utxo))> { let rune_info = self .rune_info .as_ref() .ok_or(ExchangeError::RuneNotFound(self.game_name.clone()))?; - let pool = self - .pool - .as_ref() - .ok_or(ExchangeError::PoolNotFound(self.game_name.clone()))?; + let btc_pool = CookiePools::get(&pool_address) + .ok_or(ExchangeError::PoolNotFound(pool_address.clone()))?; - let last_state = pool.last_state().ok_or(ExchangeError::LastStateNotFound)?; + let last_state = btc_pool.states().last().ok_or(ExchangeError::InvalidState( + "Pool has no states".to_string(), + ))?; let pool_expected_spend_rune = self.calculate_add_liquidity_rune_amount(); let pool_expected_spend_btc = self.gamers.len() as u128 * self.gamer_register_fee as u128; @@ -273,8 +254,8 @@ impl Game { ExchangeError::InvalidSignPsbtArgs("pool_utxo_receive not found".to_string()), )?; - let new_state = PoolState { - id: txid, + let new_state = CookiePoolState { + txid: txid, nonce: last_state .nonce .checked_add(1) @@ -285,12 +266,16 @@ impl Game { return Ok(( new_state, - (pool.key_derivation_path.clone(), last_state.utxo.clone()), + ( + btc_pool.metadata().key_derivation_path.clone(), + last_state.utxo.clone(), + ), )); } pub fn validate_register( &self, + pool_address: AddressStr, txid: Txid, nonce: u64, pool_utxo_spent: Vec, @@ -298,7 +283,7 @@ impl Game { input_coins: Vec, output_coins: Vec, address: AddressStr, - ) -> Result<(PoolState, (String, Utxo))> { + ) -> Result<(CookiePoolState, (Vec>, Utxo))> { if !matches!(self.game_status, GameStatus::Playing) { return Err(ExchangeError::GameStatusNotMatch( self.game_status.clone(), @@ -321,15 +306,12 @@ impl Game { input_coins, output_coins )))?; - // the pool_utxo_spend should be equal to the utxo of the last state - let btc_pool = self - .pool - .as_ref() - .ok_or(ExchangeError::PoolNotFound(self.game_name.clone()))?; + let btc_pool = CookiePools::get(&pool_address) + .ok_or(ExchangeError::PoolNotFound(pool_address.clone()))?; - let last_state = btc_pool - .last_state() - .ok_or(ExchangeError::LastStateNotFound)?; + let last_state = btc_pool.states().last().ok_or(ExchangeError::InvalidState( + "Pool has no states".to_string(), + ))?; // check nonce matches (last_state.nonce == nonce) @@ -362,20 +344,20 @@ impl Game { ExchangeError::InvalidSignPsbtArgs("pool_utxo_receive not found".to_string()), )?; - let new_state = PoolState { - id: txid, + let new_state = CookiePoolState { + txid: txid, nonce: last_state .nonce .checked_add(1) .ok_or(ExchangeError::Overflow)?, utxo: new_utxo, - user_action: UserAction::Register(address.clone()), + user_action: UserAction::Register(self.game_id.clone(), address.clone()), }; Ok(( new_state, ( - btc_pool.key_derivation_path.clone(), + btc_pool.metadata().key_derivation_path.clone(), last_state.utxo.clone(), ), )) @@ -383,6 +365,7 @@ impl Game { pub fn validate_withdraw( &self, + pool_address: AddressStr, txid: Txid, nonce: u64, pool_utxo_spend: Vec, @@ -390,7 +373,7 @@ impl Game { input_coins: Vec, output_coins: Vec, initiator_address: AddressStr, - ) -> Result<(PoolState, (String, Utxo))> { + ) -> Result<(CookiePoolState, (Vec>, Utxo))> { assert!( matches!(self.game_status, GameStatus::Withdrawing), "GameStatus should be Withdrawing, but got: {:?}", @@ -402,14 +385,12 @@ impl Game { .as_ref() .ok_or(ExchangeError::RuneNotFound(self.game_name.clone()))?; - let rune_pool = self - .pool - .as_ref() - .ok_or(ExchangeError::PoolNotFound(self.game_name.clone()))?; + let btc_pool = CookiePools::get(&pool_address) + .ok_or(ExchangeError::PoolNotFound(pool_address.clone()))?; - let last_state = rune_pool - .last_state() - .ok_or(ExchangeError::LastStateNotFound)?; + let last_state = btc_pool.states().last().ok_or(ExchangeError::InvalidState( + "Pool has no states".to_string(), + ))?; let gamer = self .gamers @@ -449,20 +430,20 @@ impl Game { ExchangeError::InvalidSignPsbtArgs("pool_utxo_receive not found".to_string()), )?; - let new_state = PoolState { - id: txid, + let new_state = CookiePoolState { + txid: txid, nonce: last_state .nonce .checked_add(1) .ok_or(ExchangeError::Overflow)?, utxo: new_utxo, - user_action: UserAction::AddLiquidity, + user_action: UserAction::Withdraw(self.game_id.clone(), initiator_address.clone()), }; return Ok(( new_state, ( - rune_pool.key_derivation_path.clone(), + btc_pool.metadata().key_derivation_path.clone(), last_state.utxo.clone(), ), )); @@ -489,13 +470,6 @@ pub enum GameStatus { } impl GameStatus { - // pub fn init(&self) -> GameStatus { - // match self { - // GameStatus::Initializing => GameStatus::Playing, - // _ => panic!("GameStatus should be Initializing"), - // } - // } - pub fn finish_etching(&self) -> GameStatus { match self { GameStatus::Etching => GameStatus::Playing, @@ -527,3 +501,13 @@ pub struct CreateGameArgs { pub create_address: AddressStr, pub rune_premine_amount: u128, } + +#[test] +pub fn t() { + let raw_v = [ + 77, 110, 135, 112, 3, 247, 168, 241, 210, 15, 6, 190, 50, 208, 49, 84, 144, 42, 254, 134, + 162, 175, 66, 72, 92, 153, 48, 20, 2, + ]; + let s = String::from_utf8(raw_v.to_vec()).unwrap(); + dbg!(&s); +} diff --git a/ree-cookie-canister/src/game/gamer.rs b/ree-cookie-canister/src/game/gamer.rs index 2076764..b5fa3cd 100644 --- a/ree-cookie-canister/src/game/gamer.rs +++ b/ree-cookie-canister/src/game/gamer.rs @@ -6,6 +6,7 @@ use ic_stable_structures::Storable; use crate::utils::get_chain_second_timestamp; use crate::SecondTimestamp; use crate::*; +use errors::*; #[derive(CandidType, Serialize, Deserialize, Clone, Debug)] pub struct Gamer { @@ -24,6 +25,12 @@ impl Storable for Gamer { bincode::deserialize(bytes.as_ref()).unwrap() } + fn into_bytes(self) -> Vec { + let mut bytes = vec![]; + bincode::serialize_into(&mut bytes, &self).unwrap(); + bytes + } + const BOUND: Bound = Bound::Unbounded; } diff --git a/ree-cookie-canister/src/lib.rs b/ree-cookie-canister/src/lib.rs index e7bcbc9..6c7f12e 100644 --- a/ree-cookie-canister/src/lib.rs +++ b/ree-cookie-canister/src/lib.rs @@ -1,23 +1,29 @@ pub mod canister; pub mod errors; +pub mod exchange; pub mod external; pub mod game; pub mod log; -pub mod memory; -pub mod reorg; pub mod state; pub mod utils; -pub mod pool; pub use candid::{CandidType, Principal}; -pub use errors::*; +pub use errors::ExchangeError; +use exchange::CookiePoolState; pub use external::rune_indexer::{RuneEntry, Service as RuneIndexer}; +use game::game::CreateGameArgs; +use game::game::Game; +use game::game::GameAndPool; pub use ic_canister_log::log; pub use ic_stable_structures::StableBTreeMap; pub use log::*; -pub use ree_types::Pubkey; -pub use ree_types::{Txid, Utxo}; +use ree_exchange_sdk::{ + types::{Pubkey, Txid, Utxo}, + Metadata, +}; pub use serde::{Deserialize, Serialize}; +use state::ExchangeState; +use utils::AddLiquidityInfo; pub const SIWB_TESTNET_CANISTER: &'static str = "stxih-wyaaa-aaaah-aq2la-cai"; pub const RUNE_INDEXER_CANISTER: &'static str = "f2dwm-caaaa-aaaao-qjxlq-cai"; @@ -32,6 +38,8 @@ pub type PoolId = Pubkey; pub type AddressStr = String; pub type RuneName = String; pub type RuneId = String; -pub type GameId = usize; +pub type GameId = String; pub const DUST_BTC_VALUE: u64 = 546; +// Enable Candid export +ic_cdk::export_candid!(); diff --git a/ree-cookie-canister/src/log.rs b/ree-cookie-canister/src/log.rs index 273aed2..25e3cab 100644 --- a/ree-cookie-canister/src/log.rs +++ b/ree-cookie-canister/src/log.rs @@ -1,6 +1,6 @@ use ic_canister_log::export as export_logs; use ic_canister_log::{declare_log_buffer, GlobalBuffer}; -use ic_canisters_http_types::{HttpRequest, HttpResponse, HttpResponseBuilder}; +use ic_http_types::{HttpRequest, HttpResponse, HttpResponseBuilder}; use serde_derive::Deserialize; use time::OffsetDateTime; diff --git a/ree-cookie-canister/src/memory.rs b/ree-cookie-canister/src/memory.rs deleted file mode 100644 index f2bdfd3..0000000 --- a/ree-cookie-canister/src/memory.rs +++ /dev/null @@ -1,97 +0,0 @@ -pub(crate) use std::cell::RefCell; - -use candid::Principal; -use ic_stable_structures::{ - memory_manager::{MemoryId, MemoryManager, VirtualMemory}, - Cell, DefaultMemoryImpl, StableBTreeMap, -}; -use ree_types::{exchange_interfaces::NewBlockInfo, TxRecord, Txid}; - -use crate::{game::{game::Game, gamer::Gamer}, state::ExchangeState, AddressStr}; - -pub type Memory = VirtualMemory; - -const STATE_MEMORY_ID: MemoryId = MemoryId::new(1); -const GAMERS_MEMORY_ID: MemoryId = MemoryId::new(2); -const ADDRESS_PRINCIPAL_MAP_MEMORY_ID: MemoryId = MemoryId::new(3); -const BLOCKS_MEMORY_ID: MemoryId = MemoryId::new(4); -const TX_RECORDS_MEMORY_ID: MemoryId = MemoryId::new(5); - -thread_local! { - - static MEMORY_MANAGER: RefCell> = - RefCell::new(MemoryManager::init(DefaultMemoryImpl::default())); - - pub static STATE: RefCell, Memory>> = RefCell::new( - Cell::init( - MEMORY_MANAGER.with(|m| m.borrow().get(STATE_MEMORY_ID)), - Option::None - ).expect("state memory not initialized") - ); - - pub static GAMES: RefCell> = RefCell::new( - StableBTreeMap::init( - MEMORY_MANAGER.with(|m| m.borrow().get(GAMERS_MEMORY_ID)), - ) - ); - - pub static ADDRESS_PRINCIPLE_MAP: RefCell> = RefCell::new( - StableBTreeMap::init( - MEMORY_MANAGER.with(|m| m.borrow().get(ADDRESS_PRINCIPAL_MAP_MEMORY_ID)), - ) - ); - - pub static BLOCKS: RefCell> = RefCell::new( - StableBTreeMap::init( - MEMORY_MANAGER.with(|m| m.borrow().get(BLOCKS_MEMORY_ID)), - ) - ); - - pub static TX_RECORDS: RefCell> = RefCell::new( - StableBTreeMap::init( - MEMORY_MANAGER.with(|m| m.borrow().get(TX_RECORDS_MEMORY_ID)), - ) - ); - -} - -pub fn init_gamer() -> StableBTreeMap { - // StableBTreeMap::init(with_memory_manager(|m| m.get(GAMERS_MEMORY_ID))) - StableBTreeMap::init(MEMORY_MANAGER.with(|m| m.borrow().get(GAMERS_MEMORY_ID))) -} - -// pub fn init_address_principal_map() -> StableBTreeMap { -// // StableBTreeMap::init(with_memory_manager(|m| m.get(ADDRESS_PRINCIPAL_MAP_MEMORY_ID))) -// StableBTreeMap::init(MEMORY_MANAGER.with(|m| m.borrow().get(ADDRESS_PRINCIPAL_MAP_MEMORY_ID))) -// } - -pub fn get_state() -> ExchangeState { - STATE.with(|c| c.borrow().get().clone().unwrap()) -} - -pub fn set_state(state: ExchangeState) { - STATE.with(|c| { - c.borrow_mut() - .set(Some(state)) - .expect("Failed to set SETTINGS.") - }); -} - -pub fn mutate_state(f: F) -> R -where - F: FnOnce(&mut ExchangeState) -> R, -{ - let mut state = get_state(); - let r = f(&mut state); - set_state(state); - r -} - -pub fn read_state(f: F) -> R -where - F: FnOnce(&ExchangeState) -> R, -{ - let state = get_state(); - let r = f(&state); - r -} diff --git a/ree-cookie-canister/src/pool.rs b/ree-cookie-canister/src/pool.rs deleted file mode 100644 index abeb844..0000000 --- a/ree-cookie-canister/src/pool.rs +++ /dev/null @@ -1,261 +0,0 @@ -use ree_types::{bitcoin::{key::TweakedPublicKey, Address}, exchange_interfaces::PoolInfo}; -use std::{cmp::max, collections::BTreeMap}; - -use crate::{utils::request_address, *}; - -#[derive(Deserialize, Serialize, Clone, Debug, CandidType)] -pub struct Pool { - pub key_derivation_path: String, - pub name: String, - pub pubkey: Pubkey, - pub address: AddressStr, - - pub pending_transaction_counts: usize, - pub nonce: u64, - - pub states: Vec, - - pub attributes: String, -} - -impl Pool { - pub fn init( - pool_name: String, - key_path: String, - pubkey: Pubkey, - address: AddressStr, - attributes: String, - utxo: Utxo - )->Self { - Self { - key_derivation_path: key_path, - name: pool_name, - pubkey, - address, - pending_transaction_counts: 0, - nonce: 0, - states: vec![ - PoolState { - id: utxo.txid, - nonce: 0, - utxo, - user_action: UserAction::Init, - } - ], - attributes, - } - - } - - pub fn commit(&mut self, new_state: PoolState) { - self.nonce = new_state.nonce; - self.states.push(new_state); - self.pending_transaction_counts += 1; - } - - pub(crate) fn finalize(&mut self, txid: Txid) -> Result<()> { - let tx_count_before = self.states.len(); - let idx = self - .states - .iter() - .position(|s| s.id == txid) - .ok_or(ExchangeError::InvalidState("txid not found".to_string()))?; - - if idx == 0 { - return Ok(()); - } - - self.states.rotate_left(idx); - self.states.truncate(self.states.len() - idx); - let tx_count_after = self.states.len(); - self.pending_transaction_counts -= max(self.pending_transaction_counts, tx_count_after - tx_count_before); - - Ok(()) - } - - pub fn rollback(&mut self, txid: Txid) -> Result> { - let idx = self - .states - .iter() - .position(|s| s.id == txid) - .ok_or(ExchangeError::InvalidState("txid not found".to_string()))?; - - if idx == 0 { - return Ok(vec![]); - } - - let mut rollback_states = vec![]; - while self.states.len() > idx { - let state = self.states.pop().ok_or(ExchangeError::InvalidState("No state to pop".to_string()))?; - rollback_states.push(state); - } - - Ok(rollback_states) - } - - pub fn last_state(&self) -> Option { - self.states - .last() - .cloned() - } -} - -impl TryFrom for PoolInfo { - - type Error = ExchangeError; - fn try_from(pool: Pool) -> std::result::Result { - let last_state = pool - .states - .last() - .cloned() - .ok_or(ExchangeError::LastStateNotFound)?; - Ok(PoolInfo { - key: pool.pubkey, - key_derivation_path: vec![pool.key_derivation_path.into_bytes()], - name: pool.name, - address: pool.address, - nonce: pool.nonce, - coin_reserved: last_state - .utxo - .coins.iter().map(|c| c.clone()).collect(), - btc_reserved: last_state.btc_balance(), - utxos: vec![last_state.utxo], - attributes: pool.attributes, - }) - } -} - -#[derive(Deserialize, Serialize, Clone, Debug, CandidType)] -pub struct PoolState { - pub id: Txid, - pub nonce: u64, - pub utxo: Utxo, - pub user_action: UserAction, -} - -impl PoolState { - pub fn btc_balance(&self) -> u64 { - self.utxo.sats - } -} - -#[derive(Deserialize, Serialize, Clone, Debug, CandidType)] -pub enum UserAction { - Init, - AddLiquidity, - Register(AddressStr), - Withdraw(AddressStr), -} - -#[derive(Deserialize, Serialize, Clone, Debug, CandidType)] -pub struct PoolManager { - pub btc_pools: BTreeMap, - pub rune_pool: Option, - pub path_prefix: String, -} - -impl PoolManager { - pub const MAX_PENDING_TRANSACTION_COUNTS: usize = 25; - - pub fn new( - path_prefix: String, - )->Self{ - PoolManager { - btc_pools: BTreeMap::new(), - rune_pool: None, - path_prefix, - } - } - - pub async fn try_new( - rune_id: String, - rune_name: String, - rune_utxo: Utxo - )->Result{ - - let (pubkey, _tweaked_pubkey, address) = - request_address(rune_id.clone()).await?; - - Ok(PoolManager { - btc_pools: BTreeMap::new(), - rune_pool: Some(Pool::init( - rune_name, - rune_id.clone(), - pubkey, - address.to_string(), - "".to_string(), - rune_utxo) - ), - path_prefix: rune_id, - }) - } - - pub fn get_usable_deposit_pool(&self) -> Option<&Pool> { - self.btc_pools - .values() - .find(|pool| pool.pending_transaction_counts < Self::MAX_PENDING_TRANSACTION_COUNTS) - } - - pub async fn next_new_btc_pool_address(&self) -> Result<(Pubkey, TweakedPublicKey, Address, String)> { - let next_pool_key_path = format!("{}_{}", self.path_prefix, self.btc_pools.len() ); - let (pubkey, tweaked_pubkey, address) = request_address(next_pool_key_path.clone()).await?; - Ok((pubkey, tweaked_pubkey, address, next_pool_key_path)) - } - - pub fn add_new_btc_pool( - &mut self, - pk: Pubkey, - addr: Address, - path: String, - utxo: Utxo, - ) -> Result<()> { - // let (pk, _tpk, addr, next_path) = self.next_new_btc_pool_address().await?; - self.btc_pools.insert( - addr.to_string(), - Pool::init( - path.clone(), - path, - pk, - addr.to_string(), - "".to_string(), - utxo, - ), - ); - - Ok(()) - - } - - pub fn get_rune_pool_path(&self) -> String { - return format!("{}", self.path_prefix); - } - - pub async fn get_rune_pool_address(&self) -> Result { - if let Some(rune_pool) = &self.rune_pool { - return Ok(rune_pool.address.clone()); - } else { - let path = self.get_rune_pool_path(); - let (_pubkey, _tweaked_pubkey, address) = request_address(path).await?; - return Ok(address.to_string()) - } - } - - pub fn add_rune_pool( - &mut self, - pk: Pubkey, - addr: Address, - utxo: Utxo, - ) { - - let key_path = self.get_rune_pool_path(); - - self.rune_pool = Some(Pool::init( - self.path_prefix.clone(), - key_path, - pk, - addr.to_string(), - "".to_string(), - utxo - )) ; - } -} diff --git a/ree-cookie-canister/src/reorg.rs b/ree-cookie-canister/src/reorg.rs deleted file mode 100644 index d2e8d7d..0000000 --- a/ree-cookie-canister/src/reorg.rs +++ /dev/null @@ -1,114 +0,0 @@ -use crate::{ - memory::{BLOCKS, TX_RECORDS}, - *, -}; -use ree_types::{bitcoin::Network, exchange_interfaces::NewBlockInfo}; -use thiserror::Error; - -#[derive(Debug, Error, CandidType)] -pub enum ReorgError { - #[error("{depth} block deep reorg detected at height {height}")] - Recoverable { height: u32, depth: u32 }, - - #[error("duplicate block detected at height {height} with hash {hash}")] - DuplicateBlock { height: u32, hash: String }, - - #[error("unrecoverable reorg detected")] - Unrecoverable, - - #[error("block not found in state at height {height}")] - BlockNotFoundInState { height: u32 }, -} - -pub fn get_max_recoverable_reorg_depth(network: Network) -> u32 { - match network { - Network::Regtest => 6, - Network::Testnet => 64, - Network::Testnet4 => 64, - Network::Bitcoin => 6, - Network::Signet => 6, - _ => 6, - } -} - -pub(crate) fn detect_reorg( - network: Network, - new_block: NewBlockInfo, -) -> std::result::Result<(), ReorgError> { - ic_cdk::println!( - "Processing new block - height: {}, hash: {}, timestamp: {}, confirmed_txs: {:?}", - new_block.block_height, - new_block.block_hash, - new_block.block_timestamp, - new_block.confirmed_txids - ); - let current_block = BLOCKS.with_borrow(|m| m.iter().rev().next().map(|(_height, block)| block)); - match current_block { - None => { - ic_cdk::println!("No blocks found in exchange - this is expected for new exchanges"); - return Ok(()); - } - Some(current_block) => { - ic_cdk::println!( - "Current block - height: {:?}, hash: {:?}, timestamp: {:?}", - current_block.block_height, - current_block.block_hash, - current_block.block_timestamp - ); - if new_block.block_height == current_block.block_height + 1 { - ic_cdk::println!("New block is the next block in the chain"); - return Ok(()); - } else if new_block.block_height > current_block.block_height + 1 { - ic_cdk::println!("New block is more than one block ahead of the current block"); - return Err(ReorgError::Unrecoverable); - } else { - let reorg_depth = current_block.block_height - new_block.block_height + 1; - ic_cdk::println!("Detected reorg - depth: {}", reorg_depth,); - if reorg_depth > get_max_recoverable_reorg_depth(network) { - ic_cdk::println!("Reorg depth is greater than the max recoverable reorg depth"); - return Err(ReorgError::Unrecoverable); - } - let target_block = BLOCKS.with_borrow(|m| { - m.get(&new_block.block_height) - .ok_or(ReorgError::BlockNotFoundInState { - height: new_block.block_height, - }) - })?; - if target_block.block_hash == new_block.block_hash { - ic_cdk::println!("New block is a duplicate block"); - return Err(ReorgError::DuplicateBlock { - height: new_block.block_height, - hash: new_block.block_hash, - }); - } - return Err(ReorgError::Recoverable { - height: current_block.block_height, - depth: reorg_depth, - }); - } - } - } -} - -pub fn handle_reorg(height: u32, depth: u32) { - ic_cdk::println!("Rolling back state after reorg of depth {depth} at height {height}"); - - for h in (height - depth + 1..=height).rev() { - ic_cdk::println!("Rolling back change record at height {h}"); - let block = BLOCKS.with_borrow(|m| m.get(&h).unwrap()); - for txid in block.confirmed_txids.iter() { - TX_RECORDS.with_borrow_mut(|m| { - if let Some(record) = m.remove(&(txid.clone(), true)) { - m.insert((txid.clone(), false), record); - ic_cdk::println!("Unconfirm txid: {}", txid); - } - }); - } - BLOCKS.with_borrow_mut(|m| m.remove(&h)); - } - - ic_cdk::println!( - "Successfully rolled back state to height {}", - height - depth, - ); -} diff --git a/ree-cookie-canister/src/state.rs b/ree-cookie-canister/src/state.rs index ca1d3ee..2f3fa4b 100644 --- a/ree-cookie-canister/src/state.rs +++ b/ree-cookie-canister/src/state.rs @@ -6,17 +6,20 @@ use std::collections::HashMap; use crate::game::game::Game; use crate::*; -#[derive(Deserialize, Serialize, Clone, CandidType)] +#[derive(Deserialize, Serialize, Clone, CandidType, Default)] pub struct ExchangeState { pub games: HashMap, - pub orchestrator: Principal, pub txid_game_map: HashMap, } - impl Storable for ExchangeState { fn to_bytes(&self) -> std::borrow::Cow<[u8]> { - Cow::Owned(bincode::serialize(self).unwrap()) + let bytes = bincode::serialize(self).unwrap(); + std::borrow::Cow::Owned(bytes) + } + + fn into_bytes(self) -> Vec { + bincode::serialize(&self).unwrap() } fn from_bytes(bytes: std::borrow::Cow<[u8]>) -> Self { @@ -27,25 +30,14 @@ impl Storable for ExchangeState { } impl ExchangeState { - pub fn init( - orchestrator: Principal, - ) -> Self { + pub fn init() -> Self { Self { games: HashMap::new(), - orchestrator, txid_game_map: HashMap::new(), } } } -#[derive(Deserialize, Serialize, Clone, Debug, CandidType)] -pub enum UserAction { - Init, - AddLiquidity, - Register(AddressStr), - Withdraw(AddressStr), -} - #[test] pub fn test() { let input = "225; 209; 222; 36; 248; 96; 118; 238; 2; 172; 201; 226; 207; 83; 78; 83; 28; 133; 229; 192; 29; 162; 40; 195; 199; 202; 155; 62; 2"; diff --git a/ree-cookie-canister/src/utils.rs b/ree-cookie-canister/src/utils.rs index 96454f6..82d1255 100644 --- a/ree-cookie-canister/src/utils.rs +++ b/ree-cookie-canister/src/utils.rs @@ -1,74 +1,12 @@ -use ic_cdk::api::management_canister::bitcoin::{BitcoinNetwork, Satoshi}; -use ree_types::bitcoin::{Address, key::{Secp256k1, TapTweak, TweakedPublicKey}, Network}; - -use crate::{external::management::request_schnorr_key, *}; - -pub(crate) fn tweak_pubkey_with_empty(untweaked: Pubkey) -> TweakedPublicKey { - let secp = Secp256k1::new(); - let (tweaked, _) = untweaked.to_x_only_public_key().tap_tweak(&secp, None); - tweaked -} +use crate::*; +use ic_cdk::api::management_canister::bitcoin::Satoshi; pub(crate) fn get_chain_second_timestamp() -> SecondTimestamp { ic_cdk::api::time() / 1000_000_000 } -#[derive(CandidType, Serialize, Deserialize, Clone)] -pub struct RegisterInfo { - pub untweaked_key: Pubkey, - pub tweaked_key: Pubkey, - pub address: String, - pub utxo: Utxo, - pub register_fee: Satoshi, - pub nonce: u64, -} - #[derive(CandidType, Serialize, Deserialize, Clone)] pub struct AddLiquidityInfo { pub btc_amount_for_add_liquidity: Satoshi, pub rune_amount_for_add_liquidity: u128, } - -#[test] -pub fn test_tweak_pubkey() { - let mock_raw_pubkey: Vec = vec![ - 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, - 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, - 0xF8, 0x17, 0x98, - ]; - - let pubkey = Pubkey::from_raw(mock_raw_pubkey).unwrap(); - let tweaked_pubkey = tweak_pubkey_with_empty(pubkey.clone()); - let addr = ree_types::bitcoin::Address::p2tr_tweaked( - tweaked_pubkey, - ree_types::bitcoin::Network::Bitcoin, - ); - dbg!(&addr); -} - -pub fn get_max_recoverable_reorg_depth(network: BitcoinNetwork) -> u32 { - match network { - BitcoinNetwork::Regtest => 6, - BitcoinNetwork::Testnet => 64, - BitcoinNetwork::Mainnet => 6, - } -} - -// pub fn calculate_premine_rune_amount() -> u128 { -// read_state(|s| s.game.claimed_cookies * 120 / 100) -// } - -pub async fn request_address(key_path: String)->Result<(Pubkey, TweakedPublicKey, Address)> { - let untweaked_pubkey = request_schnorr_key("key_1", key_path.into_bytes()).await?; - let tweaked_pubkey = tweak_pubkey_with_empty(untweaked_pubkey.clone()); - cfg_if::cfg_if! { - if #[cfg(feature = "testnet")] { - let address = Address::p2tr_tweaked(tweaked_pubkey, Network::Testnet4); - } else { - let address = Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin); - } - } - - return Ok((untweaked_pubkey, tweaked_pubkey, address)) - -} \ No newline at end of file diff --git a/ree-cookie-frontend/src/canister/cookie/actor.ts b/ree-cookie-frontend/src/canister/cookie/actor.ts index 5f34004..f35aa31 100644 --- a/ree-cookie-frontend/src/canister/cookie/actor.ts +++ b/ree-cookie-frontend/src/canister/cookie/actor.ts @@ -1,6 +1,6 @@ import { Actor, ActorSubclass, HttpAgent, Identity } from "@dfinity/agent"; import { ICP_HOST } from "../../constants"; -import { idlFactory, _SERVICE as CookieService, Game, GameStatus, Pool } from "./service.did"; +import { idlFactory, _SERVICE as CookieService, Game, GameStatus, GameAndPool, Metadata } from "./service.did"; export const COOKIE_CANISTER_ID = "k5j3t-jaaaa-aaaah-arcra-cai" @@ -34,6 +34,14 @@ export function game_status_str(game_status: GameStatus): GameStatusStr { } } +// export function get_pool_meta(game_and_pool: GameAndPool): Metadata | undefined { +// if(game_and_pool.pool_metadata.length ==0) { +// return undefined; +// } else { +// game_and_pool.pool_metadata[0]! +// } +// } + // export function get_btc_pool(game: Game): Pool { // return game.pool_manager.btc_pools[0]?.[1]!; // } diff --git a/ree-cookie-frontend/src/canister/cookie/service.did.d.ts b/ree-cookie-frontend/src/canister/cookie/service.did.d.ts index afb597b..d89513b 100644 --- a/ree-cookie-frontend/src/canister/cookie/service.did.d.ts +++ b/ree-cookie-frontend/src/canister/cookie/service.did.d.ts @@ -7,6 +7,12 @@ export interface AddLiquidityInfo { 'rune_amount_for_add_liquidity' : bigint, } export interface CoinBalance { 'id' : string, 'value' : bigint } +export interface CookiePoolState { + 'txid' : string, + 'utxo' : Utxo, + 'user_action' : UserAction, + 'nonce' : bigint, +} export interface CreateGameArgs { 'rune_premine_amount' : bigint, 'create_address' : string, @@ -26,7 +32,6 @@ export type ExchangeError = { 'InvalidSignPsbtArgs' : string } | { 'RuneNotFound' : string } | { 'CookieBalanceInsufficient' : bigint } | { 'GameEnd' : null } | - { 'ReorgError' : ReorgError } | { 'GamerAlreadyExist' : string } | { 'DuplicateBlock' : [number, string] } | { 'PoolStateExpired' : bigint } | @@ -39,7 +44,7 @@ export type ExchangeError = { 'InvalidSignPsbtArgs' : string } | { 'InvalidRuneId' : null } | { 'InvalidPool' : null } | { 'InvalidPsbt' : string } | - { 'GameNotFound' : bigint } | + { 'GameNotFound' : string } | { 'PoolAlreadyExists' : null } | { 'GamerCoolingDown' : [string, bigint] } | { 'InvalidTxid' : string } | @@ -58,9 +63,8 @@ export type ExchangeError = { 'InvalidSignPsbtArgs' : string } | { 'RuneIdNotMatch' : [string, string] } | { 'PoolAddressMismatch' : { 'actual' : string, 'expected' : string } }; export interface ExchangeState { - 'txid_game_map' : Array<[string, bigint]>, - 'orchestrator' : Principal, - 'games' : Array<[bigint, Game]>, + 'txid_game_map' : Array<[string, string]>, + 'games' : Array<[string, Game]>, } export interface ExecuteTxArgs { 'zero_confirmed_tx_queue_length' : number, @@ -74,17 +78,21 @@ export interface Game { 'claimed_cookies' : bigint, 'rune_premine_amount' : bigint, 'creator_address' : string, - 'pool' : [] | [Pool], 'rune_info' : [] | [RuneInfo], 'gamers' : Array<[string, Gamer]>, 'claim_amount_per_click' : bigint, - 'game_id' : bigint, + 'game_id' : string, 'game_status' : GameStatus, 'game_name' : string, 'etch_rune_commit_tx' : string, 'claim_cooling_down' : bigint, 'gamer_register_fee' : bigint, } +export interface GameAndPool { + 'game' : Game, + 'pool_state' : [] | [CookiePoolState], + 'pool_metadata' : [] | [Metadata], +} export type GameStatus = { 'WaitAddedLiquidity' : null } | { 'Playing' : null } | { 'Withdrawing' : null } | @@ -113,6 +121,12 @@ export interface IntentionSet { 'initiator_address' : string, 'intentions' : Array, } +export interface Metadata { + 'key' : string, + 'name' : string, + 'key_derivation_path' : Array, + 'address' : string, +} export interface NewBlockInfo { 'block_hash' : string, 'confirmed_txids' : Array, @@ -120,16 +134,6 @@ export interface NewBlockInfo { 'block_height' : number, } export interface OutputCoin { 'to' : string, 'coin' : CoinBalance } -export interface Pool { - 'states' : Array, - 'name' : string, - 'pubkey' : string, - 'key_derivation_path' : string, - 'attributes' : string, - 'address' : string, - 'nonce' : bigint, - 'pending_transaction_counts' : bigint, -} export interface PoolBasic { 'name' : string, 'address' : string } export interface PoolInfo { 'key' : string, @@ -142,12 +146,6 @@ export interface PoolInfo { 'nonce' : bigint, 'utxos' : Array, } -export interface PoolState { - 'id' : string, - 'utxo' : Utxo, - 'user_action' : UserAction, - 'nonce' : bigint, -} export type RejectionCode = { 'NoError' : null } | { 'CanisterError' : null } | { 'SysTransient' : null } | @@ -155,26 +153,18 @@ export type RejectionCode = { 'NoError' : null } | { 'Unknown' : null } | { 'SysFatal' : null } | { 'CanisterReject' : null }; -export type ReorgError = { - 'DuplicateBlock' : { 'height' : number, 'hash' : string } - } | - { 'BlockNotFoundInState' : { 'height' : number } } | - { 'Unrecoverable' : null } | - { 'Recoverable' : { 'height' : number, 'depth' : number } }; export type Result = { 'Ok' : bigint } | { 'Err' : ExchangeError }; -export type Result_1 = { 'Ok' : bigint } | - { 'Err' : string }; -export type Result_2 = { 'Ok' : string } | +export type Result_1 = { 'Ok' : string } | { 'Err' : string }; -export type Result_3 = { 'Ok' : null } | +export type Result_2 = { 'Ok' : null } | { 'Err' : string }; -export interface RollbackTxArgs { 'txid' : string } +export interface RollbackTxArgs { 'txid' : string, 'reason_code' : string } export interface RuneInfo { 'rune_name' : string, 'rune_id' : string } -export type UserAction = { 'Withdraw' : string } | +export type UserAction = { 'Withdraw' : [string, string] } | { 'AddLiquidity' : null } | { 'Init' : null } | - { 'Register' : string }; + { 'Register' : [string, string] }; export interface Utxo { 'coins' : Array, 'sats' : bigint, @@ -182,23 +172,20 @@ export interface Utxo { 'vout' : number, } export interface _SERVICE { - 'claim' : ActorMethod<[bigint], Result>, + 'claim' : ActorMethod<[string], Result>, 'create_game' : ActorMethod<[CreateGameArgs], Result_1>, - 'etch_rune' : ActorMethod<[bigint, string], Result_2>, - 'etching_test' : ActorMethod<[], Result_2>, - 'execute_tx' : ActorMethod<[ExecuteTxArgs], Result_2>, - 'finalize_etch' : ActorMethod<[bigint], Result_2>, + 'etch_rune' : ActorMethod<[string, string], Result_1>, + 'execute_tx' : ActorMethod<[ExecuteTxArgs], Result_1>, + 'finalize_etch' : ActorMethod<[string], Result_1>, 'get_exchange_state' : ActorMethod<[], ExchangeState>, - 'get_game_info' : ActorMethod<[bigint], [] | [Game]>, - 'get_game_pool_address' : ActorMethod<[bigint], string>, - 'get_games_info' : ActorMethod<[], Array>, + 'get_game_info' : ActorMethod<[string], [] | [GameAndPool]>, + 'get_game_pool_address' : ActorMethod<[string], string>, + 'get_games_info' : ActorMethod<[], Array>, 'get_pool_info' : ActorMethod<[GetPoolInfoArgs], [] | [PoolInfo]>, 'get_pool_list' : ActorMethod<[], Array>, - 'get_pool_states' : ActorMethod<[], Array>, - 'new_block' : ActorMethod<[NewBlockInfo], Result_3>, - 'query_add_liquidity_info' : ActorMethod<[bigint], AddLiquidityInfo>, - 'reset_blocks' : ActorMethod<[], undefined>, - 'rollback_tx' : ActorMethod<[RollbackTxArgs], Result_3>, + 'new_block' : ActorMethod<[NewBlockInfo], Result_2>, + 'query_add_liquidity_info' : ActorMethod<[string], AddLiquidityInfo>, + 'rollback_tx' : ActorMethod<[RollbackTxArgs], Result_2>, } export declare const idlFactory: IDL.InterfaceFactory; export declare const init: (args: { IDL: typeof IDL }) => IDL.Type[]; diff --git a/ree-cookie-frontend/src/canister/cookie/service.did.js b/ree-cookie-frontend/src/canister/cookie/service.did.js index a633c39..d647ce8 100644 --- a/ree-cookie-frontend/src/canister/cookie/service.did.js +++ b/ree-cookie-frontend/src/canister/cookie/service.did.js @@ -1,10 +1,4 @@ export const idlFactory = ({ IDL }) => { - const ReorgError = IDL.Variant({ - 'DuplicateBlock' : IDL.Record({ 'height' : IDL.Nat32, 'hash' : IDL.Text }), - 'BlockNotFoundInState' : IDL.Record({ 'height' : IDL.Nat32 }), - 'Unrecoverable' : IDL.Null, - 'Recoverable' : IDL.Record({ 'height' : IDL.Nat32, 'depth' : IDL.Nat32 }), - }); const GameStatus = IDL.Variant({ 'WaitAddedLiquidity' : IDL.Null, 'Playing' : IDL.Null, @@ -32,7 +26,6 @@ export const idlFactory = ({ IDL }) => { 'RuneNotFound' : IDL.Text, 'CookieBalanceInsufficient' : IDL.Nat, 'GameEnd' : IDL.Null, - 'ReorgError' : ReorgError, 'GamerAlreadyExist' : IDL.Text, 'DuplicateBlock' : IDL.Tuple(IDL.Nat32, IDL.Text), 'PoolStateExpired' : IDL.Nat64, @@ -45,7 +38,7 @@ export const idlFactory = ({ IDL }) => { 'InvalidRuneId' : IDL.Null, 'InvalidPool' : IDL.Null, 'InvalidPsbt' : IDL.Text, - 'GameNotFound' : IDL.Nat64, + 'GameNotFound' : IDL.Text, 'PoolAlreadyExists' : IDL.Null, 'GamerCoolingDown' : IDL.Tuple(IDL.Text, IDL.Nat64), 'InvalidTxid' : IDL.Text, @@ -76,8 +69,7 @@ export const idlFactory = ({ IDL }) => { 'claim_cooling_down' : IDL.Nat64, 'gamer_register_fee' : IDL.Nat64, }); - const Result_1 = IDL.Variant({ 'Ok' : IDL.Nat64, 'Err' : IDL.Text }); - const Result_2 = IDL.Variant({ 'Ok' : IDL.Text, 'Err' : IDL.Text }); + const Result_1 = IDL.Variant({ 'Ok' : IDL.Text, 'Err' : IDL.Text }); const CoinBalance = IDL.Record({ 'id' : IDL.Text, 'value' : IDL.Nat }); const InputCoin = IDL.Record({ 'coin' : CoinBalance, 'from' : IDL.Text }); const OutputCoin = IDL.Record({ 'to' : IDL.Text, 'coin' : CoinBalance }); @@ -110,28 +102,6 @@ export const idlFactory = ({ IDL }) => { 'intention_index' : IDL.Nat32, 'psbt_hex' : IDL.Text, }); - const UserAction = IDL.Variant({ - 'Withdraw' : IDL.Text, - 'AddLiquidity' : IDL.Null, - 'Init' : IDL.Null, - 'Register' : IDL.Text, - }); - const PoolState = IDL.Record({ - 'id' : IDL.Text, - 'utxo' : Utxo, - 'user_action' : UserAction, - 'nonce' : IDL.Nat64, - }); - const Pool = IDL.Record({ - 'states' : IDL.Vec(PoolState), - 'name' : IDL.Text, - 'pubkey' : IDL.Text, - 'key_derivation_path' : IDL.Text, - 'attributes' : IDL.Text, - 'address' : IDL.Text, - 'nonce' : IDL.Nat64, - 'pending_transaction_counts' : IDL.Nat64, - }); const RuneInfo = IDL.Record({ 'rune_name' : IDL.Text, 'rune_id' : IDL.Text }); const Gamer = IDL.Record({ 'is_withdrawn' : IDL.Bool, @@ -144,11 +114,10 @@ export const idlFactory = ({ IDL }) => { 'claimed_cookies' : IDL.Nat, 'rune_premine_amount' : IDL.Nat, 'creator_address' : IDL.Text, - 'pool' : IDL.Opt(Pool), 'rune_info' : IDL.Opt(RuneInfo), 'gamers' : IDL.Vec(IDL.Tuple(IDL.Text, Gamer)), 'claim_amount_per_click' : IDL.Nat, - 'game_id' : IDL.Nat64, + 'game_id' : IDL.Text, 'game_status' : GameStatus, 'game_name' : IDL.Text, 'etch_rune_commit_tx' : IDL.Text, @@ -156,9 +125,31 @@ export const idlFactory = ({ IDL }) => { 'gamer_register_fee' : IDL.Nat64, }); const ExchangeState = IDL.Record({ - 'txid_game_map' : IDL.Vec(IDL.Tuple(IDL.Text, IDL.Nat64)), - 'orchestrator' : IDL.Principal, - 'games' : IDL.Vec(IDL.Tuple(IDL.Nat64, Game)), + 'txid_game_map' : IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)), + 'games' : IDL.Vec(IDL.Tuple(IDL.Text, Game)), + }); + const UserAction = IDL.Variant({ + 'Withdraw' : IDL.Tuple(IDL.Text, IDL.Text), + 'AddLiquidity' : IDL.Null, + 'Init' : IDL.Null, + 'Register' : IDL.Tuple(IDL.Text, IDL.Text), + }); + const CookiePoolState = IDL.Record({ + 'txid' : IDL.Text, + 'utxo' : Utxo, + 'user_action' : UserAction, + 'nonce' : IDL.Nat64, + }); + const Metadata = IDL.Record({ + 'key' : IDL.Text, + 'name' : IDL.Text, + 'key_derivation_path' : IDL.Vec(IDL.Vec(IDL.Nat8)), + 'address' : IDL.Text, + }); + const GameAndPool = IDL.Record({ + 'game' : Game, + 'pool_state' : IDL.Opt(CookiePoolState), + 'pool_metadata' : IDL.Opt(Metadata), }); const GetPoolInfoArgs = IDL.Record({ 'pool_address' : IDL.Text }); const PoolInfo = IDL.Record({ @@ -179,38 +170,38 @@ export const idlFactory = ({ IDL }) => { 'block_timestamp' : IDL.Nat64, 'block_height' : IDL.Nat32, }); - const Result_3 = IDL.Variant({ 'Ok' : IDL.Null, 'Err' : IDL.Text }); + const Result_2 = IDL.Variant({ 'Ok' : IDL.Null, 'Err' : IDL.Text }); const AddLiquidityInfo = IDL.Record({ 'btc_amount_for_add_liquidity' : IDL.Nat64, 'rune_amount_for_add_liquidity' : IDL.Nat, }); - const RollbackTxArgs = IDL.Record({ 'txid' : IDL.Text }); + const RollbackTxArgs = IDL.Record({ + 'txid' : IDL.Text, + 'reason_code' : IDL.Text, + }); return IDL.Service({ - 'claim' : IDL.Func([IDL.Nat64], [Result], []), + 'claim' : IDL.Func([IDL.Text], [Result], []), 'create_game' : IDL.Func([CreateGameArgs], [Result_1], []), - 'etch_rune' : IDL.Func([IDL.Nat64, IDL.Text], [Result_2], []), - 'etching_test' : IDL.Func([], [Result_2], []), - 'execute_tx' : IDL.Func([ExecuteTxArgs], [Result_2], []), - 'finalize_etch' : IDL.Func([IDL.Nat64], [Result_2], []), + 'etch_rune' : IDL.Func([IDL.Text, IDL.Text], [Result_1], []), + 'execute_tx' : IDL.Func([ExecuteTxArgs], [Result_1], []), + 'finalize_etch' : IDL.Func([IDL.Text], [Result_1], []), 'get_exchange_state' : IDL.Func([], [ExchangeState], ['query']), - 'get_game_info' : IDL.Func([IDL.Nat64], [IDL.Opt(Game)], ['query']), - 'get_game_pool_address' : IDL.Func([IDL.Nat64], [IDL.Text], []), - 'get_games_info' : IDL.Func([], [IDL.Vec(Game)], ['query']), + 'get_game_info' : IDL.Func([IDL.Text], [IDL.Opt(GameAndPool)], ['query']), + 'get_game_pool_address' : IDL.Func([IDL.Text], [IDL.Text], []), + 'get_games_info' : IDL.Func([], [IDL.Vec(GameAndPool)], ['query']), 'get_pool_info' : IDL.Func( [GetPoolInfoArgs], [IDL.Opt(PoolInfo)], ['query'], ), 'get_pool_list' : IDL.Func([], [IDL.Vec(PoolBasic)], ['query']), - 'get_pool_states' : IDL.Func([], [IDL.Vec(PoolState)], ['query']), - 'new_block' : IDL.Func([NewBlockInfo], [Result_3], []), + 'new_block' : IDL.Func([NewBlockInfo], [Result_2], []), 'query_add_liquidity_info' : IDL.Func( - [IDL.Nat64], + [IDL.Text], [AddLiquidityInfo], ['query'], ), - 'reset_blocks' : IDL.Func([], [], []), - 'rollback_tx' : IDL.Func([RollbackTxArgs], [Result_3], []), + 'rollback_tx' : IDL.Func([RollbackTxArgs], [Result_2], []), }); }; -export const init = ({ IDL }) => { return [IDL.Principal]; }; +export const init = ({ IDL }) => { return []; }; diff --git a/ree-cookie-frontend/src/canister/orchestrator/service.did.d.ts b/ree-cookie-frontend/src/canister/orchestrator/service.did.d.ts index a65ab45..1bfb1b2 100644 --- a/ree-cookie-frontend/src/canister/orchestrator/service.did.d.ts +++ b/ree-cookie-frontend/src/canister/orchestrator/service.did.d.ts @@ -138,7 +138,6 @@ export interface OrchestratorStatus { 'pending_tx_count' : bigint, 'mempool_tx_fee_rate' : MempoolTxFeeRateView, 'invoke_paused' : boolean, - 'utxo_proof_verification_status' : UtxoProofVerificationStatus, } export interface OutpointWithValue { 'maybe_rune' : [] | [CoinBalance], diff --git a/ree-cookie-frontend/src/canister/orchestrator/service.did.js b/ree-cookie-frontend/src/canister/orchestrator/service.did.js index 51510e8..a8c573e 100644 --- a/ree-cookie-frontend/src/canister/orchestrator/service.did.js +++ b/ree-cookie-frontend/src/canister/orchestrator/service.did.js @@ -151,7 +151,6 @@ export const idlFactory = ({ IDL }) => { 'pending_tx_count' : IDL.Nat64, 'mempool_tx_fee_rate' : MempoolTxFeeRateView, 'invoke_paused' : IDL.Bool, - 'utxo_proof_verification_status' : UtxoProofVerificationStatus, }); const TxStatus = IDL.Variant({ 'Confirmed' : IDL.Nat32, diff --git a/ree-cookie-frontend/src/components/Fruit.tsx b/ree-cookie-frontend/src/components/Fruit.tsx deleted file mode 100644 index b2feddd..0000000 --- a/ree-cookie-frontend/src/components/Fruit.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import type {Fruit as FruitType} from 'api/fruits' -import {Link} from 'react-router' -import {useMediaQuery} from 'utils/useMediaQuery' -import {ImageAttribution} from './ImageAttribution' - -const PREFERRED_IMAGE_WIDTH = 384 -const MOBILE_PADDING = 16 -const ASPECT_RATIO_WIDTH = 16 -const ASPECT_RATIO_HEIGHT = 9 -const IMAGE_INDEX_BELOW_THE_FOLD = 3 - -interface Properties { - fruit: FruitType - index: number -} - -export function Fruit({fruit, index}: Properties) { - const isTabletAndUp = useMediaQuery('(min-width: 600px)') - - const imageWidth = Math.min( - PREFERRED_IMAGE_WIDTH, - window.innerWidth - MOBILE_PADDING - ) - const imageHeight = imageWidth / (ASPECT_RATIO_WIDTH / ASPECT_RATIO_HEIGHT) - - return ( - -
- {fruit.name}= IMAGE_INDEX_BELOW_THE_FOLD - ? 'async' - : 'sync' - } - height={imageHeight} - loading={ - !isTabletAndUp && index >= IMAGE_INDEX_BELOW_THE_FOLD - ? 'lazy' - : 'eager' - } - src={`${fruit.image.url}&w=${ - imageWidth * window.devicePixelRatio - }&h=${imageHeight * window.devicePixelRatio}`} - style={{ - backgroundColor: fruit.image.color - }} - width={imageWidth} - /> - -
-

{fruit.name}

- - ) -} diff --git a/ree-cookie-frontend/src/components/Head.tsx b/ree-cookie-frontend/src/components/Head.tsx deleted file mode 100644 index d4b7283..0000000 --- a/ree-cookie-frontend/src/components/Head.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import {useEffect} from 'react' - -interface Properties { - title: string -} - -export function Head({title}: Properties): null { - useEffect(() => { - document.title = title - }, [title]) - - return null -} diff --git a/ree-cookie-frontend/src/components/ImageAttribution.tsx b/ree-cookie-frontend/src/components/ImageAttribution.tsx deleted file mode 100644 index 579cd76..0000000 --- a/ree-cookie-frontend/src/components/ImageAttribution.tsx +++ /dev/null @@ -1,14 +0,0 @@ -interface Properties { - author: string -} - -export function ImageAttribution({author}: Properties) { - return ( - <> -
-
- Photo by {author} on Unsplash -
- - ) -} diff --git a/ree-cookie-frontend/src/components/Register.tsx b/ree-cookie-frontend/src/components/Register.tsx index bdf4ad4..ef34961 100644 --- a/ree-cookie-frontend/src/components/Register.tsx +++ b/ree-cookie-frontend/src/components/Register.tsx @@ -1,7 +1,7 @@ import { useLaserEyes } from "@omnisat/lasereyes"; import { Button } from "antd"; import { cookieActor } from "canister/cookie/actor"; -import { Game, Gamer } from "canister/cookie/service.did"; +import { CookiePoolState, Game, GameAndPool, Gamer, Metadata } from "canister/cookie/service.did"; import { ocActor } from "canister/orchestrator/actor"; import { OrchestratorStatus } from "canister/orchestrator/service.did"; import { COOKIE_EXCHANGE_ID } from "../constants/common"; @@ -19,12 +19,13 @@ import { connectWalletModalOpenAtom } from "./ConnectDialog"; export function Register({ game, -}: // paymentAddress, -// paymentAddressUtxos + pool_state, + pool_metadata, +}: { game: Game; - // paymentAddress: string; - // paymentAddressUtxos: UnspentOutput[] | undefined; + pool_state: CookiePoolState; + pool_metadata: Metadata; }) { const [connectWalletModalOpen, setConnectWalletModalOpen] = useAtom( connectWalletModalOpenAtom @@ -45,12 +46,11 @@ export function Register({ alert("No UTXOs found"); return; } - // let register_info: RegisterInfo = await cookieActor.get_register_info() - // const btc_pool = get_btc_pool(game); - const btc_pool = game.pool[0]!; - const last_state = btc_pool.states[btc_pool.states.length - 1]; + + const last_state = pool_state; + console.log({pool_state, pool_metadata}) const { address: poolAddress, output } = getP2trAressAndScript( - btc_pool.pubkey + pool_metadata.key ); // let recommendedFeeRate = await Orchestrator.getRecommendedFee() let recommendedFeeRate = await ocActor @@ -77,13 +77,15 @@ export function Register({ userBtcUtxos: (btcUtxos ?? []).map((e) => convertMaestroUtxo(e, publicKey) ), - poolBtcUtxo: convertUtxo(last_state?.utxo!, btc_pool.pubkey), + poolBtcUtxo: convertUtxo(last_state?.utxo!, pool_metadata.key), paymentAddress: paymentAddress, poolAddress: poolAddress!, feeRate: recommendedFeeRate, registerFee: game.gamer_register_fee, }); + + console.log(psbt); console.log(psbt.toHex()); const psbtBase64 = psbt.toBase64(); @@ -116,7 +118,7 @@ export function Register({ pool_utxo_spent: [], pool_utxo_received: [], output_coins: outputCoins, - pool_address: btc_pool.address, + pool_address: pool_metadata.address, action_params: JSON.stringify({ game_id: Number(game.game_id), }), diff --git a/ree-cookie-frontend/src/components/modals/CreateGameModal.tsx b/ree-cookie-frontend/src/components/modals/CreateGameModal.tsx index b119b6f..1ba8c9b 100644 --- a/ree-cookie-frontend/src/components/modals/CreateGameModal.tsx +++ b/ree-cookie-frontend/src/components/modals/CreateGameModal.tsx @@ -77,7 +77,7 @@ export function CreateGameModal() { - label="Click Cooling Down" + label="Click Cooling Down(Seconds)" name="claimCoolingDown" rules={[{ required: true, message: "Please input your click cooling down!" }]} > diff --git a/ree-cookie-frontend/src/hooks/use-pool.ts b/ree-cookie-frontend/src/hooks/use-pool.ts index 6b8a619..522d157 100644 --- a/ree-cookie-frontend/src/hooks/use-pool.ts +++ b/ree-cookie-frontend/src/hooks/use-pool.ts @@ -1,11 +1,11 @@ import { useQuery } from "@tanstack/react-query"; import { cookieActor } from "../canister/cookie/actor"; -import type { Game } from "../canister/cookie/service.did"; +import type { Game, GameAndPool } from "../canister/cookie/service.did"; import { etchActor } from "canister/etching/actor"; export function useGames() { - return useQuery({ + return useQuery({ queryKey: ["games"], queryFn: async () => { const games = await cookieActor.get_games_info(); @@ -18,10 +18,10 @@ export function useGames() { export function useGame( gameId: string) { - return useQuery({ + return useQuery({ queryKey: ["game", gameId], queryFn: async () => { - const game = await cookieActor.get_game_info(BigInt(gameId)); + const game = await cookieActor.get_game_info(gameId); return game[0]!; }, retry: false, diff --git a/ree-cookie-frontend/src/pages/Game.tsx b/ree-cookie-frontend/src/pages/Game.tsx index 88f295d..2d67169 100644 --- a/ree-cookie-frontend/src/pages/Game.tsx +++ b/ree-cookie-frontend/src/pages/Game.tsx @@ -18,9 +18,12 @@ import { } from "canister/cookie/actor"; import { AddLiquidityInfo, + CookiePoolState, Game, + GameAndPool, Gamer, GameStatus, + Metadata, } from "canister/cookie/service.did"; import { ocActor } from "canister/orchestrator/actor"; import { OrchestratorStatus } from "canister/orchestrator/service.did"; @@ -64,14 +67,14 @@ export const stateStepIndex = (game_status: GameStatus) => { export function GameDetail() { const { game_id } = useParams<{ game_id: string }>(); - const { data: game, isLoading, isError, error } = useGame(game_id!); - const [current, setCurrent] = useState(0); + const { data: game_and_pool, isLoading, isError, error } = useGame(game_id!); + const [current, setCurrent] = useState(0); useEffect(() => { - if (game) { - setCurrent(stateStepIndex(game!.game_status)); + if (game_and_pool) { + setCurrent(stateStepIndex(game_and_pool.game!.game_status)); } - }, [game]); + }, [game_and_pool]); if (isLoading) { return
Loading...
; @@ -81,22 +84,39 @@ export function GameDetail() { return
Error loading game: {error.message}
; } + console.log({ game_and_pool }); + + const steps = [ { title: "Etching", - content: , + content: , }, { title: "Playing", - content: , + content: , }, { title: "Wait Added Liquidity", - content: , + content: , }, { title: "Withdrawing", - content: , + content: ( + + ), }, ]; const items = steps.map((item) => ({ key: item.title, title: item.title })); @@ -116,7 +136,15 @@ export function GameDetail() { ); } -function Playing({ game }: { game: Game }) { +function Playing({ + game, + pool_state, + pool_metadata, +}: { + game: Game, + pool_state: CookiePoolState, + pool_metadata: Metadata +}) { // const ope // const [connectWalletModalOpen, setConnectWalletModalOpen] = useAtom( // connectWalletModalOpenAtom @@ -124,33 +152,11 @@ function Playing({ game }: { game: Game }) { const setConnectWalletModalOpen = useSetAtom(connectWalletModalOpenAtom); const { identityAddress, identity } = useSiwbIdentity(); const currentGamer = useMemo(() => { - return game.gamers.find((gamer) => gamer[0] === identityAddress)?.[1]; + return game.gamers.find( + (gamer) => gamer[0] === identityAddress + )?.[1]; }, [game.gamers, identityAddress]); const isGameEnd = stateStepIndex(game.game_status) > 1; - // const { address, connect } = useLaserEyes(); - // const [isRegistered, setIsRegistered] = useState(false); - // const [loading, setLoading] = useState(true); - // const [lastClaimTime, setLastClaimTime] = useState(BigInt(0)); - // const [claimCoolingDown, setClaimCoolingDown] = useState(BigInt(0)); - // const [claimedCookies, setClaimedCookies] = useState(BigInt(0)); - // const [cookieAmountPerClick, setCookieAmountPerClick] = useState( - // BigInt(0) - // ); - // const [messageApi, contextHolder] = message.useMessage(); - - // const isLoading = useMemo(()=> { - - // }, []) - - // return ( - // currentGamer ? - // - // : - // - // ) return (
@@ -165,14 +171,13 @@ function Playing({ game }: { game: Game }) { ) : ( - + ) ) : ( @@ -189,11 +194,9 @@ function Playing({ game }: { game: Game }) { function EtchProcess({ commit_txid, - game_id, game, }: { commit_txid: string | undefined; - game_id: bigint; game: Game; }) { const { identity } = useSiwbIdentity(); @@ -264,7 +267,7 @@ function EtchProcess({ onClick={() => { setFinalizing(true); cookieActorWithIdentity(identity!) - .finalize_etch(game_id!) + .finalize_etch(game.game_id!) .then(() => {}) .catch((e) => { alert("Finalize Etch Failed: " + e.message); @@ -291,26 +294,20 @@ function EtchProcess({ ); } -function Etching({ game }: { game: Game }) { +function Etching({ game_and_pool }: { game_and_pool: GameAndPool }) { // game. const [isEtching, setIsEtching] = useState(false); const { identity } = useSiwbIdentity(); - let commit_txid = game.etch_rune_commit_tx; + let commit_txid = game_and_pool.game.etch_rune_commit_tx; return (
{commit_txid ? ( - + ) : (
-

- Please transfer 1 $ICP to {COOKIE_CANISTER_ID} before etch -

+

Please transfer 1 $ICP to this canister before etch:

{COOKIE_CANISTER_ID}

{ setIsEtching(true); cookieActorWithIdentity(identity!) - .etch_rune(game.game_id, value) + .etch_rune(game_and_pool.game.game_id, value) .then((r) => { if ("Ok" in r) { alert("Etch Success: " + JSON.stringify(r.Ok)); @@ -360,7 +357,15 @@ function Etching({ game }: { game: Game }) { //
// } -function WaitAddedLiquidity({ game }: { game: Game }) { +function WaitAddedLiquidity({ + game, + pool_state, + pool_metadata +}: { + game: Game, + pool_state: CookiePoolState, + pool_metadata: Metadata +}) { const setConnectWalletModalOpen = useSetAtom(connectWalletModalOpenAtom); const [loading, setLoading] = useState(false); const [isCalling, setIsCalling] = useState(false); @@ -388,8 +393,9 @@ function WaitAddedLiquidity({ game }: { game: Game }) { f(); }, []); - const pool = game.pool[0]!; - const last_pool_state = pool.states[pool.states.length - 1]; + // const pool = game.pool[0]!; + // const last_pool_state = pool.states[pool.states.length - 1]; + const last_pool_state = pool_state; // const btc_pool = game.pool_manager.btc_pools[0]![1]; // const rune_pool = game.pool_manager.rune_pool[0]!; @@ -441,13 +447,13 @@ function WaitAddedLiquidity({ game }: { game: Game }) { gameid: Number(game.game_id), runeAmountForAddLiquidity: addLiquidityInfo!.rune_amount_for_add_liquidity, - cookiePoolUtxo: convertUtxo(last_pool_state!.utxo, pool.pubkey), + cookiePoolUtxo: convertUtxo(last_pool_state!.utxo, pool_metadata.key), paymentAddress: paymentAddress, swapPoolAddress: gameSwapPool!.address, - cookiePoolAddress: pool.address, + cookiePoolAddress: pool_metadata.address, feeRate: Number(recommendedFeeRate.toString()), signPsbt: signPsbt, - cookiePoolNonce: BigInt(pool.nonce), + cookiePoolNonce: BigInt(pool_state.nonce), swapPoolNonce: liquidityOffer.nonce, }); }; @@ -503,13 +509,22 @@ function WaitAddedLiquidity({ game }: { game: Game }) { ); } -function Withdrawing({ game }: { game: Game }) { +function Withdrawing({ + game, + pool_state, + pool_metadata, +}: { + game: Game; + pool_state: CookiePoolState; + pool_metadata: Metadata; +}) { const [calling, setCalling] = useState(false); const { address, paymentAddress, signPsbt } = useLaserEyes(); const setConnectWalletModalOpen = useSetAtom(connectWalletModalOpenAtom); const userBtcUtxos = useWalletBtcUtxos(); - const pool = game.pool[0]!; - const last_pool_state = pool.states[pool.states.length - 1]; + // const pool = game.pool[0]!; + // const last_pool_state = pool.states[pool.states.length - 1]; + const last_pool_state = pool_state; const rune_id = game.rune_info[0]!.rune_id; @@ -531,13 +546,13 @@ function Withdrawing({ game }: { game: Game }) { userBtcUtxos: userBtcUtxos!, runeId: rune_id, gameId: Number(game.game_id), - cookiePoolBtcUtxo: convertUtxo(last_pool_state!.utxo, pool.pubkey), + cookiePoolBtcUtxo: convertUtxo(last_pool_state!.utxo, pool_metadata.key), paymentAddress: paymentAddress, address: address, - cookiePoolAddress: pool.address, + cookiePoolAddress: pool_metadata.address, feeRate: Number(recommendedFeeRate.toString()), signPsbt: signPsbt, - cookiePoolNonce: pool.nonce, + cookiePoolNonce: pool_state.nonce, withdrawAmount: BigInt(currentGamer!.cookies), }); }; @@ -568,7 +583,7 @@ function Withdrawing({ game }: { game: Game }) { }); }} > - Withdraw {currentGamer!.cookies} game rune token + Withdraw {currentGamer!.cookies} game rune token ) ) : ( @@ -689,80 +704,3 @@ type InitUtxo = { // runeId?: string; // runeValue?: bigint; }; - -// function InitGame({ game }: { game: Game }) { -// // const [messageApi, contextHolder] = message.useMessage(); -// const isInitializing = stateStepIndex(game.game_status) === 0; -// const [poolAddress, setPoolAddress] = useState(undefined); - -// useEffect(() => { -// cookieActor.get_new_btc_pool_address(game.game_id).then((res) => { -// console.log("get_new_btc_pool_address", res); -// setPoolAddress(res); -// }); -// }, []); - -// const onFinish: FormProps["onFinish"] = async (values) => { -// console.log("Success Finish form:", values); -// await cookieActor -// .add_new_btc_pool(game.game_id, { -// txid: values.txid!, -// vout: Number(values.vout!), -// sats: BigInt(values.sats!), -// coins: [], -// }) -// .then((res) => { -// console.log("init utxo", res); -// window.location.reload(); -// }); -// }; - -// return ( -//
-// {!isInitializing ? ( -//
Finished Init
-// ) : ( -//
-// {poolAddress ? ( -//
-//

New Pool Address: {poolAddress}

-//

-// Please Transfer at least 546 sats to Pool Address to init pool. -//

-//
-// ) : ( -// -// )} -//
-// -// label="txid" -// name="txid" -// rules={[{ required: true, message: "Please input txid!" }]} -// > -// -// -// -// label="vout" -// name="vout" -// rules={[{ required: true, message: "Please input vout!" }]} -// > -// -// -// -// label="sats" -// name="sats" -// rules={[{ required: true, message: "Please input sats!" }]} -// > -// -// -// -// -// -// -//
-// )} -//
-// ); -// } diff --git a/ree-cookie-frontend/src/pages/Home.tsx b/ree-cookie-frontend/src/pages/Home.tsx index 6855589..057e95b 100644 --- a/ree-cookie-frontend/src/pages/Home.tsx +++ b/ree-cookie-frontend/src/pages/Home.tsx @@ -5,7 +5,6 @@ import { List } from "antd"; import { useSetAtom } from "jotai"; import { createGameModalOpenAtom } from "components/modals/CreateGameModal"; import { useLaserEyes } from "@omnisat/lasereyes"; -import { ad } from "vitest/dist/chunks/reporters.d.DL9pg5DB.js"; import { } from "components/modals/ConnetWalletModal"; import { game_status_str } from "canister/cookie/actor"; import { Link } from "react-router-dom"; @@ -40,7 +39,7 @@ export function Home() { grid={{ gutter: 16, }} - dataSource={games ?? []} + dataSource={games?.map(e=>e.game) ?? []} renderItem={(game: Game) => (