wan-ton-sdk 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Bridge.compile.ts +8 -0
- package/Bridge.ts +645 -0
- package/Bridge.ts.org +647 -0
- package/Fake.compile.ts +8 -0
- package/GroupApprove.compile.ts +6 -0
- package/GroupApprove.ts +274 -0
- package/JettonMinter.compile.ts +5 -0
- package/JettonMinter.ts +135 -0
- package/JettonWallet.compile.ts +5 -0
- package/JettonWallet.ts +127 -0
- package/README.md +24 -0
- package/Signature.compile.ts +6 -0
- package/Signature.ts +105 -0
- package/address.compile.ts +8 -0
- package/client/1.json +1730 -0
- package/client/client.ts +73 -0
- package/client/log/.ba8901062aebb86bf525b42c65ff84f9485419e4-audit.json +15 -0
- package/client/log/wan-ton-sdk.out.2024-12-19 +0 -0
- package/code/decode.spec.ts +81 -0
- package/code/encode-decode.ts +622 -0
- package/code/log/.ba8901062aebb86bf525b42c65ff84f9485419e4-audit.json +20 -0
- package/code/log/wan-ton-sdk.out.2025-01-15 +0 -0
- package/code/log/wan-ton-sdk.out.2025-01-20 +0 -0
- package/code/userLock.ts +291 -0
- package/common.ts +62 -0
- package/config/config-ex.ts +25 -0
- package/config/config.ts +1 -0
- package/const/const-value.ts +33 -0
- package/contractAccess/bridgeAccess.ts +60 -0
- package/contractAccess/groupApproveAccess.ts +59 -0
- package/data/EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs.json +7348 -0
- package/db/Db.spec.ts +193 -0
- package/db/Db.ts +736 -0
- package/db/DbAccess.spec.ts +23 -0
- package/db/DbAccess.ts +174 -0
- package/db/common.ts +94 -0
- package/db/log/.ba8901062aebb86bf525b42c65ff84f9485419e4-audit.json +15 -0
- package/db/log/wan-ton-sdk.out.2025-04-21 +0 -0
- package/event/getEvents.ts +441 -0
- package/event/log/.ba8901062aebb86bf525b42c65ff84f9485419e4-audit.json +15 -0
- package/event/log/wan-ton-sdk.out.2024-12-19 +0 -0
- package/example/0:1.txt +1 -0
- package/example/AddToken-ex.ts +148 -0
- package/example/README.md +21 -0
- package/example/addSmg-ex.ts +78 -0
- package/example/addTokenPair-ex.ts +73 -0
- package/example/compileContract-ex.ts +10 -0
- package/example/converTranToTonTran.ts +43 -0
- package/example/createDb-ex.ts +8 -0
- package/example/dbFeedTrans-ex.ts +20 -0
- package/example/delTokenPair-ex.ts +63 -0
- package/example/deploy-ex.ts +68 -0
- package/example/getAllEvents-ex.ts +61 -0
- package/example/getAllTrans.ts +32 -0
- package/example/getContractState-ex.ts +33 -0
- package/example/getEventByHash-ex.ts +39 -0
- package/example/getEvents-ex.ts +55 -0
- package/example/getJettonInfo-ex.ts +44 -0
- package/example/getTokenPair-ex.ts +47 -0
- package/example/getTransByRange-ex.ts +81 -0
- package/example/getTransaction-ex.ts +62 -0
- package/example/isTranSuccess-ex.ts +33 -0
- package/example/locateTx-ex.ts +44 -0
- package/example/log/.ba8901062aebb86bf525b42c65ff84f9485419e4-audit.json +55 -0
- package/example/log/wan-ton-sdk.out.2025-04-21 +447 -0
- package/example/log/wan-ton-sdk.out.2025-04-22 +1918 -0
- package/example/log/wan-ton-sdk.out.2025-04-23 +4216 -0
- package/example/log/wan-ton-sdk.out.2025-04-24.gz +0 -0
- package/example/log/wan-ton-sdk.out.2025-04-25 +46814 -0
- package/example/log/wan-ton-sdk.out.2025-04-27.gz +0 -0
- package/example/log/wan-ton-sdk.out.2025-04-28 +4966 -0
- package/example/log/wan-ton-sdk.out.2025-04-29 +1328 -0
- package/example/log/wan-ton-sdk.out.2025-04-30 +9 -0
- package/example/mintToken-ex.ts +82 -0
- package/example/setFee-ex.ts +82 -0
- package/example/setFeeProxy.ts +70 -0
- package/example/smgRelease-ex.ts +173 -0
- package/example/upgradeBridgeSc-ex.ts +49 -0
- package/example/userLock-ex.ts +78 -0
- package/fee/fee.ts +23 -0
- package/index.ts +67 -0
- package/jest.config.ts +9 -0
- package/log/.ba8901062aebb86bf525b42c65ff84f9485419e4-audit.json +20 -0
- package/log/wan-ton-sdk.out.2025-04-21 +0 -0
- package/log/wan-ton-sdk.out.2025-04-30 +10 -0
- package/opcodes.ts +58 -0
- package/package.json +34 -0
- package/publish.sh +78 -0
- package/sign/buildHash.ts +47 -0
- package/sign/log/.ba8901062aebb86bf525b42c65ff84f9485419e4-audit.json +15 -0
- package/sign/log/wan-ton-sdk.out.2025-04-14 +3 -0
- package/sign/rawTrans.spec.ts +117 -0
- package/sign/rawTrans.ts +122 -0
- package/sign/tools-secp256k1.js +210 -0
- package/testData/JettonMinter.compile.func.ts +8 -0
- package/testData/JettonWallet.compile.func.ts +8 -0
- package/testData/addressList.json +6 -0
- package/testData/bridge.compile.func.ts +8 -0
- package/testData/bridge.compiled.json +1 -0
- package/testData/contractAddress.json +7 -0
- package/testData/jettonTokenInfo.json +14 -0
- package/testData/prvlist.json +6 -0
- package/testData/smg.json +5 -0
- package/testData/tokenInfo.json +23 -0
- package/transResult/transResult.ts +621 -0
- package/tsconfig.json +19 -0
- package/utils/.compiled.json +1 -0
- package/utils/compileContract.ts +60 -0
- package/utils/log/.ba8901062aebb86bf525b42c65ff84f9485419e4-audit.json +15 -0
- package/utils/log/wan-ton-sdk.out.2025-01-08 +0 -0
- package/utils/logger.spec.ts +14 -0
- package/utils/logger.ts +96 -0
- package/utils/utils.spec.ts +21 -0
- package/utils/utils.ts +295 -0
- package/wallet/balance.ts +29 -0
- package/wallet/jetton.spec.ts +27 -0
- package/wallet/jetton.ts +159 -0
- package/wallet/walletContract.spec.ts +111 -0
- package/wallet/walletContract.ts +105 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
import {compileFunc, compilerVersion, CompilerConfig, CompilerVersion} from '@ton-community/func-js';
|
2
|
+
import {Cell} from '@ton/core';
|
3
|
+
import fs_1 from "fs";
|
4
|
+
|
5
|
+
import {logger} from '../utils/logger'
|
6
|
+
const formatUtil = require('util');
|
7
|
+
|
8
|
+
export interface CR {
|
9
|
+
version:CompilerVersion,
|
10
|
+
hashHex:string,
|
11
|
+
codeBase64:string,
|
12
|
+
}
|
13
|
+
|
14
|
+
export async function compileContract(conf: CompilerConfig) {
|
15
|
+
// You can get compiler version
|
16
|
+
let version = await compilerVersion();
|
17
|
+
|
18
|
+
let result = await compileFunc(conf);
|
19
|
+
|
20
|
+
if (result.status === 'error') {
|
21
|
+
console.error(result.message)
|
22
|
+
return;
|
23
|
+
}
|
24
|
+
|
25
|
+
let codeCell = Cell.fromBoc(Buffer.from(result.codeBoc, "base64"))[0];
|
26
|
+
logger.info(formatUtil.format("hash=>",codeCell.hash().toString('hex')));
|
27
|
+
let cr:CR = {
|
28
|
+
version,
|
29
|
+
hashHex:codeCell.hash().toString('hex'),
|
30
|
+
codeBase64: result.codeBoc,
|
31
|
+
}
|
32
|
+
return cr;
|
33
|
+
}
|
34
|
+
|
35
|
+
export function writeCR(filePath:string,cr:CR){
|
36
|
+
return fs_1.writeFileSync(filePath,JSON.stringify(cr));
|
37
|
+
}
|
38
|
+
|
39
|
+
export async function doCompile(conf:CompilerConfig,resultFilePath?:string){
|
40
|
+
let ret = await compileContract(conf);
|
41
|
+
//logger.info(formatUtil.format(ret?.toBoc().toString('base64'));
|
42
|
+
|
43
|
+
logger.info(formatUtil.format("result file path: %s",resultFilePath));
|
44
|
+
if(resultFilePath){
|
45
|
+
writeCR(resultFilePath,ret);
|
46
|
+
let cr:CR = JSON.parse(fs_1.readFileSync(resultFilePath,'utf-8'));
|
47
|
+
let codeCell = Cell.fromBoc(Buffer.from(cr.codeBase64, "base64"))[0];
|
48
|
+
return {
|
49
|
+
status:codeCell.hash().toString('hex') == cr.hashHex && cr.hashHex == ret?.hashHex,
|
50
|
+
codeCell:codeCell
|
51
|
+
}
|
52
|
+
}else{
|
53
|
+
let codeCell = Cell.fromBoc(Buffer.from(ret?.codeBase64, "base64"))[0];
|
54
|
+
return {
|
55
|
+
status:true,
|
56
|
+
codeCell:codeCell
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"keep": {
|
3
|
+
"days": true,
|
4
|
+
"amount": 10
|
5
|
+
},
|
6
|
+
"auditLog": "log/.ba8901062aebb86bf525b42c65ff84f9485419e4-audit.json",
|
7
|
+
"files": [
|
8
|
+
{
|
9
|
+
"date": 1736305494907,
|
10
|
+
"name": "log/wan-ton-sdk.out.2025-01-08",
|
11
|
+
"hash": "51ab306b7b02734edef3a311247d781fcca3d2c4118fc13713f863b2e9b1b14b"
|
12
|
+
}
|
13
|
+
],
|
14
|
+
"hashType": "sha256"
|
15
|
+
}
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import {logger} from './logger'
|
2
|
+
const formatUtil = require('util');
|
3
|
+
|
4
|
+
describe('logger', () => {
|
5
|
+
|
6
|
+
beforeAll(async () => {
|
7
|
+
},50000);
|
8
|
+
|
9
|
+
it('logger.info', async () => {
|
10
|
+
logger.info("Entering ");
|
11
|
+
logger.info(formatUtil.format("hello %s %s","Jacob", "alice"));
|
12
|
+
},500000);
|
13
|
+
|
14
|
+
});
|
package/utils/logger.ts
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
import winston from "winston";
|
2
|
+
import DailyRotateFile from 'winston-daily-rotate-file';
|
3
|
+
const moment = require('moment');
|
4
|
+
const path = require('path');
|
5
|
+
|
6
|
+
const customFormat = winston.format.printf(({ level, message, timestamp}) => {
|
7
|
+
return `${timestamp} [${level}]: ${message}`;
|
8
|
+
});
|
9
|
+
|
10
|
+
class Logger {
|
11
|
+
private filePath: any;
|
12
|
+
private errorFilePath: string;
|
13
|
+
private level: string;
|
14
|
+
private errorFile: any;
|
15
|
+
private file: any;
|
16
|
+
private name: any;
|
17
|
+
private logger: any;
|
18
|
+
|
19
|
+
constructor(name, file, errorFile, level = 'info') {
|
20
|
+
this.name = name;
|
21
|
+
this.file = file;
|
22
|
+
this.errorFile = errorFile;
|
23
|
+
this.level = level ? level : 'info';
|
24
|
+
if (global.pkg) {
|
25
|
+
this.filePath = path.join(process.cwd(), file);
|
26
|
+
this.errorFilePath = path.join(process.cwd(), errorFile);
|
27
|
+
} else {
|
28
|
+
this.filePath = file;
|
29
|
+
this.errorFilePath = errorFile;
|
30
|
+
}
|
31
|
+
|
32
|
+
this.init(this.name, this.file, this.errorFile, this.level);
|
33
|
+
}
|
34
|
+
|
35
|
+
init(name, file, errorFile, level) {
|
36
|
+
this.logger = winston.createLogger({
|
37
|
+
levels: winston.config.syslog.levels,
|
38
|
+
level: level,
|
39
|
+
format: winston.format.combine(
|
40
|
+
winston.format.timestamp(),
|
41
|
+
customFormat
|
42
|
+
),
|
43
|
+
transports: [
|
44
|
+
//
|
45
|
+
// - Write to all logs with level `level` and below to file
|
46
|
+
// - Write all logs error (and below) to errorFile.
|
47
|
+
//
|
48
|
+
new winston.transports.Console({
|
49
|
+
handleExceptions: true
|
50
|
+
}),
|
51
|
+
new (DailyRotateFile)({
|
52
|
+
filename: this.filePath,
|
53
|
+
level: level,
|
54
|
+
datePattern: 'YYYY-MM-DD',
|
55
|
+
zippedArchive: true,
|
56
|
+
maxSize: '50m',
|
57
|
+
maxFiles: (global.testnet || global.isLeader) ? '30d' : '10d'
|
58
|
+
})
|
59
|
+
],
|
60
|
+
exitOnError: false
|
61
|
+
});
|
62
|
+
}
|
63
|
+
|
64
|
+
debug(...params) {
|
65
|
+
try {
|
66
|
+
this.logger.debug(...params);
|
67
|
+
} catch (err) {
|
68
|
+
this.error(err);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
info(...params) {
|
73
|
+
try {
|
74
|
+
this.logger.info(...params);
|
75
|
+
} catch (err) {
|
76
|
+
this.error(err);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
warn(...params) {
|
81
|
+
try {
|
82
|
+
this.logger.warning(...params);
|
83
|
+
} catch (err) {
|
84
|
+
this.error(err);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
error(...params) {
|
89
|
+
try {
|
90
|
+
this.logger.error(...params);
|
91
|
+
} catch (err) {
|
92
|
+
console.log(err);
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
export const logger = new Logger("wan-ton-sdk", './log/wan-ton-sdk.out', './log/wan-ton-sdk.err', global.SDK_LOG_LEVEL);
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import {logger} from './logger'
|
2
|
+
const formatUtil = require('util');
|
3
|
+
import {getQueryID} from "./utils";
|
4
|
+
|
5
|
+
describe('queryID', () => {
|
6
|
+
|
7
|
+
beforeAll(async () => {
|
8
|
+
},50000);
|
9
|
+
|
10
|
+
it('getQueryID', async () => {
|
11
|
+
logger.info("Entering ");
|
12
|
+
while(true){
|
13
|
+
let queryID = await getQueryID();
|
14
|
+
if(queryID<0){
|
15
|
+
console.log("queryId",queryID);
|
16
|
+
break;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
},500000);
|
20
|
+
|
21
|
+
});
|
package/utils/utils.ts
ADDED
@@ -0,0 +1,295 @@
|
|
1
|
+
|
2
|
+
import { Address, toNano, fromNano } from "@ton/core";
|
3
|
+
import {getSecureRandomNumber} from '@ton/crypto';
|
4
|
+
|
5
|
+
export const randomAddress = (wc: number = 0) => {
|
6
|
+
const buf = Buffer.alloc(32);
|
7
|
+
for (let i = 0; i < buf.length; i++) {
|
8
|
+
buf[i] = Math.floor(Math.random() * 256);
|
9
|
+
}
|
10
|
+
return new Address(wc, buf);
|
11
|
+
};
|
12
|
+
|
13
|
+
const getRandom = (min:number, max:number) => {
|
14
|
+
return Math.random() * (max - min) + min;
|
15
|
+
}
|
16
|
+
|
17
|
+
export const getRandomTon = (min:number, max:number): bigint => {
|
18
|
+
return toNano(getRandom(min, max).toFixed(9));
|
19
|
+
}
|
20
|
+
|
21
|
+
export const BufferrToHexString = (buff: Buffer): string =>{
|
22
|
+
return "0x" + buff.toString('hex');
|
23
|
+
}
|
24
|
+
|
25
|
+
export const HexStringToBuffer = (str:String): Buffer =>{
|
26
|
+
return Buffer.from(str,'hex')
|
27
|
+
}
|
28
|
+
|
29
|
+
export async function sleep(ms:number) {
|
30
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
31
|
+
}
|
32
|
+
|
33
|
+
|
34
|
+
export async function getQueryID(){
|
35
|
+
while(true){
|
36
|
+
let queryID = await getSecureRandomNumber(1,Math.pow(2,52)-1);
|
37
|
+
if(queryID>0){
|
38
|
+
return queryID;
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
/*export function bigIntReviver(key, value) {
|
45
|
+
if (typeof value === "string" && value.endsWith("n")) {
|
46
|
+
return BigInt(value.slice(0, -1));
|
47
|
+
}
|
48
|
+
return value;
|
49
|
+
}
|
50
|
+
|
51
|
+
export function bigIntReplacer(key, value) {
|
52
|
+
if (typeof value === "bigint") {
|
53
|
+
return value.toString() + "n";
|
54
|
+
}
|
55
|
+
return value;
|
56
|
+
}*/
|
57
|
+
|
58
|
+
export function bigIntReviver(key, value) {
|
59
|
+
if (typeof value === "string" && value.endsWith("n")) {
|
60
|
+
return BigInt(value.slice(0, -1));
|
61
|
+
}
|
62
|
+
if(typeof value === "string"){
|
63
|
+
return BigInt(value);
|
64
|
+
}
|
65
|
+
return value;
|
66
|
+
}
|
67
|
+
|
68
|
+
export function bigIntReplacer(key, value) {
|
69
|
+
if (typeof value === "bigint") {
|
70
|
+
return value.toString(10);
|
71
|
+
}
|
72
|
+
return value;
|
73
|
+
}
|
74
|
+
|
75
|
+
export function isAddressEqual(src:Address|string,dst:Address|string){
|
76
|
+
let srcAddr :Address;
|
77
|
+
let dstAddr :Address;
|
78
|
+
if(!(src instanceof Address)){
|
79
|
+
srcAddr = Address.parse(src)
|
80
|
+
}else{
|
81
|
+
srcAddr = src
|
82
|
+
}
|
83
|
+
|
84
|
+
if(!(dst instanceof Address)){
|
85
|
+
dstAddr = Address.parse(dst)
|
86
|
+
}else{
|
87
|
+
dstAddr = dst
|
88
|
+
}
|
89
|
+
|
90
|
+
return srcAddr.equals(dstAddr);
|
91
|
+
}
|
92
|
+
|
93
|
+
export function bigIntToBytes32(value:bigint) {
|
94
|
+
|
95
|
+
if (value < 0n || value >= 2n ** 256n) {
|
96
|
+
throw new Error("Value must be a 256-bit unsigned integer");
|
97
|
+
}
|
98
|
+
const hex = value.toString(16).padStart(64, '0');
|
99
|
+
return Buffer.from(hex, 'hex');
|
100
|
+
}
|
101
|
+
|
102
|
+
export function int64ToByte32(int64Value) {
|
103
|
+
// 确保输入是 BigInt
|
104
|
+
if (typeof int64Value !== 'bigint') {
|
105
|
+
throw new Error('Input must be a BigInt');
|
106
|
+
}
|
107
|
+
|
108
|
+
// 创建一个 8 字节的缓冲区(64 位)
|
109
|
+
const buffer = new ArrayBuffer(8);
|
110
|
+
const view = new DataView(buffer);
|
111
|
+
|
112
|
+
// 将 BigInt 写入缓冲区(小端序)
|
113
|
+
view.setBigUint64(0, int64Value, true);
|
114
|
+
|
115
|
+
// 将缓冲区转换为字节数组
|
116
|
+
const byteArray = new Uint8Array(buffer);
|
117
|
+
|
118
|
+
// 创建一个 32 字节的缓冲区
|
119
|
+
const byte32Buffer = new ArrayBuffer(32);
|
120
|
+
const byte32Array = new Uint8Array(byte32Buffer);
|
121
|
+
|
122
|
+
// 将 8 字节的 int64 复制到 32 字节缓冲区的末尾(右对齐)
|
123
|
+
byte32Array.set(byteArray, 24); // 24 = 32 - 8
|
124
|
+
|
125
|
+
// 将字节数组转换为十六进制字符串
|
126
|
+
let hexString = '0x';
|
127
|
+
byte32Array.forEach(byte => {
|
128
|
+
hexString += byte.toString(16).padStart(2, '0');
|
129
|
+
});
|
130
|
+
|
131
|
+
return hexString;
|
132
|
+
}
|
133
|
+
|
134
|
+
export function remove0x(str:string){
|
135
|
+
return (str.slice(0,2).toLowerCase() == '0x') ? str.slice(2):str;
|
136
|
+
}
|
137
|
+
|
138
|
+
export function add0x(str:string){
|
139
|
+
return (str.slice(0,2).toLowerCase() == '0x') ? str:'0x' + str;
|
140
|
+
}
|
141
|
+
|
142
|
+
|
143
|
+
const fs = require('node:fs/promises');
|
144
|
+
const path = require('node:path');
|
145
|
+
|
146
|
+
export async function ensureFileAndPath(fullFilePath:string):Promise<boolean>{
|
147
|
+
try {
|
148
|
+
await fs.access(fullFilePath);
|
149
|
+
console.log(`file exist: ${fullFilePath}`);
|
150
|
+
} catch (error) {
|
151
|
+
if (error.code === 'ENOENT') {
|
152
|
+
const directoryPath = path.dirname(fullFilePath);
|
153
|
+
|
154
|
+
try {
|
155
|
+
await fs.access(directoryPath);
|
156
|
+
} catch (dirError) {
|
157
|
+
if (dirError.code === 'ENOENT') {
|
158
|
+
console.log(`mkdir: ${directoryPath}`);
|
159
|
+
await fs.mkdir(directoryPath, { recursive: true });
|
160
|
+
} else {
|
161
|
+
console.error(`mkdir (${directoryPath}):`, dirError);
|
162
|
+
return false;
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
try {
|
167
|
+
await fs.writeFile(fullFilePath, '');
|
168
|
+
console.log(`file created: ${fullFilePath}`);
|
169
|
+
} catch (fileError) {
|
170
|
+
console.error(`create file fail (${fullFilePath}):`, fileError);
|
171
|
+
return false;
|
172
|
+
}
|
173
|
+
} else {
|
174
|
+
console.error(`access file fail (${fullFilePath}):`, error);
|
175
|
+
return false
|
176
|
+
}
|
177
|
+
}
|
178
|
+
return true;
|
179
|
+
}
|
180
|
+
|
181
|
+
export async function ensurePath(fullFilePath:string):Promise<boolean>{
|
182
|
+
try {
|
183
|
+
await fs.access(fullFilePath);
|
184
|
+
console.log(`file exist: ${fullFilePath}`);
|
185
|
+
} catch (error) {
|
186
|
+
if (error.code === 'ENOENT') {
|
187
|
+
const directoryPath = path.dirname(fullFilePath);
|
188
|
+
|
189
|
+
try {
|
190
|
+
await fs.access(directoryPath);
|
191
|
+
} catch (dirError) {
|
192
|
+
if (dirError.code === 'ENOENT') {
|
193
|
+
console.log(`mkdir: ${directoryPath}`);
|
194
|
+
await fs.mkdir(directoryPath, { recursive: true });
|
195
|
+
} else {
|
196
|
+
console.error(`mkdir (${directoryPath}):`, dirError);
|
197
|
+
return false;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
} else {
|
201
|
+
console.error(`access file fail (${fullFilePath}):`, error);
|
202
|
+
return false
|
203
|
+
}
|
204
|
+
}
|
205
|
+
return true;
|
206
|
+
}
|
207
|
+
|
208
|
+
export async function removeFile(fullFilePath:string):Promise<boolean>{
|
209
|
+
try {
|
210
|
+
await fs.access(fullFilePath);
|
211
|
+
console.log(`file exist: ${fullFilePath}`);
|
212
|
+
await fs.unlink(fullFilePath);
|
213
|
+
} catch (error) {
|
214
|
+
if (error.code === 'ENOENT') {
|
215
|
+
return true
|
216
|
+
} else {
|
217
|
+
console.error(`access file fail (${fullFilePath}):`, formatError(error));
|
218
|
+
return false
|
219
|
+
}
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
|
224
|
+
const util = require('util');
|
225
|
+
|
226
|
+
const ERROR_WHITELIST = new Set(['message', 'code', 'cause', 'name', 'status']);
|
227
|
+
|
228
|
+
function extractErrorDetails(err, depth = 0, maxDepth = 3) {
|
229
|
+
if (depth > maxDepth) return '[Max Depth Exceeded]';
|
230
|
+
if (!err || typeof err !== 'object') return err;
|
231
|
+
|
232
|
+
const details = {};
|
233
|
+
ERROR_WHITELIST.forEach((key) => {
|
234
|
+
|
235
|
+
const value = err[key];
|
236
|
+
if (value !== undefined) {
|
237
|
+
details[key] = key === 'cause'
|
238
|
+
? extractErrorDetails(value, depth + 1, maxDepth)
|
239
|
+
: value;
|
240
|
+
}
|
241
|
+
});
|
242
|
+
|
243
|
+
if(err.response?.config?.data){
|
244
|
+
details['response.config.data'] = err.response?.config?.data;
|
245
|
+
}
|
246
|
+
if(err.response?.data){
|
247
|
+
details['response.data.error'] = err.response?.data;
|
248
|
+
}
|
249
|
+
return details;
|
250
|
+
}
|
251
|
+
|
252
|
+
export function formatError(err:any):string{
|
253
|
+
return JSON.stringify(extractErrorDetails(err))
|
254
|
+
}
|
255
|
+
|
256
|
+
function isHexStringWithPrefix(str) {
|
257
|
+
return /^(0x)?[0-9a-fA-F]+$/.test(str);
|
258
|
+
}
|
259
|
+
|
260
|
+
function isEvenLengthHex(str) {
|
261
|
+
return /^[0-9a-fA-F]+$/.test(str) && str.length % 2 === 0;
|
262
|
+
}
|
263
|
+
|
264
|
+
export function isValidHexString(str:string){
|
265
|
+
return isHexStringWithPrefix && isValidHexString;
|
266
|
+
}
|
267
|
+
|
268
|
+
|
269
|
+
export function isNotBase64(str) {
|
270
|
+
// 同时匹配标准Base64和URL安全Base64的正则表达式
|
271
|
+
const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$|^(?:[A-Za-z0-9\-_]{4})*(?:[A-Za-z0-9\-_]{2}==|[A-Za-z0-9\-_]{3}=)?$/;
|
272
|
+
|
273
|
+
// 类型检查
|
274
|
+
if (typeof str !== 'string') return true;
|
275
|
+
|
276
|
+
// 基础校验
|
277
|
+
const len = str.length;
|
278
|
+
if (len === 0) return false; // 空字符串视为有效
|
279
|
+
if (len % 4 !== 0) return true; // 长度必须是4的倍数
|
280
|
+
|
281
|
+
// 检查编码格式
|
282
|
+
return !BASE64_REGEX.test(str);
|
283
|
+
}
|
284
|
+
|
285
|
+
export function toBase64(str){
|
286
|
+
if(isNotBase64(str) && isValidHexString(str)){
|
287
|
+
return Buffer.from(str,'hex').toString('base64');
|
288
|
+
}else{
|
289
|
+
if(!isNotBase64(str)){
|
290
|
+
return str;
|
291
|
+
}else{
|
292
|
+
throw new Error(`invalid string ${str}`)
|
293
|
+
}
|
294
|
+
}
|
295
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import {JettonMaster, TonClient} from "@ton/ton";
|
2
|
+
import {Blockchain} from "@ton/sandbox";
|
3
|
+
import {Address} from "@ton/core";
|
4
|
+
import {getJettonBalance} from "./jetton";
|
5
|
+
import {JettonMinter} from "../JettonMinter";
|
6
|
+
import {JettonWallet} from "../JettonWallet";
|
7
|
+
|
8
|
+
export async function CoinBalance(client:TonClient|Blockchain, addr:Address) {
|
9
|
+
if(client instanceof TonClient){
|
10
|
+
return await client.getBalance(addr)
|
11
|
+
}else{
|
12
|
+
return (await client.getContract(addr)).balance
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
export async function TokenBalance(client:TonClient|Blockchain, tokenAddr:Address,addr:Address) {
|
17
|
+
if(client instanceof TonClient){
|
18
|
+
return await getJettonBalance(client,tokenAddr,addr)
|
19
|
+
}else{
|
20
|
+
let jetttonMaster = JettonMinter.createFromAddress(tokenAddr);
|
21
|
+
let jetttonMasterOpened = await client.openContract(jetttonMaster)
|
22
|
+
let jettonAddr = await jetttonMasterOpened.getWalletAddress(addr)
|
23
|
+
|
24
|
+
|
25
|
+
let jettonWallet = JettonWallet.createFromAddress(jettonAddr)
|
26
|
+
let jettonWalletOpened = await client.openContract(jettonWallet)
|
27
|
+
return await jettonWalletOpened.getJettonBalance()
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import {buildWrappedJettonContent,parseWrappedJettonContent} from "./jetton";
|
2
|
+
|
3
|
+
const opts= {
|
4
|
+
name:'dog', // string
|
5
|
+
symbol:'dog symbol', // string
|
6
|
+
decimal:'5', // string
|
7
|
+
}
|
8
|
+
|
9
|
+
describe('jetton content', () => {
|
10
|
+
|
11
|
+
beforeAll(async () => {
|
12
|
+
});
|
13
|
+
|
14
|
+
beforeEach(async () => {
|
15
|
+
|
16
|
+
});
|
17
|
+
|
18
|
+
|
19
|
+
it('build jetton content', async () => {
|
20
|
+
let ret = await buildWrappedJettonContent(opts);
|
21
|
+
console.log(ret);
|
22
|
+
|
23
|
+
let optsNew = await parseWrappedJettonContent(ret);
|
24
|
+
console.log(optsNew);
|
25
|
+
});
|
26
|
+
|
27
|
+
});
|