Skip to content

Commit

Permalink
v1.20.17
Browse files Browse the repository at this point in the history
  • Loading branch information
mytonwalletorg committed Jul 15, 2024
1 parent 99b06a6 commit 2c761dd
Show file tree
Hide file tree
Showing 17 changed files with 133 additions and 75 deletions.
1 change: 1 addition & 0 deletions changelogs/1.20.17.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bug fixes and performance improvements
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mytonwallet",
"version": "1.20.16",
"version": "1.20.17",
"description": "The most feature-rich web wallet and browser extension for TON – with support of multi-accounts, tokens (jettons), NFT, TON DNS, TON Sites, TON Proxy, and TON Magic.",
"main": "index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion public/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.20.16
1.20.17
11 changes: 6 additions & 5 deletions src/api/blockchains/ton/contracts/NominatorPool.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {
Cell, Contract, ContractProvider, TupleItem,
Cell, Contract, ContractProvider,
} from '@ton/core';
import {
Address, beginCell, contractAddress, TupleReader,
Expand Down Expand Up @@ -33,11 +33,12 @@ export class NominatorPool implements Contract {
withdrawRequested: boolean;
}[]> {
const res = await provider.get('list_nominators', []);
const tupleReader = (res.stack as TupleReader).readTuple();
const itemsArray = (tupleReader as any).items as bigint[][];

const items = (res.stack as any).items[0].items;

return items.map((item: { items: TupleItem[] }) => {
const tuple = new TupleReader(item.items);
return itemsArray.map((items: bigint[]) => {
const tupleItems = items.map((value) => ({ type: 'int' as const, value }));
const tuple = new TupleReader(tupleItems);

const hash = tuple.readBigNumber().toString(16).padStart(64, '0');
const address = Address.parse(`0:${hash}`);
Expand Down
4 changes: 3 additions & 1 deletion src/api/blockchains/ton/nfts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { ApiNft, ApiNftUpdate } from '../../types';
import type { ApiCheckTransactionDraftResult } from './types';

import {
BURN_ADDRESS,
NFT_BATCH_SIZE,
NOTCOIN_EXCHANGERS,
NOTCOIN_FORWARD_TON_AMOUNT,
Expand Down Expand Up @@ -156,7 +157,8 @@ export async function submitNftTransfers(options: {

const messages = nftAddresses.map((nftAddress, index) => {
const nft = nfts?.[index];
const isNotcoinBurn = nft?.collectionAddress === NOTCOIN_VOUCHERS_ADDRESS;
const isNotcoinBurn = nft?.collectionAddress === NOTCOIN_VOUCHERS_ADDRESS
&& (toAddress === BURN_ADDRESS || NOTCOIN_EXCHANGERS.includes(toAddress as any));
const payload = isNotcoinBurn
? buildNotcoinVoucherExchange(fromAddress, nftAddress, nft!.index)
: buildNftTransferPayload(fromAddress, toAddress, comment);
Expand Down
5 changes: 2 additions & 3 deletions src/api/blockchains/ton/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { parseTxId } from './util';
import { fetchAddressBook, fetchLatestTxId, fetchTransactions } from './util/apiV3';
import { decryptMessageComment, encryptMessageComment } from './util/encryption';
import { buildNft, parseWalletTransactionBody } from './util/metadata';
import { sendExternal } from './util/sendExternal';
import { fetchNftItems } from './util/tonapiio';
import {
commentToBytes,
Expand All @@ -52,7 +53,6 @@ import {
parseAddress,
parseBase64,
resolveTokenWalletAddress,
sendExternal,
toBase64Address,
} from './util/tonCore';
import { fetchStoredAccount, fetchStoredAddress } from '../../common/accounts';
Expand Down Expand Up @@ -169,9 +169,8 @@ export async function checkTransactionDraft(

const account = await fetchStoredAccount(accountId);
const { address } = account;
const isLedger = !!account.ledger;

if (data && typeof data === 'string' && !isBase64Data && !isLedger) {
if (data && typeof data === 'string' && !isBase64Data) {
data = commentToBytes(data);
}

Expand Down
1 change: 1 addition & 0 deletions src/api/blockchains/ton/util/TonClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { logDebug } from '../../../../util/logs';

axiosRetry(axios, {
retries: DEFAULT_RETRIES,
shouldResetTimeout: true,
retryDelay: (retryCount) => {
return retryCount * DEFAULT_ERROR_PAUSE;
},
Expand Down
51 changes: 51 additions & 0 deletions src/api/blockchains/ton/util/sendExternal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { Cell } from '@ton/core';
import { beginCell, external, storeMessage } from '@ton/core';

import type { TonClient } from './TonClient';
import type { TonWallet } from './tonCore';

import { dieselSendBoc } from './diesel';

export async function sendExternal(
client: TonClient,
wallet: TonWallet,
message: Cell,
withDiesel?: boolean,
) {
const {
address,
init,
} = wallet;

let neededInit: { data: Cell; code: Cell } | undefined;
if (init && !await client.isContractDeployed(address)) {
neededInit = init;
}

const ext = external({
to: address,
init: neededInit ? {
code: neededInit.code,
data: neededInit.data,
} : undefined,
body: message,
});

const cell = beginCell()
.store(storeMessage(ext))
.endCell();

const msgHash = cell.hash().toString('base64');
const boc = cell.toBoc().toString('base64');

if (withDiesel) {
await dieselSendBoc(boc);
} else {
await client.sendFile(boc);
}

return {
boc,
msgHash,
};
}
53 changes: 13 additions & 40 deletions src/api/blockchains/ton/util/tonCore.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import type { OpenedContract } from '@ton/core';
import {
Address, beginCell, Builder, Cell, external, storeMessage,
} from '@ton/core';
import { Address, Builder, Cell } from '@ton/core';
import axios from 'axios';
import { WalletContractV1R1 } from '@ton/ton/dist/wallets/WalletContractV1R1';
import { WalletContractV1R2 } from '@ton/ton/dist/wallets/WalletContractV1R2';
Expand Down Expand Up @@ -32,9 +30,13 @@ import { JettonWallet } from '../contracts/JettonWallet';
import { hexToBytes } from '../../../common/utils';
import { getEnvironment } from '../../../environment';
import {
DEFAULT_IS_BOUNCEABLE, DNS_ZONES_MAP, JettonOpCode, LiquidStakingOpCode, OpCode, WORKCHAIN,
DEFAULT_IS_BOUNCEABLE,
DNS_ZONES_MAP,
JettonOpCode,
LiquidStakingOpCode,
OpCode,
WORKCHAIN,
} from '../constants';
import { dieselSendBoc } from './diesel';
import { generateQueryId } from './index';

import { TonClient } from './TonClient';
Expand Down Expand Up @@ -225,6 +227,12 @@ export function packBytesAsSnake(bytes: Uint8Array, maxBytes = TON_MAX_COMMENT_B
return bytes;
}

return packBytesAsSnakeCell(bytes);
}

export function packBytesAsSnakeCell(bytes: Uint8Array): Cell {
const buffer = Buffer.from(bytes);

const mainBuilder = new Builder();
let prevBuilder: Builder | undefined;
let currentBuilder = mainBuilder;
Expand Down Expand Up @@ -365,38 +373,3 @@ export async function getDnsItemDomain(network: ApiNetwork, address: Address | s

return `${base}${zone}`;
}

export async function sendExternal(
client: TonClient,
wallet: TonWallet,
message: Cell,
withDiesel?: boolean,
) {
const { address, init } = wallet;

let neededInit: { data: Cell; code: Cell } | undefined;
if (init && !await client.isContractDeployed(address)) {
neededInit = init;
}

const ext = external({
to: address,
init: neededInit ? { code: neededInit.code, data: neededInit.data } : undefined,
body: message,
});

const cell = beginCell()
.store(storeMessage(ext))
.endCell();

const msgHash = cell.hash().toString('base64');
const boc = cell.toBoc().toString('base64');

if (withDiesel) {
await dieselSendBoc(boc);
} else {
await client.sendFile(boc);
}

return { boc, msgHash };
}
2 changes: 1 addition & 1 deletion src/components/settings/SettingsWalletVersion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function SettingsWalletVersion({
<div className={styles.blockWalletVersionReadMore}>
{lang('$read_more_about_wallet_version', {
ton_link: (
<a href="https://docs.ton.org/ko/participate/wallets/contracts" target="_blank" rel="noreferrer">
<a href="https://docs.ton.org/participate/wallets/contracts" target="_blank" rel="noreferrer">
ton.org
</a>
),
Expand Down
4 changes: 2 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export const PROXY_HOSTS = process.env.PROXY_HOSTS;

export const TINY_TRANSFER_MAX_COST = 0.01;

export const LANG_CACHE_NAME = 'mtw-lang-118';
export const LANG_CACHE_NAME = 'mtw-lang-120';

export const LANG_LIST: LangItem[] = [{
langCode: 'en',
Expand Down Expand Up @@ -292,7 +292,7 @@ export const BURN_ADDRESS = 'UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJKZ';
export const DEFAULT_WALLET_VERSION: ApiWalletVersion = 'v4R2';
export const POPULAR_WALLET_VERSIONS: ApiWalletVersion[] = ['v3R1', 'v3R2', 'v4R2', 'W5'];

export const DEFAULT_TIMEOUT = 5000;
export const DEFAULT_TIMEOUT = 10000;
export const DEFAULT_RETRIES = 3;
export const DEFAULT_ERROR_PAUSE = 500;

Expand Down
13 changes: 13 additions & 0 deletions src/global/actions/api/swap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ const PAIRS_CACHE: Record<string, { data: ApiSwapPairAsset[]; timestamp: number
const CACHE_DURATION = 15 * 60 * 1000; // 15 minutes
const WAIT_FOR_CHANGELLY = 5 * 1000;
const CLOSING_BOTTOM_SHEET_DURATION = 100; // Like in `useDelegatingBottomSheet`
let isEstimateSwapBeingExecuted = false;
let isEstimateCexSwapBeingExecuted = false;

function buildSwapBuildRequest(global: GlobalState): ApiSwapBuildRequest {
const {
Expand Down Expand Up @@ -523,6 +525,9 @@ addActionHandler('setSlippage', (global, actions, { slippage }) => {
});

addActionHandler('estimateSwap', async (global, actions, { shouldBlock, isEnoughToncoin }) => {
if (isEstimateSwapBeingExecuted) return;

isEstimateSwapBeingExecuted = true;
const resetParams = {
amountOutMin: '0',
transactionFee: '0',
Expand All @@ -547,6 +552,7 @@ addActionHandler('estimateSwap', async (global, actions, { shouldBlock, isEnough
...resetParams,
});
setGlobal(global);
isEstimateSwapBeingExecuted = false;
return;
}

Expand All @@ -565,6 +571,7 @@ addActionHandler('estimateSwap', async (global, actions, { shouldBlock, isEnough
errorType: SwapErrorType.InvalidPair,
});
setGlobal(global);
isEstimateSwapBeingExecuted = false;
return;
}

Expand Down Expand Up @@ -593,6 +600,7 @@ addActionHandler('estimateSwap', async (global, actions, { shouldBlock, isEnough
shouldTryDiesel: isEnoughToncoin === false,
});

isEstimateSwapBeingExecuted = false;
global = getGlobal();

if (!estimate || 'error' in estimate) {
Expand Down Expand Up @@ -648,6 +656,9 @@ addActionHandler('estimateSwap', async (global, actions, { shouldBlock, isEnough
});

addActionHandler('estimateSwapCex', async (global, actions, { shouldBlock }) => {
if (isEstimateCexSwapBeingExecuted) return;

isEstimateCexSwapBeingExecuted = true;
const amount = global.currentSwap.inputSource === SwapInputSource.In
? { amountOut: undefined }
: { amountIn: undefined };
Expand Down Expand Up @@ -681,6 +692,7 @@ addActionHandler('estimateSwapCex', async (global, actions, { shouldBlock }) =>
...resetParams,
});
setGlobal(global);
isEstimateCexSwapBeingExecuted = false;
return;
}

Expand Down Expand Up @@ -716,6 +728,7 @@ addActionHandler('estimateSwapCex', async (global, actions, { shouldBlock }) =>
});

global = getGlobal();
isEstimateCexSwapBeingExecuted = false;

if (!estimate || 'errors' in estimate) {
global = updateCurrentSwap(global, {
Expand Down
13 changes: 5 additions & 8 deletions src/i18n/ru.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ View Address on %ton_explorer_name%: Открыть в %ton_explorer_name%
No suggestions, you're on your own!: Ничего не найдено :(
Play Sounds: Включить звуки
Focus on asset value rather than current balance: Фокус на стоимости активов вместо текущего баланса
$tiny_transfers_help: Отключите эту опцию, чтобы показывать переводы стоимостью менее $%value%. Имейте в виду, что такие переводы часто используются для спама и мошенничества.
$tiny_transfers_help: Скрыть переводы стоимостью менее $%value%. Имейте в виду такие суммы часто отправляют спамеры и мошенники.
Today: Сегодня
Yesterday: Вчера
Now: Сейчас
Expand Down Expand Up @@ -279,9 +279,9 @@ $dapps-description: Вы можете подключиться к децентр
Logged in with MyTonWallet: Подключены с помощью MyTonWallet
No active connections: Нет активных подключений
Other: Другие
Assets & Activity: Активы и Лента
Assets & Activity: Активы и лента
Token Settings: Настройки токенов
My Tokens: Мои Токены
My Tokens: Мои токены
Add Token: Добавить токен
Delete Token: Удалить токен
Are you sure you want to delete?: Вы уверены, что хотите удалить %token%?
Expand Down Expand Up @@ -528,10 +528,7 @@ Required: Обязательно
Comment is too long.: Комментарий слишком длинный.
Memo: Memo
Memo was copied!: Memo был скопирован!
$hide_tokens_no_cost_help: |
Выключите эту опцию, чтобы отображать в вашей учётной записи токены со стоимостью менее $%value%.
Пожалуйста, имейте в виду, что такие жетоны часто используются для спама и мошенничества.
Вы также можете выборочно включить и отключить конкретные токены, используя список ниже на этом экране.
$hide_tokens_no_cost_help: Скрыть токены стоимостью менее $%value%. Имейте в виду — такие токены часто отправляют спамеры и мошенники. На этом же экране ниже вы можете скрыть отдельные токены.
No internet connection. Please check your connection and try again.: Отсутствует подключение к интернету. Пожалуйста, проверьте своё соединение и попробуйте снова.
To use this feature, first enable Face ID in your phone settings.: Чтобы использовать эту функцию, сначала активируйте идентификацию лица в настройках телефона.
To use this feature, first enable biometrics in your phone settings.: Чтобы использовать эту функцию, сначала активируйте биометрию в настройках телефона.
Expand Down Expand Up @@ -608,7 +605,7 @@ until %date%: до %date%
"%volume% in %amount% parts": "%volume% в %amount% частях"
Unfreeze: Разморозить
Claim: Заклеймить
Confirm Unfreezing: Подтверждение размораживания
Confirm Unfreezing: Подтвердите размораживание
Insufficient Balance for Fee.: Недостаточный баланс для комиссии.
$fee_value_bold: "**Комиссия:** %fee%"
MyTonWallet Features: Функции MyTonWallet
Expand Down
6 changes: 3 additions & 3 deletions src/util/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { pause } from './schedulers';

type QueryParams = Record<string, string | number | boolean | string[]>;

const DEFAULT_TIMEOUTS = [15000, 30000]; // 15, 15, 30 sec
const MAX_TIMEOUT = 30000; // 30 sec

export async function fetchJson(url: string | URL, data?: QueryParams, init?: RequestInit) {
const urlObject = new URL(url);
Expand Down Expand Up @@ -37,7 +37,7 @@ export async function fetchWithRetry(url: string | URL, init?: RequestInit, opti
}) {
const {
retries = DEFAULT_RETRIES,
timeouts = DEFAULT_TIMEOUTS,
timeouts = DEFAULT_TIMEOUT,
shouldSkipRetryFn = isNotTemporaryError,
} = options ?? {};

Expand All @@ -52,7 +52,7 @@ export async function fetchWithRetry(url: string | URL, init?: RequestInit, opti

const timeout = Array.isArray(timeouts)
? timeouts[i - 1] ?? timeouts[timeouts.length - 1]
: timeouts;
: Math.min(timeouts * i, MAX_TIMEOUT);
const response = await fetchWithTimeout(url, init, timeout);
statusCode = response.status;

Expand Down
Loading

0 comments on commit 2c761dd

Please sign in to comment.