Skip to content

Commit

Permalink
fix: dao creation (#755)
Browse files Browse the repository at this point in the history
Signed-off-by: Norman Meier <[email protected]>
  • Loading branch information
n0izn0iz authored Nov 17, 2023
1 parent e8f0b84 commit 3814aa7
Show file tree
Hide file tree
Showing 21 changed files with 495 additions and 140 deletions.
2 changes: 1 addition & 1 deletion networks.json
Original file line number Diff line number Diff line change
Expand Up @@ -9167,7 +9167,7 @@
"socialFeedContractAddress": "tori1umsk53n6rf5j2lam80zuz50sz9sdw2vdpr0vvd2xaaryprfa7ryslyvm69",
"daoCw20CodeId": 99,
"daoFactoryCodeId": 100,
"daoCoreCodeId": 101,
"daoCoreCodeId": 176,
"daoPreProposeSingleCodeId": 102,
"daoProposalSingleCodeId": 103,
"daoVotingCw20StakedCodeId": 104,
Expand Down
3 changes: 2 additions & 1 deletion packages/components/inputs/TextInputCustom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ export const TextInputCustom = <T extends FieldValues>({
</View>

{isLoading ? (
<ActivityIndicator color={secondaryColor} />
<ActivityIndicator color={secondaryColor} size="small" />
) : (
<>{children}</>
)}
Expand All @@ -312,6 +312,7 @@ const styles = StyleSheet.create({
alignItems: "flex-start",
paddingHorizontal: 12,
paddingVertical: 10,
minHeight: 50,
backgroundColor: neutral22,
},
noCropBorderBg: {
Expand Down
8 changes: 5 additions & 3 deletions packages/hooks/cosmwasm/useCosmWasmContractInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ export const useIsDAO = (userId: string | undefined) => {
return { isDAO: true };
}
return {
isDAO: ["crates.io:dao-core", "crates.io:cw-core"].includes(
contractVersion?.contract || "",
),
isDAO: [
"crates.io:dao-core",
"crates.io:cw-core",
"crates.io:dao-dao-core",
].includes(contractVersion?.contract || ""),
};
};
2 changes: 1 addition & 1 deletion packages/hooks/useCoingeckoPrices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const useCoingeckoPrices = (coins: CoingeckoCoin[]) => {
},
{
initialData: {},
refetchInterval: 20000,
refetchInterval: 60000,
staleTime: Infinity,
initialDataUpdatedAt: 0,
},
Expand Down
125 changes: 125 additions & 0 deletions packages/hooks/useNSAvailability.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Decimal } from "@cosmjs/math";

import { useCoingeckoPrices } from "./useCoingeckoPrices";
import { useNSMintAvailability } from "./useNSMintAvailability";
import { useNSMintPrice } from "./useNSMintPrice";
import { useVaultNFTInfo } from "./useVaultNFTInfo";
import { getCosmosNetwork, getNativeCurrency, getNftId } from "../networks";
import { CoingeckoCoin } from "../utils/coingecko";
import { prettyPrice } from "../utils/coins";

export type NSAvailability =
| {
availability: "loading";
}
| {
availability: "invalid";
}
| {
availability: "mint" | "market";
price: {
denom: string;
amount: string;
};
usdPrice?: number;
prettyPrice: string;
}
| {
availability: "none";
};

// TODO: support gno

export const useNSAvailability = (
networkId: string | undefined,
name: string,
): NSAvailability => {
const cosmosNetwork = getCosmosNetwork(networkId);
const tokenId = name + cosmosNetwork?.nameServiceTLD;
const { nsMintPrice, isLoading: isLoadingNSMintPrice } = useNSMintPrice(
networkId,
tokenId,
);
const { nameAvailable, loading: isLoadingNameAvailability } =
useNSMintAvailability(networkId, tokenId);
const { vaultNFTInfo, isLoading: isLoadingVaultNFTInfo } = useVaultNFTInfo(
getNftId(networkId, cosmosNetwork?.nameServiceContractAddress, tokenId),
);
const requestedPrices: CoingeckoCoin[] = [];
if (nsMintPrice) {
requestedPrices.push({ networkId, denom: nsMintPrice.denom });
}
if (vaultNFTInfo) {
requestedPrices.push({ networkId, denom: vaultNFTInfo.denom });
}
const { prices } = useCoingeckoPrices(requestedPrices);

// TODO: handle already owned case

if (
isLoadingNSMintPrice ||
isLoadingNameAvailability ||
isLoadingVaultNFTInfo
) {
return {
availability: "loading",
};
}

if (nsMintPrice?.invalid) {
return {
availability: "invalid",
};
}

if (nameAvailable && nsMintPrice) {
const currency = getNativeCurrency(networkId, nsMintPrice.denom);
const currencyUSDPrice = prices[currency?.coingeckoId || ""]?.usd;
const usdPrice = currencyUSDPrice
? currencyUSDPrice *
Decimal.fromAtomics(
nsMintPrice.amount,
currency?.decimals || 0,
).toFloatApproximation()
: undefined;
return {
availability: "mint",
price: nsMintPrice,
prettyPrice: prettyPrice(
cosmosNetwork?.id,
nsMintPrice.amount,
nsMintPrice.denom,
),
usdPrice,
};
}

if (vaultNFTInfo) {
const currency = getNativeCurrency(networkId, vaultNFTInfo.denom);
const currencyUSDPrice = prices[currency?.coingeckoId || ""]?.usd;
const usdPrice = currencyUSDPrice
? currencyUSDPrice *
Decimal.fromAtomics(
vaultNFTInfo.amount,
getNativeCurrency(networkId, vaultNFTInfo.denom)?.decimals || 0,
).toFloatApproximation()
: undefined;
return {
availability: "market",
price: {
denom: vaultNFTInfo.denom,
amount: vaultNFTInfo.amount,
},
prettyPrice: prettyPrice(
cosmosNetwork?.id,
vaultNFTInfo.amount,
vaultNFTInfo.denom,
),
usdPrice,
};
}

return {
availability: "none",
};
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useNSNameInfo } from "./useNSNameInfo";

export const useNSNameAvailability = (
export const useNSMintAvailability = (
networkId: string | undefined,
tokenId: string | undefined,
) => {
Expand Down
28 changes: 23 additions & 5 deletions packages/hooks/useNSMintPrice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,17 @@ export const useNSMintPrice = (
networkId: string | undefined,
tokenId: string,
) => {
const { data } = useQuery(
const { data, ...other } = useQuery(
["nsMintPrice", networkId, tokenId],
async () => {
if (tokenId !== tokenId.toLowerCase()) {
return {
denom: "unknown",
amount: "0",
invalid: true,
};
}

if (!networkId) {
return null;
}
Expand All @@ -29,12 +37,22 @@ export const useNSMintPrice = (

const info = await tnsClient.contractInfo();

const amount = await tnsClient.mintPrice({ tokenId });

return { denom: info.native_denom, amount: amount?.toString() || "0" };
try {
const amount = await tnsClient.mintPrice({ tokenId });
return {
denom: info.native_denom,
amount: amount?.toString() || "0",
invalid: false,
};
} catch (e) {
if (e instanceof Error && e.message.includes("Token Name Invalid")) {
return { denom: info.native_denom, amount: "0", invalid: true };
}
throw e;
}
},
{ staleTime: Infinity },
);

return data;
return { nsMintPrice: data, ...other };
};
44 changes: 44 additions & 0 deletions packages/hooks/useVaultNFTInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useQuery } from "@tanstack/react-query";

import { TeritoriNftVaultQueryClient } from "../contracts-clients/teritori-nft-vault/TeritoriNftVault.client";
import {
getCosmosNetwork,
mustGetNonSigningCosmWasmClient,
parseNftId,
} from "../networks";

export const useVaultNFTInfo = (nftId: string | undefined) => {
const { data, ...other } = useQuery(
["vaultNFTInfo", nftId],
async () => {
console.log("getting nft info of ", nftId);

const [nftNetwork, nftContractAddress, tokenId] = parseNftId(nftId);
if (!nftNetwork || !nftContractAddress || !tokenId) {
return null;
}

console.log("parsed nft info", nftNetwork, nftContractAddress, tokenId);

const network = getCosmosNetwork(nftNetwork.id);
if (!network?.vaultContractAddress) {
return null;
}

console.log("network nft info", network);

const client = await mustGetNonSigningCosmWasmClient(network.id);
const vaultClient = new TeritoriNftVaultQueryClient(
client,
network?.vaultContractAddress,
);
return await vaultClient.nftInfo({
nftContractAddr: nftContractAddress,
nftTokenId: tokenId,
});
},
{ staleTime: Infinity },
);

return { vaultNFTInfo: data, ...other };
};
15 changes: 15 additions & 0 deletions packages/networks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,21 @@ export const getNetworkObjectId = (
return `${network?.idPrefix}-${subId}`;
};

export const getNftId = (
networkId: string | null | undefined,
nftContractAddress: string | null | undefined,
tokenId: string | null | undefined,
) => {
if (!networkId || !nftContractAddress || !tokenId) {
return "";
}
const network = getNetwork(networkId);
if (!network) {
return "";
}
return `${network.idPrefix}-${nftContractAddress}-${tokenId}`;
};

export const getUserId = (
networkId: string | null | undefined,
address: string | null | undefined,
Expand Down
2 changes: 1 addition & 1 deletion packages/networks/teritori-testnet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const teritoriTestnetNetwork: NetworkInfo = {
"tori1umsk53n6rf5j2lam80zuz50sz9sdw2vdpr0vvd2xaaryprfa7ryslyvm69",
daoCw20CodeId: 99,
daoFactoryCodeId: 100,
daoCoreCodeId: 101,
daoCoreCodeId: 176,
daoPreProposeSingleCodeId: 102,
daoProposalSingleCodeId: 103,
daoVotingCw20StakedCodeId: 104,
Expand Down
28 changes: 25 additions & 3 deletions packages/screens/Organizations/OrganizationDeployerScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useQueryClient } from "@tanstack/react-query";
import React, { useState } from "react";
import { StyleSheet, View } from "react-native";

Expand All @@ -19,6 +20,7 @@ import {
import { BrandText } from "../../components/BrandText";
import { ScreenContainer } from "../../components/ScreenContainer";
import { useFeedbacks } from "../../context/FeedbacksProvider";
import { nsNameInfoQueryKey } from "../../hooks/useNSNameInfo";
import useSelectedWallet from "../../hooks/useSelectedWallet";
import {
NetworkKind,
Expand Down Expand Up @@ -55,6 +57,7 @@ export const OrganizationDeployerScreen = () => {
useState<TokenSettingFormType>();
const [step3MemberSettingFormData, setStep3MemberSettingFormData] =
useState<MemberSettingFormType>();
const queryClient = useQueryClient();
const [launchingStep, setLaunchingStep] = useState(0);
const getPercent = (num: number | undefined): string => {
let ret_num = 0;
Expand All @@ -80,7 +83,7 @@ export const OrganizationDeployerScreen = () => {
try {
switch (network?.kind) {
case NetworkKind.Gno: {
const name = step1DaoInfoFormData?.associatedTeritoriNameService!;
const name = step1DaoInfoFormData?.associatedHandle!;
const pkgPath = await adenaDeployGnoDAO(
network.id,
selectedWallet?.address!,
Expand Down Expand Up @@ -140,7 +143,7 @@ export const OrganizationDeployerScreen = () => {
daoCoreCodeId: network.daoCoreCodeId!,
name: step1DaoInfoFormData.organizationName,
description: step1DaoInfoFormData.organizationDescription,
tns: step1DaoInfoFormData.associatedTeritoriNameService,
tns: step1DaoInfoFormData.associatedHandle,
imageUrl: step1DaoInfoFormData.imageUrl,
tokenName: step3TokenSettingFormData.tokenName,
tokenSymbol: step3TokenSettingFormData.tokenSymbol,
Expand Down Expand Up @@ -175,7 +178,7 @@ export const OrganizationDeployerScreen = () => {
daoVotingCw4CodeId: network.daoVotingCw4CodeId!,
name: step1DaoInfoFormData.organizationName,
description: step1DaoInfoFormData.organizationDescription,
tns: step1DaoInfoFormData.associatedTeritoriNameService,
tns: step1DaoInfoFormData.associatedHandle,
imageUrl: step1DaoInfoFormData.imageUrl,
members: step3MemberSettingFormData.members.map((value) => ({
addr: value.addr,
Expand Down Expand Up @@ -311,6 +314,25 @@ export const OrganizationDeployerScreen = () => {
<LaunchingOrganizationSection
id={getUserId(selectedWallet?.networkId, daoAddress)}
isLaunched={launchingStep === LAUNCHING_PROCESS_STEPS.length}
resetForm={async () => {
let tokenId = step1DaoInfoFormData?.associatedHandle;
const network = getNetwork(selectedWallet?.networkId);
if (network?.kind === NetworkKind.Gno) {
tokenId += ".gno";
} else if (network?.kind === NetworkKind.Cosmos) {
tokenId += network.nameServiceTLD || "";
}
await queryClient.invalidateQueries(
nsNameInfoQueryKey(selectedWallet?.networkId, tokenId),
);
setStep1DaoInfoFormData(undefined);
setStep2ConfigureVotingFormData(undefined);
setStep3MemberSettingFormData(undefined);
setStep3TokenSettingFormData(undefined);
setCurrentStep(0);
setDAOAddress("");
setLaunchingStep(0);
}}
/>
</View>
</View>
Expand Down
Loading

0 comments on commit 3814aa7

Please sign in to comment.