From d41bb6b0bc3958c1bf9a63e8c16b97cecd8e9d7d Mon Sep 17 00:00:00 2001 From: n0izn0iz Date: Thu, 31 Oct 2024 17:42:19 +0100 Subject: [PATCH 01/14] chore: upgade gno (#1319) * chore: upgade gno Signed-off-by: Norman Meier * feat: shared gno version Signed-off-by: Norman Meier --------- Signed-off-by: Norman Meier --- .gnoversion | 1 + Makefile | 3 ++- packages/scripts/install-gno.ts | 5 ++++- 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .gnoversion diff --git a/.gnoversion b/.gnoversion new file mode 100644 index 0000000000..ddef93042d --- /dev/null +++ b/.gnoversion @@ -0,0 +1 @@ +9786fa366f922f04e1251ec6f1df6423b4fd2bf4 diff --git a/Makefile b/Makefile index 3862dec8c4..ac8db6d800 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ CANDYMACHINE_REPO=teritori-nfts BUNKER_MINTER_PACKAGE=teritori-bunker-minter GO?=go GOFMT?=$(shell $(GO) env GOROOT)/bin/gofmt +CAT := $(if $(filter $(OS),Windows_NT),type,cat) COSMWASM_CONTRACTS_DIR=rust/cw-contracts INTERNAL_COSMWASM_CONTRACTS=$(wildcard $(COSMWASM_CONTRACTS_DIR)/*) @@ -446,7 +447,7 @@ start.gnodev-e2e: clone-gno: rm -fr gnobuild mkdir -p gnobuild - cd gnobuild && git clone https://github.com/gnolang/gno.git && cd gno && git checkout 8f800ece85a765113dfa4924da1c06f56865460c + cd gnobuild && git clone https://github.com/gnolang/gno.git && cd gno && git checkout $(shell $(CAT) .gnoversion) cp -r ./gno/p ./gnobuild/gno/examples/gno.land/p/teritori cp -r ./gno/r ./gnobuild/gno/examples/gno.land/r/teritori diff --git a/packages/scripts/install-gno.ts b/packages/scripts/install-gno.ts index 66db6555c3..d3185e536e 100644 --- a/packages/scripts/install-gno.ts +++ b/packages/scripts/install-gno.ts @@ -5,10 +5,13 @@ import path from "path"; import sqh from "./sqh"; -const ref = "fec2d18f630b44ccc2121472aa2284cd9c8caf6f"; +const gnoVersionFilepath = path.join(__dirname, "..", "..", ".gnoversion"); const remote = "https://github.com/gnolang/gno.git"; const main = async () => { + const ref = ( + await fs.readFile(gnoVersionFilepath, { encoding: "utf-8" }) + ).trim(); const buildDir = await fs.mkdtemp(path.join(os.tmpdir(), "gno-build-")); const cmd = `git clone ${sqh(remote)} ${sqh(buildDir)} && cd ${sqh(buildDir)} && git checkout ${sqh(ref)} && make install`; console.log(">", cmd); From 7a27ad3ca8c8cbb4aff14ac84b8eb81f0dc84b30 Mon Sep 17 00:00:00 2001 From: WaDadidou <50441633+WaDadidou@users.noreply.github.com> Date: Thu, 31 Oct 2024 21:28:33 -0400 Subject: [PATCH 02/14] feat: merge cw address list contract (#1320) * feat: add new contract * chore: add config to contact * instantiated cw-address-list contract, make generate * chore: rust contract: use scripts instead of Makefile * fix: remove test script, add network feature * chore: remove export * chore: use existing feature for cw-address-list * fix: handle umber in zod feature object * make generate --- Cargo.lock | 127 +- go/pkg/networks/features.gen.go | 26 + networks.json | 5 + .../cw-address-list/CwAddressList.client.ts | 2 +- .../cw-address-list/CwAddressList.types.ts | 2 +- .../cw-address-list/index.ts | 2 + packages/networks/features.ts | 14 +- packages/networks/teritori-testnet/index.ts | 10 +- packages/networks/types.ts | 2 + .../codegen/generateGoNetworkFeatures.ts | 4 +- .../network-setup/deployCwAddressList.ts | 119 ++ .../cw-address-list/.cargo/config.toml | 4 + rust/cw-contracts/cw-address-list/.gitignore | 2 + rust/cw-contracts/cw-address-list/Cargo.lock | 1146 +++++++++++++++++ rust/cw-contracts/cw-address-list/Cargo.toml | 19 + .../schema/cw-address-list.json | 243 ++++ .../cw-address-list/schema/raw/execute.json | 75 ++ .../schema/raw/instantiate.json | 13 + .../cw-address-list/schema/raw/query.json | 114 ++ .../schema/raw/response_to_addresses.json | 14 + .../schema/raw/response_to_admin.json | 18 + .../cw-address-list/src/bin/schema.rs | 10 + .../cw-address-list/src/contract.rs | 180 +++ .../cw-contracts/cw-address-list/src/error.rs | 23 + rust/cw-contracts/cw-address-list/src/lib.rs | 4 + .../cw-address-list/src/multitest.rs | 59 + 26 files changed, 2222 insertions(+), 15 deletions(-) create mode 100644 packages/contracts-clients/cw-address-list/index.ts create mode 100644 packages/scripts/network-setup/deployCwAddressList.ts create mode 100644 rust/cw-contracts/cw-address-list/.cargo/config.toml create mode 100644 rust/cw-contracts/cw-address-list/.gitignore create mode 100644 rust/cw-contracts/cw-address-list/Cargo.lock create mode 100644 rust/cw-contracts/cw-address-list/Cargo.toml create mode 100644 rust/cw-contracts/cw-address-list/schema/cw-address-list.json create mode 100644 rust/cw-contracts/cw-address-list/schema/raw/execute.json create mode 100644 rust/cw-contracts/cw-address-list/schema/raw/instantiate.json create mode 100644 rust/cw-contracts/cw-address-list/schema/raw/query.json create mode 100644 rust/cw-contracts/cw-address-list/schema/raw/response_to_addresses.json create mode 100644 rust/cw-contracts/cw-address-list/schema/raw/response_to_admin.json create mode 100644 rust/cw-contracts/cw-address-list/src/bin/schema.rs create mode 100644 rust/cw-contracts/cw-address-list/src/contract.rs create mode 100644 rust/cw-contracts/cw-address-list/src/error.rs create mode 100644 rust/cw-contracts/cw-address-list/src/lib.rs create mode 100644 rust/cw-contracts/cw-address-list/src/multitest.rs diff --git a/Cargo.lock b/Cargo.lock index 4d14d11115..98c163bad7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,7 +174,7 @@ dependencies = [ "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.2", "sha2 0.10.8", "static_assertions", "thiserror", @@ -245,6 +245,19 @@ dependencies = [ "cosmwasm-std", ] +[[package]] +name = "cw-address-list" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "schemars", + "serde", + "sylvia 0.9.3", + "thiserror", +] + [[package]] name = "cw-multi-test" version = "0.16.5" @@ -256,14 +269,34 @@ dependencies = [ "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "derivative", - "itertools", + "itertools 0.10.5", "k256 0.11.6", - "prost", + "prost 0.9.0", "schemars", "serde", "thiserror", ] +[[package]] +name = "cw-multi-test" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc392a5cb7e778e3f90adbf7faa43c4db7f35b6623224b08886d796718edb875" +dependencies = [ + "anyhow", + "bech32", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "derivative", + "itertools 0.12.1", + "prost 0.12.6", + "schemars", + "serde", + "sha2 0.10.8", + "thiserror", +] + [[package]] name = "cw-ownable" version = "0.5.1" @@ -567,7 +600,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "sylvia", + "sylvia 0.7.1", "thiserror", ] @@ -861,6 +894,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -962,7 +1004,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "sylvia", + "sylvia 0.7.1", "thiserror", ] @@ -1048,7 +1090,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" dependencies = [ "bytes", - "prost-derive", + "prost-derive 0.9.0", +] + +[[package]] +name = "prost" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +dependencies = [ + "bytes", + "prost-derive 0.12.6", ] [[package]] @@ -1058,12 +1110,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "prost-derive" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "quote" version = "1.0.37" @@ -1200,6 +1265,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" version = "1.0.210" @@ -1319,14 +1393,33 @@ dependencies = [ "anyhow", "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", + "cw-multi-test 0.16.5", "derivative", "konst", "schemars", "serde", "serde-cw-value", - "serde-json-wasm", - "sylvia-derive", + "serde-json-wasm 0.5.2", + "sylvia-derive 0.7.1", +] + +[[package]] +name = "sylvia" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99d4ee0dde6fd6bf3f7d93d90021669e33bc4518bcc3f6c882d64c163fa79d4" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test 0.20.1", + "derivative", + "konst", + "schemars", + "serde", + "serde-cw-value", + "serde-json-wasm 1.0.1", + "sylvia-derive 0.9.3", ] [[package]] @@ -1343,6 +1436,20 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "sylvia-derive" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "178e7a0f1a957b2164dc0fd5dfe8c5db1e5fbc7299bffcdac7627b802114ce6f" +dependencies = [ + "convert_case", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "syn" version = "1.0.109" diff --git a/go/pkg/networks/features.gen.go b/go/pkg/networks/features.gen.go index a7a133bd78..ff8362cc8f 100644 --- a/go/pkg/networks/features.gen.go +++ b/go/pkg/networks/features.gen.go @@ -103,6 +103,26 @@ func (nb *NetworkBase) GetFeatureLaunchpadERC20() (*FeatureLaunchpadERC20, error return feature.(*FeatureLaunchpadERC20), nil } +type FeatureNFTMarketplace struct { + *FeatureBase + CwAddressListContractAddress string `json:"cwAddressListContractAddress"` + CwAddressListCodeId float64 `json:"cwAddressListCodeId"` +} + +var _ Feature = &FeatureNFTMarketplace{} + +func (f FeatureNFTMarketplace) Type() FeatureType { + return FeatureTypeNFTMarketplace +} + +func (nb *NetworkBase) GetFeatureNFTMarketplace() (*FeatureNFTMarketplace, error) { + feature, err := nb.GetFeature(FeatureTypeNFTMarketplace) + if err != nil { + return nil, err + } + return feature.(*FeatureNFTMarketplace), nil +} + func UnmarshalFeature(b []byte) (Feature, error) { var base FeatureBase if err := json.Unmarshal(b, &base); err != nil { @@ -133,6 +153,12 @@ func UnmarshalFeature(b []byte) (Feature, error) { return nil, errors.Wrap(err, "failed to unmarshal feature LaunchpadERC20") } return &f, nil + case FeatureTypeNFTMarketplace: + var f FeatureNFTMarketplace + if err := json.Unmarshal(b, &f); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal feature NFTMarketplace") + } + return &f, nil } return nil, errors.Errorf("unknown feature type %s", base.Type) } diff --git a/networks.json b/networks.json index 724d0927fe..68a54b1426 100644 --- a/networks.json +++ b/networks.json @@ -11668,6 +11668,11 @@ { "type": "CosmWasmNFTsBurner", "burnerContractAddress": "tori1qyl0j7a24amk8k8gcmvv07y2zjx7nkcwpk73js24euh64hkja6esd2p2xp" + }, + { + "type": "NFTMarketplace", + "cwAddressListCodeId": 63, + "cwAddressListContractAddress": "tori1x72plnprsjnmszylmdm3cnvu5h6u55fyf0pe02lye9p6q2ws05ps33qmft" } ], "currencies": [ diff --git a/packages/contracts-clients/cw-address-list/CwAddressList.client.ts b/packages/contracts-clients/cw-address-list/CwAddressList.client.ts index c26bdb36d7..4ce4e17cc7 100644 --- a/packages/contracts-clients/cw-address-list/CwAddressList.client.ts +++ b/packages/contracts-clients/cw-address-list/CwAddressList.client.ts @@ -1,5 +1,5 @@ /** -* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3. +* This file was automatically generated by @cosmwasm/ts-codegen@0.35.7. * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, * and run the @cosmwasm/ts-codegen generate command to regenerate this file. */ diff --git a/packages/contracts-clients/cw-address-list/CwAddressList.types.ts b/packages/contracts-clients/cw-address-list/CwAddressList.types.ts index ab0bb3c8e7..da8d65f259 100644 --- a/packages/contracts-clients/cw-address-list/CwAddressList.types.ts +++ b/packages/contracts-clients/cw-address-list/CwAddressList.types.ts @@ -1,5 +1,5 @@ /** -* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3. +* This file was automatically generated by @cosmwasm/ts-codegen@0.35.7. * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, * and run the @cosmwasm/ts-codegen generate command to regenerate this file. */ diff --git a/packages/contracts-clients/cw-address-list/index.ts b/packages/contracts-clients/cw-address-list/index.ts new file mode 100644 index 0000000000..6005786b94 --- /dev/null +++ b/packages/contracts-clients/cw-address-list/index.ts @@ -0,0 +1,2 @@ +export * from "./CwAddressList.client"; +export * from "./CwAddressList.types"; \ No newline at end of file diff --git a/packages/networks/features.ts b/packages/networks/features.ts index 56fdd0ee27..9f05394953 100644 --- a/packages/networks/features.ts +++ b/packages/networks/features.ts @@ -19,6 +19,16 @@ export enum NetworkFeature { CosmWasmNFTsBurner = "CosmWasmNFTsBurner", } +// Marketplace + +const zodNFTMarketplace = z.object({ + type: z.literal(NetworkFeature.NFTMarketplace), + cwAddressListContractAddress: z.string(), + cwAddressListCodeId: z.number(), +}); + +export type NFTMarketplace = z.infer; + // CosmWasm Premium Feed const zodCosmWasmPremiumFeed = z.object({ @@ -72,6 +82,7 @@ export const allFeatureObjects = [ zodCosmWasmNFTsBurner, zodGnoProjectManager, zodLaunchpadERC20, + zodNFTMarketplace, ]; export type NetworkFeatureObject = @@ -79,4 +90,5 @@ export type NetworkFeatureObject = | CosmWasmSocialFeed | CosmWasmNFTsBurner | GnoProjectManager - | LaunchpadERC20; + | LaunchpadERC20 + | NFTMarketplace; diff --git a/packages/networks/teritori-testnet/index.ts b/packages/networks/teritori-testnet/index.ts index 8ea49b815e..e0ed91553c 100644 --- a/packages/networks/teritori-testnet/index.ts +++ b/packages/networks/teritori-testnet/index.ts @@ -3,6 +3,7 @@ import { CosmWasmNFTsBurner, CosmWasmPremiumFeed, NetworkFeature, + NFTMarketplace, } from "../features"; import { CosmosNetworkInfo, NetworkKind } from "../types"; @@ -21,6 +22,13 @@ const nftsBurnerFeature: CosmWasmNFTsBurner = { "tori1qyl0j7a24amk8k8gcmvv07y2zjx7nkcwpk73js24euh64hkja6esd2p2xp", }; +const nftMarketplace: NFTMarketplace = { + type: NetworkFeature.NFTMarketplace, + cwAddressListCodeId: 63, + cwAddressListContractAddress: + "tori1x72plnprsjnmszylmdm3cnvu5h6u55fyf0pe02lye9p6q2ws05ps33qmft", +}; + const riotContractAddressGen0 = "tori1r8raaqul4j05qtn0t05603mgquxfl8e9p7kcf7smwzcv2hc5rrlq0vket0"; const riotContractAddressGen1 = ""; @@ -45,7 +53,7 @@ export const teritoriTestnetNetwork: CosmosNetworkInfo = { NetworkFeature.NFTMarketplaceLeaderboard, NetworkFeature.CosmWasmNFTsBurner, ], - featureObjects: [premiumFeedFeature, nftsBurnerFeature], + featureObjects: [premiumFeedFeature, nftsBurnerFeature, nftMarketplace], currencies: teritoriTestnetCurrencies, txExplorer: "https://explorer.teritori.com/teritori-testnet/tx/$hash", accountExplorer: diff --git a/packages/networks/types.ts b/packages/networks/types.ts index a591787572..495fc6a773 100644 --- a/packages/networks/types.ts +++ b/packages/networks/types.ts @@ -72,6 +72,8 @@ export type CosmosNetworkInfo = NetworkInfoBase & { daoVotingCw4CodeId?: number; cwAdminFactoryContractAddress?: string; coreDAOAddress?: string; + cwAddressListContractAddress?: string; + cwAddressListCodeId?: number; }; export type EthereumNetworkInfo = NetworkInfoBase & { diff --git a/packages/scripts/codegen/generateGoNetworkFeatures.ts b/packages/scripts/codegen/generateGoNetworkFeatures.ts index b5a5718d2c..60897ffc80 100644 --- a/packages/scripts/codegen/generateGoNetworkFeatures.ts +++ b/packages/scripts/codegen/generateGoNetworkFeatures.ts @@ -1,4 +1,4 @@ -import { ZodString } from "zod"; +import { ZodNumber, ZodString } from "zod"; import { NetworkFeature, allFeatureObjects } from "@/networks/features"; import { capitalize } from "@/utils/text"; @@ -42,6 +42,8 @@ const zodToGoType = (zodType: unknown) => { switch (true) { case zodType instanceof ZodString: return "string"; + case zodType instanceof ZodNumber: + return "float64"; default: throw new Error(`failed to convert zod type ${zodType} to go type`); } diff --git a/packages/scripts/network-setup/deployCwAddressList.ts b/packages/scripts/network-setup/deployCwAddressList.ts new file mode 100644 index 0000000000..0d77f89cbc --- /dev/null +++ b/packages/scripts/network-setup/deployCwAddressList.ts @@ -0,0 +1,119 @@ +import { bech32 } from "bech32"; +import { program } from "commander"; +import { cloneDeep } from "lodash"; +import os from "os"; +import path from "path"; + +import { + CosmosNetworkInfo, + getCosmosNetwork, + getNetworkFeature, + NetworkFeature, +} from "@/networks"; +import { execPromise } from "@/scripts/lib"; +import { + instantiateContract, + storeWASM, +} from "@/scripts/network-setup/deployLib"; + +const deployCwAddressList = async ({ + opts, + networkId, + wallet, +}: { + networkId: string; + wallet: string; + opts: { home: string; binaryPath: string; keyringBackend?: string }; +}) => { + const network = cloneDeep(getCosmosNetwork(networkId)); + if (!network) { + console.error(`Cosmos network ${networkId} not found`); + process.exit(1); + } + console.log(`Deploying to ${network.displayName}`); + + let walletAddr = ( + await execPromise( + `${opts.binaryPath} keys show --keyring-backend ${opts.keyringBackend || "test"} -a ${wallet} --home ${opts.home}`, + { encoding: "utf-8" }, + ) + ).stdout.trim(); + if (walletAddr.startsWith("Successfully migrated")) { + walletAddr = walletAddr.substring(walletAddr.indexOf("\n")).trim(); + } + bech32.decode(walletAddr); + console.log("Wallet address:", walletAddr); + + const nftMarketplaceFeature = cloneDeep( + getNetworkFeature(networkId, NetworkFeature.NFTMarketplace), + ); + if (!nftMarketplaceFeature) { + console.error(`NFT Marketplace feature not found on ${networkId}`); + process.exit(1); + } + + if (!nftMarketplaceFeature.cwAddressListContractAddress) { + console.log("Storing cw address list"); + const cwAddressListWasmFilePath = path.join( + __dirname, + "cw_address_list.wasm", + ); + network.cwAdminFactoryCodeId = await storeWASM( + opts, + wallet, + network, + cwAddressListWasmFilePath, + ); + + console.log("Instantiating cw address list", network.cwAdminFactoryCodeId); + nftMarketplaceFeature.cwAddressListContractAddress = + await instantiateCwAddressList(opts, wallet, walletAddr, network); + + network.featureObjects = network.featureObjects?.map((featureObject) => { + if (featureObject.type === NetworkFeature.NFTMarketplace) { + return nftMarketplaceFeature; + } else return featureObject; + }); + } +}; + +const instantiateCwAddressList = async ( + opts: { home: string; binaryPath: string; keyringBackend?: string }, + wallet: string, + adminAddr: string, + network: CosmosNetworkInfo, +) => { + const codeId = network.cwAdminFactoryCodeId; + if (!codeId) { + throw new Error("CW Address List code ID not found"); + } + return await instantiateContract( + opts, + wallet, + network, + codeId, + adminAddr, + "Teritori CW Address List", + {}, + ); +}; + +const main = async () => { + program.argument("", "Network id to deploy to"); + program.argument("", "Wallet to deploy from"); + program.option("--keyring-backend [keyring-backend]", "Keyring backend"); + program.parse(); + const [networkId, wallet] = program.args; + const { keyringBackend } = program.opts(); + + await deployCwAddressList({ + opts: { + home: path.join(os.homedir(), ".teritorid"), + binaryPath: "teritorid", + keyringBackend, + }, + networkId, + wallet, + }); +}; +main(); diff --git a/rust/cw-contracts/cw-address-list/.cargo/config.toml b/rust/cw-contracts/cw-address-list/.cargo/config.toml new file mode 100644 index 0000000000..9354fae229 --- /dev/null +++ b/rust/cw-contracts/cw-address-list/.cargo/config.toml @@ -0,0 +1,4 @@ +[alias] +wasm = "build --target wasm32-unknown-unknown --release --lib" +wasm-debug = "build --target wasm32-unknown-unknown --lib" +schema = "run schema" diff --git a/rust/cw-contracts/cw-address-list/.gitignore b/rust/cw-contracts/cw-address-list/.gitignore new file mode 100644 index 0000000000..42dafca836 --- /dev/null +++ b/rust/cw-contracts/cw-address-list/.gitignore @@ -0,0 +1,2 @@ +/target +/artifacts \ No newline at end of file diff --git a/rust/cw-contracts/cw-address-list/Cargo.lock b/rust/cw-contracts/cw-address-list/Cargo.lock new file mode 100644 index 0000000000..c2e87686c0 --- /dev/null +++ b/rust/cw-contracts/cw-address-list/Cargo.lock @@ -0,0 +1,1146 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bnum" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "const_panic" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cosmwasm-crypto" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8bb3c77c3b7ce472056968c745eb501c440fbc07be5004eba02782c35bfbbe3" +dependencies = [ + "digest 0.10.7", + "ecdsa 0.16.9", + "ed25519-zebra", + "k256 0.13.2", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea73e9162e6efde00018d55ed0061e93a108b5d6ec4548b4f8ce3c706249687" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-schema" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0df41ea55f2946b6b43579659eec048cc2f66e8c8e2e3652fc5e5e476f673856" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43609e92ce1b9368aa951b334dd354a2d0dd4d484931a5f83ae10e12a26c8ba9" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04d6864742e3a7662d024b51a94ea81c9af21db6faea2f9a6d2232bb97c6e53e" +dependencies = [ + "base64", + "bech32", + "bnum", + "cosmwasm-crypto", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm", + "sha2 0.10.8", + "static_assertions", + "thiserror", +] + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "cw-multi-test" +version = "0.16.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "127c7bb95853b8e828bdab97065c81cb5ddc20f7339180b61b2300565aaa99d1" +dependencies = [ + "anyhow", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "derivative", + "itertools", + "k256 0.11.6", + "prost", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-storage-plus" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-utils" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw_address_list" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", + "sylvia", + "thiserror", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dyn-clone" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.8", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek", + "hashbrown 0.12.3", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", +] + +[[package]] +name = "k256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "once_cell", + "sha2 0.10.8", + "signature 2.2.0", +] + +[[package]] +name = "konst" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29a6ee015a18f4a121ba670f947f801b207139f0f810b3cd266e319065129782" +dependencies = [ + "const_panic", + "konst_kernel", + "konst_proc_macros", + "typewit", +] + +[[package]] +name = "konst_kernel" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3376133edc39f027d551eb77b077c2865a0ef252b2e7d0dd6b6dc303db95d8b5" +dependencies = [ + "typewit", +] + +[[package]] +name = "konst_proc_macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e28ab1dc35e09d60c2b8c90d12a9a8d9666c876c10a3739a3196db0103b6043" + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.8", + "spki 0.7.3", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.8", + "generic-array", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-cw-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75d32da6b8ed758b7d850b6c3c08f1d7df51a4df3cb201296e63e34a78e99d4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.8", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "sylvia" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f358d505f46900e55154f028f18811961ebb58f7a92954ec03086ffb2b26cf51" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "derivative", + "konst", + "schemars", + "serde", + "serde-cw-value", + "serde-json-wasm", + "sylvia-derive", +] + +[[package]] +name = "sylvia-derive" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed182fb775d756fdfe7e87174a4e43f1c446c8f9aff1de38a2165dd04b7d805" +dependencies = [ + "convert_case", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "typewit" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6779a69cc5f9a7388274a0a8a353eb1c9e45195f9ae74a26690b055a7cf9592a" +dependencies = [ + "typewit_proc_macros", +] + +[[package]] +name = "typewit_proc_macros" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winnow" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +dependencies = [ + "memchr", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/rust/cw-contracts/cw-address-list/Cargo.toml b/rust/cw-contracts/cw-address-list/Cargo.toml new file mode 100644 index 0000000000..23f3abf018 --- /dev/null +++ b/rust/cw-contracts/cw-address-list/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "cw-address-list" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +cosmwasm-std = { version = "1.5.3", features = ["staking"] } +sylvia = "0.9.3" +schemars = "0.8.16" +cosmwasm-schema = "1.5.3" +serde = "1.0.197" +cw-storage-plus = "1.2.0" +thiserror = "1.0.57" + +[dev-dependencies] +sylvia = { version = "0.9.3", features = ["mt"] } \ No newline at end of file diff --git a/rust/cw-contracts/cw-address-list/schema/cw-address-list.json b/rust/cw-contracts/cw-address-list/schema/cw-address-list.json new file mode 100644 index 0000000000..dcd90e9c8b --- /dev/null +++ b/rust/cw-contracts/cw-address-list/schema/cw-address-list.json @@ -0,0 +1,243 @@ +{ + "contract_name": "cw-address-list", + "contract_version": "0.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "string" + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "anyOf": [ + { + "$ref": "#/definitions/ExecMsg" + } + ], + "definitions": { + "ExecMsg": { + "oneOf": [ + { + "type": "object", + "required": [ + "add" + ], + "properties": { + "add": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "remove" + ], + "properties": { + "remove": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "change_admin" + ], + "properties": { + "change_admin": { + "type": "object", + "properties": { + "addr": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "additionalProperties": false + } + ] + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "anyOf": [ + { + "$ref": "#/definitions/QueryMsg" + } + ], + "definitions": { + "Bound": { + "oneOf": [ + { + "type": "object", + "required": [ + "inclusive" + ], + "properties": { + "inclusive": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "exclusive" + ], + "properties": { + "exclusive": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Order": { + "type": "string", + "enum": [ + "ascending", + "descending" + ] + }, + "QueryMsg": { + "oneOf": [ + { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "object" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "addresses" + ], + "properties": { + "addresses": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "max": { + "anyOf": [ + { + "$ref": "#/definitions/Bound" + }, + { + "type": "null" + } + ] + }, + "min": { + "anyOf": [ + { + "$ref": "#/definitions/Bound" + }, + { + "type": "null" + } + ] + }, + "order": { + "anyOf": [ + { + "$ref": "#/definitions/Order" + }, + { + "type": "null" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + } + } + }, + "migrate": null, + "sudo": null, + "responses": { + "addresses": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Array_of_Addr", + "type": "array", + "items": { + "$ref": "#/definitions/Addr" + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, + "admin": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_Addr", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + } + } +} diff --git a/rust/cw-contracts/cw-address-list/schema/raw/execute.json b/rust/cw-contracts/cw-address-list/schema/raw/execute.json new file mode 100644 index 0000000000..66c89283f0 --- /dev/null +++ b/rust/cw-contracts/cw-address-list/schema/raw/execute.json @@ -0,0 +1,75 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "anyOf": [ + { + "$ref": "#/definitions/ExecMsg" + } + ], + "definitions": { + "ExecMsg": { + "oneOf": [ + { + "type": "object", + "required": [ + "add" + ], + "properties": { + "add": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "remove" + ], + "properties": { + "remove": { + "type": "object", + "required": [ + "addr" + ], + "properties": { + "addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "change_admin" + ], + "properties": { + "change_admin": { + "type": "object", + "properties": { + "addr": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/rust/cw-contracts/cw-address-list/schema/raw/instantiate.json b/rust/cw-contracts/cw-address-list/schema/raw/instantiate.json new file mode 100644 index 0000000000..04a6e5114d --- /dev/null +++ b/rust/cw-contracts/cw-address-list/schema/raw/instantiate.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "string" + } + } +} diff --git a/rust/cw-contracts/cw-address-list/schema/raw/query.json b/rust/cw-contracts/cw-address-list/schema/raw/query.json new file mode 100644 index 0000000000..2e2052e94b --- /dev/null +++ b/rust/cw-contracts/cw-address-list/schema/raw/query.json @@ -0,0 +1,114 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "anyOf": [ + { + "$ref": "#/definitions/QueryMsg" + } + ], + "definitions": { + "Bound": { + "oneOf": [ + { + "type": "object", + "required": [ + "inclusive" + ], + "properties": { + "inclusive": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "exclusive" + ], + "properties": { + "exclusive": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "Order": { + "type": "string", + "enum": [ + "ascending", + "descending" + ] + }, + "QueryMsg": { + "oneOf": [ + { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "object" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "addresses" + ], + "properties": { + "addresses": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "max": { + "anyOf": [ + { + "$ref": "#/definitions/Bound" + }, + { + "type": "null" + } + ] + }, + "min": { + "anyOf": [ + { + "$ref": "#/definitions/Bound" + }, + { + "type": "null" + } + ] + }, + "order": { + "anyOf": [ + { + "$ref": "#/definitions/Order" + }, + { + "type": "null" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/rust/cw-contracts/cw-address-list/schema/raw/response_to_addresses.json b/rust/cw-contracts/cw-address-list/schema/raw/response_to_addresses.json new file mode 100644 index 0000000000..bf06b01c2f --- /dev/null +++ b/rust/cw-contracts/cw-address-list/schema/raw/response_to_addresses.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Array_of_Addr", + "type": "array", + "items": { + "$ref": "#/definitions/Addr" + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } +} diff --git a/rust/cw-contracts/cw-address-list/schema/raw/response_to_admin.json b/rust/cw-contracts/cw-address-list/schema/raw/response_to_admin.json new file mode 100644 index 0000000000..970164b3e7 --- /dev/null +++ b/rust/cw-contracts/cw-address-list/schema/raw/response_to_admin.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_Addr", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } +} diff --git a/rust/cw-contracts/cw-address-list/src/bin/schema.rs b/rust/cw-contracts/cw-address-list/src/bin/schema.rs new file mode 100644 index 0000000000..92d9dac1b4 --- /dev/null +++ b/rust/cw-contracts/cw-address-list/src/bin/schema.rs @@ -0,0 +1,10 @@ +use cosmwasm_schema::write_api; +use cw_address_list::contract::sv::{ContractExecMsg, ContractQueryMsg, InstantiateMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ContractExecMsg, + query: ContractQueryMsg, + } +} diff --git a/rust/cw-contracts/cw-address-list/src/contract.rs b/rust/cw-contracts/cw-address-list/src/contract.rs new file mode 100644 index 0000000000..8a490631ac --- /dev/null +++ b/rust/cw-contracts/cw-address-list/src/contract.rs @@ -0,0 +1,180 @@ +use crate::error::ContractError; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Order as CwOrder, Response, StdResult}; +use cw_storage_plus::{Bound as CwBound, Item, Map}; +use sylvia::types::{ExecCtx, InstantiateCtx, QueryCtx}; +use sylvia::{contract, entry_points}; + +pub struct AddressListContract { + pub(crate) admin: Item<'static, Option>, + pub(crate) addresses: Map<'static, Addr, ()>, +} + +pub const QUERY_BATCH_MAX_LIMIT: u32 = 50; + +#[cw_serde] +pub enum Order { + Ascending, + Descending, +} + +impl Into for Order { + fn into(self) -> CwOrder { + match self { + Order::Ascending => CwOrder::Ascending, + Order::Descending => CwOrder::Descending, + } + } +} + +#[cw_serde] +pub enum Bound { + Inclusive(String), + Exclusive(String), +} + +impl Into> for Bound { + fn into(self) -> CwBound<'static, Addr> { + match self { + Bound::Inclusive(addr) => CwBound::inclusive(Addr::unchecked(addr)), + Bound::Exclusive(addr) => CwBound::exclusive(Addr::unchecked(addr)), + } + } +} + +#[entry_points] +#[contract] +#[error(ContractError)] +impl AddressListContract { + pub const fn new() -> Self { + Self { + admin: Item::new("admin_v0"), + addresses: Map::new("addresses_v0"), + } + } + + #[msg(instantiate)] + pub fn instantiate(&self, ctx: InstantiateCtx, admin: String) -> StdResult { + let admin = ctx.deps.api.addr_validate(admin.as_str())?; + self.admin.save(ctx.deps.storage, &Some(admin))?; + Ok(Response::default()) + } + + // Mutations + + #[msg(exec)] + pub fn add(&self, ctx: ExecCtx, addr: String) -> Result { + self.assert_admin(&ctx)?; + + let addr = ctx.deps.api.addr_validate(addr.as_str())?; + + self.addresses + .update(ctx.deps.storage, addr, |value| match value { + Some(_) => Err(ContractError::AddressAlreadyRegistered), + None => Ok(()), + })?; + + Ok(Response::default()) + } + + #[msg(exec)] + pub fn remove(&self, ctx: ExecCtx, addr: String) -> Result { + self.assert_admin(&ctx)?; + + let addr = ctx.deps.api.addr_validate(addr.as_str())?; + + if !self.addresses.has(ctx.deps.storage, addr.clone()) { + return Err(ContractError::AddressNotRegistered); + } + + self.addresses.remove(ctx.deps.storage, addr); + + Ok(Response::default()) + } + + #[msg(exec)] + pub fn change_admin( + &self, + ctx: ExecCtx, + addr: Option, + ) -> Result { + self.assert_admin(&ctx)?; + + let admin = self.admin.load(ctx.deps.storage)?; + + let opt = match addr { + Some(addr) => { + let addr = ctx.deps.api.addr_validate(addr.as_str())?; + if admin == Some(addr.clone()) { + return Err(ContractError::AlreadyAdmin); + } + Some(addr) + } + None => None, + }; + + self.admin.save(ctx.deps.storage, &opt)?; + + Ok(Response::default()) + } + + fn assert_admin(&self, ctx: &ExecCtx) -> Result<(), ContractError> { + let admin = self.admin.load(ctx.deps.storage)?; + match admin { + Some(admin) => { + if admin != ctx.info.sender { + Err(ContractError::Unauthorized) + } else { + Ok(()) + } + } + None => Err(ContractError::Unauthorized), + } + } + + // Queries + + #[msg(query)] + pub fn admin(&self, ctx: QueryCtx) -> Result, ContractError> { + let admin = self.admin.load(ctx.deps.storage)?; + Ok(admin) + } + + #[msg(query)] + pub fn addresses( + &self, + ctx: QueryCtx, + min: Option, + max: Option, + order: Option, + limit: Option, + ) -> Result, ContractError> { + let limit = limit + .map(|limit| { + if limit > QUERY_BATCH_MAX_LIMIT { + QUERY_BATCH_MAX_LIMIT + } else { + limit + } + }) + .unwrap_or(QUERY_BATCH_MAX_LIMIT); + + let order = order.unwrap_or(Order::Ascending); + + let addrs: Result, _> = self + .addresses + .range( + ctx.deps.storage, + min.map(|m| m.into()), + max.map(|m| m.into()), + order.into(), + ) + .take(limit as usize) + .map(|item| -> Result { + let (addr, _) = item?; + Ok(addr) + }) + .collect(); + Ok(addrs?) + } +} diff --git a/rust/cw-contracts/cw-address-list/src/error.rs b/rust/cw-contracts/cw-address-list/src/error.rs new file mode 100644 index 0000000000..cffb2ed4ce --- /dev/null +++ b/rust/cw-contracts/cw-address-list/src/error.rs @@ -0,0 +1,23 @@ +use cosmwasm_std::StdError; +use thiserror::Error; + +#[derive(Error, Debug, PartialEq)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("Address already registered.")] + AddressAlreadyRegistered, + + #[error("Address not registered.")] + AddressNotRegistered, + + #[error("Invalid cursor.")] + InvalidCursor, + + #[error("Unauthorized.")] + Unauthorized, + + #[error("Already admin.")] + AlreadyAdmin, +} diff --git a/rust/cw-contracts/cw-address-list/src/lib.rs b/rust/cw-contracts/cw-address-list/src/lib.rs new file mode 100644 index 0000000000..ae5b855d2f --- /dev/null +++ b/rust/cw-contracts/cw-address-list/src/lib.rs @@ -0,0 +1,4 @@ +pub mod contract; +pub mod error; +#[cfg(test)] +pub mod multitest; diff --git a/rust/cw-contracts/cw-address-list/src/multitest.rs b/rust/cw-contracts/cw-address-list/src/multitest.rs new file mode 100644 index 0000000000..d53bfa4ed6 --- /dev/null +++ b/rust/cw-contracts/cw-address-list/src/multitest.rs @@ -0,0 +1,59 @@ +use cosmwasm_std::Addr; +use sylvia::multitest::App; + +use crate::contract::sv::multitest_utils::CodeId; + + +#[test] +fn instantiate() { + let app = App::default(); + let code_id = CodeId::store_code(&app); + + let owner = "owner"; + let owner_addr = Addr::unchecked(owner); + + let contract = code_id.instantiate(owner.to_string()).call(owner).unwrap(); + + let admin = contract.admin().unwrap(); + assert_eq!(admin, Some(owner_addr)); + + let addrs = contract.addresses(None, None, None, None).unwrap(); + assert_eq!(addrs, Vec::::new()); + + let col1 = "col1"; + let col1_addr = Addr::unchecked(col1); + contract.add(col1.to_string()).call(owner).unwrap(); + let addrs = contract.addresses(None, None, None, None).unwrap(); + assert_eq!(addrs, vec![col1_addr.clone()]); + + let col2 = "col2"; + let col2_addr = Addr::unchecked(col2); + contract.add(col2.to_string()).call(owner).unwrap(); + let addrs = contract.addresses(None, None, None, None).unwrap(); + assert_eq!(addrs, vec![col1_addr.clone(), col2_addr.clone()]); + let addrs = contract + .addresses(None, None, Some(crate::contract::Order::Descending), None) + .unwrap(); + assert_eq!(addrs, vec![col2_addr.clone(), col1_addr.clone()]); + + let addrs = contract.addresses(None, None, None, Some(1)).unwrap(); + assert_eq!(addrs, vec![col1_addr.clone()]); + + let addrs = contract + .addresses( + Some(crate::contract::Bound::Exclusive(col1.to_string())), + None, + None, + None, + ) + .unwrap(); + assert_eq!(addrs, vec![col2_addr.clone()]); + + contract.remove(col1.to_string()).call(owner).unwrap(); + let addrs = contract.addresses(None, None, None, None).unwrap(); + assert_eq!(addrs, vec![col2_addr]); + + contract.remove(col2.to_string()).call(owner).unwrap(); + let addrs = contract.addresses(None, None, None, None).unwrap(); + assert_eq!(addrs, Vec::::new()); +} From 33f398ade25c1c5e9fce02a9f786557a296d98df Mon Sep 17 00:00:00 2001 From: WaDadidou <50441633+WaDadidou@users.noreply.github.com> Date: Sat, 2 Nov 2024 11:06:25 -0400 Subject: [PATCH 03/14] feat: make title optional in Section component (#1324) --- packages/components/Section.tsx | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/components/Section.tsx b/packages/components/Section.tsx index d2dec203a1..dccc538991 100644 --- a/packages/components/Section.tsx +++ b/packages/components/Section.tsx @@ -8,7 +8,7 @@ import { fontSemibold20 } from "../utils/style/fonts"; import { layout } from "../utils/style/layout"; export const Section: React.FC<{ - title: string; + title?: string; subtitle?: string; topRightChild?: ReactNode; children: ReactNode; @@ -36,16 +36,18 @@ export const Section: React.FC<{ }} > - - {title} - + {!!title && ( + + {title} + + )} {subtitle ? ( Date: Sat, 2 Nov 2024 11:05:01 -0400 Subject: [PATCH 04/14] chore: extract pinata service from feed folder (#1323) * chore: extract pinata service from feed folder * chore: remove ou-of-scope change --- go/cmd/feed-clean-pinata-keys/main.go | 16 ++++++++-------- go/pkg/feed/service.go | 7 ++++--- go/pkg/{feed => pinata}/pinata.go | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) rename go/pkg/{feed => pinata}/pinata.go (99%) diff --git a/go/cmd/feed-clean-pinata-keys/main.go b/go/cmd/feed-clean-pinata-keys/main.go index 3e55079a08..63a7f6b281 100644 --- a/go/cmd/feed-clean-pinata-keys/main.go +++ b/go/cmd/feed-clean-pinata-keys/main.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/TERITORI/teritori-dapp/go/pkg/feed" + "github.com/TERITORI/teritori-dapp/go/pkg/pinata" "github.com/go-co-op/gocron" "github.com/peterbourgon/ff/v3" "github.com/pkg/errors" @@ -44,7 +44,7 @@ func main() { panic(errors.Wrap(err, "failed to init logger")) } - pinata := feed.NewPinataService(*pinataJWT) + pinataService := pinata.NewPinataService(*pinataJWT) schedule := gocron.NewScheduler(time.UTC) isProcessing := false @@ -55,7 +55,7 @@ func main() { isProcessing = true - keysResp, err := pinata.GetAPIKeys(0) + keysResp, err := pinataService.GetAPIKeys(0) if err != nil { logger.Error(fmt.Sprintf("failed to count keys: %s", err)) isProcessing = false @@ -64,7 +64,7 @@ func main() { logger.Info("cleaning Pinata API keys", zap.Int("count", keysResp.Count)) - remainingPages := keysResp.Count / feed.PINATA_LIMIT_PER_PAGE + remainingPages := keysResp.Count / pinata.PINATA_LIMIT_PER_PAGE totalSkip := 0 totalRemaining := 0 totalRevoked := 0 @@ -72,7 +72,7 @@ func main() { // Get all existing keys keysData := keysResp.Keys for i := 0; i < remainingPages; i++ { - respI, err := pinata.GetAPIKeys(i) + respI, err := pinataService.GetAPIKeys(i) if err != nil { logger.Error(fmt.Sprintf("failed to get API keys: %s", err)) isProcessing = false @@ -84,7 +84,7 @@ func main() { // Process each key for _, keyData := range keysData { - if keyData.Revoked || keyData.Scopes.Admin || !strings.HasPrefix(keyData.Name, feed.FEED_KEY_PREFIX) { + if keyData.Revoked || keyData.Scopes.Admin || !strings.HasPrefix(keyData.Name, pinata.FEED_KEY_PREFIX) { totalSkip++ continue } @@ -92,12 +92,12 @@ func main() { now := time.Now() diff := now.Sub(keyData.CreatedAt) - if diff.Seconds() <= feed.KEY_TTL { + if diff.Seconds() <= pinata.KEY_TTL { totalRemaining++ continue } - if err := pinata.RevokeAPIKey(keyData.Key); err != nil { + if err := pinataService.RevokeAPIKey(keyData.Key); err != nil { logger.Error(fmt.Sprintf("failed revoke API key %s: %s", keyData.Key, err)) isProcessing = false return diff --git a/go/pkg/feed/service.go b/go/pkg/feed/service.go index 1f6404f90a..6b944bae2e 100644 --- a/go/pkg/feed/service.go +++ b/go/pkg/feed/service.go @@ -10,6 +10,7 @@ import ( "github.com/TERITORI/teritori-dapp/go/internal/indexerdb" "github.com/TERITORI/teritori-dapp/go/pkg/feedpb" "github.com/TERITORI/teritori-dapp/go/pkg/networks" + "github.com/TERITORI/teritori-dapp/go/pkg/pinata" "github.com/dgraph-io/ristretto" "github.com/pkg/errors" "go.uber.org/zap" @@ -62,15 +63,15 @@ func (s *FeedService) IPFSKey(ctx context.Context, req *feedpb.IPFSKeyRequest) ( }, nil } - pinata := NewPinataService(s.conf.PinataJWT) - credential, err := pinata.GenerateAPIKey() + pinataService := pinata.NewPinataService(s.conf.PinataJWT) + credential, err := pinataService.GenerateAPIKey() if err != nil { return nil, errors.Wrap(err, "failed to generate api key") } // With normal upload flow, suppose that time between posts always > TTL => we always generate a new key // In abnormal case, time < TTL then we return the cached key, the worst case user still have 4s to make the upload request - s.cache.SetWithTTL(cacheKey, credential.JWT, 0, time.Second*(KEY_TTL-4)) + s.cache.SetWithTTL(cacheKey, credential.JWT, 0, time.Second*(pinata.KEY_TTL-4)) return &feedpb.IPFSKeyResponse{ Jwt: credential.JWT, diff --git a/go/pkg/feed/pinata.go b/go/pkg/pinata/pinata.go similarity index 99% rename from go/pkg/feed/pinata.go rename to go/pkg/pinata/pinata.go index 288d70c017..3d8e2ff6be 100644 --- a/go/pkg/feed/pinata.go +++ b/go/pkg/pinata/pinata.go @@ -1,4 +1,4 @@ -package feed +package pinata import ( "encoding/json" From 4c30ddc51b5cd6927db9c8acd8c1df390303f1e5 Mon Sep 17 00:00:00 2001 From: WaDadidou <50441633+WaDadidou@users.noreply.github.com> Date: Sat, 2 Nov 2024 11:07:56 -0400 Subject: [PATCH 05/14] chore: add regex variables and factorize (#1325) --- packages/components/inputs/AvailableNamesInput.tsx | 3 ++- packages/components/inputs/TextInputCustomBorder.tsx | 4 +++- packages/components/teritoriNameService/FindAName.tsx | 4 +++- packages/components/teritoriNameService/NameDataForm.tsx | 4 +++- packages/screens/Launchpad/MintCollectionScreen.tsx | 3 ++- packages/utils/formRules.ts | 6 ++++-- packages/utils/regex.ts | 2 ++ 7 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/components/inputs/AvailableNamesInput.tsx b/packages/components/inputs/AvailableNamesInput.tsx index 0bf7d1e9b6..2644a04893 100644 --- a/packages/components/inputs/AvailableNamesInput.tsx +++ b/packages/components/inputs/AvailableNamesInput.tsx @@ -9,6 +9,7 @@ import { BrandText } from "../BrandText"; import { useNSAvailability } from "@/hooks/useNSAvailability"; import { useSelectedNetworkInfo } from "@/hooks/useSelectedNetwork"; import { NetworkInfo, NetworkKind, getNetwork } from "@/networks"; +import { LETTERS_REGEXP } from "@/utils/regex"; import { neutral17, neutral33, @@ -154,7 +155,7 @@ export const AvailableNamesInput = ({ onPressEnter={onPressEnter} value={value} rules={{ required: true }} - regexp={new RegExp(/^[a-zA-Z]+$/)} + regexp={new RegExp(LETTERS_REGEXP)} style={style} readOnly={readOnly} boxMainContainerStyle={{ diff --git a/packages/components/inputs/TextInputCustomBorder.tsx b/packages/components/inputs/TextInputCustomBorder.tsx index df22703e86..82dd4a072e 100644 --- a/packages/components/inputs/TextInputCustomBorder.tsx +++ b/packages/components/inputs/TextInputCustomBorder.tsx @@ -10,6 +10,8 @@ import { import { neutral22, neutral33 } from "../../utils/style/colors"; import { SVG } from "../SVG"; +import { NUMBERS_REGEXP } from "@/utils/regex"; + // A custom TextInput. You can add children (Ex: An icon or a small container) export const TextInputCustomBorder: React.FC<{ value: string; @@ -39,7 +41,7 @@ export const TextInputCustomBorder: React.FC<{ if (onlyNumbers) { const withoutCommaValue = thousandSeparatedToNumber(value); // Set value only if fully number - const reg = new RegExp(/^\d+$/); + const reg = new RegExp(NUMBERS_REGEXP); if (reg.test(withoutCommaValue)) { onChangeText(numberWithThousandsSeparator(withoutCommaValue)); } diff --git a/packages/components/teritoriNameService/FindAName.tsx b/packages/components/teritoriNameService/FindAName.tsx index d2db86b210..d8953c066c 100644 --- a/packages/components/teritoriNameService/FindAName.tsx +++ b/packages/components/teritoriNameService/FindAName.tsx @@ -6,6 +6,8 @@ import { NameStatus } from "./NameStatus"; import { neutral17 } from "../../utils/style/colors"; import { TextInputCustom } from "../inputs/TextInputCustom"; +import { LETTERS_REGEXP } from "@/utils/regex"; + // TODO: Maybe it can be a screen that is called in Register and Explore flow... TNSRegisterScreen.tsx and TNSExploreScreen.tsx have duplicated code // A title + Name status (minted or available) + NFT card + optional buttons @@ -37,7 +39,7 @@ export const FindAName: React.FC<{ style={{ marginBottom: 12 }} onChangeText={setName} value={name || ""} - regexp={new RegExp(/^[a-zA-Z]+$/)} + regexp={new RegExp(LETTERS_REGEXP)} squaresBackgroundColor={neutral17} /> diff --git a/packages/components/teritoriNameService/NameDataForm.tsx b/packages/components/teritoriNameService/NameDataForm.tsx index 8d0b1b5040..f83c0f31f5 100644 --- a/packages/components/teritoriNameService/NameDataForm.tsx +++ b/packages/components/teritoriNameService/NameDataForm.tsx @@ -10,6 +10,8 @@ import { ExternalLink } from "../ExternalLink"; import { PrimaryButton } from "../buttons/PrimaryButton"; import { TextInputCustom } from "../inputs/TextInputCustom"; +import { LETTERS_REGEXP } from "@/utils/regex"; + export const NameDataForm: React.FC<{ isMintPath?: boolean; btnLabel: string; @@ -122,7 +124,7 @@ export const NameDataForm: React.FC<{ placeHolder="Type name here" value={publicName} onChangeText={setPublicName} - regexp={new RegExp(/^[a-zA-Z]+$/)} + regexp={new RegExp(LETTERS_REGEXP)} squaresBackgroundColor={neutral17} /> diff --git a/packages/screens/Launchpad/MintCollectionScreen.tsx b/packages/screens/Launchpad/MintCollectionScreen.tsx index 4ae81ab245..86e627e3cc 100644 --- a/packages/screens/Launchpad/MintCollectionScreen.tsx +++ b/packages/screens/Launchpad/MintCollectionScreen.tsx @@ -15,6 +15,7 @@ import { import ConfettiCannon from "react-native-confetti-cannon"; import CountDown from "react-native-countdown-component"; +import { NUMBERS_REGEXP } from "./../../utils/regex"; import balanceSVG from "../../../assets/icons/balance.svg"; import minusSVG from "../../../assets/icons/minus.svg"; import plusSVG from "../../../assets/icons/plus.svg"; @@ -131,7 +132,7 @@ export const MintCollectionScreen: ScreenFC<"MintCollection"> = ({ const mintButtonDisabled = minted; const updateTotalBulkMint = (newTotalBulkMint: number | string) => { - const numOnlyRegexp = new RegExp(/^\d+$/); + const numOnlyRegexp = new RegExp(NUMBERS_REGEXP); if (!numOnlyRegexp.test("" + newTotalBulkMint)) { return; } diff --git a/packages/utils/formRules.ts b/packages/utils/formRules.ts index 9a121bae94..f2b788a98e 100644 --- a/packages/utils/formRules.ts +++ b/packages/utils/formRules.ts @@ -1,6 +1,8 @@ import { bech32 } from "bech32"; import { ValidationRule } from "react-hook-form"; +import { LETTERS_REGEXP, NUMBERS_REGEXP } from "./regex"; + // validator should return false or string to trigger error export const validateAddress = (value: string) => { try { @@ -13,12 +15,12 @@ export const validateAddress = (value: string) => { }; export const patternOnlyLetters: ValidationRule = { - value: /^[A-Za-z]+$/, + value: LETTERS_REGEXP, message: "Only letters are allowed", }; export const patternOnlyNumbers: ValidationRule = { - value: /^\d+$/, + value: NUMBERS_REGEXP, message: "Only numbers are allowed", }; diff --git a/packages/utils/regex.ts b/packages/utils/regex.ts index de79f51d4c..a21ab7a143 100644 --- a/packages/utils/regex.ts +++ b/packages/utils/regex.ts @@ -4,3 +4,5 @@ export const URL_REGEX = export const HASHTAG_REGEX = /#\S+/; export const HTML_TAG_REGEXP = /(<([^>]+)>)/gi; export const GIF_URL_REGEX = /https?:\/\/.*\.(gif)(\?.*)?$/; +export const NUMBERS_REGEXP = /^\d+$/; +export const LETTERS_REGEXP = /^[A-Za-z]+$/; From 284e2c9bbb6c17b7e7ef845cec4f7028c7dc4882 Mon Sep 17 00:00:00 2001 From: WaDadidou <50441633+WaDadidou@users.noreply.github.com> Date: Sat, 2 Nov 2024 11:09:05 -0400 Subject: [PATCH 06/14] fix: set a prop as optional and remove usage (#1326) * fix: make paginationProps to avoid calling TableWrapper with it * chore: remove useless prop usage --- packages/components/table/TableWrapper.tsx | 4 ++-- .../component/LaunchpadERC20AirdropsTable.tsx | 12 +---------- .../component/LaunchpadERC20SalesTable.tsx | 12 +---------- .../component/LaunchpadERC20TokensTable.tsx | 12 +---------- .../component/MarketplaceLeaderboardTable.tsx | 21 +++---------------- 5 files changed, 8 insertions(+), 53 deletions(-) diff --git a/packages/components/table/TableWrapper.tsx b/packages/components/table/TableWrapper.tsx index b0e5011ff4..55040c6c80 100644 --- a/packages/components/table/TableWrapper.tsx +++ b/packages/components/table/TableWrapper.tsx @@ -6,7 +6,7 @@ import { SpacerColumn } from "@/components/spacer"; export const TableWrapper: FC<{ children: ReactNode; - paginationProps: PaginationProps; + paginationProps?: PaginationProps; showPagination?: boolean; horizontalScrollBreakpoint?: number; }> = ({ @@ -31,7 +31,7 @@ export const TableWrapper: FC<{ - {showPagination && ( + {showPagination && paginationProps && ( <> diff --git a/packages/screens/LaunchpadERC20/component/LaunchpadERC20AirdropsTable.tsx b/packages/screens/LaunchpadERC20/component/LaunchpadERC20AirdropsTable.tsx index f8c1a3c15a..9b462a541e 100644 --- a/packages/screens/LaunchpadERC20/component/LaunchpadERC20AirdropsTable.tsx +++ b/packages/screens/LaunchpadERC20/component/LaunchpadERC20AirdropsTable.tsx @@ -69,17 +69,7 @@ export const AirdropsTable: React.FC = ({ networkId }) => { > Latest ERC20 Airdrops Created - {}, - onChangePage: () => {}, - }} - horizontalScrollBreakpoint={breakpointM} - > + {airdrops && ( = ({ networkId }) => { > Latest ERC20 Sales Created - {}, - onChangePage: () => {}, - }} - horizontalScrollBreakpoint={breakpointM} - > + {sales && ( = ({ networkId }) => { > Latest ERC20 Tokens Created - {}, - onChangePage: () => {}, - }} - horizontalScrollBreakpoint={breakpointM} - > + {tokens && ( = React.memo(({ networkId, timePeriodHours }) => { - const [pageIndex, setPageIndex] = useState(0); - const [itemsPerPage, setItemsPerPage] = useState(100); const { data: leaderboard } = useMarketplaceLeaderboard( networkId, timePeriodHours, ); - // NOTE: we only show the first 100 items, because getting the total count to properly find maxPage will slow the query down + // NOTE: we only show the first 100 items (limit from backend), because getting the total count to properly find maxPage will slow the query down // see https://stackoverflow.com/questions/28888375/run-a-query-with-a-limit-offset-and-also-get-the-total-number-of-rows - const numItems = leaderboard?.length || 0; - const maxPage = Math.max(Math.ceil(numItems / itemsPerPage), 1); - return ( - + Date: Sat, 2 Nov 2024 16:42:06 +0100 Subject: [PATCH 07/14] test: e2e gno organization deployer (#1304) * test: e2e test to create dao creation flow * wip: e2e test to create dao creation flow * wip: e2e test handle filling all steps in dao creation form * wip: e2e test handle filling all steps in dao creation form * wip: e2e test handle filling all steps in dao creation form * wip: e2e test handle filling all steps in dao creation form * fix: remove unused std from gno dao realm generation * feat: add adena mock deploy pkg function * fix: finish e2e test organization creation flow on gno * chore: refactor project structure by moving all e2e test files into gno subfolder * style: run eslint * revert: useless modification on e2e test * fix: delete useless pkg comment * fix: run lint on networks files * fix: delete useless console.log * feat: use enum to handle adena type message value * fix: delete mint & burn tori token for common dao * fix(dao): remove modboard related code * fix(gnovm): remove leftover of tori import * feat: add a call to members JSON * feat: add a call to members JSON * fix: remove tori admin handler * chore: run eslint * fix: add a TODO to fix later the groupId * fix: remove groupId * fix: keep only e2e related code * fix: keep only e2e related code --------- Co-authored-by: n0izn0iz --- cypress/e2e/{ => gno}/lib.ts | 0 cypress/e2e/gno/organization-creation.cy.ts | 35 ++++++ .../e2e/{ => gno}/projects-contractor.cy.ts | 0 cypress/e2e/{ => gno}/projects-funder.cy.ts | 0 cypress/e2e/{ => gno}/upp-form.cy.ts | 0 networks.json | 6 ++ packages/components/dao/GnoDemo.tsx | 8 +- .../socialFeed/SocialActions/FlagModal.tsx | 9 +- .../socialFeed/SocialActions/TipModal.tsx | 9 +- .../socialFeed/modals/FlagConfirmModal.tsx | 7 +- .../user/modals/EditProfileModal.tsx | 13 ++- .../context/WalletsProvider/gnotest/index.tsx | 59 ++++++++-- packages/hooks/feed/useFeedPosting.ts | 8 +- packages/hooks/feed/useSocialReactions.ts | 4 +- packages/networks/gno-dev/index.ts | 3 +- packages/networks/gno-portal/index.ts | 2 + packages/networks/gno-teritori/index.ts | 2 + packages/networks/types.ts | 2 + .../components/CreateDAOSection.tsx | 1 + .../components/MemberSettingsSection.tsx | 1 + packages/utils/gno.ts | 19 ++-- packages/utils/gnodao/deploy.ts | 102 +++++++++--------- 22 files changed, 195 insertions(+), 95 deletions(-) rename cypress/e2e/{ => gno}/lib.ts (100%) create mode 100644 cypress/e2e/gno/organization-creation.cy.ts rename cypress/e2e/{ => gno}/projects-contractor.cy.ts (100%) rename cypress/e2e/{ => gno}/projects-funder.cy.ts (100%) rename cypress/e2e/{ => gno}/upp-form.cy.ts (100%) diff --git a/cypress/e2e/lib.ts b/cypress/e2e/gno/lib.ts similarity index 100% rename from cypress/e2e/lib.ts rename to cypress/e2e/gno/lib.ts diff --git a/cypress/e2e/gno/organization-creation.cy.ts b/cypress/e2e/gno/organization-creation.cy.ts new file mode 100644 index 0000000000..81bc06c404 --- /dev/null +++ b/cypress/e2e/gno/organization-creation.cy.ts @@ -0,0 +1,35 @@ +import { connectWallet, resetChain } from "./lib"; + +describe("Create an organization flow", () => { + it("works", () => { + resetChain(); + + cy.visit("http://localhost:8081/orgs?network=gno-dev", { + timeout: 300000, + }); + + connectWallet(); + + const daoName = "Test Dao"; + const handle = "testdao"; + const url = + "https://images.unsplash.com/photo-1492571350019-22de08371fd3?fm=jpg&q=60&w=3000&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"; + const description = "Test Dao description"; + + cy.contains("Create Dao").click(); + + cy.get("input[placeholder='Type organization\\'s name here']").type( + daoName, + ); + cy.get("input[placeholder='your_organization']").type(handle); + cy.get("input[placeholder='https://example.com/preview.png']").type(url); + cy.get('[data-testid="organization-description"]').type(description); + + cy.contains("Next: Configure voting").click(); + cy.contains("Next: Set tokens or members").click(); + cy.get('[data-testid="member-settings-next"]').click(); + cy.contains("Confirm & Launch the Organization").click(); + + cy.contains("Get Started", { timeout: 10000 }).should("exist"); + }); +}); diff --git a/cypress/e2e/projects-contractor.cy.ts b/cypress/e2e/gno/projects-contractor.cy.ts similarity index 100% rename from cypress/e2e/projects-contractor.cy.ts rename to cypress/e2e/gno/projects-contractor.cy.ts diff --git a/cypress/e2e/projects-funder.cy.ts b/cypress/e2e/gno/projects-funder.cy.ts similarity index 100% rename from cypress/e2e/projects-funder.cy.ts rename to cypress/e2e/gno/projects-funder.cy.ts diff --git a/cypress/e2e/upp-form.cy.ts b/cypress/e2e/gno/upp-form.cy.ts similarity index 100% rename from cypress/e2e/upp-form.cy.ts rename to cypress/e2e/gno/upp-form.cy.ts diff --git a/networks.json b/networks.json index 68a54b1426..13cc298df9 100644 --- a/networks.json +++ b/networks.json @@ -4526,6 +4526,8 @@ "profilePkgPath": "gno.land/r/demo/profile", "daoInterfacesPkgPath": "gno.land/p/teritori/dao_interfaces", "daoCorePkgPath": "gno.land/p/teritori/dao_core", + "daoUtilsPkgPath": "gno.land/p/teritori/dao_utils", + "toriPkgPath": "gno.land/r/teritori/tori", "nameServiceDefaultImage": "ipfs://bafkreignptjimiu7wuux6mk6uh4hb4odb6ff62ny4bvdokrhes7g67huse", "gnowebURL": "http://127.0.0.1:8888", "txIndexerURL": "http://127.0.0.1:8546" @@ -4574,6 +4576,8 @@ "daoProposalSinglePkgPath": "gno.land/p/teritori/dao_proposal_single", "daoInterfacesPkgPath": "gno.land/p/teritori/dao_interfaces", "daoCorePkgPath": "gno.land/p/teritori/dao_core", + "daoUtilsPkgPath": "gno.land/r/teritori/dao_utils", + "toriPkgPath": "gno.land/r/teritori/tori", "profilePkgPath": "gno.land/r/demo/profile", "txIndexerURL": "https://indexer.portal-loop.gno.testnet.teritori.com" }, @@ -4628,7 +4632,9 @@ "votingGroupPkgPath": "gno.land/p/teritori/dao_voting_group_v2", "daoProposalSinglePkgPath": "gno.land/p/teritori/dao_proposal_single_v4", "daoInterfacesPkgPath": "gno.land/p/teritori/dao_interfaces_v5", + "daoUtilsPkgPath": "", "daoCorePkgPath": "gno.land/p/teritori/dao_core_v4", + "toriPkgPath": "", "gnowebURL": "https://testnet.gno.teritori.com", "faucetURL": "https://testnet.gno.teritori.com:5050/?toaddr=$addr" }, diff --git a/packages/components/dao/GnoDemo.tsx b/packages/components/dao/GnoDemo.tsx index 4dc94295fb..4fed515cac 100644 --- a/packages/components/dao/GnoDemo.tsx +++ b/packages/components/dao/GnoDemo.tsx @@ -10,10 +10,10 @@ import { NetworkKind, parseUserId } from "../../networks"; import { adenaVMCall, extractGnoNumber } from "../../utils/gno"; import { GnoDAOUpdateSettings, - GnoSingleChoiceProposal, - GnoModboardsDeletePostMessage, - GnoModboardsCreateMessage, GnoMintToriMessage, + GnoModboardsCreateMessage, + GnoModboardsDeletePostMessage, + GnoSingleChoiceProposal, } from "../../utils/gnodao/messages"; import { fontSemibold20 } from "../../utils/style/fonts"; import { modalMarginPadding } from "../../utils/style/modals"; @@ -376,7 +376,7 @@ const GnoCreateProposal: React.FC<{ daoId: string | undefined }> = ({ { caller: selectedWallet.address, send: "", - pkg_path: daoAddress, + pkg_path: "gno.land/r/" + selectedWallet, func: "ProposeJSON", args: ["0", JSON.stringify(propReq)], }, diff --git a/packages/components/socialFeed/SocialActions/FlagModal.tsx b/packages/components/socialFeed/SocialActions/FlagModal.tsx index 9c3d46e4c9..128a690116 100644 --- a/packages/components/socialFeed/SocialActions/FlagModal.tsx +++ b/packages/components/socialFeed/SocialActions/FlagModal.tsx @@ -6,8 +6,11 @@ import { useSelectedNetworkInfo } from "../../../hooks/useSelectedNetwork"; import useSelectedWallet from "../../../hooks/useSelectedWallet"; import { mustGetGnoNetwork } from "../../../networks"; import { TERITORI_FEED_ID } from "../../../utils/feed/constants"; -import { adenaDoContract } from "../../../utils/gno"; -import { neutral77, neutral33 } from "../../../utils/style/colors"; +import { + adenaDoContract, + AdenaDoContractMessageType, +} from "../../../utils/gno"; +import { neutral33, neutral77 } from "../../../utils/style/colors"; import { fontSemibold14, fontSemibold16 } from "../../../utils/style/fonts"; import { BrandText } from "../../BrandText"; import FlexRow from "../../FlexRow"; @@ -53,7 +56,7 @@ export const FlagModal: React.FC = ({ try { await adenaDoContract( selectedNetworkId || "", - [{ type: "/vm.m_call", value: vmCall }], + [{ type: AdenaDoContractMessageType.CALL, value: vmCall }], { gasWanted: 2_000_000, }, diff --git a/packages/components/socialFeed/SocialActions/TipModal.tsx b/packages/components/socialFeed/SocialActions/TipModal.tsx index e359b675cf..39f2d14bea 100644 --- a/packages/components/socialFeed/SocialActions/TipModal.tsx +++ b/packages/components/socialFeed/SocialActions/TipModal.tsx @@ -11,14 +11,17 @@ import { useBalances } from "../../../hooks/useBalances"; import { useSelectedNetworkInfo } from "../../../hooks/useSelectedNetwork"; import useSelectedWallet from "../../../hooks/useSelectedWallet"; import { - NetworkKind, getStakingCurrency, keplrCurrencyFromNativeCurrencyInfo, + NetworkKind, } from "../../../networks"; import { prettyPrice } from "../../../utils/coins"; import { defaultSocialFeedFee } from "../../../utils/fee"; import { TERITORI_FEED_ID } from "../../../utils/feed/constants"; -import { adenaDoContract } from "../../../utils/gno"; +import { + adenaDoContract, + AdenaDoContractMessageType, +} from "../../../utils/gno"; import { neutral77, primaryColor } from "../../../utils/style/colors"; import { fontSemibold13, fontSemibold14 } from "../../../utils/style/fonts"; import { BrandText } from "../../BrandText"; @@ -95,7 +98,7 @@ export const TipModal: React.FC<{ try { await adenaDoContract( selectedNetworkId || "", - [{ type: "/vm.m_call", value: vmCall }], + [{ type: AdenaDoContractMessageType.CALL, value: vmCall }], { gasWanted: 1_000_000, }, diff --git a/packages/components/socialFeed/modals/FlagConfirmModal.tsx b/packages/components/socialFeed/modals/FlagConfirmModal.tsx index 230d0680bc..5a6d576825 100644 --- a/packages/components/socialFeed/modals/FlagConfirmModal.tsx +++ b/packages/components/socialFeed/modals/FlagConfirmModal.tsx @@ -7,7 +7,10 @@ import { useFeedbacks } from "../../../context/FeedbacksProvider"; import { useSelectedNetworkId } from "../../../hooks/useSelectedNetwork"; import useSelectedWallet from "../../../hooks/useSelectedWallet"; import { mustGetGnoNetwork } from "../../../networks"; -import { adenaDoContract } from "../../../utils/gno"; +import { + adenaDoContract, + AdenaDoContractMessageType, +} from "../../../utils/gno"; import { GnoDAOVoteRequest } from "../../../utils/gnodao/messages"; import { neutral77 } from "../../../utils/style/colors"; import { @@ -74,7 +77,7 @@ export const FlagConfirmModal: React.FC = ({ const txHash = await adenaDoContract( selectedNetworkId, - [{ type: "/vm.m_call", value: vmCall }], + [{ type: AdenaDoContractMessageType.CALL, value: vmCall }], { gasWanted: 2_000_000, }, diff --git a/packages/components/user/modals/EditProfileModal.tsx b/packages/components/user/modals/EditProfileModal.tsx index 8c838d8bcb..3b5fa3eae4 100644 --- a/packages/components/user/modals/EditProfileModal.tsx +++ b/packages/components/user/modals/EditProfileModal.tsx @@ -6,8 +6,8 @@ import React, { useMemo } from "react"; import { View } from "react-native"; import { - ExecuteMsg as TNSExecuteMsg, Metadata, + ExecuteMsg as TNSExecuteMsg, } from "../../../contracts-clients/teritori-name-service/TeritoriNameService.types"; import { EditProfileForm } from "../forms/EditProfileForm"; import { TNSModalCommonProps } from "../types"; @@ -22,7 +22,12 @@ import { useNSUserInfo } from "@/hooks/useNSUserInfo"; import { useRunOrProposeTransaction } from "@/hooks/useRunOrProposeTransaction"; import useSelectedWallet from "@/hooks/useSelectedWallet"; import { getNetwork, NetworkKind, UserKind } from "@/networks"; -import { adenaDoContract, AdenaDoContractMessage, VmCall } from "@/utils/gno"; +import { + adenaDoContract, + AdenaDoContractMessage, + AdenaDoContractMessageType, + VmCall, +} from "@/utils/gno"; import { neutral17, neutral77 } from "@/utils/style/colors"; import { fontMedium16 } from "@/utils/style/fonts"; import { EMPTY_PROFILE, ProfileData } from "@/utils/upp"; @@ -183,7 +188,7 @@ export const EditProfileModal: React.FC = ({ func: "Register", args: ["", usernameValue, ""], }; - msgs.push({ type: "/vm.m_call", value: vmCall }); + msgs.push({ type: AdenaDoContractMessageType.CALL, value: vmCall }); } // FIXME: the contract supports only update data one by one @@ -242,7 +247,7 @@ export const EditProfileModal: React.FC = ({ args: [field, val], }; - msgs.push({ type: "/vm.m_call", value: vmCall }); + msgs.push({ type: AdenaDoContractMessageType.CALL, value: vmCall }); } if (msgs.length === 0) { diff --git a/packages/context/WalletsProvider/gnotest/index.tsx b/packages/context/WalletsProvider/gnotest/index.tsx index 89eb65347c..04ebacd001 100644 --- a/packages/context/WalletsProvider/gnotest/index.tsx +++ b/packages/context/WalletsProvider/gnotest/index.tsx @@ -1,10 +1,12 @@ import { GnoJSONRPCProvider, GnoWallet, + MemFile, + MemPackage, MsgSend, decodeTxMessages, } from "@gnolang/gno-js-client"; -import { TxFee, TransactionEndpoint, Tx } from "@gnolang/tm2-js-client"; +import { TransactionEndpoint, Tx, TxFee } from "@gnolang/tm2-js-client"; import Long from "long"; import React from "react"; import { Pressable } from "react-native"; @@ -16,7 +18,11 @@ import { getUserId } from "@/networks"; import { gnoDevNetwork } from "@/networks/gno-dev"; import { setSelectedWalletId } from "@/store/slices/settings"; import { useAppDispatch } from "@/store/store"; -import { RequestDocontractMessage } from "@/utils/gno"; +import { + AdenaDoContractMessage, + AdenaDoContractMessageType, + RequestDocontractMessage, +} from "@/utils/gno"; import { WalletProvider } from "@/utils/walletProvider"; type UseGnotestResult = [true, boolean, Wallet[]] | [false, boolean, undefined]; @@ -268,7 +274,10 @@ const setupAdenaMock = () => { throw new Error("Wallet not connected"); } const msg = req.messages[0]; - if (msg.type !== "/vm.m_call") { + if ( + msg.type !== AdenaDoContractMessageType.CALL && + msg.type !== AdenaDoContractMessageType.ADD_PKG + ) { throw new Error("Unsupported message type: " + msg.type); } const txFee: TxFee = { @@ -283,14 +292,19 @@ const setupAdenaMock = () => { console.log("docontract sendAmount", sendAmount); sendMap.set("ugnot", +sendAmount); } - const res = await state.wallet.callMethod( - msg.value.pkg_path, - msg.value.func, - msg.value.args, - TransactionEndpoint.BROADCAST_TX_COMMIT, - sendMap, - txFee, - ); + let res; + if (msg.type === AdenaDoContractMessageType.CALL) { + res = await state.wallet.callMethod( + msg.value.pkg_path, + msg.value.func, + msg.value.args, + TransactionEndpoint.BROADCAST_TX_COMMIT, + sendMap, + txFee, + ); + } else { + res = await deployPackage(state.wallet, msg, sendMap, txFee); + } return { status: "success", data: { @@ -313,6 +327,29 @@ const setupAdenaMock = () => { }; }; +const deployPackage = async ( + wallet: GnoWallet, + msg: AdenaDoContractMessage, + funds: Map | undefined, + txFee: TxFee, +) => { + const files: MemFile[] = msg.value.package.files; + + const pkg: MemPackage = { + name: msg.value.package.name, + path: msg.value.package.path, + files, + }; + + const tx = await wallet.deployPackage( + pkg, + TransactionEndpoint.BROADCAST_TX_COMMIT, + funds, + txFee, + ); + return tx; +}; + export const useGnotest: () => UseGnotestResult = () => { const { wallet, address } = useGnotestStore(); const wallets: Wallet[] = []; diff --git a/packages/hooks/feed/useFeedPosting.ts b/packages/hooks/feed/useFeedPosting.ts index 0139bc52ca..40376b9e24 100644 --- a/packages/hooks/feed/useFeedPosting.ts +++ b/packages/hooks/feed/useFeedPosting.ts @@ -13,16 +13,16 @@ import { useBalances } from "../useBalances"; import { signingSocialFeedClient } from "@/client-creators/socialFeedClient"; import { - parseUserId, getStakingCurrency, mustGetCosmosNetwork, NetworkKind, + parseUserId, } from "@/networks"; import { prettyPrice } from "@/utils/coins"; import { defaultSocialFeedFee } from "@/utils/fee"; import { TERITORI_FEED_ID } from "@/utils/feed/constants"; -import { FeedPostingStepId, feedPostingStep } from "@/utils/feed/posting"; -import { adenaDoContract } from "@/utils/gno"; +import { feedPostingStep, FeedPostingStepId } from "@/utils/feed/posting"; +import { adenaDoContract, AdenaDoContractMessageType } from "@/utils/gno"; import { PostCategory } from "@/utils/types/feed"; export const useFeedPosting = ( @@ -124,7 +124,7 @@ export const useFeedPosting = ( const txHash = await adenaDoContract( network.id, - [{ type: "/vm.m_call", value: vmCall }], + [{ type: AdenaDoContractMessageType.CALL, value: vmCall }], { gasWanted: 2_000_000 }, ); diff --git a/packages/hooks/feed/useSocialReactions.ts b/packages/hooks/feed/useSocialReactions.ts index af9ab02ac9..3dc42f3c6b 100644 --- a/packages/hooks/feed/useSocialReactions.ts +++ b/packages/hooks/feed/useSocialReactions.ts @@ -15,7 +15,7 @@ import { NetworkKind, } from "@/networks"; import { TERITORI_FEED_ID } from "@/utils/feed/constants"; -import { adenaDoContract } from "@/utils/gno"; +import { adenaDoContract, AdenaDoContractMessageType } from "@/utils/gno"; import { DISLIKE_EMOJI, getUpdatedReactions, @@ -77,7 +77,7 @@ export const useSocialReactions = ({ }; const txHash = await adenaDoContract( post.networkId, - [{ type: "/vm.m_call", value: vmCall }], + [{ type: AdenaDoContractMessageType.CALL, value: vmCall }], { gasWanted: 2_000_000, }, diff --git a/packages/networks/gno-dev/index.ts b/packages/networks/gno-dev/index.ts index b7349f907f..8f1e2e06f9 100644 --- a/packages/networks/gno-dev/index.ts +++ b/packages/networks/gno-dev/index.ts @@ -47,9 +47,10 @@ export const gnoDevNetwork: GnoNetworkInfo = { votingGroupPkgPath: "gno.land/p/teritori/dao_voting_group", daoProposalSinglePkgPath: "gno.land/p/teritori/dao_proposal_single", profilePkgPath: "gno.land/r/demo/profile", - daoInterfacesPkgPath: "gno.land/p/teritori/dao_interfaces", daoCorePkgPath: "gno.land/p/teritori/dao_core", + daoUtilsPkgPath: "gno.land/p/teritori/dao_utils", + toriPkgPath: "gno.land/r/teritori/tori", nameServiceDefaultImage: "ipfs://bafkreignptjimiu7wuux6mk6uh4hb4odb6ff62ny4bvdokrhes7g67huse", gnowebURL: "http://127.0.0.1:8888", diff --git a/packages/networks/gno-portal/index.ts b/packages/networks/gno-portal/index.ts index 5409578d13..a2fa0d2dce 100644 --- a/packages/networks/gno-portal/index.ts +++ b/packages/networks/gno-portal/index.ts @@ -38,6 +38,8 @@ export const gnoPortalNetwork: GnoNetworkInfo = { daoProposalSinglePkgPath: "gno.land/p/teritori/dao_proposal_single", daoInterfacesPkgPath: "gno.land/p/teritori/dao_interfaces", daoCorePkgPath: "gno.land/p/teritori/dao_core", + daoUtilsPkgPath: "gno.land/r/teritori/dao_utils", + toriPkgPath: "gno.land/r/teritori/tori", profilePkgPath: "gno.land/r/demo/profile", txIndexerURL: "https://indexer.portal-loop.gno.testnet.teritori.com", }; diff --git a/packages/networks/gno-teritori/index.ts b/packages/networks/gno-teritori/index.ts index ff21695a40..b511fd9053 100644 --- a/packages/networks/gno-teritori/index.ts +++ b/packages/networks/gno-teritori/index.ts @@ -42,7 +42,9 @@ export const gnoTeritoriNetwork: GnoNetworkInfo = { votingGroupPkgPath: "gno.land/p/teritori/dao_voting_group_v2", daoProposalSinglePkgPath: "gno.land/p/teritori/dao_proposal_single_v4", daoInterfacesPkgPath: "gno.land/p/teritori/dao_interfaces_v5", + daoUtilsPkgPath: "", //TODO: fill with the correct path daoCorePkgPath: "gno.land/p/teritori/dao_core_v4", + toriPkgPath: "", //TODO: fill with the correct path gnowebURL: "https://testnet.gno.teritori.com", faucetURL: "https://testnet.gno.teritori.com:5050/?toaddr=$addr", }; diff --git a/packages/networks/types.ts b/packages/networks/types.ts index 495fc6a773..6349851cdb 100644 --- a/packages/networks/types.ts +++ b/packages/networks/types.ts @@ -119,6 +119,8 @@ export type GnoNetworkInfo = NetworkInfoBase & { daoInterfacesPkgPath?: string; daoCorePkgPath?: string; groupsPkgPath?: string; + daoUtilsPkgPath?: string; + toriPkgPath?: string; profilePkgPath?: string; faucetURL?: string; txIndexerURL?: string; diff --git a/packages/screens/Organizations/components/CreateDAOSection.tsx b/packages/screens/Organizations/components/CreateDAOSection.tsx index 29ef7ca0ca..1ed41a2c15 100644 --- a/packages/screens/Organizations/components/CreateDAOSection.tsx +++ b/packages/screens/Organizations/components/CreateDAOSection.tsx @@ -131,6 +131,7 @@ export const CreateDAOSection: React.FC = ({ // isAsterickSign multiline numberOfLines={3} + testID="organization-description" /> diff --git a/packages/screens/Organizations/components/MemberSettingsSection.tsx b/packages/screens/Organizations/components/MemberSettingsSection.tsx index 03d724349f..6c44dc3d40 100644 --- a/packages/screens/Organizations/components/MemberSettingsSection.tsx +++ b/packages/screens/Organizations/components/MemberSettingsSection.tsx @@ -112,6 +112,7 @@ export const MemberSettingsSection: React.FC = ({ size="M" text={`Next: ${ORGANIZATION_DEPLOYER_STEPS[3]}`} onPress={handleSubmit(onSubmit)} + testID="member-settings-next" /> diff --git a/packages/utils/gno.ts b/packages/utils/gno.ts index 42ff6dfdd6..de41e6fcda 100644 --- a/packages/utils/gno.ts +++ b/packages/utils/gno.ts @@ -2,6 +2,11 @@ import { GnoJSONRPCProvider } from "@gnolang/gno-js-client"; import { mustGetGnoNetwork } from "../networks"; +export enum AdenaDoContractMessageType { + CALL = "/vm.m_call", + ADD_PKG = "/vm.m_addpkg", +} + export interface AdenaDoContractMessage { type: string; value: { [key in string]: any }; @@ -72,20 +77,20 @@ export const adenaVMCall = async ( ) => { await adenaDoContract( networkId, - [{ type: "/vm.m_call", value: vmCall }], + [{ type: AdenaDoContractMessageType.CALL, value: vmCall }], opts, ); }; interface Package { - Name: string; - Path: string; - Files: PackageFile[]; + name: string; + path: string; + files: PackageFile[]; } interface PackageFile { - Name: string; - Body: string; + name: string; + body: string; } interface VmAddPackage { @@ -101,7 +106,7 @@ export const adenaAddPkg = async ( ) => { await adenaDoContract( networkId, - [{ type: "/vm.m_addpkg", value: vmAddPackage }], + [{ type: AdenaDoContractMessageType.ADD_PKG, value: vmAddPackage }], { ...opts, }, diff --git a/packages/utils/gnodao/deploy.ts b/packages/utils/gnodao/deploy.ts index eafbd5bb3e..7c50be7315 100644 --- a/packages/utils/gnodao/deploy.ts +++ b/packages/utils/gnodao/deploy.ts @@ -27,33 +27,29 @@ const generateDAORealmSource = (networkId: string, conf: GnoDAOConfig) => { dao_core "${network.daoCorePkgPath}" dao_interfaces "${network.daoInterfacesPkgPath}" proposal_single "${network.daoProposalSinglePkgPath}" + "${network.daoUtilsPkgPath}" voting_group "${network.votingGroupPkgPath}" - "${network.groupsPkgPath}" - modboards "${network.modboardsPkgPath}" "${network.daoRegistryPkgPath}" ) - var ( - daoCore dao_interfaces.IDAOCore - mainBoardName = "${conf.name}" - groupName = mainBoardName + "_voting_group" - groupID groups.GroupID - ) - - func init() { - modboards.CreateBoard(mainBoardName) - - votingModuleFactory := func(core dao_interfaces.IDAOCore) dao_interfaces.IVotingModule { - groupID = groups.CreateGroup(groupName) +var ( + daoCore dao_interfaces.IDAOCore + group *voting_group.VotingGroup + registered bool +) + +func init() { + votingModuleFactory := func(core dao_interfaces.IDAOCore) dao_interfaces.IVotingModule { + group = voting_group.NewVotingGroup() ${conf.initialMembers .map( (member) => - `groups.AddMember(groupID, "${member.address}", ${member.weight}, "");`, + `group.SetMemberPower("${member.address}", ${member.weight});`, ) .join("\n\t")} - return voting_group.NewVotingGroup(groupID) - } - + return group + } + // TODO: consider using factories that return multiple modules and handlers proposalModulesFactories := []dao_interfaces.ProposalModuleFactory{ @@ -65,7 +61,7 @@ const generateDAORealmSource = (networkId: string, conf: GnoDAOConfig) => { conf.quorumPercent * 100, )}) // ${Math.ceil(conf.quorumPercent * 100) / 100}% return proposal_single.NewDAOProposalSingle(core, &proposal_single.DAOProposalSingleOpts{ - MaxVotingPeriod: time.Second * ${conf.maxVotingPeriodSeconds}, + MaxVotingPeriod: dao_utils.DurationTime(time.Second * ${conf.maxVotingPeriodSeconds}), Threshold: &proposal_single.ThresholdThresholdQuorum{ Threshold: &tt, Quorum: &tq, @@ -74,35 +70,24 @@ const generateDAORealmSource = (networkId: string, conf: GnoDAOConfig) => { }, } - messageHandlersFactories := []dao_interfaces.MessageHandlerFactory{ - func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler { - return groups.NewAddMemberHandler() - }, - func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler { - return groups.NewDeleteMemberHandler() - }, - func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler { - // TODO: add a router to support multiple proposal modules - propMod := core.ProposalModules()[0] - return proposal_single.NewUpdateSettingsHandler(propMod.Module.(*proposal_single.DAOProposalSingle)) - }, - func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler { - return modboards.NewCreateBoardHandler() - }, - func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler { - return modboards.NewDeletePostHandler() - }, - } - - daoCore = dao_core.NewDAOCore(votingModuleFactory, proposalModulesFactories, messageHandlersFactories) + messageHandlersFactories := []dao_interfaces.MessageHandlerFactory{ + func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler { + return group.UpdateMembersHandler() + }, + func(core dao_interfaces.IDAOCore) dao_interfaces.MessageHandler { + // TODO: add a router to support multiple proposal modules + propMod := core.ProposalModules()[0] + return proposal_single.NewUpdateSettingsHandler(propMod.Module.(*proposal_single.DAOProposalSingle)) + }, + } - dao_registry.Register(${JSON.stringify(conf.displayName)}, ${JSON.stringify( - conf.description, - )}, ${JSON.stringify(conf.imageURI)}) + daoCore = dao_core.NewDAOCore(votingModuleFactory, proposalModulesFactories, messageHandlersFactories) + + dao_registry.Register(func() dao_interfaces.IDAOCore { return daoCore }, "${conf.displayName}", "${conf.description}", "${conf.imageURI}") } func Render(path string) string { - return "[[board](/r/demo/modboards:" + mainBoardName + ")]\\n\\n" + daoCore.Render(path) + return daoCore.Render(path) } func VoteJSON(moduleIndex int, proposalID int, voteJSON string) { @@ -111,32 +96,41 @@ const generateDAORealmSource = (networkId: string, conf: GnoDAOConfig) => { if !module.Enabled { panic("proposal module is not enabled") } + module.Module.VoteJSON(proposalID, voteJSON) } - + func Execute(moduleIndex int, proposalID int) { // move check in dao core module := dao_core.GetProposalModule(daoCore, moduleIndex) if !module.Enabled { panic("proposal module is not enabled") } + module.Module.Execute(proposalID) } - - func ProposeJSON(moduleIndex int, proposalJSON string) { + + func ProposeJSON(moduleIndex int, proposalJSON string) int { // move check in dao core module := dao_core.GetProposalModule(daoCore, moduleIndex) if !module.Enabled { panic("proposal module is not enabled") } - module.Module.ProposeJSON(proposalJSON) + + return module.Module.ProposeJSON(proposalJSON) } - + func getProposalsJSON(moduleIndex int, limit int, startAfter string, reverse bool) string { // move logic in dao core module := dao_core.GetProposalModule(daoCore, moduleIndex) return module.Module.ProposalsJSON(limit, startAfter, reverse) } + + func getProposalJSON(moduleIndex int, proposalIndex int) string { + // move logic in dao core + module := dao_core.GetProposalModule(daoCore, moduleIndex) + return module.Module.ProposalJSON(proposalIndex) + } `; }; @@ -146,19 +140,19 @@ export const adenaDeployGnoDAO = async ( conf: GnoDAOConfig, ) => { const source = generateDAORealmSource(networkId, conf); - const pkgPath = `gno.land/r/demo/${conf.name}`; + const pkgPath = `gno.land/r/${creator}/${conf.name}`; await adenaAddPkg( networkId, { creator, deposit: "1ugnot", package: { - Name: conf.name, - Path: pkgPath, - Files: [{ Name: `${conf.name}.gno`, Body: source }], + name: conf.name, + path: pkgPath, + files: [{ name: `${conf.name}.gno`, body: source }], }, }, - { gasWanted: 10000000 }, + { gasWanted: 20000000 }, ); return pkgPath; }; From 9d7246b3d97004f2a09431182e98be301ca6a102 Mon Sep 17 00:00:00 2001 From: n0izn0iz Date: Sat, 2 Nov 2024 19:27:12 +0100 Subject: [PATCH 08/14] chore: improve rust CI (#1327) Signed-off-by: Norman Meier --- .github/workflows/rust.yml | 23 +++++++++++++++---- Makefile | 19 +++++++++++---- .../cw-address-list/src/multitest.rs | 1 - .../.cargo/{config => config.toml} | 0 4 files changed, 34 insertions(+), 9 deletions(-) rename rust/cw-contracts/nft-marketplace/.cargo/{config => config.toml} (100%) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 48bcfa9b5d..c09b43fa54 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -14,12 +14,27 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-unknown - - name: Build - run: make build.rust + - name: Format + run: make fmt.rust + + - name: Lint + run: make lint.rust - name: Test run: make test.rust - - name: Check diff - run: git diff --exit-code + - name: Build + run: make build.rust + + - name: Check that there is no diff + run: | + mrdiff=$(git status --porcelain) + if [[ $mrdiff ]]; then + echo 'ERROR: Diff found!' + echo $mrdiff + git diff + exit 1 + fi diff --git a/Makefile b/Makefile index ac8db6d800..117ed255db 100644 --- a/Makefile +++ b/Makefile @@ -83,7 +83,7 @@ generate.graphql-thegraph: go run github.com/Khan/genqlient@85e2e8dffd211c83a2be626474993ef68e44a242 go/pkg/thegraph/genqlient.yaml .PHONY: lint -lint: lint.buf lint.js +lint: lint.buf lint.js lint.rust .PHONY: lint.buf lint.buf: @@ -94,6 +94,14 @@ lint.buf: lint.js: node_modules yarn lint +.PHONY: lint.rust +lint.rust: + cargo clippy + +.PHONY: fmt.rust +fmt.rust: + cargo fmt + .PHONY: go/pkg/holagql/holaplex-schema.graphql go/pkg/holagql/holaplex-schema.graphql: rover graph introspect https://graph.65.108.73.219.nip.io/v1 > $@ @@ -396,6 +404,7 @@ bump-app-build-number: .PHONY: test.rust test.rust: + set -e ; \ for file in $(INTERNAL_COSMWASM_CONTRACTS); do \ echo "> Testing $${file}" ; \ cd $${file} ; \ @@ -405,6 +414,7 @@ test.rust: .PHONY: build.rust build.rust: + set -e ; \ for file in $(INTERNAL_COSMWASM_CONTRACTS); do \ echo "> Building $${file}" ; \ cd $${file} ; \ @@ -414,10 +424,11 @@ build.rust: .PHONY: generate.internal-contracts-clients generate.internal-contracts-clients: node_modules + set -e ; \ for indir in $(INTERNAL_COSMWASM_CONTRACTS) ; do \ echo "> Generating client for $${indir}" ; \ rm -fr $${indir}/schema ; \ - (cd $${indir} && cargo schema && cd -) || exit 1 ; \ + cd $${indir} && cargo schema && cd - ; \ pkgname="$$(basename $${indir})" ; \ outdir="$(CONTRACTS_CLIENTS_DIR)/$${pkgname}" ; \ rm -fr $${outdir} ; \ @@ -427,8 +438,8 @@ generate.internal-contracts-clients: node_modules --out $${outdir} \ --name $${pkgname} \ --no-bundle \ - || exit 1 ;\ - npx tsx packages/scripts/makeTypescriptIndex $${outdir} || exit 1 ; \ + ;\ + npx tsx packages/scripts/makeTypescriptIndex $${outdir} ; \ done .PHONY: install-gno diff --git a/rust/cw-contracts/cw-address-list/src/multitest.rs b/rust/cw-contracts/cw-address-list/src/multitest.rs index d53bfa4ed6..4ea0a4a328 100644 --- a/rust/cw-contracts/cw-address-list/src/multitest.rs +++ b/rust/cw-contracts/cw-address-list/src/multitest.rs @@ -3,7 +3,6 @@ use sylvia::multitest::App; use crate::contract::sv::multitest_utils::CodeId; - #[test] fn instantiate() { let app = App::default(); diff --git a/rust/cw-contracts/nft-marketplace/.cargo/config b/rust/cw-contracts/nft-marketplace/.cargo/config.toml similarity index 100% rename from rust/cw-contracts/nft-marketplace/.cargo/config rename to rust/cw-contracts/nft-marketplace/.cargo/config.toml From f2ebe3fcf4e4082e0dddf03b3348bd3d2f746b5a Mon Sep 17 00:00:00 2001 From: WaDadidou <50441633+WaDadidou@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:16:59 -0500 Subject: [PATCH 09/14] feat(launchpad): add a spacing value (#1333) * feat: add a layout.spacing value and use it as example, use spacing values in MintCollectionScreen * yarn lint-fix --- .../Launchpad/MintCollectionScreen.tsx | 62 ++++++++++++++----- packages/utils/style/layout.ts | 4 ++ 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/packages/screens/Launchpad/MintCollectionScreen.tsx b/packages/screens/Launchpad/MintCollectionScreen.tsx index 86e627e3cc..525b131f43 100644 --- a/packages/screens/Launchpad/MintCollectionScreen.tsx +++ b/packages/screens/Launchpad/MintCollectionScreen.tsx @@ -84,7 +84,7 @@ import { import { layout } from "@/utils/style/layout"; const maxImageSize = 532; -const cardsHalfGap = 6; +const cardsHalfGap = layout.spacing_x0_75; const sleep = (duration: number) => new Promise((resolve) => setTimeout(resolve, duration)); @@ -349,7 +349,13 @@ export const MintCollectionScreen: ScreenFC<"MintCollection"> = ({ if (notFound) { return ( - + Collection not found @@ -377,9 +383,11 @@ export const MintCollectionScreen: ScreenFC<"MintCollection"> = ({ margin: layout.spacing_x2, }} > - {info.name} + + {info.name} + - + = ({ margin: layout.spacing_x2, }} > - + {info.image ? ( = ({ justifyContent: "center", }} > - + )} - + Activity {info.mintStarted ? ( @@ -768,12 +781,15 @@ const AttributesCard: React.FC<{ height={62} mainContainerStyle={{ alignItems: "flex-start", - paddingHorizontal: 12, - paddingVertical: 14, + paddingHorizontal: layout.spacing_x1_5, + paddingVertical: layout.spacing_x1_75, }} > {label} @@ -815,7 +831,7 @@ const PresaleActivy: React.FC<{ Whitelist @@ -842,7 +861,7 @@ const PresaleActivy: React.FC<{ borderRadius: 999, width: 2, height: 2, - marginHorizontal: 12, + marginHorizontal: layout.spacing_x1_5, backgroundColor: neutral77, }} /> @@ -850,20 +869,29 @@ const PresaleActivy: React.FC<{ {maxPerAddress && maxPerAddress !== "0" ? ( <> Max {maxPerAddress} Token ) : ( Unlimited diff --git a/packages/utils/style/layout.ts b/packages/utils/style/layout.ts index 43ac47f75f..fcd3dde5f0 100644 --- a/packages/utils/style/layout.ts +++ b/packages/utils/style/layout.ts @@ -62,6 +62,10 @@ export const layout = Object.freeze({ get spacing_x1_5() { return this.base * 1.5; }, + // 14 + get spacing_x1_75() { + return this.base * 1.75; + }, // 16 get spacing_x2() { return this.base * 2; From b6b26a9f863db751047e56c987a95bcfc5155aa5 Mon Sep 17 00:00:00 2001 From: WaDadidou <50441633+WaDadidou@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:17:06 -0500 Subject: [PATCH 10/14] feat(launchpad): add form error messages (#1332) * feat: add form error messages * chore(launchpad): rollback form error message --- packages/utils/errors.ts | 5 +++++ packages/utils/formRules.ts | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/utils/errors.ts b/packages/utils/errors.ts index 7286d73a92..1996d18b6a 100644 --- a/packages/utils/errors.ts +++ b/packages/utils/errors.ts @@ -1,6 +1,11 @@ export const DEFAULT_FORM_ERRORS = { required: "This field is required", datetime: "Invalid", + onlyLetters: "Only letters are allowed", + onlyNumbers: "Only numbers are allowed", + onlyUrl: "Only URL is allowed", + onlyIpfsUri: "Only IPFS URI is allowed", + onlyEmail: "Only email address is allowed", }; export const DETAULT_PROCESS_ERROR = diff --git a/packages/utils/formRules.ts b/packages/utils/formRules.ts index f2b788a98e..0f457a873f 100644 --- a/packages/utils/formRules.ts +++ b/packages/utils/formRules.ts @@ -3,6 +3,8 @@ import { ValidationRule } from "react-hook-form"; import { LETTERS_REGEXP, NUMBERS_REGEXP } from "./regex"; +import { DEFAULT_FORM_ERRORS } from "@/utils/errors"; + // validator should return false or string to trigger error export const validateAddress = (value: string) => { try { @@ -16,12 +18,12 @@ export const validateAddress = (value: string) => { export const patternOnlyLetters: ValidationRule = { value: LETTERS_REGEXP, - message: "Only letters are allowed", + message: DEFAULT_FORM_ERRORS.onlyLetters, }; export const patternOnlyNumbers: ValidationRule = { value: NUMBERS_REGEXP, - message: "Only numbers are allowed", + message: DEFAULT_FORM_ERRORS.onlyNumbers, }; export const validateMaxNumber = (value: string, max: number) => { From a5e2cc6ce83f69e09421ec0ee3720d1214786299 Mon Sep 17 00:00:00 2001 From: WaDadidou <50441633+WaDadidou@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:17:13 -0500 Subject: [PATCH 11/14] feat: Make an svg color dynamic (#1331) --- assets/icons/info.svg | 6 +-- .../Swap/components/SwapView/SwapSettings.tsx | 43 +++++++++++-------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/assets/icons/info.svg b/assets/icons/info.svg index 157da7b8f5..49a4431253 100644 --- a/assets/icons/info.svg +++ b/assets/icons/info.svg @@ -1,5 +1,5 @@ - - - + + + diff --git a/packages/screens/Swap/components/SwapView/SwapSettings.tsx b/packages/screens/Swap/components/SwapView/SwapSettings.tsx index 74769d3c1b..c6bba344a4 100644 --- a/packages/screens/Swap/components/SwapView/SwapSettings.tsx +++ b/packages/screens/Swap/components/SwapView/SwapSettings.tsx @@ -8,15 +8,16 @@ import React, { } from "react"; import { Pressable, View } from "react-native"; -import infoSVG from "../../../../../assets/icons/info.svg"; import { FadeInView } from "../FadeInView"; +import infoSVG from "@/assets/icons/info.svg"; import { BrandText } from "@/components/BrandText"; import { SVG } from "@/components/SVG"; -import { LegacyTertiaryBox } from "@/components/boxes/LegacyTertiaryBox"; +import { Box } from "@/components/boxes/Box"; import { CustomPressable } from "@/components/buttons/CustomPressable"; import { TextInputCustom } from "@/components/inputs/TextInputCustom"; import { + neutral33, neutral77, neutralA3, primaryColor, @@ -131,13 +132,13 @@ export const SwapSettings: React.FC<{ if (settingsOpened) return ( - Transaction Settings @@ -161,17 +162,17 @@ export const SwapSettings: React.FC<{ onHoverIn={() => setInfoVisible(true)} onHoverOut={() => setInfoVisible(false)} > - + - {slippageItems.map((item, index) => ( - + {/*====== Info box */} {infoVisible && ( - Your transaction will revert if the price changes {"\n"} unfavorably by more than this percentage. - + )} - + ); return <>; From c3328516019f968c006cf6c2375510631e7a81b0 Mon Sep 17 00:00:00 2001 From: WaDadidou <50441633+WaDadidou@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:17:21 -0500 Subject: [PATCH 12/14] feat(launchpad): make a svg color dynamic (#1330) * feat: make an svg color synamic, remove unused svg * chore: simplify import * yarn lint-fix --- assets/icons/warning-triangle-orange.svg | 3 -- assets/icons/warning-triangle.svg | 8 ++-- .../screens/Stake/components/WarningBox.tsx | 38 ++++++++----------- 3 files changed, 19 insertions(+), 30 deletions(-) delete mode 100644 assets/icons/warning-triangle-orange.svg diff --git a/assets/icons/warning-triangle-orange.svg b/assets/icons/warning-triangle-orange.svg deleted file mode 100644 index d3fc2d7c81..0000000000 --- a/assets/icons/warning-triangle-orange.svg +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/assets/icons/warning-triangle.svg b/assets/icons/warning-triangle.svg index 7761721a99..9d2a2af883 100644 --- a/assets/icons/warning-triangle.svg +++ b/assets/icons/warning-triangle.svg @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/packages/screens/Stake/components/WarningBox.tsx b/packages/screens/Stake/components/WarningBox.tsx index 86272253b0..4626ed3adf 100644 --- a/packages/screens/Stake/components/WarningBox.tsx +++ b/packages/screens/Stake/components/WarningBox.tsx @@ -1,8 +1,7 @@ import React from "react"; -import { StyleSheet, View, useWindowDimensions } from "react-native"; - -import warningTriangleSVG from "../../../../assets/icons/warning-triangle.svg"; +import { View, useWindowDimensions } from "react-native"; +import warningTriangleSVG from "@/assets/icons/warning-triangle.svg"; import { BrandText } from "@/components/BrandText"; import { SVG } from "@/components/SVG"; import { SpacerColumn, SpacerRow } from "@/components/spacer"; @@ -17,11 +16,22 @@ export const WarningBox: React.FC<{ const { width: windowWidth } = useWindowDimensions(); const maxWidth = windowWidth - 20 >= 490 ? 350 : 300; return ( - + @@ -30,28 +40,10 @@ export const WarningBox: React.FC<{ {title} - + {description} ); }; - -// FIXME: remove StyleSheet.create -// eslint-disable-next-line no-restricted-syntax -const styles = StyleSheet.create({ - stakeWarningContainer: { - flexDirection: "row", - alignItems: "center", - borderWidth: 1, - borderColor: errorColor, - borderRadius: layout.borderRadius * 0.65, - paddingVertical: layout.spacing_x1_5, - paddingHorizontal: layout.spacing_x3, - }, - alternateText: { - ...StyleSheet.flatten(fontSemibold12), - color: neutral77, - }, -}); From 1dbef317e86bfb8fd91f60265ae86a0a2a4e032f Mon Sep 17 00:00:00 2001 From: WaDadidou <50441633+WaDadidou@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:17:57 -0500 Subject: [PATCH 13/14] chore(launchpad): move banner (#1329) * chore: move LaunchpadBanner.tsx * fix: LaunchpadBanner import * fix(launchpad): imports paths --- .../Launchpad/LaunchpadApply/LaunchpadApplyScreen.tsx | 2 +- .../LaunchpadCreate}/components/LaunchpadBanner.tsx | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) rename packages/screens/Launchpad/{ => LaunchpadApply/LaunchpadCreate}/components/LaunchpadBanner.tsx (89%) diff --git a/packages/screens/Launchpad/LaunchpadApply/LaunchpadApplyScreen.tsx b/packages/screens/Launchpad/LaunchpadApply/LaunchpadApplyScreen.tsx index 2df6c998b0..3236178dae 100644 --- a/packages/screens/Launchpad/LaunchpadApply/LaunchpadApplyScreen.tsx +++ b/packages/screens/Launchpad/LaunchpadApply/LaunchpadApplyScreen.tsx @@ -1,7 +1,7 @@ import React from "react"; import { StyleSheet, View } from "react-native"; -import { LaunchpadBanner } from "../components/LaunchpadBanner"; +import { LaunchpadBanner } from "./LaunchpadCreate/components/LaunchpadBanner"; import { BrandText } from "@/components/BrandText"; import { ScreenContainer } from "@/components/ScreenContainer"; diff --git a/packages/screens/Launchpad/components/LaunchpadBanner.tsx b/packages/screens/Launchpad/LaunchpadApply/LaunchpadCreate/components/LaunchpadBanner.tsx similarity index 89% rename from packages/screens/Launchpad/components/LaunchpadBanner.tsx rename to packages/screens/Launchpad/LaunchpadApply/LaunchpadCreate/components/LaunchpadBanner.tsx index c6beedf612..2dbb2263ac 100644 --- a/packages/screens/Launchpad/components/LaunchpadBanner.tsx +++ b/packages/screens/Launchpad/LaunchpadApply/LaunchpadCreate/components/LaunchpadBanner.tsx @@ -1,9 +1,8 @@ import React from "react"; import { Image, View } from "react-native"; -import LaunchpadBannerImage from "../../../../assets/banners/launchpad.jpg"; -import LogoSimpleSvg from "../../../../assets/icons/logo-simple.svg"; - +import LaunchpadBannerImage from "@/assets/banners/launchpad.jpg"; +import LogoSimpleSvg from "@/assets/icons/logo-simple.svg"; import { BrandText } from "@/components/BrandText"; import { SVG } from "@/components/SVG"; import { SpacerColumn } from "@/components/spacer"; From 14ff1ee1b22c77d166d6d1495ba7b98f9be9d547 Mon Sep 17 00:00:00 2001 From: WaDadidou <50441633+WaDadidou@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:07:09 -0500 Subject: [PATCH 14/14] feat(launchpad): add pluralize lib (#1334) * feat: enhance pluralOrNot function * chore: use library to handle plural strings --- package.json | 2 ++ .../FileUploaderSmall/FileUploaderSmall.web.tsx | 5 ++--- .../FeedNewArticle/FeedNewArticleScreen.tsx | 4 ++-- packages/utils/text.tsx | 3 --- yarn.lock | 16 ++++++++++++++++ 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 05078338ab..73a2363631 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "@types/leaflet": "^1.9.12", "@types/leaflet.markercluster": "^1.5.4", "@types/papaparse": "^5.3.14", + "@types/pluralize": "^0.0.33", "assert": "^2.1.0", "axios": "^1.6.2", "bech32": "^2.0.0", @@ -126,6 +127,7 @@ "osmojs": "16.9.0", "papaparse": "^5.4.1", "plausible-tracker": "^0.3.8", + "pluralize": "^8.0.0", "protobufjs": "^7.2.5", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/packages/components/inputs/FileUploaderSmall/FileUploaderSmall.web.tsx b/packages/components/inputs/FileUploaderSmall/FileUploaderSmall.web.tsx index 6cda44ab67..29288413be 100644 --- a/packages/components/inputs/FileUploaderSmall/FileUploaderSmall.web.tsx +++ b/packages/components/inputs/FileUploaderSmall/FileUploaderSmall.web.tsx @@ -1,3 +1,4 @@ +import pluralize from "pluralize"; import React, { forwardRef, SyntheticEvent, @@ -27,7 +28,6 @@ import { DeleteButton } from "@/components/FilePreview/DeleteButton"; import { OptimizedImage } from "@/components/OptimizedImage"; import { CustomPressable } from "@/components/buttons/CustomPressable"; import { SpacerRow } from "@/components/spacer"; -import { pluralOrNot } from "@/utils/text"; import { LocalFileData } from "@/utils/types/files"; export const FileUploaderSmall = forwardRef< @@ -193,8 +193,7 @@ export const FileUploaderSmall = forwardRef< : !multiple && !filesCount ? "Select file" : multiple && filesCount - ? filesCount + - ` ${pluralOrNot("file", filesCount)} selected` + ? `${pluralize("file", filesCount, true)} selected` : multiple && !filesCount ? "Select files" : ""} diff --git a/packages/screens/FeedNewArticle/FeedNewArticleScreen.tsx b/packages/screens/FeedNewArticle/FeedNewArticleScreen.tsx index c7e5e8dc04..2b82e3faa4 100644 --- a/packages/screens/FeedNewArticle/FeedNewArticleScreen.tsx +++ b/packages/screens/FeedNewArticle/FeedNewArticleScreen.tsx @@ -1,3 +1,4 @@ +import pluralize from "pluralize"; import React, { useEffect, useRef, useState } from "react"; import { Controller, useForm } from "react-hook-form"; import { ScrollView, View } from "react-native"; @@ -45,7 +46,6 @@ import { } from "@/utils/style/colors"; import { fontSemibold13, fontSemibold20 } from "@/utils/style/fonts"; import { layout, screenContentMaxWidth } from "@/utils/style/layout"; -import { pluralOrNot } from "@/utils/text"; import { CustomLatLngExpression, NewArticleFormValues, @@ -291,7 +291,7 @@ export const FeedNewArticleScreen: ScreenFC<"FeedNewArticle"> = () => { ]} > {freePostCount - ? `You have ${freePostCount} free ${pluralOrNot( + ? `You have ${freePostCount} free ${pluralize( "Article", freePostCount, )} left` diff --git a/packages/utils/text.tsx b/packages/utils/text.tsx index 8b9ceaaf63..2ecc03bcee 100644 --- a/packages/utils/text.tsx +++ b/packages/utils/text.tsx @@ -32,6 +32,3 @@ export const replaceBetweenString = ( insertion: string, ) => `${origin.substring(0, startIndex)}${insertion}${origin.substring(endIndex)}`; - -export const pluralOrNot = (word: string, quantity: number) => - quantity > 1 ? word + "s" : word; diff --git a/yarn.lock b/yarn.lock index 7b057ed53d..764cde2450 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6878,6 +6878,13 @@ __metadata: languageName: node linkType: hard +"@types/pluralize@npm:^0.0.33": + version: 0.0.33 + resolution: "@types/pluralize@npm:0.0.33" + checksum: 282d42dc0187e5e0912f9f36ee0f5615bfd273a08d40afe5bf5881cb28daf1977abe10564543032aa0f42352ebba739ff3d86bf5562ac4691c6d1761fcc7cf39 + languageName: node + linkType: hard + "@types/prettier@npm:^2.6.1": version: 2.7.3 resolution: "@types/prettier@npm:2.7.3" @@ -17023,6 +17030,13 @@ __metadata: languageName: node linkType: hard +"pluralize@npm:^8.0.0": + version: 8.0.0 + resolution: "pluralize@npm:8.0.0" + checksum: 08931d4a6a4a5561a7f94f67a31c17e6632cb21e459ab3ff4f6f629d9a822984cf8afef2311d2005fbea5d7ef26016ebb090db008e2d8bce39d0a9a9d218736e + languageName: node + linkType: hard + "pngjs@npm:^3.3.0": version: 3.4.0 resolution: "pngjs@npm:3.4.0" @@ -20213,6 +20227,7 @@ __metadata: "@types/markdown-it": ^13.0.7 "@types/node": ^20.9.1 "@types/papaparse": ^5.3.14 + "@types/pluralize": ^0.0.33 "@types/react": ~18.2.45 "@types/react-native-countdown-component": ^2.7.0 "@types/uuid": ^9.0.0 @@ -20279,6 +20294,7 @@ __metadata: papaparse: ^5.4.1 patch-package: ^7.0.2 plausible-tracker: ^0.3.8 + pluralize: ^8.0.0 postinstall-postinstall: ^2.1.0 prettier: ^3.0.3 protobufjs: ^7.2.5