diff --git a/.env.sample b/.env.sample index 34aa4b73..f5e2a704 100644 --- a/.env.sample +++ b/.env.sample @@ -12,3 +12,8 @@ NEXT_PUBLIC_OG_NFT_CONTRACT=0x3cb654f2f557a7f71a0c16d97c05a2dec62a0b744979d11afc CRON_SECRET= + +# mainnet or sepolia +# Note: Not everything is supported on sepolia +# Default: mainnet +NEXT_PUBLIC_NETWORK=mainnet \ No newline at end of file diff --git a/next.config.mjs b/next.config.mjs index 9b833cdc..ce4ebb7a 100755 --- a/next.config.mjs +++ b/next.config.mjs @@ -2,9 +2,9 @@ const nextConfig = { // output: 'export', compiler: { - // removeConsole: { - // exclude: ['error', 'debug'], - // }, + removeConsole: { + exclude: ['error'], + }, }, async rewrites() { return [ diff --git a/public/banners/endur.svg b/public/banners/endur.svg new file mode 100644 index 00000000..6df51de7 --- /dev/null +++ b/public/banners/endur.svg @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/banners/endur_mobile.svg b/public/banners/endur_mobile.svg new file mode 100644 index 00000000..770a4ce5 --- /dev/null +++ b/public/banners/endur_mobile.svg @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/abi/master.abi.json b/src/abi/master.abi.json index 051ee7c4..4b405f92 100755 --- a/src/abi/master.abi.json +++ b/src/abi/master.abi.json @@ -1,12 +1,12 @@ [ { - "name": "ExternalImpl", "type": "impl", + "name": "ExternalImpl", "interface_name": "strkfarm::strats::master::IMaster" }, { - "name": "core::integer::u256", "type": "struct", + "name": "core::integer::u256", "members": [ { "name": "low", @@ -19,12 +19,85 @@ ] }, { - "name": "strkfarm::strats::master::IMaster", + "type": "struct", + "name": "strkfarm::strats::master::Settings", + "members": [ + { + "name": "nimbora_referral", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { "type": "interface", + "name": "strkfarm::strats::master::IMaster", "items": [ { + "type": "function", "name": "invest_auto_strk", + "inputs": [ + { + "name": "strategy", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "amount", + "type": "core::integer::u256" + }, + { + "name": "receiver", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "external" + }, + { "type": "function", + "name": "deposit_nimbora", + "inputs": [ + { + "name": "nimbora_strategy_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "harvest_invest_strategy", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "token_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "assets", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_settings", + "inputs": [], + "outputs": [ + { + "type": "strkfarm::strats::master::Settings" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "invest_to_xstrk_auto", "inputs": [ { "name": "strategy", @@ -47,8 +120,8 @@ "state_mutability": "external" }, { - "name": "upgrade", "type": "function", + "name": "upgrade", "inputs": [ { "name": "class_hash", @@ -61,17 +134,17 @@ ] }, { - "name": "OwnableTwoStepImpl", "type": "impl", - "interface_name": "openzeppelin::access::ownable::interface::IOwnableTwoStep" + "name": "OwnableTwoStepImpl", + "interface_name": "openzeppelin_access::ownable::interface::IOwnableTwoStep" }, { - "name": "openzeppelin::access::ownable::interface::IOwnableTwoStep", "type": "interface", + "name": "openzeppelin_access::ownable::interface::IOwnableTwoStep", "items": [ { - "name": "owner", "type": "function", + "name": "owner", "inputs": [], "outputs": [ { @@ -81,8 +154,8 @@ "state_mutability": "view" }, { - "name": "pending_owner", "type": "function", + "name": "pending_owner", "inputs": [], "outputs": [ { @@ -92,15 +165,15 @@ "state_mutability": "view" }, { - "name": "accept_ownership", "type": "function", + "name": "accept_ownership", "inputs": [], "outputs": [], "state_mutability": "external" }, { - "name": "transfer_ownership", "type": "function", + "name": "transfer_ownership", "inputs": [ { "name": "new_owner", @@ -111,8 +184,8 @@ "state_mutability": "external" }, { - "name": "renounce_ownership", "type": "function", + "name": "renounce_ownership", "inputs": [], "outputs": [], "state_mutability": "external" @@ -120,115 +193,157 @@ ] }, { - "name": "constructor", + "type": "struct", + "name": "strkfarm::interfaces::zkLend::IZkLendMarketDispatcher", + "members": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "struct", + "name": "strkfarm::interfaces::oracle::IPriceOracleDispatcher", + "members": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "struct", + "name": "strkfarm::components::zkLend::zkLendStruct", + "members": [ + { + "name": "zkLendRouter", + "type": "strkfarm::interfaces::zkLend::IZkLendMarketDispatcher" + }, + { + "name": "oracle", + "type": "strkfarm::interfaces::oracle::IPriceOracleDispatcher" + } + ] + }, + { "type": "constructor", + "name": "constructor", "inputs": [ { "name": "owner", "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "lend_settings", + "type": "strkfarm::components::zkLend::zkLendStruct" + }, + { + "name": "nimbora_referral", + "type": "core::starknet::contract_address::ContractAddress" } ] }, { - "kind": "enum", - "name": "openzeppelin::security::reentrancyguard::ReentrancyGuardComponent::Event", "type": "event", + "name": "openzeppelin_security::reentrancyguard::ReentrancyGuardComponent::Event", + "kind": "enum", "variants": [] }, { - "kind": "struct", - "name": "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferred", "type": "event", + "name": "openzeppelin_access::ownable::ownable::OwnableComponent::OwnershipTransferred", + "kind": "struct", "members": [ { - "kind": "key", "name": "previous_owner", - "type": "core::starknet::contract_address::ContractAddress" + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" }, { - "kind": "key", "name": "new_owner", - "type": "core::starknet::contract_address::ContractAddress" + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" } ] }, { - "kind": "struct", - "name": "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferStarted", "type": "event", + "name": "openzeppelin_access::ownable::ownable::OwnableComponent::OwnershipTransferStarted", + "kind": "struct", "members": [ { - "kind": "key", "name": "previous_owner", - "type": "core::starknet::contract_address::ContractAddress" + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" }, { - "kind": "key", "name": "new_owner", - "type": "core::starknet::contract_address::ContractAddress" + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" } ] }, { - "kind": "enum", - "name": "openzeppelin::access::ownable::ownable::OwnableComponent::Event", "type": "event", + "name": "openzeppelin_access::ownable::ownable::OwnableComponent::Event", + "kind": "enum", "variants": [ { - "kind": "nested", "name": "OwnershipTransferred", - "type": "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferred" + "type": "openzeppelin_access::ownable::ownable::OwnableComponent::OwnershipTransferred", + "kind": "nested" }, { - "kind": "nested", "name": "OwnershipTransferStarted", - "type": "openzeppelin::access::ownable::ownable::OwnableComponent::OwnershipTransferStarted" + "type": "openzeppelin_access::ownable::ownable::OwnableComponent::OwnershipTransferStarted", + "kind": "nested" } ] }, { - "kind": "struct", - "name": "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded", "type": "event", + "name": "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Upgraded", + "kind": "struct", "members": [ { - "kind": "data", "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" } ] }, { - "kind": "enum", - "name": "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event", "type": "event", + "name": "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Event", + "kind": "enum", "variants": [ { - "kind": "nested", "name": "Upgraded", - "type": "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Upgraded" + "type": "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Upgraded", + "kind": "nested" } ] }, { - "kind": "enum", - "name": "strkfarm::strats::master::Master::Event", "type": "event", + "name": "strkfarm::strats::master::Master::Event", + "kind": "enum", "variants": [ { - "kind": "flat", "name": "ReentrancyGuardEvent", - "type": "openzeppelin::security::reentrancyguard::ReentrancyGuardComponent::Event" + "type": "openzeppelin_security::reentrancyguard::ReentrancyGuardComponent::Event", + "kind": "flat" }, { - "kind": "flat", "name": "OwnableEvent", - "type": "openzeppelin::access::ownable::ownable::OwnableComponent::Event" + "type": "openzeppelin_access::ownable::ownable::OwnableComponent::Event", + "kind": "flat" }, { - "kind": "flat", "name": "UpgradeableEvent", - "type": "openzeppelin::upgrades::upgradeable::UpgradeableComponent::Event" + "type": "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Event", + "kind": "flat" } ] } diff --git a/src/abi/rewards.abi.json b/src/abi/rewards.abi.json new file mode 100644 index 00000000..ab1057a5 --- /dev/null +++ b/src/abi/rewards.abi.json @@ -0,0 +1,187 @@ +[ + { + "type": "impl", + "name": "MyRewardsImpl", + "interface_name": "strkfarm::strats::myrewards::IMyRewards" + }, + { + "type": "struct", + "name": "strkfarm::strats::myrewards::IConfig", + "members": [ + { + "name": "rewards_per_second", + "type": "core::integer::u128" + }, + { + "name": "token", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "reward_receiver", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "start_time", + "type": "core::integer::u64" + } + ] + }, + { + "type": "interface", + "name": "strkfarm::strats::myrewards::IMyRewards", + "items": [ + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "upgrade", + "inputs": [ + { + "name": "new_class", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_config", + "inputs": [ + { + "name": "config", + "type": "strkfarm::strats::myrewards::IConfig" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_config", + "inputs": [], + "outputs": [ + { + "type": "strkfarm::strats::myrewards::IConfig" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "withdraw", + "inputs": [ + { + "name": "amount", + "type": "core::integer::u128" + }, + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "rewards", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u128" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "give_rewards", + "inputs": [], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "constructor", + "name": "constructor", + "inputs": [ + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "config", + "type": "strkfarm::strats::myrewards::IConfig" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Upgraded", + "kind": "struct", + "members": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "Upgraded", + "type": "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Upgraded", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "strkfarm::strats::myrewards::MyRewards::RewardSent", + "kind": "struct", + "members": [ + { + "name": "amount", + "type": "core::integer::u128", + "kind": "data" + }, + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "strkfarm::strats::myrewards::MyRewards::Event", + "kind": "enum", + "variants": [ + { + "name": "UpgradeableEvent", + "type": "openzeppelin_upgrades::upgradeable::UpgradeableComponent::Event", + "kind": "flat" + }, + { + "name": "RewardSent", + "type": "strkfarm::strats::myrewards::MyRewards::RewardSent", + "kind": "nested" + } + ] + } +] diff --git a/src/app/api/tnc/signUser/route.ts b/src/app/api/tnc/signUser/route.ts index dd777d32..c127acaf 100644 --- a/src/app/api/tnc/signUser/route.ts +++ b/src/app/api/tnc/signUser/route.ts @@ -9,16 +9,9 @@ import Mixpanel from 'mixpanel'; const mixpanel = Mixpanel.init('118f29da6a372f0ccb6f541079cad56b'); export async function POST(req: Request) { - const { address, signature, _signature } = await req.json(); - - console.debug( - 'address', - address, - 'signature', - signature, - '_signature', - _signature, - ); + const { address, signature } = await req.json(); + + console.debug('address', address, 'signature', signature); if (!address || !signature) { return NextResponse.json({ success: false, @@ -57,64 +50,64 @@ export async function POST(req: Request) { console.debug(`Verifying signature for address: ${parsedAddress}`); console.debug(`SIGNING_DATA`, SIGNING_DATA); const hash = await myAccount.hashMessage(SIGNING_DATA); - try { - // await debug(); - isValid = await verifyMessageHash(myAccount, hash, parsedSignature); - console.debug('isValid', isValid); - mixpanel.track('TnC signed', { - address, - signature, - _signature, - step: 1, - hash, - }); - } catch (error) { - console.error('verification failed [1]:', error); - if (_signature) { + console.debug('hash', hash); + + const function_sigs = ['is_valid_signature', 'isValidSignature']; + const signatures = [ + parsedSignature, + parsedSignature.slice(parsedSignature.length - 2, parsedSignature.length), + ]; + + for (const fn_sig of function_sigs) { + for (const sig of signatures) { try { - const parsedSignature2 = JSON.parse(_signature) as string[]; - isValid = await verifyMessageHash(myAccount, hash, parsedSignature2); + console.log(`Checking: ${fn_sig}`); + console.log(`Signature: ${JSON.stringify(sig)}`); + isValid = await verifyMessageHash(myAccount, hash, sig, fn_sig); console.debug('isValid', isValid); mixpanel.track('TnC signed', { address, signature, - _signature, + step: 1, hash, - step: 2, - }); - } catch (err) { - console.error('verification failed [2]:', err); - - // temporarily accepting all signtures - isValid = true; - mixpanel.track('TnC signing failed', { - address, - signature, - hash, - isValid, - _signature, + fn_sig, }); + break; + } catch (error) { + console.warn(`verification failed [${fn_sig}]:`, error); } } + if (isValid) { + break; + } } - if (!isValid) { - mixpanel.track('TnC signing failed', { - address, - signature, - _signature, - hash, - isValid, - }); - isValid = true; // temporarily accepting all signtures - } + // if (!isValid) { + // mixpanel.track('TnC signing failed', { + // address, + // signature, + // hash, + // isValid, + // }); + // isValid = true; // temporarily accepting all signtures + // } if (!isValid) { - return NextResponse.json({ - success: false, - message: 'Invalid signature. Ensure account is deployed.', - user: null, - }); + try { + const cls = await provider.getClassAt(address, 'pending'); + // means account is deployed + return NextResponse.json({ + success: false, + message: 'Invalid signature. Please contact us if issue persists.', + user: null, + }); + } catch (error) { + return NextResponse.json({ + success: false, + message: 'Invalid signature. Ensure account is deployed.', + user: null, + }); + } } const user = await db.user.findFirst({ @@ -186,18 +179,11 @@ async function verifyMessageHash( }); console.debug('verifyMessageHash resp', resp); if (Number(resp[0]) == 0) { - return false; + throw new Error('Invalid signature'); } return true; } catch (err: any) { console.error('Error verifying signature:', err); - if (entrypoint === 'isValidSignature') { - console.debug( - 'could be Invalid message selector, trying with is_valid_signature', - ); - return verifyMessageHash(account, hash, signature, 'is_valid_signature'); - } - if ( [ 'argent/invalid-signature', diff --git a/src/app/page.tsx b/src/app/page.tsx index a498a717..20d19297 100755 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -32,9 +32,9 @@ import { isMobile } from 'react-device-detect'; const banner_images = [ { - desktop: '/banners/ognft.svg', - mobile: '/banners/ognft_small.svg', - link: 'https://x.com/strkfarm/status/1788558092109775029', + desktop: '/banners/endur.svg', + mobile: '/banners/endur_mobile.svg', + link: 'https://endur.fi/r/strkfarm', }, { desktop: '/banners/seed_grant.svg', @@ -114,7 +114,7 @@ export default function Home() { - + {banner_images.map((banner, index) => ( + {/*
+ +
*/} + Choose a strategy and invest {strategies .filter((s) => s.isLive()) diff --git a/src/app/slinks/template.tsx b/src/app/slinks/template.tsx index 679d6d29..55454e2f 100755 --- a/src/app/slinks/template.tsx +++ b/src/app/slinks/template.tsx @@ -1,6 +1,6 @@ 'use client'; -import Navbar, { MYCONNECTORS } from '@/components/Navbar'; +import Navbar, { getConnectors } from '@/components/Navbar'; import { MY_STORE } from '@/store'; import { Center, @@ -16,6 +16,7 @@ import mixpanel from 'mixpanel-browser'; import Image from 'next/image'; import { usePathname } from 'next/navigation'; import * as React from 'react'; +import { isMobile } from 'react-device-detect'; import { Toaster } from 'react-hot-toast'; import { RpcProviderOptions, constants } from 'starknet'; @@ -96,7 +97,7 @@ export default function Template({ children }: { children: React.ReactNode }) { diff --git a/src/app/strategy/[strategyId]/_components/Strategy.tsx b/src/app/strategy/[strategyId]/_components/Strategy.tsx index be369268..21df5fb9 100755 --- a/src/app/strategy/[strategyId]/_components/Strategy.tsx +++ b/src/app/strategy/[strategyId]/_components/Strategy.tsx @@ -330,20 +330,22 @@ const Strategy = ({ params }: StrategyParams) => { /> {strategy.settings.alerts != undefined && ( - {strategy.settings.alerts.map((alert, index) => ( - - - {alert.text} - - ))} + {strategy.settings.alerts + .filter((a) => a.tab == 'deposit') + .map((alert, index) => ( + + + {alert.text} + + ))} )} @@ -358,6 +360,26 @@ const Strategy = ({ params }: StrategyParams) => { buttonText="Redeem" callsInfo={strategy.withdrawMethods} /> + {strategy.settings.alerts != undefined && ( + + {strategy.settings.alerts + .filter((a) => a.tab == 'withdraw') + .map((alert, index) => ( + + + {alert.text} + + ))} + + )} diff --git a/src/app/template.tsx b/src/app/template.tsx index acd3d808..2b8664d8 100755 --- a/src/app/template.tsx +++ b/src/app/template.tsx @@ -1,6 +1,6 @@ 'use client'; -import Navbar, { MYCONNECTORS } from '@/components/Navbar'; +import Navbar, { getConnectors } from '@/components/Navbar'; import { MY_STORE } from '@/store'; import { Center, @@ -20,6 +20,7 @@ import { Toaster } from 'react-hot-toast'; import { RpcProviderOptions, constants } from 'starknet'; import { Inter } from 'next/font/google'; +import { isMobile } from 'react-device-detect'; const inter = Inter({ subsets: ['latin'] }); mixpanel.init('118f29da6a372f0ccb6f541079cad56b'); @@ -108,7 +109,7 @@ export default function Template({ children }: { children: React.ReactNode }) { diff --git a/src/components/HarvestTime.tsx b/src/components/HarvestTime.tsx index 088bbfdd..61c52a38 100644 --- a/src/components/HarvestTime.tsx +++ b/src/components/HarvestTime.tsx @@ -126,7 +126,7 @@ const HarvestTime: React.FC = ({ strategy, balData }) => { - {!isMobile && ( + {!isMobile && !strategy.settings.hideHarvestInfo && ( @@ -213,37 +213,39 @@ const HarvestTime: React.FC = ({ strategy, balData }) => { )} - - - Harvested{' '} - - {getDisplayCurrencyAmount( - harvestTime?.data?.totalStrkHarvestedByContract.STRKAmount || 0, - 2, - )}{' '} - STRK - {' '} - over {harvestTime?.data?.totalHarvestsByContract} claims.{' '} - {lastHarvest && ( - - Last harvested {timeAgo(lastHarvest)}. - - )} - - + + Harvested{' '} + + {getDisplayCurrencyAmount( + harvestTime?.data?.totalStrkHarvestedByContract.STRKAmount || 0, + 2, + )}{' '} + STRK + {' '} + over {harvestTime?.data?.totalHarvestsByContract} claims.{' '} + {lastHarvest && ( + + Last harvested {timeAgo(lastHarvest)}. + + )} + +
+ )}
); }; diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index fe7bcc51..fa756331 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -22,15 +22,19 @@ import { useDisclosure, } from '@chakra-ui/react'; import { useAtom, useSetAtom } from 'jotai'; -import { useStarknetkitConnectModal } from 'starknetkit'; +import { + connect, + ConnectOptionsWithConnectors, + StarknetkitConnector, +} from 'starknetkit'; -import { CONNECTOR_NAMES } from '@/app/template'; import tg from '@/assets/tg.svg'; import CONSTANTS from '@/constants'; import { getERC20Balance } from '@/store/balance.atoms'; import { addressAtom } from '@/store/claims.atoms'; import { lastWalletAtom } from '@/store/utils.atoms'; import { + getEndpoint, getTokenInfoFromName, MyMenuItemProps, MyMenuListProps, @@ -47,7 +51,7 @@ import { useStarkProfile, } from '@starknet-react/core'; import mixpanel from 'mixpanel-browser'; -import { useEffect } from 'react'; +import { useEffect, useMemo } from 'react'; import { isMobile } from 'react-device-detect'; import { ArgentMobileConnector, @@ -55,30 +59,48 @@ import { } from 'starknetkit/argentMobile'; import { WebWalletConnector } from 'starknetkit/webwallet'; import TncModal from './TncModal'; +import { constants } from 'starknet'; + +export function getConnectors(isMobile: boolean) { + const mobileConnector = ArgentMobileConnector.init({ + options: { + dappName: 'STRKFarm', + url: getEndpoint(), + chainId: constants.NetworkName.SN_MAIN, + }, + inAppBrowserOptions: {}, + }) as StarknetkitConnector; + + const argentXConnector = new InjectedConnector({ + options: { + id: 'argentX', + name: 'Argent X', + }, + }); + + const braavosConnector = new InjectedConnector({ + options: { + id: 'braavos', + name: 'Braavos', + }, + }); -export const MYCONNECTORS: any[] = isInArgentMobileAppBrowser() - ? [ - ArgentMobileConnector.init({ - options: { - dappName: 'STRKFarm', - projectId: 'strkfarm', - url: 'https://app.strkfarm.xyz', - }, - inAppBrowserOptions: {}, - }), - ] - : [ - new InjectedConnector({ options: { id: 'braavos', name: 'Braavos' } }), - new InjectedConnector({ options: { id: 'argentX', name: 'Argent X' } }), - new WebWalletConnector({ url: 'https://web.argent.xyz' }), - ArgentMobileConnector.init({ - options: { - dappName: 'STRKFarm', - projectId: 'strkfarm', - url: 'https://app.strkfarm.xyz', - }, - }), - ]; + const webWalletConnector = new WebWalletConnector({ + url: 'https://web.argent.xyz', + }) as StarknetkitConnector; + + if (isInArgentMobileAppBrowser()) { + return [mobileConnector]; + } else if (isMobile) { + return [braavosConnector, mobileConnector, webWalletConnector]; + } + return [ + argentXConnector, + braavosConnector, + mobileConnector, + webWalletConnector, + ]; +} interface NavbarProps { hideTg?: boolean; @@ -87,29 +109,15 @@ interface NavbarProps { export default function Navbar(props: NavbarProps) { const { address, connector, account } = useAccount(); - const { connect, connectors } = useConnect(); const { disconnectAsync } = useDisconnect(); const setAddress = useSetAtom(addressAtom); const { data: starkProfile } = useStarkProfile({ address, useDefaultPfp: true, }); + const { connect: connectSnReact } = useConnect(); const [lastWallet, setLastWallet] = useAtom(lastWalletAtom); - const { starknetkitConnectModal: starknetkitConnectModal1 } = - useStarknetkitConnectModal({ - modalMode: 'canAsk', - modalTheme: 'dark', - connectors: MYCONNECTORS, - }); - - // backup - const { starknetkitConnectModal: starknetkitConnectModal2 } = - useStarknetkitConnectModal({ - modalMode: 'alwaysAsk', - modalTheme: 'dark', - connectors: MYCONNECTORS, - }); const getTokenBalance = async (token: string, address: string) => { const tokenInfo = getTokenInfoFromName(token); @@ -120,6 +128,41 @@ export default function Navbar(props: NavbarProps) { console.log(account, 'account'); + const connectorConfig: ConnectOptionsWithConnectors = useMemo(() => { + return { + modalMode: 'canAsk', + modalTheme: 'dark', + webWalletUrl: 'https://web.argent.xyz', + argentMobileOptions: { + dappName: 'STRKFarm', + chainId: constants.NetworkName.SN_MAIN, + url: getEndpoint(), + }, + dappName: 'STRKFarm', + connectors: getConnectors(isMobile) as StarknetkitConnector[], + }; + }, [isMobile]); + + async function connectWallet(config = connectorConfig) { + try { + const { connector } = await connect(config); + + if (connector) { + connectSnReact({ connector: connector as any }); + } + } catch (error) { + console.error('connectWallet error', error); + } + } + + useEffect(() => { + const config = connectorConfig; + connectWallet({ + ...config, + modalMode: 'neverAsk', + }); + }, []); + useEffect(() => { (async () => { if (address) { @@ -137,55 +180,6 @@ export default function Navbar(props: NavbarProps) { })(); }, [address]); - // Connect wallet using starknetkit - const connectWallet = async () => { - try { - const result = await starknetkitConnectModal1(); - if (!result.connector) { - throw new Error('No connector found'); - } - - connect({ connector: result.connector }); - } catch (error) { - console.warn('connectWallet error', error); - try { - const result = await starknetkitConnectModal2(); - if (!result.connector) { - throw new Error('No connector found'); - } - connect({ connector: result.connector }); - } catch (error) { - console.error('connectWallet error', error); - alert('Error connecting wallet'); - } - } - }; - - function autoConnect(retry = 0) { - console.log('lastWallet', lastWallet, connectors); - try { - if (!address && lastWallet) { - const connectorIndex = CONNECTOR_NAMES.findIndex( - (name) => name === lastWallet, - ); - if (connectorIndex >= 0) { - connect({ connector: MYCONNECTORS[connectorIndex] }); - } - } - } catch (error) { - console.error('lastWallet error', error); - if (retry < 10) { - setTimeout(() => { - autoConnect(retry + 1); - }, 1000); - } - } - } - // Auto-connects to last wallet - useEffect(() => { - autoConnect(); - }, [lastWallet]); - // Set last wallet when a new wallet is connected useEffect(() => { console.log('lastWallet connector', connector?.name); @@ -291,7 +285,7 @@ export default function Navbar(props: NavbarProps) { Home - + {/* - + */}