From 66a1feb790816fddb5b7d12197b493476f5f7572 Mon Sep 17 00:00:00 2001
From: thekiba
Date: Mon, 12 Feb 2024 19:55:26 +0400
Subject: [PATCH 1/5] chore: update @ton/core@^0.55.0
---
package.json | 2 +-
yarn.lock | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index 7f3acf8..11534a9 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
},
"devDependencies": {
"@release-it/keep-a-changelog": "^3.1.0",
- "@ton/core": "^0.53.0",
+ "@ton/core": "^0.55.0",
"@ton/crypto": "3.2.0",
"@ton/emulator": "^2.1.1",
"@types/jest": "^27.0.1",
diff --git a/yarn.lock b/yarn.lock
index 2941bd0..6eacba3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -950,14 +950,14 @@ __metadata:
languageName: node
linkType: hard
-"@ton/core@npm:^0.53.0":
- version: 0.53.0
- resolution: "@ton/core@npm:0.53.0"
+"@ton/core@npm:^0.55.0":
+ version: 0.55.0
+ resolution: "@ton/core@npm:0.55.0"
dependencies:
symbol.inspect: 1.0.1
peerDependencies:
"@ton/crypto": ">=3.2.0"
- checksum: 6d84040bce46b8167d106ca07183c60a935b3be1934a8049f8296c7a957a7d9ae8f1f1d885df2c388c801813cfa5ac742190dfabd2b34529c338754160040d44
+ checksum: 62201f0358cb9f5b1014f85681589008c9db193dd97294d48d22b590d468c33574371f4d8b203406fe8b1721d437930eb1b896c357a997fed29fd222e7da2681
languageName: node
linkType: hard
@@ -1000,7 +1000,7 @@ __metadata:
resolution: "@ton/ton@workspace:."
dependencies:
"@release-it/keep-a-changelog": ^3.1.0
- "@ton/core": ^0.53.0
+ "@ton/core": ^0.55.0
"@ton/crypto": 3.2.0
"@ton/emulator": ^2.1.1
"@types/jest": ^27.0.1
From 637af3abecc6ba0b5e153154809d2de2429de503 Mon Sep 17 00:00:00 2001
From: thekiba
Date: Mon, 12 Feb 2024 20:08:46 +0400
Subject: [PATCH 2/5] feat: extend TonClient and TonClient4 providers with open
and getTransactions methods
---
src/client/TonClient.ts | 39 ++++++++++++++++++++++++++++++++-------
src/client/TonClient4.ts | 27 +++++++++++++++++----------
2 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/src/client/TonClient.ts b/src/client/TonClient.ts
index 4cd0b59..b38d1f7 100644
--- a/src/client/TonClient.ts
+++ b/src/client/TonClient.ts
@@ -8,7 +8,26 @@
import { HttpApi } from "./api/HttpApi";
import { AxiosAdapter } from 'axios';
-import { Address, beginCell, Cell, comment, Contract, ContractProvider, ContractState, external, loadTransaction, Message, openContract, storeMessage, toNano, Transaction, TupleItem, TupleReader } from '@ton/core';
+import {
+ Address,
+ beginCell,
+ Cell,
+ comment,
+ Contract,
+ ContractProvider,
+ ContractState,
+ external,
+ loadTransaction,
+ Message,
+ openContract,
+ storeMessage,
+ toNano,
+ Transaction,
+ TupleItem,
+ TupleReader,
+ StateInit,
+ OpenedContract
+} from '@ton/core';
import { Maybe } from "../utils/maybe";
export type TonClientParameters = {
@@ -257,7 +276,7 @@ export class TonClient {
} else {
const message = external({
to: contract.address,
- init: { code: contract.init.code, data: contract.init.data },
+ init: contract.init,
body: src
});
await this.sendMessage(message);
@@ -314,7 +333,7 @@ export class TonClient {
* @param init optional init
* @returns provider
*/
- provider(address: Address, init: { code: Cell | null, data: Cell | null } | null) {
+ provider(address: Address, init: StateInit | null) {
return createProvider(this, address, init);
}
}
@@ -372,7 +391,7 @@ function parseStack(src: any[]) {
return new TupleReader(stack);
}
-function createProvider(client: TonClient, address: Address, init: { code: Cell | null, data: Cell | null } | null): ContractProvider {
+function createProvider(client: TonClient, address: Address, init: StateInit | null): ContractProvider {
return {
async getState(): Promise {
let state = await client.getContractState(address);
@@ -422,7 +441,7 @@ function createProvider(client: TonClient, address: Address, init: { code: Cell
// Resolve init
//
- let neededInit: { code: Cell | null, data: Cell | null } | null = null;
+ let neededInit: StateInit | null = null;
if (init && !await client.isContractDeployed(address)) {
neededInit = init;
}
@@ -433,7 +452,7 @@ function createProvider(client: TonClient, address: Address, init: { code: Cell
const ext = external({
to: address,
- init: neededInit ? { code: neededInit.code, data: neededInit.data } : null,
+ init: neededInit,
body: message
})
let boc = beginCell()
@@ -445,7 +464,7 @@ function createProvider(client: TonClient, address: Address, init: { code: Cell
async internal(via, message) {
// Resolve init
- let neededInit: { code: Cell | null, data: Cell | null } | null = null;
+ let neededInit: StateInit | null = null;
if (init && (!await client.isContractDeployed(address))) {
neededInit = init;
}
@@ -481,6 +500,12 @@ function createProvider(client: TonClient, address: Address, init: { code: Cell
init: neededInit,
body
});
+ },
+ open(contract: T): OpenedContract {
+ return openContract(contract, (args) => createProvider(client, args.address, args.init ?? null));
+ },
+ getTransactions(address: Address, lt: bigint, hash: Buffer, limit?: number): Promise {
+ return client.getTransactions(address, { limit: limit ?? 100, lt: lt.toString(), hash: hash.toString('base64'), inclusive: true });
}
}
}
diff --git a/src/client/TonClient4.ts b/src/client/TonClient4.ts
index c498508..b503796 100644
--- a/src/client/TonClient4.ts
+++ b/src/client/TonClient4.ts
@@ -7,7 +7,7 @@
*/
import axios, { AxiosAdapter } from "axios";
-import { Address, beginCell, Cell, comment, Contract, ContractProvider, ContractState, external, loadTransaction, openContract, parseTuple, serializeTuple, StateInit, storeMessage, toNano, Transaction, TupleItem, TupleReader } from "@ton/core";
+import { Address, beginCell, Cell, comment, Contract, ContractProvider, ContractState, external, loadTransaction, openContract, OpenedContract, parseTuple, serializeTuple, StateInit, storeMessage, toNano, Transaction, TupleItem, TupleReader } from "@ton/core";
import { Maybe } from "../utils/maybe";
import { toUrlSafe } from "../utils/toUrlSafe";
import { z } from 'zod';
@@ -293,8 +293,8 @@ export class TonClient4 {
* @param init optional init data
* @returns provider
*/
- provider(address: Address, init?: { code: Cell, data: Cell } | null) {
- return createProvider(this, null, address, init ? init : null);
+ provider(address: Address, init?: StateInit | null) {
+ return createProvider(this, null, address, init ?? null);
}
/**
@@ -304,12 +304,12 @@ export class TonClient4 {
* @param init optional init data
* @returns provider
*/
- providerAt(block: number, address: Address, init?: { code: Cell, data: Cell } | null) {
- return createProvider(this, block, address, init ? init : null);
+ providerAt(block: number, address: Address, init?: StateInit | null) {
+ return createProvider(this, block, address, init ?? null);
}
}
-function createProvider(client: TonClient4, block: number | null, address: Address, init: { code: Cell, data: Cell } | null): ContractProvider {
+function createProvider(client: TonClient4, block: number | null, address: Address, init: StateInit | null): ContractProvider {
return {
async getState(): Promise {
@@ -380,7 +380,7 @@ function createProvider(client: TonClient4, block: number | null, address: Addre
let last = await client.getLastBlock();
// Resolve init
- let neededInit: { code: Cell | null, data: Cell | null } | null = null;
+ let neededInit: StateInit | null = null;
if (init && (await client.getAccountLite(last.last.seqno, address)).account.state.type !== 'active') {
neededInit = init;
}
@@ -388,7 +388,7 @@ function createProvider(client: TonClient4, block: number | null, address: Addre
// Send with state init
const ext = external({
to: address,
- init: neededInit ? { code: neededInit.code, data: neededInit.data } : null,
+ init: neededInit,
body: message
});
let pkg = beginCell()
@@ -403,7 +403,7 @@ function createProvider(client: TonClient4, block: number | null, address: Addre
let last = await client.getLastBlock();
// Resolve init
- let neededInit: { code: Cell | null, data: Cell | null } | null = null;
+ let neededInit: StateInit | null = null;
if (init && (await client.getAccountLite(last.last.seqno, address)).account.state.type !== 'active') {
neededInit = init;
}
@@ -439,6 +439,13 @@ function createProvider(client: TonClient4, block: number | null, address: Addre
init: neededInit,
body
});
+ },
+ open(contract: T): OpenedContract {
+ return openContract(contract, (args) => createProvider(client, block, args.address, args.init ?? null));
+ },
+ async getTransactions(address: Address, lt: bigint, hash: Buffer): Promise {
+ const result = await client.getAccountTransactions(address, lt, hash);
+ return result.flatMap(x => x.tx);
}
}
}
@@ -724,4 +731,4 @@ export type ParsedTransaction = z.infer;
export type ParsedTransactions = {
blocks: z.infer,
transactions: ParsedTransaction[]
-};
\ No newline at end of file
+};
From a53b2b5392abe0cee30778da50838dd4dab823d4 Mon Sep 17 00:00:00 2001
From: thekiba
Date: Fri, 23 Feb 2024 15:47:32 +0400
Subject: [PATCH 3/5] refactor: make init parameter optional in provider method
of TonClient
---
src/client/TonClient.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/client/TonClient.ts b/src/client/TonClient.ts
index b38d1f7..fd13b8e 100644
--- a/src/client/TonClient.ts
+++ b/src/client/TonClient.ts
@@ -333,8 +333,8 @@ export class TonClient {
* @param init optional init
* @returns provider
*/
- provider(address: Address, init: StateInit | null) {
- return createProvider(this, address, init);
+ provider(address: Address, init?: StateInit | null) {
+ return createProvider(this, address, init ?? null);
}
}
From 51103254e2cb1eb7449724eb1e4be52ba420053b Mon Sep 17 00:00:00 2001
From: thekiba
Date: Fri, 23 Feb 2024 15:48:13 +0400
Subject: [PATCH 4/5] feat: enhance getTransactions of TonClient4 priovider
with limit handling
---
src/client/TonClient4.ts | 43 +++++++++++++++++++++++++++++++++++++---
1 file changed, 40 insertions(+), 3 deletions(-)
diff --git a/src/client/TonClient4.ts b/src/client/TonClient4.ts
index b503796..50080fc 100644
--- a/src/client/TonClient4.ts
+++ b/src/client/TonClient4.ts
@@ -443,9 +443,46 @@ function createProvider(client: TonClient4, block: number | null, address: Addre
open(contract: T): OpenedContract {
return openContract(contract, (args) => createProvider(client, block, args.address, args.init ?? null));
},
- async getTransactions(address: Address, lt: bigint, hash: Buffer): Promise {
- const result = await client.getAccountTransactions(address, lt, hash);
- return result.flatMap(x => x.tx);
+ async getTransactions(address: Address, lt: bigint, hash: Buffer, limit?: number): Promise {
+ // Resolve last
+ const useLimit = typeof limit === 'number';
+ if (useLimit && limit <= 0) {
+ return [];
+ }
+
+ // Load transactions
+ let transactions: Transaction[] = [];
+ do {
+ const txs = await client.getAccountTransactions(address, lt, hash);
+
+ const firstTx = txs[0].tx;
+ const [firstLt, firstHash] = [firstTx.lt, firstTx.hash()];
+ const needSkipFirst = firstLt === lt && firstHash.equals(hash);
+ if (needSkipFirst) {
+ txs.shift();
+ }
+
+ if (txs.length === 0) {
+ break;
+ }
+ const lastTx = txs[txs.length - 1].tx;
+ const [lastLt, lastHash] = [lastTx.lt, lastTx.hash()];
+ if (lastLt === lt && lastHash.equals(hash)) {
+ break;
+ }
+
+ transactions.push(...txs.map(tx => tx.tx));
+ lt = lastLt;
+ hash = lastHash;
+ } while (useLimit && transactions.length < limit);
+
+ // Apply limit
+ if (useLimit) {
+ transactions = transactions.slice(0, limit);
+ }
+
+ // Return transactions
+ return transactions;
}
}
}
From a847874730fb7ffaa706c88e0c214a180afb0be7 Mon Sep 17 00:00:00 2001
From: thekiba
Date: Fri, 23 Feb 2024 16:28:40 +0400
Subject: [PATCH 5/5] fix: refine condition to skip first transaction in
getTransactions
---
src/client/TonClient4.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/client/TonClient4.ts b/src/client/TonClient4.ts
index 50080fc..78fc249 100644
--- a/src/client/TonClient4.ts
+++ b/src/client/TonClient4.ts
@@ -457,7 +457,7 @@ function createProvider(client: TonClient4, block: number | null, address: Addre
const firstTx = txs[0].tx;
const [firstLt, firstHash] = [firstTx.lt, firstTx.hash()];
- const needSkipFirst = firstLt === lt && firstHash.equals(hash);
+ const needSkipFirst = transactions.length > 0 && firstLt === lt && firstHash.equals(hash);
if (needSkipFirst) {
txs.shift();
}