import { CyberClient } from '@cybercongress/cyber-js';
import { OfflineSigner } from '@cybercongress/cyber-js/build/signingcyberclient';
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
import { useEffect } from 'react';
import { useQueryClient } from 'src/contexts/queryClient';
import { getPassport } from 'src/services/passports/lcd';
import { Nullable } from 'src/types';
import { Citizenship } from 'src/types/citizenship';
import { AccountValue } from 'src/types/defaultAccount';
import { isLedgerSigner } from 'src/utils/ledgerSigner';

const AMOUNT_ALL_STAGE = 90;
const NEW_RELEASE = 1000; // release 1% every 1k claims
const CONSTITUTION_HASH = 'QmcHB9GKHAKCLQhmSj71qNJhENJJg8Gymd1PvvsCQBhG7M';

// test root
// const CONTRACT_ADDRESS_GIFT =
//   'bostrom1dwzfa74hzpt6393czajlldnxjup8zk3xh3skegnm67yzqx33k2cssyduk8';
// const CONTRACT_ADDRESS_PASSPORT =
//   'bostrom1fzm6gzyccl8jvdv3qq6hp9vs6ylaruervs4m06c7k0ntzn2f8faq7ha2z2';

// prod root
const CONTRACT_ADDRESS_GIFT = 'bostrom16t6tucgcqdmegye6c9ltlkr237z8yfndmasrhvh7ucrfuqaev6xq7cpvek';
const CONTRACT_ADDRESS_PASSPORT =
  'bostrom1xut80d09q0tgtch8p0z4k5f88d3uvt8cvtzm5h3tu3tsy4jk9xlsfzhxel';

const DICTIONARY = {
  Astronauts: 'Astronaut',
  'Average Citizens. ETH Analysis': 'Average Citizens',
  'Cyberpunks. ERC20 and ERC721 Analysis': 'Cyberpunk',
  'Extraordinary Hackers. Gas Analysis': 'Extraordinary Hacker',
  'Key Opinion Leaders. ERC20 Analysis': 'Key Opinion Leader',
  'Masters of the Great Web. Gas and ERC721 Analysis': 'Master of the Great Web',
  'Passionate Investors. ERC20 Analysis': 'Passionate Investor',
  'Heroes of the Great Web. Genesis and ETH2 Stakers': 'True Hero of the Great Web',
  Leeches: 'Devil',
};

const GIFT_ICON = '๐ŸŽ';
const BOOT_ICON = '๐ŸŸข';

const useGetActivePassport = (addressActive: Nullable<AccountValue>, updateFunc?: number) => {
  const queryClient = useQueryClient();
  const data = useQuery(
    ['active_passport', addressActive?.bech32],
    () => activePassport(queryClient, addressActive?.bech32),
    {
      enabled: Boolean(addressActive) && Boolean(queryClient),
    }
  );

  useEffect(() => {
    if (updateFunc) {
      data.refetch();
    }
  }, [updateFunc, data.refetch]);

  return {
    citizenship: data.data,
    loading: data.isFetching,
  };
};

// TODO: replace with hook
const activePassport = async (
  client: CyberClient,
  address: string
): Promise<Nullable<Citizenship>> => {
  try {
    const query = {
      active_passport: {
        address,
      },
    };
    const response = await client.queryContractSmart(CONTRACT_ADDRESS_PASSPORT, query);
    return response;
  } catch (error) {
    console.log('error', error);
    return null;
  }
};

const parseValue = (data) => {
  if (data.length > 0) {
    const newData = data.replace(/'/g, '"');
    return JSON.parse(newData);
  }
  return null;
};

const parseValueDetails = (data) => {
  const value = parseValue(data);
  if (value !== null) {
    const details = {};
    value.forEach((item) => {
      details[DICTIONARY[item.audience]] = { gift: item.gift };
    });
    return details;
  }
  return null;
};

const parseResponse = (obj) => {
  return {
    ...obj,
    details: parseValueDetails(obj.details),
    proof: parseValue(obj.proof),
  };
};

const checkGift = async (address) => {
  try {
    const response = await axios({
      method: 'GET',
      url: `https://titan.cybernode.ai/graphql/api/rest/get-cybergift/${address}`, // prod root
      // url: `https://titan.cybernode.ai/graphql/api/rest/get-test-gift/${address}`, // test root
    });

    if (response?.data) {
      const { data } = response;
      if (
        Object.hasOwn(data, 'cyber_gift_proofs') &&
        Object.keys(data.cyber_gift_proofs).length > 0
      ) {
        const { cyber_gift_proofs: cyberGiftData } = data;
        return parseResponse(cyberGiftData[0]);
      }
      if (Object.hasOwn(data, 'test_gift') && Object.keys(data.test_gift).length > 0) {
        const { test_gift: cyberGiftData } = data;
        return parseResponse(cyberGiftData[0]);
      }
    }
    return null;
  } catch (_error) {
    return null;
  }
};

const queryContractSmartPassport = async (_client, query) => {
  try {
    const response = await getPassport(query);
    // const response = await client.queryContractSmart(
    //   CONTRACT_ADDRESS_PASSPORT,
    //   query
    // );
    return response;
  } catch (error) {
    console.log('error', error);
    return null;
  }
};

const queryContractSmartGift = async (client, query) => {
  try {
    const response = await client.queryContractSmart(CONTRACT_ADDRESS_GIFT, query);
    return response;
  } catch (error) {
    console.log('error', error);
    return null;
  }
};

const getStateGift = async (client) => {
  try {
    const query = {
      state: {},
    };
    const response = await queryContractSmartGift(client, query);
    return response;
  } catch (error) {
    console.log('error', error);
    return null;
  }
};

const getConfigGift = async (client) => {
  try {
    const query = {
      config: {},
    };
    const response = await queryContractSmartGift(client, query);
    return response;
  } catch (error) {
    console.log('error', error);
    return null;
  }
};

const getReleaseState = async (client, address) => {
  try {
    const query = {
      release_state: {
        address,
      },
    };
    const response = await queryContractSmartGift(client, query);
    return response;
  } catch (error) {
    console.log('error', error);
    return null;
  }
};

const getClaimedAmount = async (client, address) => {
  try {
    const query = {
      claim: {
        address,
      },
    };
    const response = await queryContractSmartGift(client, query);
    return response;
  } catch (error) {
    console.log('error', error);
    return null;
  }
};

const getIsClaimed = async (client, address) => {
  try {
    const query = {
      is_claimed: {
        address,
      },
    };
    const response = await queryContractSmartGift(client, query);
    return response;
  } catch (error) {
    console.log('error', error);
    return null;
  }
};

const getPassportByNickname = async (client, nickname) => {
  try {
    const query = {
      passport_by_nickname: {
        nickname,
      },
    };
    const response = await queryContractSmartPassport(client, query);
    return response;
  } catch (error) {
    console.log('error', error);
    return null;
  }
};

const getNumTokens = async (client) => {
  try {
    const query = {
      num_tokens: {},
    };
    const response = await queryContractSmartPassport(client, query);
    return response;
  } catch (error) {
    console.log('error', error);
    return null;
  }
};

const tooMuthAddressError =
  'failed to execute message; message index: 0: Address is not eligible to claim airdrop, Too many addresses: execute wasm contract failed';

const canProve8AddressNewError = 'You can prove only 8 addresses for one passport';

const parseRowLog = (rawlog) => {
  if (rawlog === tooMuthAddressError) {
    return canProve8AddressNewError;
  }

  return rawlog;
};

type SignerKeyInfo = {
  bech32Address: string;
  isNanoLedger: boolean;
  pubKey: Uint8Array;
  name: string;
};

/**
 * Get key info from signer โ€” works for wallet (mnemonic) and Ledger signers.
 */
async function getSignerKeyInfo(
  signer: OfflineSigner,
  _chainId: string
): Promise<SignerKeyInfo> {
  const [account] = await signer.getAccounts();
  const isLedger = isLedgerSigner(signer);

  return {
    bech32Address: account.address,
    isNanoLedger: isLedger,
    pubKey: account.pubkey,
    name: isLedger ? 'Ledger' : 'Wallet',
  };
}

export {
  activePassport,
  getSignerKeyInfo,
  CONTRACT_ADDRESS_PASSPORT,
  useGetActivePassport,
  CONSTITUTION_HASH,
  CONTRACT_ADDRESS_GIFT,
  GIFT_ICON,
  BOOT_ICON,
  AMOUNT_ALL_STAGE,
  NEW_RELEASE,
  checkGift,
  getConfigGift,
  getStateGift,
  getReleaseState,
  getClaimedAmount,
  getIsClaimed,
  getPassportByNickname,
  parseRowLog,
  getNumTokens,
};

Synonyms

soft3.js/examples/utils.ts
cyb/src/utils/utils.ts
pussy-ts/src/utils/utils.ts
bostrom.network/src/lib/utils.ts
pussy-ts/src/services/ibc-history/utils.ts
cyb/src/services/CozoDb/utils.ts
cyb/src/features/ibc-history/utils.ts
cyb/src/containers/mint/utils.ts
pussy-ts/src/containers/portal/utils.ts
cyb/src/utils/search/utils.ts
pussy-ts/src/services/CozoDb/utils.ts
pussy-ts/src/utils/search/utils.ts
cyb/src/containers/warp/utils.ts
cyb/src/components/time/utils.ts
pussy-ts/src/containers/warp/utils.ts
cyb/src/pages/teleport/swap/utils.ts
pussy-ts/src/pages/teleport/swap/utils.ts
cyb/src/features/studio/utils/utils.ts
cyb/src/containers/sigma/hooks/utils.ts
cyb/src/pages/robot/Brain/utils.ts
cyb/src/services/backend/services/sync/utils.ts
pussy-ts/src/services/backend/services/sync/utils.ts
cyb/src/pages/teleport/components/Inputs/utils.ts
pussy-ts/src/services/backend/services/indexer/utils.ts
pussy-ts/src/services/backend/services/lcd/utils.ts
pussy-ts/src/pages/teleport/components/Inputs/utils.ts
cyb/src/features/studio/components/Editor/utils/utils.ts
cyb/src/pages/robot/_refactor/account/tabs/feeds/utils.ts

Neighbours