Skip to content

Commit

Permalink
fix: resolve post-reload interaction issues with deployed contracts (#43
Browse files Browse the repository at this point in the history
)

Resolves #14
  • Loading branch information
rahulyadav-57 authored Jun 20, 2024
1 parent d4e65df commit 71f1b30
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/components/workspace/ABIUi/ABIUi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const ABIUi: FC<Props> = ({

if (response?.logs) {
for (const log of response?.logs) {
createLog(log);
createLog(log, response?.status || 'info');
}
} else {
createLog(JSON.stringify(response));
Expand Down
151 changes: 135 additions & 16 deletions src/components/workspace/BuildProject/BuildProject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import {
} from '@/interfaces/workspace.interface';
import { Analytics } from '@/utility/analytics';
import { buildTs } from '@/utility/typescriptHelper';
import { delay, getContractLINK, getFileExtension } from '@/utility/utils';
import {
delay,
getContractLINK,
getFileExtension,
tonHttpEndpoint,
} from '@/utility/utils';
import { Network } from '@orbs-network/ton-access';
import { Cell } from '@ton/core';
import { Blockchain } from '@ton/sandbox';
Expand All @@ -23,6 +28,7 @@ import s from './BuildProject.module.scss';

import AppIcon from '@/components/ui/icon';
import { useSettingAction } from '@/hooks/setting.hooks';
import { TonClient } from '@ton/ton';
import { useForm } from 'antd/lib/form/Form';
import packageJson from 'package.json';
import {
Expand Down Expand Up @@ -182,7 +188,7 @@ const BuildProject: FC<Props> = ({
onFinish={initDeploy}
onValuesChange={(changedValues) => {
if (Object.hasOwn(changedValues, 'contract')) {
setSelectedContract(changedValues.contract);
updateSelectedContract(changedValues.contract);
}
}}
>
Expand Down Expand Up @@ -231,7 +237,8 @@ const BuildProject: FC<Props> = ({
disabled={selectedContract === undefined}
className="w-100 item-center-align ant-btn-primary-gradient"
>
<AppIcon name="Rocket" /> Deploy
<AppIcon name="Rocket" />
{activeProject?.contractAddress ? 'Redeploy' : 'Deploy'}
</Button>
</Form>
</>
Expand Down Expand Up @@ -436,24 +443,17 @@ const BuildProject: FC<Props> = ({
);
}

const finalJsoutput = jsOutout[0].code
.replace(/^import\s+{/, 'const {')
.replace(/}\s+from\s.+/, '} = window.TonCore;')
.replace(/^\s*export\s+\{[^}]*\};\s*/m, '');
const finalJsoutput = fromJSModule(jsOutout[0].code);

const contractName = selectedContract
.replace('dist/', '')
.replace('.abi', '')
.replace('tact_', '')
.replace('func_', '');
const contractName = extractContractName(selectedContract);

if (activeProject?.language == 'tact') {
const _code = `async function main() {
${finalJsoutput}
const contractInit = await ${contractName}.fromInit(${initParams});
return contractInit;
} main()`;
const contractInit = await eval(_code);
} return main()`;
const contractInit = await new Function(_code)();
(window as any).contractInit = contractInit;
deploy();
return;
Expand Down Expand Up @@ -586,11 +586,128 @@ const BuildProject: FC<Props> = ({
);
};

const updatNetworkEnvironment = (network: NetworkEnvironment) => {
updateProjectById(
{
network,
},
projectId
);
setEnvironment(network);
};

const updateSelectedContract = (contract: string) => {
if (!contract) return;
setSelectedContract(contract);
updateProjectById(
{
selectedContract: contract,
},
projectId
);
};

const extractContractName = (currentContractName: string) => {
return currentContractName
.replace('dist/', '')
.replace('.abi', '')
.replace('tact_', '')
.replace('func_', '');
};

const fromJSModule = (jsModuleCode: string) => {
return jsModuleCode
.replace(/^import\s+{/, 'const {')
.replace(/}\s+from\s.+/, '} = window.TonCore;')
.replace(/^\s*export\s+\{[^}]*\};\s*/m, '');
};

const getSelectedContractJsBuild = async (
currentContractName: String,
language: 'tact' | 'func',
supressErrors = false
) => {
const contractScriptPath = currentContractName?.replace('.abi', '.ts');
const contractScript = await getFileByPath(contractScriptPath, projectId);
if (language === 'tact' && !contractScript?.content) {
if (supressErrors) {
return;
}
throw 'Contract script is missing. Rebuild the contract.';
}

let jsOutout = await buildTs(
{
'tact.ts': contractScript?.content,
},
'tact.ts'
);

const finalJsoutput = fromJSModule(jsOutout[0].code);

return { finalJsoutput };
};

const updateContractInstance = async () => {
if (
!selectedContract ||
!activeProject?.contractAddress ||
activeProject?.language !== 'tact' ||
(window as any).contractInit
) {
return;
}

if (activeProject?.contractAddress && environment == 'SANDBOX') {
return;
}

const output = await getSelectedContractJsBuild(
selectedContract,
'tact',
true
);
if (!output) return;

const contractName = extractContractName(selectedContract);

const _code = `async function main() {
${output.finalJsoutput}
const contractInit = await ${contractName}.fromAddress(window.TonCore.Address.parse('${activeProject?.contractAddress}'));
return contractInit;
} return main()`;
const contractInit = await new Function(_code)();
(window as any).contractInit = contractInit;

const endpoint = tonHttpEndpoint({
network: environment?.toLocaleLowerCase() as Network,
});

const client = new TonClient({ endpoint });
const _userContract = client.open(contractInit);
updateContract(_userContract);
};

useEffect(() => {
updateABI();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedContract, contract]);

useEffect(() => {
try {
updateContractInstance();
} catch (e) {}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedContract]);

useEffect(() => {
if (activeProject?.network) {
setEnvironment(activeProject?.network);
}
if (activeProject?.selectedContract) {
setSelectedContract(activeProject?.selectedContract);
deployForm.setFieldsValue({ contract: activeProject?.selectedContract });
}
const handler = (
event: MessageEvent<{
name: string;
Expand Down Expand Up @@ -645,8 +762,10 @@ const BuildProject: FC<Props> = ({
className={`${s.formItem} select-search-input-dark`}
>
<Select
defaultValue="SANDBOX"
onChange={(value) => setEnvironment(value as NetworkEnvironment)}
value={environment}
onChange={(value) =>
updatNetworkEnvironment(value as NetworkEnvironment)
}
options={[
{ value: 'SANDBOX', label: 'Sandbox' },
{ value: 'TESTNET', label: 'Testnet' },
Expand Down
22 changes: 13 additions & 9 deletions src/hooks/contract.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import {
ParameterType,
Project,
} from '@/interfaces/workspace.interface';
import { capitalizeFirstLetter, convertToText } from '@/utility/utils';
import { Config, Network } from '@orbs-network/ton-access';
import {
capitalizeFirstLetter,
convertToText,
tonHttpEndpoint as getHttpEndpoint,
} from '@/utility/utils';
import { Network } from '@orbs-network/ton-access';
import {
Address,
Cell,
Expand Down Expand Up @@ -35,12 +39,6 @@ import { message } from 'antd';
import BN from 'bn.js';
import { useSettingAction } from './setting.hooks';

const getHttpEndpoint = ({ network }: Config) => {
return `https://${
network === 'testnet' ? 'testnet.' : ''
}toncenter.com/api/v2/jsonRPC`;
};

export function useContractAction() {
const [tonConnector] = useTonConnectUI();
const { getTonAmountForInteraction } = useSettingAction();
Expand Down Expand Up @@ -225,7 +223,7 @@ export function useContractAction() {
const _dataCell = Cell.fromBoc(Buffer.from(dataCell as any, 'base64'))[0];
if (network.toUpperCase() === 'SANDBOX') {
if (!contract) {
message.error('Contract is not deployed');
message.error('The contract has not been deployed yet.');
return;
}
const call = await contract.sendData(
Expand Down Expand Up @@ -358,6 +356,12 @@ export function useContractAction() {
};
}
});
if (network === 'SANDBOX' && !contract) {
return {
logs: ['The contract has not been deployed yet.'],
status: 'error',
};
}
if (network === 'SANDBOX' && contract) {
let responseValues = [];
if (language === 'tact') {
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces/workspace.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ export interface Project {
contractScript?: Buffer;
initParams?: InitParams[];
contractName?: string;
selectedContract?: string;
isPublic?: boolean;
network?: NetworkEnvironment;
createdAt?: Date;
updatedAt?: Date;
cellABI?: CellABI;
Expand Down
7 changes: 7 additions & 0 deletions src/utility/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FileExtensionToFileType, FileType } from '@/enum/file';
import { NetworkEnvironment } from '@/interfaces/workspace.interface';
import { Config } from '@orbs-network/ton-access';
import { Address, Cell, Dictionary, Slice } from '@ton/core';

export function fileTypeFromFileName(name: string): FileType {
Expand Down Expand Up @@ -195,3 +196,9 @@ export const convertToText = (obj: any): string => {

return string.join(',');
};

export const tonHttpEndpoint = ({ network }: Config) => {
return `https://${
network === 'testnet' ? 'testnet.' : ''
}toncenter.com/api/v2/jsonRPC`;
};

0 comments on commit 71f1b30

Please sign in to comment.