@ton/ton
Version:
[](https://www.npmjs.com/package/ton)
703 lines (702 loc) • 29.1 kB
JavaScript
"use strict";
/**
* Copyright (c) Whales Corp.
* All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _TonClient4_endpoint, _TonClient4_timeout, _TonClient4_adapter, _TonClient4_axios;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TonClient4 = void 0;
const axios_1 = __importDefault(require("axios"));
const core_1 = require("@ton/core");
const toUrlSafe_1 = require("../utils/toUrlSafe");
const zod_1 = require("zod");
class TonClient4 {
constructor(args) {
_TonClient4_endpoint.set(this, void 0);
_TonClient4_timeout.set(this, void 0);
_TonClient4_adapter.set(this, void 0);
_TonClient4_axios.set(this, void 0);
__classPrivateFieldSet(this, _TonClient4_axios, axios_1.default.create(), "f");
__classPrivateFieldSet(this, _TonClient4_endpoint, args.endpoint, "f");
__classPrivateFieldSet(this, _TonClient4_timeout, args.timeout || 5000, "f");
__classPrivateFieldSet(this, _TonClient4_adapter, args.httpAdapter, "f");
if (args.requestInterceptor) {
__classPrivateFieldGet(this, _TonClient4_axios, "f").interceptors.request.use(args.requestInterceptor);
}
}
/**
* Get Last Block
* @returns last block info
*/
async getLastBlock() {
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").get(__classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/block/latest', { adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"), timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f") });
let lastBlock = lastBlockCodec.safeParse(res.data);
if (!lastBlock.success) {
throw Error('Mailformed response: ' + lastBlock.error.format()._errors.join(', '));
}
return lastBlock.data;
}
/**
* Get block info
* @param seqno block sequence number
* @returns block info
*/
async getBlock(seqno) {
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").get(__classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/block/' + seqno, { adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"), timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f") });
let block = blockCodec.safeParse(res.data);
if (!block.success) {
throw Error('Mailformed response');
}
if (!block.data.exist) {
throw Error('Block is out of scope');
}
return block.data.block;
}
/**
* Get block info by unix timestamp
* @param ts unix timestamp
* @returns block info
*/
async getBlockByUtime(ts) {
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").get(__classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/block/utime/' + ts, { adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"), timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f") });
let block = blockCodec.safeParse(res.data);
if (!block.success) {
throw Error('Mailformed response');
}
if (!block.data.exist) {
throw Error('Block is out of scope');
}
return block.data.block;
}
/**
* Get block info by unix timestamp
* @param seqno block sequence number
* @param address account address
* @returns account info
*/
async getAccount(seqno, address) {
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").get(__classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/block/' + seqno + '/' + address.toString({ urlSafe: true }), { adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"), timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f") });
let account = accountCodec.safeParse(res.data);
if (!account.success) {
throw Error('Mailformed response');
}
return account.data;
}
/**
* Get account lite info (without code and data)
* @param seqno block sequence number
* @param address account address
* @returns account lite info
*/
async getAccountLite(seqno, address) {
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").get(__classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/block/' + seqno + '/' + address.toString({ urlSafe: true }) + '/lite', { adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"), timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f") });
let account = accountLiteCodec.safeParse(res.data);
if (!account.success) {
throw Error('Mailformed response');
}
return account.data;
}
/**
* Check if contract is deployed
* @param address addres to check
* @returns true if contract is in active state
*/
async isContractDeployed(seqno, address) {
let account = await this.getAccountLite(seqno, address);
return account.account.state.type === 'active';
}
/**
* Check if account was updated since
* @param seqno block sequence number
* @param address account address
* @param lt account last transaction lt
* @returns account change info
*/
async isAccountChanged(seqno, address, lt) {
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").get(__classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/block/' + seqno + '/' + address.toString({ urlSafe: true }) + '/changed/' + lt.toString(10), { adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"), timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f") });
let changed = changedCodec.safeParse(res.data);
if (!changed.success) {
throw Error('Mailformed response');
}
return changed.data;
}
/**
* Load unparsed account transactions
* @param address address
* @param lt last transaction lt
* @param hash last transaction hash
* @returns unparsed transactions
*/
async getAccountTransactions(address, lt, hash) {
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").get(__classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/account/' + address.toString({ urlSafe: true }) + '/tx/' + lt.toString(10) + '/' + (0, toUrlSafe_1.toUrlSafe)(hash.toString('base64')), { adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"), timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f") });
let transactions = transactionsCodec.safeParse(res.data);
if (!transactions.success) {
throw Error('Mailformed response');
}
let data = transactions.data;
let tx = [];
let cells = core_1.Cell.fromBoc(Buffer.from(data.boc, 'base64'));
for (let i = 0; i < data.blocks.length; i++) {
tx.push({
block: data.blocks[i],
tx: (0, core_1.loadTransaction)(cells[i].beginParse())
});
}
return tx;
}
/**
* Load parsed account transactions
* @param address address
* @param lt last transaction lt
* @param hash last transaction hash
* @param count number of transactions to load
* @returns parsed transactions
*/
async getAccountTransactionsParsed(address, lt, hash, count = 20) {
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").get(__classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/account/' + address.toString({ urlSafe: true }) + '/tx/parsed/' + lt.toString(10) + '/' + (0, toUrlSafe_1.toUrlSafe)(hash.toString('base64')), {
adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"),
timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f"),
params: {
count
}
});
let parsedTransactionsRes = parsedTransactionsCodec.safeParse(res.data);
if (!parsedTransactionsRes.success) {
throw Error('Mailformed response');
}
return parsedTransactionsRes.data;
}
/**
* Get network config
* @param seqno block sequence number
* @param ids optional config ids
* @returns network config
*/
async getConfig(seqno, ids) {
let tail = '';
if (ids && ids.length > 0) {
tail = '/' + [...ids].sort().join(',');
}
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").get(__classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/block/' + seqno + '/config' + tail, { adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"), timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f") });
let config = configCodec.safeParse(res.data);
if (!config.success) {
throw Error('Mailformed response');
}
return config.data;
}
/**
* Execute run method
* @param seqno block sequence number
* @param address account address
* @param name method name
* @param args method arguments
* @returns method result
*/
async runMethod(seqno, address, name, args) {
let tail = args && args.length > 0 ? '/' + (0, toUrlSafe_1.toUrlSafe)((0, core_1.serializeTuple)(args).toBoc({ idx: false, crc32: false }).toString('base64')) : '';
let url = __classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/block/' + seqno + '/' + address.toString({ urlSafe: true }) + '/run/' + encodeURIComponent(name) + tail;
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").get(url, { adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"), timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f") });
let runMethod = runMethodCodec.safeParse(res.data);
if (!runMethod.success) {
throw Error('Mailformed response');
}
let resultTuple = runMethod.data.resultRaw ? (0, core_1.parseTuple)(core_1.Cell.fromBoc(Buffer.from(runMethod.data.resultRaw, 'base64'))[0]) : [];
return {
exitCode: runMethod.data.exitCode,
result: resultTuple,
resultRaw: runMethod.data.resultRaw,
block: runMethod.data.block,
shardBlock: runMethod.data.shardBlock,
reader: new core_1.TupleReader(resultTuple),
};
}
/**
* Send external message
* @param message message boc
* @returns message status
*/
async sendMessage(message) {
let res = await __classPrivateFieldGet(this, _TonClient4_axios, "f").post(__classPrivateFieldGet(this, _TonClient4_endpoint, "f") + '/send', { boc: message.toString('base64') }, { adapter: __classPrivateFieldGet(this, _TonClient4_adapter, "f"), timeout: __classPrivateFieldGet(this, _TonClient4_timeout, "f") });
let send = sendCodec.safeParse(res.data);
if (!send.success) {
throw Error('Mailformed response');
}
return { status: res.data.status };
}
/**
* Open smart contract
* @param contract contract
* @returns opened contract
*/
open(contract) {
return (0, core_1.openContract)(contract, (args) => createProvider(this, null, args.address, args.init));
}
/**
* Open smart contract
* @param block block number
* @param contract contract
* @returns opened contract
*/
openAt(block, contract) {
return (0, core_1.openContract)(contract, (args) => createProvider(this, block, args.address, args.init));
}
/**
* Create provider
* @param address address
* @param init optional init data
* @returns provider
*/
provider(address, init) {
return createProvider(this, null, address, init ?? null);
}
/**
* Create provider at specified block number
* @param block block number
* @param address address
* @param init optional init data
* @returns provider
*/
providerAt(block, address, init) {
return createProvider(this, block, address, init ?? null);
}
}
exports.TonClient4 = TonClient4;
_TonClient4_endpoint = new WeakMap(), _TonClient4_timeout = new WeakMap(), _TonClient4_adapter = new WeakMap(), _TonClient4_axios = new WeakMap();
function createProvider(client, block, address, init) {
return {
async getState() {
// Resolve block
let sq = block;
if (sq === null) {
let res = await client.getLastBlock();
sq = res.last.seqno;
}
// Load state
let state = await client.getAccount(sq, address);
// Convert state
let last = state.account.last ? { lt: BigInt(state.account.last.lt), hash: Buffer.from(state.account.last.hash, 'base64') } : null;
let storage;
if (state.account.state.type === 'active') {
storage = {
type: 'active',
code: state.account.state.code ? Buffer.from(state.account.state.code, 'base64') : null,
data: state.account.state.data ? Buffer.from(state.account.state.data, 'base64') : null,
};
}
else if (state.account.state.type === 'uninit') {
storage = {
type: 'uninit',
};
}
else if (state.account.state.type === 'frozen') {
storage = {
type: 'frozen',
stateHash: Buffer.from(state.account.state.stateHash, 'base64'),
};
}
else {
throw Error('Unsupported state');
}
let ecMap = null;
if (state.account.balance.currencies) {
ecMap = {};
let currencies = state.account.balance.currencies;
for (let [k, v] of Object.entries(currencies)) {
ecMap[Number(k)] = BigInt(v);
}
}
return {
balance: BigInt(state.account.balance.coins),
extracurrency: ecMap,
last: last,
state: storage
};
},
async get(name, args) {
if (typeof name !== 'string') {
throw new Error('Method name must be a string for TonClient4 provider');
}
let sq = block;
if (sq === null) {
let res = await client.getLastBlock();
sq = res.last.seqno;
}
let method = await client.runMethod(sq, address, name, args);
if (method.exitCode !== 0 && method.exitCode !== 1) {
throw Error('Exit code: ' + method.exitCode);
}
return {
stack: new core_1.TupleReader(method.result),
};
},
async external(message) {
// Resolve last
let last = await client.getLastBlock();
// Resolve init
let neededInit = null;
if (init && (await client.getAccountLite(last.last.seqno, address)).account.state.type !== 'active') {
neededInit = init;
}
// Send with state init
const ext = (0, core_1.external)({
to: address,
init: neededInit,
body: message
});
let pkg = (0, core_1.beginCell)()
.store((0, core_1.storeMessage)(ext))
.endCell()
.toBoc();
await client.sendMessage(pkg);
},
async internal(via, message) {
// Resolve last
let last = await client.getLastBlock();
// Resolve init
let neededInit = null;
if (init && (await client.getAccountLite(last.last.seqno, address)).account.state.type !== 'active') {
neededInit = init;
}
// Resolve bounce
let bounce = true;
if (message.bounce !== null && message.bounce !== undefined) {
bounce = message.bounce;
}
// Resolve value
let value;
if (typeof message.value === 'string') {
value = (0, core_1.toNano)(message.value);
}
else {
value = message.value;
}
// Resolve body
let body = null;
if (typeof message.body === 'string') {
body = (0, core_1.comment)(message.body);
}
else if (message.body) {
body = message.body;
}
// Send internal message
await via.send({
to: address,
value,
extracurrency: message.extracurrency,
bounce,
sendMode: message.sendMode,
init: neededInit,
body
});
},
open(contract) {
return (0, core_1.openContract)(contract, (args) => createProvider(client, block, args.address, args.init ?? null));
},
async getTransactions(address, lt, hash, limit) {
// Resolve last
const useLimit = typeof limit === 'number';
if (useLimit && limit <= 0) {
return [];
}
// Load transactions
let transactions = [];
do {
const txs = await client.getAccountTransactions(address, lt, hash);
const firstTx = txs[0].tx;
const [firstLt, firstHash] = [firstTx.lt, firstTx.hash()];
const needSkipFirst = transactions.length > 0 && 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;
}
};
}
//
// Codecs
//
const lastBlockCodec = zod_1.z.object({
last: zod_1.z.object({
seqno: zod_1.z.number(),
shard: zod_1.z.string(),
workchain: zod_1.z.number(),
fileHash: zod_1.z.string(),
rootHash: zod_1.z.string()
}),
init: zod_1.z.object({
fileHash: zod_1.z.string(),
rootHash: zod_1.z.string()
}),
stateRootHash: zod_1.z.string(),
now: zod_1.z.number()
});
const blockCodec = zod_1.z.union([zod_1.z.object({
exist: zod_1.z.literal(false)
}), zod_1.z.object({
exist: zod_1.z.literal(true),
block: zod_1.z.object({
shards: zod_1.z.array(zod_1.z.object({
workchain: zod_1.z.number(),
seqno: zod_1.z.number(),
shard: zod_1.z.string(),
rootHash: zod_1.z.string(),
fileHash: zod_1.z.string(),
transactions: zod_1.z.array(zod_1.z.object({
account: zod_1.z.string(),
hash: zod_1.z.string(),
lt: zod_1.z.string()
}))
}))
})
})]);
// {"lastPaid":1653099243,"duePayment":null,"used":{"bits":119,"cells":1,"publicCells":0}}
const storageStatCodec = zod_1.z.object({
lastPaid: zod_1.z.number(),
duePayment: zod_1.z.union([zod_1.z.null(), zod_1.z.string()]),
used: zod_1.z.object({
bits: zod_1.z.number(),
cells: zod_1.z.number(),
publicCells: zod_1.z.number()
})
});
const accountCodec = zod_1.z.object({
account: zod_1.z.object({
state: zod_1.z.union([
zod_1.z.object({ type: zod_1.z.literal('uninit') }),
zod_1.z.object({ type: zod_1.z.literal('active'), code: zod_1.z.union([zod_1.z.string(), zod_1.z.null()]), data: zod_1.z.union([zod_1.z.string(), zod_1.z.null()]) }),
zod_1.z.object({ type: zod_1.z.literal('frozen'), stateHash: zod_1.z.string() })
]),
balance: zod_1.z.object({
coins: zod_1.z.string(),
currencies: zod_1.z.record(zod_1.z.string(), zod_1.z.string())
}),
last: zod_1.z.union([
zod_1.z.null(),
zod_1.z.object({
lt: zod_1.z.string(),
hash: zod_1.z.string()
})
]),
storageStat: zod_1.z.union([zod_1.z.null(), storageStatCodec])
}),
block: zod_1.z.object({
workchain: zod_1.z.number(),
seqno: zod_1.z.number(),
shard: zod_1.z.string(),
rootHash: zod_1.z.string(),
fileHash: zod_1.z.string()
})
});
const accountLiteCodec = zod_1.z.object({
account: zod_1.z.object({
state: zod_1.z.union([
zod_1.z.object({ type: zod_1.z.literal('uninit') }),
zod_1.z.object({ type: zod_1.z.literal('active'), codeHash: zod_1.z.string(), dataHash: zod_1.z.string() }),
zod_1.z.object({ type: zod_1.z.literal('frozen'), stateHash: zod_1.z.string() })
]),
balance: zod_1.z.object({
coins: zod_1.z.string(),
currencies: zod_1.z.record(zod_1.z.string(), zod_1.z.string())
}),
last: zod_1.z.union([
zod_1.z.null(),
zod_1.z.object({
lt: zod_1.z.string(),
hash: zod_1.z.string()
})
]),
storageStat: zod_1.z.union([zod_1.z.null(), storageStatCodec])
})
});
const changedCodec = zod_1.z.object({
changed: zod_1.z.boolean(),
block: zod_1.z.object({
workchain: zod_1.z.number(),
seqno: zod_1.z.number(),
shard: zod_1.z.string(),
rootHash: zod_1.z.string(),
fileHash: zod_1.z.string()
})
});
const runMethodCodec = zod_1.z.object({
exitCode: zod_1.z.number(),
resultRaw: zod_1.z.union([zod_1.z.string(), zod_1.z.null()]),
block: zod_1.z.object({
workchain: zod_1.z.number(),
seqno: zod_1.z.number(),
shard: zod_1.z.string(),
rootHash: zod_1.z.string(),
fileHash: zod_1.z.string()
}),
shardBlock: zod_1.z.object({
workchain: zod_1.z.number(),
seqno: zod_1.z.number(),
shard: zod_1.z.string(),
rootHash: zod_1.z.string(),
fileHash: zod_1.z.string()
})
});
const configCodec = zod_1.z.object({
config: zod_1.z.object({
cell: zod_1.z.string(),
address: zod_1.z.string(),
globalBalance: zod_1.z.object({
coins: zod_1.z.string()
})
})
});
const sendCodec = zod_1.z.object({
status: zod_1.z.number()
});
const blocksCodec = zod_1.z.array(zod_1.z.object({
workchain: zod_1.z.number(),
seqno: zod_1.z.number(),
shard: zod_1.z.string(),
rootHash: zod_1.z.string(),
fileHash: zod_1.z.string()
}));
const transactionsCodec = zod_1.z.object({
blocks: blocksCodec,
boc: zod_1.z.string()
});
const parsedAddressExternalCodec = zod_1.z.object({
bits: zod_1.z.number(),
data: zod_1.z.string()
});
const parsedMessageInfoCodec = zod_1.z.union([
zod_1.z.object({
type: zod_1.z.literal('internal'),
value: zod_1.z.string(),
dest: zod_1.z.string(),
src: zod_1.z.string(),
bounced: zod_1.z.boolean(),
bounce: zod_1.z.boolean(),
ihrDisabled: zod_1.z.boolean(),
createdAt: zod_1.z.number(),
createdLt: zod_1.z.string(),
fwdFee: zod_1.z.string(),
ihrFee: zod_1.z.string()
}),
zod_1.z.object({
type: zod_1.z.literal('external-in'),
dest: zod_1.z.string(),
src: zod_1.z.union([parsedAddressExternalCodec, zod_1.z.null()]),
importFee: zod_1.z.string()
}),
zod_1.z.object({
type: zod_1.z.literal('external-out'),
dest: zod_1.z.union([parsedAddressExternalCodec, zod_1.z.null()])
})
]);
const parsedStateInitCodec = zod_1.z.object({
splitDepth: zod_1.z.union([zod_1.z.number(), zod_1.z.null()]),
code: zod_1.z.union([zod_1.z.string(), zod_1.z.null()]),
data: zod_1.z.union([zod_1.z.string(), zod_1.z.null()]),
special: zod_1.z.union([zod_1.z.object({ tick: zod_1.z.boolean(), tock: zod_1.z.boolean() }), zod_1.z.null()])
});
const parsedMessageCodec = zod_1.z.object({
body: zod_1.z.string(),
info: parsedMessageInfoCodec,
init: zod_1.z.union([parsedStateInitCodec, zod_1.z.null()])
});
const accountStatusCodec = zod_1.z.union([zod_1.z.literal('uninitialized'), zod_1.z.literal('frozen'), zod_1.z.literal('active'), zod_1.z.literal('non-existing')]);
const txBodyCodec = zod_1.z.union([
zod_1.z.object({ type: zod_1.z.literal('comment'), comment: zod_1.z.string() }),
zod_1.z.object({ type: zod_1.z.literal('payload'), cell: zod_1.z.string() }),
]);
const parsedOperationItemCodec = zod_1.z.union([
zod_1.z.object({ kind: zod_1.z.literal('ton'), amount: zod_1.z.string() }),
zod_1.z.object({ kind: zod_1.z.literal('token'), amount: zod_1.z.string() })
]);
const supportedMessageTypeCodec = zod_1.z.union([
zod_1.z.literal('jetton::excesses'),
zod_1.z.literal('jetton::transfer'),
zod_1.z.literal('jetton::transfer_notification'),
zod_1.z.literal('deposit'),
zod_1.z.literal('deposit::ok'),
zod_1.z.literal('withdraw'),
zod_1.z.literal('withdraw::all'),
zod_1.z.literal('withdraw::delayed'),
zod_1.z.literal('withdraw::ok'),
zod_1.z.literal('airdrop')
]);
const opCodec = zod_1.z.object({
type: supportedMessageTypeCodec,
options: zod_1.z.optional(zod_1.z.record(zod_1.z.string()))
});
const parsedOperationCodec = zod_1.z.object({
address: zod_1.z.string(),
comment: zod_1.z.optional(zod_1.z.string()),
items: zod_1.z.array(parsedOperationItemCodec),
op: zod_1.z.optional(opCodec)
});
const parsedTransactionCodec = zod_1.z.object({
address: zod_1.z.string(),
lt: zod_1.z.string(),
hash: zod_1.z.string(),
prevTransaction: zod_1.z.object({
lt: zod_1.z.string(),
hash: zod_1.z.string()
}),
time: zod_1.z.number(),
outMessagesCount: zod_1.z.number(),
oldStatus: accountStatusCodec,
newStatus: accountStatusCodec,
fees: zod_1.z.string(),
update: zod_1.z.object({
oldHash: zod_1.z.string(),
newHash: zod_1.z.string()
}),
inMessage: zod_1.z.union([parsedMessageCodec, zod_1.z.null()]),
outMessages: zod_1.z.array(parsedMessageCodec),
parsed: zod_1.z.object({
seqno: zod_1.z.union([zod_1.z.number(), zod_1.z.null()]),
body: zod_1.z.union([txBodyCodec, zod_1.z.null()]),
status: zod_1.z.union([zod_1.z.literal('success'), zod_1.z.literal('failed'), zod_1.z.literal('pending')]),
dest: zod_1.z.union([zod_1.z.string(), zod_1.z.null()]),
kind: zod_1.z.union([zod_1.z.literal('out'), zod_1.z.literal('in')]),
amount: zod_1.z.string(),
resolvedAddress: zod_1.z.string(),
bounced: zod_1.z.boolean(),
mentioned: zod_1.z.array(zod_1.z.string())
}),
operation: parsedOperationCodec
});
const parsedTransactionsCodec = zod_1.z.object({
blocks: blocksCodec,
transactions: zod_1.z.array(parsedTransactionCodec)
});