diff --git a/src/components/ui/icon/index.tsx b/src/components/ui/icon/index.tsx index d1e5029..36bda78 100644 --- a/src/components/ui/icon/index.tsx +++ b/src/components/ui/icon/index.tsx @@ -6,6 +6,7 @@ import { AiOutlineHome, AiOutlineLogout, AiOutlineProject, + AiOutlineReload, } from 'react-icons/ai'; import { BsFillPlayFill } from 'react-icons/bs'; import { FaRegClone } from 'react-icons/fa'; @@ -63,7 +64,8 @@ export type AppIconType = | 'Eye' | 'Clear' | 'Download' - | 'Import'; + | 'Import' + | 'Reload'; export interface AppIconInterface { name: AppIconType; @@ -101,6 +103,7 @@ const Components = { Clear: GrClear, Download: AiOutlineDownload, Import, + Reload: AiOutlineReload, }; const AppIcon: FC = ({ name, className = '' }) => { diff --git a/src/components/workspace/WorkspaceSidebar/WorkspaceSidebar.module.scss b/src/components/workspace/WorkspaceSidebar/WorkspaceSidebar.module.scss index 5cc9109..4b136b6 100644 --- a/src/components/workspace/WorkspaceSidebar/WorkspaceSidebar.module.scss +++ b/src/components/workspace/WorkspaceSidebar/WorkspaceSidebar.module.scss @@ -55,3 +55,25 @@ font-size: 1.3rem; } } +.settingItem { + margin: 0 !important; + padding: 1rem 0; + &:not(:last-child) { + border-bottom: 1px solid rgba(255, 255, 255, 0.2); + } + > div { + margin: 0 !important; + } +} +.resetAmount { + display: flex; + align-items: center; + padding: 0 0.5rem; + height: 100%; + cursor: pointer; + position: absolute; + right: 0; + &:hover { + background-color: rgba(177, 213, 221, 0.2); + } +} diff --git a/src/components/workspace/WorkspaceSidebar/WorkspaceSidebar.tsx b/src/components/workspace/WorkspaceSidebar/WorkspaceSidebar.tsx index 0a987c6..bb19d1a 100644 --- a/src/components/workspace/WorkspaceSidebar/WorkspaceSidebar.tsx +++ b/src/components/workspace/WorkspaceSidebar/WorkspaceSidebar.tsx @@ -5,7 +5,7 @@ import { useAuthAction } from '@/hooks/auth.hooks'; import { useSettingAction } from '@/hooks/setting.hooks'; import { useWorkspaceActions } from '@/hooks/workspace.hooks'; import { Project } from '@/interfaces/workspace.interface'; -import { Form, Popover, Switch } from 'antd'; +import { Form, Input, Popover, Switch } from 'antd'; import Link from 'next/link'; import { FC } from 'react'; import s from './WorkspaceSidebar.module.scss'; @@ -36,6 +36,8 @@ const WorkspaceSidebar: FC = ({ toggleContractDebug, isFormatOnSave, toggleFormatOnSave, + updateTonAmountForInteraction, + getTonAmountForInteraction, } = useSettingAction(); const hasEditAccess = isProjectEditable(projectId as string, user); @@ -81,11 +83,7 @@ const WorkspaceSidebar: FC = ({

- + { @@ -94,6 +92,39 @@ const WorkspaceSidebar: FC = ({ />
+ +
+ + { + if (isNaN(Number(e.target.value))) return; + updateTonAmountForInteraction(e.target.value); + }} + placeholder="in TON" + suffix={ +
updateTonAmountForInteraction('', true)} + > + +
+ } + /> +
+

+ *{' '} + + This amount will be used for all the
contract interaction + like deployment and sending internal messages. +
+

+
); diff --git a/src/hooks/contract.hooks.ts b/src/hooks/contract.hooks.ts index 4fa86ee..56eb1d6 100644 --- a/src/hooks/contract.hooks.ts +++ b/src/hooks/contract.hooks.ts @@ -33,6 +33,7 @@ import { ITonConnect, SendTransactionRequest } from '@tonconnect/sdk'; import { useTonConnectUI } from '@tonconnect/ui-react'; import { message } from 'antd'; import BN from 'bn.js'; +import { useSettingAction } from './setting.hooks'; const getHttpEndpoint = ({ network }: Config) => { return `https://${ @@ -42,6 +43,8 @@ const getHttpEndpoint = ({ network }: Config) => { export function useContractAction() { const [tonConnector] = useTonConnectUI(); + const { getTonAmountForInteraction } = useSettingAction(); + const tonAmountForInteraction = toNano(getTonAmountForInteraction()); return { deployContract, @@ -65,8 +68,6 @@ export function useContractAction() { let sender: Sender | null = null; - // Amount to send to contract. Gas fee - const value = toNano('0.05'); let stateInit: StateInit = {}; if (project.language === 'tact') { const _contractInit = (window as any).contractInit; @@ -124,7 +125,7 @@ export function useContractAction() { const response = await _userContract.send( sender, { - value, + value: tonAmountForInteraction, }, messageParams ); @@ -161,7 +162,11 @@ export function useContractAction() { stateInit.data as Cell ); const userContract = sandboxBlockchain.openContract(_userContract); - const response = await userContract.sendData(sandboxWallet!!.getSender()); + const response = await userContract.sendData( + sandboxWallet!!.getSender(), + Cell.EMPTY, + tonAmountForInteraction + ); if (network.toUpperCase() !== 'SANDBOX') { message.success('Contract Deployed'); } @@ -192,7 +197,7 @@ export function useContractAction() { messages: [ { address: _contractAddress.toString(), - amount: value.toString(), + amount: tonAmountForInteraction.toString(), stateInit: initCell.toBoc().toString('base64'), }, ], @@ -223,7 +228,11 @@ export function useContractAction() { message.error('Contract is not deployed'); return; } - const call = await contract.sendData(wallet.getSender(), _dataCell); + const call = await contract.sendData( + wallet.getSender(), + _dataCell, + tonAmountForInteraction + ); return; } try { @@ -232,7 +241,7 @@ export function useContractAction() { messages: [ { address: contractAddress, - amount: toNano('0.02').toString(), + amount: tonAmountForInteraction.toString(), payload: _dataCell.toBoc().toString('base64'), }, ], @@ -295,7 +304,7 @@ export function useContractAction() { const response = await (contract as any).send( sender, - { value: toNano('0.1') }, + { value: tonAmountForInteraction }, messageParams ); return { @@ -409,10 +418,11 @@ export class UserContract implements Contract { async sendData( provider: ContractProvider, via: Sender, - body: Cell = Cell.EMPTY + body: Cell = Cell.EMPTY, + amount: bigint ) { await provider.internal(via, { - value: '0.02', + value: amount, bounce: false, body, }); diff --git a/src/hooks/setting.hooks.ts b/src/hooks/setting.hooks.ts index e81c412..9f59591 100644 --- a/src/hooks/setting.hooks.ts +++ b/src/hooks/setting.hooks.ts @@ -1,3 +1,4 @@ +import { SettingInterface } from '@/interfaces/setting.interface'; import { settingState } from '@/state/setting.state'; import { useRecoilState } from 'recoil'; @@ -5,10 +6,13 @@ export function useSettingAction() { const [setting, updateSetting] = useRecoilState(settingState); return { + getSettingStateByKey, isContractDebugEnabled, toggleContractDebug, isFormatOnSave, toggleFormatOnSave, + updateTonAmountForInteraction, + getTonAmountForInteraction, }; function updateStateByKey(dataByKey: any) { @@ -20,6 +24,10 @@ export function useSettingAction() { }); } + function getSettingStateByKey(key: keyof SettingInterface) { + return setting[key]; + } + function isContractDebugEnabled() { return setting.contractDebug; } @@ -39,4 +47,14 @@ export function useSettingAction() { formatOnSave: active, }); } + + function getTonAmountForInteraction() { + return setting.tonAmountForInteraction || '0.05'; + } + + function updateTonAmountForInteraction(value: string, reset = false) { + return updateStateByKey({ + tonAmountForInteraction: reset ? '0.05' : value, + }); + } } diff --git a/src/interfaces/setting.interface.ts b/src/interfaces/setting.interface.ts index 0ffc873..1a001c6 100644 --- a/src/interfaces/setting.interface.ts +++ b/src/interfaces/setting.interface.ts @@ -1,4 +1,5 @@ export interface SettingInterface { contractDebug: boolean; formatOnSave: boolean; + tonAmountForInteraction: string; } diff --git a/src/state/setting.state.ts b/src/state/setting.state.ts index b0dcda8..f64b980 100644 --- a/src/state/setting.state.ts +++ b/src/state/setting.state.ts @@ -9,6 +9,7 @@ export const settingState = atom({ default: { contractDebug: false, formatOnSave: false, + tonAmountForInteraction: '0.05', }, effects_UNSTABLE: [persistAtom], });