diff --git a/src/components/DevTools/ContractManageForm.vue b/src/components/DevTools/ContractManageForm.vue
index 3b43e5d..eff67d7 100644
--- a/src/components/DevTools/ContractManageForm.vue
+++ b/src/components/DevTools/ContractManageForm.vue
@@ -5,10 +5,9 @@
{{ $t("message.DevTools.DefaultText") }}
+
-
-
-
+
@@ -21,7 +20,9 @@
\ No newline at end of file
diff --git a/src/components/Fields/AddressField.vue b/src/components/Fields/AddressField.vue
index 2ec94c7..b044840 100644
--- a/src/components/Fields/AddressField.vue
+++ b/src/components/Fields/AddressField.vue
@@ -1,25 +1,40 @@
-
+
+
+
\ No newline at end of file
diff --git a/src/components/Fields/SliceField.vue b/src/components/Fields/SliceField.vue
index 18d8a67..7fbc80c 100644
--- a/src/components/Fields/SliceField.vue
+++ b/src/components/Fields/SliceField.vue
@@ -1,39 +1,40 @@
- Slice
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/src/components/Inputs/BooleanInput.vue b/src/components/Inputs/BooleanInput.vue
deleted file mode 100644
index 3a6f218..0000000
--- a/src/components/Inputs/BooleanInput.vue
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/components/Inputs/NumberInput.vue b/src/components/Inputs/NumberInput.vue
deleted file mode 100644
index 2543489..0000000
--- a/src/components/Inputs/NumberInput.vue
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/components/Inputs/TextAreaInput.vue b/src/components/Inputs/TextAreaInput.vue
deleted file mode 100644
index b89949b..0000000
--- a/src/components/Inputs/TextAreaInput.vue
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/components/Inputs/TextInput.vue b/src/components/Inputs/TextInput.vue
deleted file mode 100644
index 9afe051..0000000
--- a/src/components/Inputs/TextInput.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-
\ No newline at end of file
diff --git a/src/devTools/base.ts b/src/devTools/base.ts
new file mode 100644
index 0000000..e8e6699
--- /dev/null
+++ b/src/devTools/base.ts
@@ -0,0 +1,34 @@
+import type { BaseFieldElement } from "@/components/Fields/FieldList.vue";
+import { FieldsManager, type InputItem } from "./fields";
+
+/**
+ * Base extractor/parser class for contract ABI
+ */
+export class BaseDevTools {
+ protected fields: FieldsManager;
+ protected title?: string;
+
+ constructor() {
+ this.fields = new FieldsManager();
+ }
+
+ /**
+ * List of fields
+ * @returns
+ */
+ public getFields(): InputItem[] {
+ return this.fields.getFields();
+ }
+
+ public getTitle(): string | null{
+ return this.title ?? null;
+ }
+
+ public async execute(elements: BaseFieldElement[]): Promise {
+ let success = true;
+ for (const el of elements) {
+ success = success && el.validate();
+ }
+ return success;
+ }
+}
\ No newline at end of file
diff --git a/src/utils/devTools.ts b/src/devTools/fields.ts
similarity index 60%
rename from src/utils/devTools.ts
rename to src/devTools/fields.ts
index da467c3..937e81e 100644
--- a/src/utils/devTools.ts
+++ b/src/devTools/fields.ts
@@ -1,8 +1,4 @@
-import AddressField from "@/components/Fields/AddressField.vue";
-import SliceField from "@/components/Fields/SliceField.vue";
-import { TonConnectUI } from "@tonconnect/ui";
-import { beginCell, type ABIField, type ABIGetter, type ABIReceiver, type ABIType, type Builder, type ContractProvider, type TupleItem } from "ton-core";
-import type { CreateComponentPublicInstanceWithMixins } from "vue";
+import type { ABIField, ABIGetter, ABIReceiver, ABIType } from "ton-core";
export interface BaseFieldInput {
optional: boolean,
@@ -40,10 +36,6 @@ export interface SimpleFieldParameters {
format?: string | number | boolean;
};
-export type BaseFieldElement = CreateComponentPublicInstanceWithMixins<{
- validate(): boolean,
- store(builder: Builder): void,
-}>;
export class FieldsManager {
private fields: InputItem[];
@@ -90,7 +82,7 @@ export class FieldsManager {
* @param receiver
* @param types
*/
- public storeGetterFields(getter: ABIGetter, types: ABIType[]) {
+ public storeGetterFields(getter: ABIGetter) {
if (!getter.arguments) {
return;
}
@@ -193,6 +185,18 @@ export class FieldsManager {
}
}
+ /**
+ * Store `bool` field
+ * @param type
+ */
+ public storeBoolean(type: SimpleFieldParameters) {
+ this.fields.push({
+ type: "bool",
+ label: type.name,
+ optional: type.optional,
+ });
+ }
+
/**
* Store `slice` field
* @param type
@@ -235,7 +239,7 @@ export class FieldsManager {
case "int":
return this.storeUnknown(type.type); // TODO
case "bool":
- return this.storeUnknown(type.type); // TODO
+ return this.storeBoolean(type);
case "cell":
return this.storeUnknown(type.type); // TODO
case "slice":
@@ -275,146 +279,3 @@ export class FieldsManager {
}
}
}
-
-/**
- * Base extractor/parser class for contract ABI
- */
-export class BaseDevTools {
- protected fields: FieldsManager;
- protected title?: string;
- protected elements: BaseFieldElement[];
-
- constructor() {
- this.fields = new FieldsManager();
- this.elements = [];
- }
-
- /**
- * List of fields
- * @returns
- */
- public getFields(): InputItem[] {
- return this.fields.getFields();
- }
-
- public registerInput(el: BaseFieldElement) {
- console.log("NEW INPUT", this.elements.length, el);
- this.elements.push(el);
- }
-
- public getTitle(): string | null{
- return this.title ?? null;
- }
-
- public async execute(): Promise {
- let success = true;
- for (const el of this.elements) {
- success &&= el.validate();
- }
- return success;
- }
-}
-
-interface ReceiverDevToolsOptions {
- receiver: ABIReceiver;
- types: ABIType[];
- tonConnectUI: TonConnectUI;
- address: string;
- tonAmount: bigint;
-}
-
-export class ReceiverDevTools extends BaseDevTools {
- private header?: number;
- private address: string;
- private tonConnectUI: TonConnectUI;
- private tonAmount: bigint;
-
- constructor(options: ReceiverDevToolsOptions) {
- super();
-
- this.tonConnectUI = options.tonConnectUI;
- this.address = options.address;
- this.tonAmount = options.tonAmount;
-
- if (options.receiver.message.kind == "typed") {
- const type = this.fields.findTypeByName(options.types, options.receiver.message.type);
- if (type) {
- this.header = type.header ?? undefined;
- this.title = type.name;
- }
- }
-
- this.fields.storeReceiverFields(options.receiver, options.types);
- }
-
- public override async execute(): Promise {
- if (!await super.execute()) {
- return false;
- }
-
- const tx = beginCell();
-
- if (this.header) {
- tx.storeUint(this.header, 32);
- }
-
- for (const el of this.elements) {
- tx.store(el.store);
- }
-
- await this.tonConnectUI.sendTransaction(
- {
- validUntil: Math.floor(Date.now() / 1000) + 360,
- messages: [
- {
- address: this.address,
- amount: this.tonAmount.toString(),
- payload: tx.endCell().toBoc().toString("base64"),
- }
- ]
- }
- );
-
- return true;
- }
-}
-
-interface GetterDevToolsOptions {
- getter: ABIGetter;
- types: ABIType[];
- provider: ContractProvider;
-}
-
-export class GetterDevTools extends BaseDevTools {
- private name: string;
- private provider: ContractProvider;
-
- constructor(options: GetterDevToolsOptions) {
- super();
-
- this.provider = options.provider;
-
- this.name = options.getter.name;
- this.title = options.getter.name;
-
- this.fields.storeGetterFields(options.getter, options.types);
- }
-
- public override async execute(): Promise {
- if (!await super.execute()) {
- return false;
- }
-
- const args = [] as TupleItem[];
- for (const el of this.elements) {
- args.push({
- type: "slice",
- cell: beginCell().store(el.store).endCell()
- })
- }
-
- const result = await this.provider.get(this.name, args);
-
- return true;
- }
-}
diff --git a/src/devTools/getter.ts b/src/devTools/getter.ts
new file mode 100644
index 0000000..2556194
--- /dev/null
+++ b/src/devTools/getter.ts
@@ -0,0 +1,42 @@
+import type { BaseFieldElement } from "@/components/Fields/FieldList.vue";
+import { beginCell, type ABIGetter, type ContractProvider, type TupleItem } from "ton-core";
+import { BaseDevTools } from "./base";
+
+interface GetterDevToolsOptions {
+ getter: ABIGetter;
+ provider: ContractProvider;
+}
+
+export class GetterDevTools extends BaseDevTools {
+ private name: string;
+ private provider: ContractProvider;
+
+ constructor(options: GetterDevToolsOptions) {
+ super();
+
+ this.provider = options.provider;
+
+ this.name = options.getter.name;
+ this.title = options.getter.name;
+
+ this.fields.storeGetterFields(options.getter);
+ }
+
+ public override async execute(elements: BaseFieldElement[]): Promise {
+ if (!await super.execute(elements)) {
+ return false;
+ }
+
+ const args = [] as TupleItem[];
+ for (const el of elements) {
+ args.push({
+ type: "slice",
+ cell: beginCell().store(el.store).endCell()
+ })
+ }
+
+ await this.provider.get(this.name, args); // TODO
+
+ return true;
+ }
+}
diff --git a/src/devTools/receiver.ts b/src/devTools/receiver.ts
new file mode 100644
index 0000000..b0c12e9
--- /dev/null
+++ b/src/devTools/receiver.ts
@@ -0,0 +1,68 @@
+import type { TonConnectUI } from "@tonconnect/ui";
+import { beginCell, type ABIReceiver, type ABIType } from "ton-core";
+import { BaseDevTools } from "./base";
+import type { BaseFieldElement } from "@/components/Fields/FieldList.vue";
+
+interface ReceiverDevToolsOptions {
+ receiver: ABIReceiver;
+ types: ABIType[];
+ tonConnectUI: TonConnectUI;
+ address: string;
+ tonAmount: bigint;
+}
+
+export class ReceiverDevTools extends BaseDevTools {
+ private header?: number;
+ private address: string;
+ private tonConnectUI: TonConnectUI;
+ private tonAmount: bigint;
+
+ constructor(options: ReceiverDevToolsOptions) {
+ super();
+
+ this.tonConnectUI = options.tonConnectUI;
+ this.address = options.address;
+ this.tonAmount = options.tonAmount;
+
+ if (options.receiver.message.kind == "typed") {
+ const type = this.fields.findTypeByName(options.types, options.receiver.message.type);
+ if (type) {
+ this.header = type.header ?? undefined;
+ this.title = type.name;
+ }
+ }
+
+ this.fields.storeReceiverFields(options.receiver, options.types);
+ }
+
+ public override async execute(elements: BaseFieldElement[]): Promise {
+ if (!await super.execute(elements)) {
+ return false;
+ }
+
+ const tx = beginCell();
+
+ if (this.header) {
+ tx.storeUint(this.header, 32);
+ }
+
+ for (const el of elements) {
+ tx.store(el.store);
+ }
+
+ await this.tonConnectUI.sendTransaction(
+ {
+ validUntil: Math.floor(Date.now() / 1000) + 360,
+ messages: [
+ {
+ address: this.address,
+ amount: this.tonAmount.toString(),
+ payload: tx.endCell().toBoc().toString("base64"),
+ }
+ ]
+ }
+ );
+
+ return true;
+ }
+}
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 91b8d81..b8522a1 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -103,21 +103,41 @@
},
"Common": {
"Warning": "Warning!",
- "requiredField": "required field",
- "RequiredField": "This field is required",
- "NaN": "Not a number"
+ "requiredField": "required field"
},
"Fields": {
- "Address_Placeholder": "e.g. 0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkT",
- "Address_HelpText": "TON address in any format",
- "Coins_Placeholder": "e.g. 1337",
- "Coins_HelpText": "Coins amount",
- "Uint_Placeholder": "Numbers from {min} to {max}",
- "Uint_HelpText": "Unsigned {format}-bit integer field",
- "Slice_Placeholder": "",
- "Slice_HelpText": "Slice value in base64 format",
- "String_Placeholder": "",
- "String_HelpText": "String field"
+ "Errors": {
+ "RequiredField": "This field is required",
+ "WrongAddress": "Cannot parse address",
+ "InvalidNumber": "Value must be number",
+ "MustBeMoreThan": "Value must be more than {min}",
+ "MustBeLessThan": "Value must be less than {max}",
+ "InvalidBase64": "Invalid base64"
+ },
+ "Address": {
+ "Placeholder": "e.g. 0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkT",
+ "HelpText": "TON address in any format"
+ },
+ "Coins": {
+ "Placeholder": "e.g. 1337",
+ "HelpText": "Coins amount"
+ },
+ "Uint": {
+ "Placeholder": "Numbers from {min} to {max}",
+ "HelpText": "Unsigned {format}-bit integer field"
+ },
+ "Boolean": {
+ "Placeholder": "",
+ "HelpText": ""
+ },
+ "Slice": {
+ "Placeholder": "base64",
+ "HelpText": "Slice value in base64 format"
+ },
+ "String": {
+ "Placeholder": "e.g. Hello World",
+ "HelpText": "String field"
+ }
}
}
}
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index a6dea84..36113ee 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -103,22 +103,41 @@
},
"Common": {
"Warning": "Внимание!",
- "requiredField": "обязательное поле",
- "RequiredField": "Обязательное поле",
- "NaN": "Ожидалось число",
- "InvalidSlice": "Неправильный формат slice"
+ "requiredField": "обязательное поле"
},
"Fields": {
- "Address_Placeholder": "напр. 0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkT",
- "Address_HelpText": "TON адрес в любом формате",
- "Coins_Placeholder": "напр. 1337",
- "Coins_HelpText": "Количество монет",
- "Uint_Placeholder": "Число от {min} до {max}",
- "Uint_HelpText": "Целое {format}-битное число без знака",
- "Slice_Placeholder": "",
- "Slice_HelpText": "Slice в формате base64",
- "String_Placeholder": "",
- "String_HelpText": "Строка"
+ "Errors": {
+ "RequiredField": "Обязательное поле",
+ "WrongAddress": "Некорректный формат адреса",
+ "InvalidNumber": "Должно быть числом",
+ "MustBeMoreThan": "Значение должно быть больше чем {min}",
+ "MustBeLessThan": "Значение должно быть меньше чем {max}",
+ "InvalidBase64": "Неправильное значение base64"
+ },
+ "Address": {
+ "Placeholder": "напр. 0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkT",
+ "HelpText": "Адрес контракта в любом формате"
+ },
+ "Coins": {
+ "Placeholder": "напр. 1337",
+ "HelpText": "Количество токенов"
+ },
+ "Uint": {
+ "Placeholder": "Число от {min} до {max}",
+ "HelpText": "Целое {format}-битное число без знака"
+ },
+ "Boolean": {
+ "Placeholder": "",
+ "HelpText": ""
+ },
+ "Slice": {
+ "Placeholder": "base64",
+ "HelpText": "Slice в формате base64"
+ },
+ "String": {
+ "Placeholder": "напр. Привет Мир",
+ "HelpText": "Строковое поле"
+ }
}
}
}
diff --git a/src/views/DevTools.vue b/src/views/DevTools.vue
index 1b07529..d3ea92d 100644
--- a/src/views/DevTools.vue
+++ b/src/views/DevTools.vue
@@ -64,8 +64,7 @@