@thru/thru-sdk 0.1.33 → 0.1.36
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/dist/VersionInfo-BBuhryfs.d.ts +930 -0
- package/dist/chunk-PU2M7EPY.js +2851 -0
- package/dist/chunk-PU2M7EPY.js.map +1 -0
- package/dist/client.d.ts +6 -3
- package/dist/client.js +8 -3
- package/dist/client.js.map +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/sdk.d.ts +3 -4
- package/dist/sdk.js +2 -371
- package/dist/sdk.js.map +1 -1
- package/package.json +6 -7
- package/dist/VersionInfo-BGciKJJA.d.ts +0 -2172
- package/dist/chunk-ZLV6WP54.js +0 -2534
- package/dist/chunk-ZLV6WP54.js.map +0 -1
|
@@ -0,0 +1,2851 @@
|
|
|
1
|
+
import { utils, etc, Point, CURVE, getPublicKeyAsync } from '@noble/ed25519';
|
|
2
|
+
import { create } from '@bufbuild/protobuf';
|
|
3
|
+
import { encodeAddress, decodeAddress, isHexString, hexToBytes, encodeSignature, decodeSignature, ensureBytes } from '@thru/helpers';
|
|
4
|
+
import { AccountView, BlockView, TransactionView, ConsensusStatus, VersionContextSchema, CurrentVersionSchema, PubkeySchema, TaPubkeySchema, SignatureSchema, TsSignatureSchema, TransactionVmError, StreamingService, CommandService, QueryService, PageRequestSchema, PageResponseSchema, StateProofRequestSchema, GenerateStateProofRequestSchema, GetAccountRequestSchema, GetRawAccountRequestSchema, ListAccountsRequestSchema, StateProofType, ExecutionStatus, GetBlockRequestSchema, GetRawBlockRequestSchema, ListBlocksRequestSchema, CurrentOrHistoricalVersionSchema, GetEventRequestSchema, ListEventsRequestSchema, GetHeightRequestSchema, FilterParamValueSchema, FilterSchema, StreamBlocksRequestSchema, StreamAccountUpdatesRequestSchema, StreamTransactionsRequestSchema, StreamEventsRequestSchema, TrackTransactionRequestSchema, StreamHeightRequestSchema, GetTransactionRequestSchema, GetRawTransactionRequestSchema, GetTransactionStatusRequestSchema, ListTransactionsForAccountRequestSchema, ListTransactionsRequestSchema, BatchSendTransactionsRequestSchema, SendTransactionRequestSchema, BlockHashSchema } from '@thru/proto';
|
|
5
|
+
import { createClient } from '@connectrpc/connect';
|
|
6
|
+
import { createGrpcWebTransport } from '@connectrpc/connect-web';
|
|
7
|
+
import { sha256 } from '@noble/hashes/sha2';
|
|
8
|
+
import { ThruHDWallet, getWebCrypto } from '@thru/crypto';
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var SignatureDomain = /* @__PURE__ */ ((SignatureDomain2) => {
|
|
16
|
+
SignatureDomain2[SignatureDomain2["TXN"] = 0] = "TXN";
|
|
17
|
+
SignatureDomain2[SignatureDomain2["BLOCK_HEADER"] = 1] = "BLOCK_HEADER";
|
|
18
|
+
SignatureDomain2[SignatureDomain2["BLOCK"] = 2] = "BLOCK";
|
|
19
|
+
SignatureDomain2[SignatureDomain2["GOSSIP"] = 3] = "GOSSIP";
|
|
20
|
+
return SignatureDomain2;
|
|
21
|
+
})(SignatureDomain || {});
|
|
22
|
+
var DOMAIN_TAGS = {
|
|
23
|
+
[0 /* TXN */]: 1n,
|
|
24
|
+
[1 /* BLOCK_HEADER */]: 2n,
|
|
25
|
+
[2 /* BLOCK */]: 3n,
|
|
26
|
+
[3 /* GOSSIP */]: 4n
|
|
27
|
+
};
|
|
28
|
+
var DOMAIN_BLOCK_SIZE = 128;
|
|
29
|
+
var SIGNATURE_SIZE = 64;
|
|
30
|
+
var PUBKEY_SIZE = 32;
|
|
31
|
+
function createDomainBlock(domain) {
|
|
32
|
+
const block = new Uint8Array(DOMAIN_BLOCK_SIZE);
|
|
33
|
+
block.fill(0);
|
|
34
|
+
const tag = DOMAIN_TAGS[domain];
|
|
35
|
+
if (tag === void 0) {
|
|
36
|
+
throw new Error(`Invalid signature domain: ${domain}`);
|
|
37
|
+
}
|
|
38
|
+
const view = new DataView(block.buffer, block.byteOffset, block.byteLength);
|
|
39
|
+
view.setBigUint64(0, tag, false);
|
|
40
|
+
return block;
|
|
41
|
+
}
|
|
42
|
+
function copyBytes(bytes) {
|
|
43
|
+
const out = new Uint8Array(bytes.length);
|
|
44
|
+
out.set(bytes);
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
function concatBytes(...arrays) {
|
|
48
|
+
return etc.concatBytes(...arrays);
|
|
49
|
+
}
|
|
50
|
+
function bytesToNumberLE(bytes) {
|
|
51
|
+
let value = 0n;
|
|
52
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
53
|
+
value += BigInt(bytes[i]) << 8n * BigInt(i);
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
function modOrder(value) {
|
|
58
|
+
const modulus = CURVE.n;
|
|
59
|
+
const result = value % modulus;
|
|
60
|
+
return result >= 0n ? result : result + modulus;
|
|
61
|
+
}
|
|
62
|
+
function numberToBytesLE(value, length) {
|
|
63
|
+
const out = new Uint8Array(length);
|
|
64
|
+
let current = value;
|
|
65
|
+
for (let i = 0; i < length; i++) {
|
|
66
|
+
out[i] = Number(current & 0xffn);
|
|
67
|
+
current >>= 8n;
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
async function signWithDomain(message, privateKey, publicKey, domain = 0 /* TXN */) {
|
|
72
|
+
if (privateKey.length !== PUBKEY_SIZE) {
|
|
73
|
+
throw new Error("Private key must contain 32 bytes");
|
|
74
|
+
}
|
|
75
|
+
const domainBlock = createDomainBlock(domain);
|
|
76
|
+
const messageBytes = copyBytes(message);
|
|
77
|
+
const extended = await utils.getExtendedPublicKeyAsync(privateKey);
|
|
78
|
+
const publicKeyBytes = publicKey ? copyBytes(publicKey) : extended.pointBytes;
|
|
79
|
+
if (publicKeyBytes.length !== PUBKEY_SIZE) {
|
|
80
|
+
throw new Error("Public key must contain 32 bytes");
|
|
81
|
+
}
|
|
82
|
+
const rInput = concatBytes(domainBlock, extended.prefix, messageBytes);
|
|
83
|
+
const r = modOrder(bytesToNumberLE(await etc.sha512Async(rInput)));
|
|
84
|
+
const R = Point.BASE.multiply(r).toBytes();
|
|
85
|
+
const kInput = concatBytes(domainBlock, R, publicKeyBytes, messageBytes);
|
|
86
|
+
const k = modOrder(bytesToNumberLE(await etc.sha512Async(kInput)));
|
|
87
|
+
const s = modOrder(r + k * extended.scalar);
|
|
88
|
+
const signature = new Uint8Array(SIGNATURE_SIZE);
|
|
89
|
+
signature.set(R, 0);
|
|
90
|
+
signature.set(numberToBytesLE(s, PUBKEY_SIZE), PUBKEY_SIZE);
|
|
91
|
+
return signature;
|
|
92
|
+
}
|
|
93
|
+
async function verifyWithDomain(signature, message, publicKey, domain = 0 /* TXN */) {
|
|
94
|
+
if (signature.length !== SIGNATURE_SIZE || publicKey.length !== PUBKEY_SIZE) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const domainBlock = createDomainBlock(domain);
|
|
98
|
+
const messageBytes = copyBytes(message);
|
|
99
|
+
const rBytes = signature.subarray(0, PUBKEY_SIZE);
|
|
100
|
+
const s = bytesToNumberLE(signature.subarray(PUBKEY_SIZE));
|
|
101
|
+
if (s >= CURVE.n) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
let R;
|
|
105
|
+
let A;
|
|
106
|
+
try {
|
|
107
|
+
R = Point.fromHex(rBytes);
|
|
108
|
+
A = Point.fromHex(publicKey);
|
|
109
|
+
} catch {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
const kInput = concatBytes(domainBlock, rBytes, publicKey, messageBytes);
|
|
113
|
+
const k = modOrder(bytesToNumberLE(await etc.sha512Async(kInput)));
|
|
114
|
+
const lhs = Point.BASE.multiply(s);
|
|
115
|
+
const rhs = R.add(A.multiply(k));
|
|
116
|
+
return lhs.add(rhs.negate()).clearCofactor().is0();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// thru-ts-client-sdk/domain/primitives/byte-utils.ts
|
|
120
|
+
function copyBytes2(source) {
|
|
121
|
+
const bytes = new Uint8Array(source.length);
|
|
122
|
+
bytes.set(source);
|
|
123
|
+
return bytes;
|
|
124
|
+
}
|
|
125
|
+
function ensureExactLength(bytes, expected) {
|
|
126
|
+
if (bytes.length !== expected) {
|
|
127
|
+
throw new Error(`Must contain ${expected} bytes`);
|
|
128
|
+
}
|
|
129
|
+
return copyBytes2(bytes);
|
|
130
|
+
}
|
|
131
|
+
function bytesEqual(a, b) {
|
|
132
|
+
if (a.length !== b.length) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
for (let i = 0; i < a.length; i++) {
|
|
136
|
+
if (a[i] !== b[i]) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
function bytesToHex(bytes) {
|
|
143
|
+
const hex = new Array(bytes.length);
|
|
144
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
145
|
+
hex[i] = bytes[i].toString(16).padStart(2, "0");
|
|
146
|
+
}
|
|
147
|
+
return hex.join("");
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// thru-ts-client-sdk/domain/primitives/constants.ts
|
|
151
|
+
var PUBKEY_LENGTH = 32;
|
|
152
|
+
var SIGNATURE_LENGTH = 64;
|
|
153
|
+
var TA_ADDRESS_LENGTH = 46;
|
|
154
|
+
var TS_SIGNATURE_LENGTH = 90;
|
|
155
|
+
|
|
156
|
+
// thru-ts-client-sdk/domain/primitives/Pubkey.ts
|
|
157
|
+
var Pubkey = class _Pubkey {
|
|
158
|
+
constructor(bytes) {
|
|
159
|
+
this.bytes = bytes;
|
|
160
|
+
}
|
|
161
|
+
static from(value) {
|
|
162
|
+
if (value instanceof _Pubkey) {
|
|
163
|
+
return value;
|
|
164
|
+
}
|
|
165
|
+
if (value instanceof Uint8Array) {
|
|
166
|
+
return new _Pubkey(ensureExactLength(value, PUBKEY_LENGTH));
|
|
167
|
+
}
|
|
168
|
+
if (typeof value === "string") {
|
|
169
|
+
return new _Pubkey(_Pubkey.bytesFromString(value));
|
|
170
|
+
}
|
|
171
|
+
throw new Error(
|
|
172
|
+
`Must be provided as Uint8Array, hex string, or ta-address`
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
static isThruFmt(value) {
|
|
176
|
+
return value.startsWith("ta") && value.length === TA_ADDRESS_LENGTH;
|
|
177
|
+
}
|
|
178
|
+
toBytes() {
|
|
179
|
+
return copyBytes2(this.bytes);
|
|
180
|
+
}
|
|
181
|
+
toBytesUnsafe() {
|
|
182
|
+
return this.bytes;
|
|
183
|
+
}
|
|
184
|
+
toThruFmt() {
|
|
185
|
+
return encodeAddress(this.bytes);
|
|
186
|
+
}
|
|
187
|
+
toHex() {
|
|
188
|
+
return bytesToHex(this.bytes);
|
|
189
|
+
}
|
|
190
|
+
equals(other) {
|
|
191
|
+
const candidate = _Pubkey.from(other);
|
|
192
|
+
return bytesEqual(this.bytes, candidate.bytes);
|
|
193
|
+
}
|
|
194
|
+
toProtoPubkey() {
|
|
195
|
+
return create(PubkeySchema, { value: this.toBytes() });
|
|
196
|
+
}
|
|
197
|
+
toProtoTaPubkey() {
|
|
198
|
+
return create(TaPubkeySchema, { value: this.toThruFmt() });
|
|
199
|
+
}
|
|
200
|
+
static fromProtoPubkey(proto) {
|
|
201
|
+
if (!proto?.value) {
|
|
202
|
+
throw new Error(`Proto is missing value`);
|
|
203
|
+
}
|
|
204
|
+
return new _Pubkey(ensureExactLength(proto.value, PUBKEY_LENGTH));
|
|
205
|
+
}
|
|
206
|
+
static fromProtoTaPubkey(proto) {
|
|
207
|
+
if (!proto?.value) {
|
|
208
|
+
throw new Error(`Proto is missing value`);
|
|
209
|
+
}
|
|
210
|
+
return new _Pubkey(ensureExactLength(decodeAddress(proto.value), PUBKEY_LENGTH));
|
|
211
|
+
}
|
|
212
|
+
static bytesFromString(value) {
|
|
213
|
+
if (_Pubkey.isThruFmt(value)) {
|
|
214
|
+
return ensureExactLength(decodeAddress(value), PUBKEY_LENGTH);
|
|
215
|
+
}
|
|
216
|
+
if (isHexString(value)) {
|
|
217
|
+
return ensureExactLength(hexToBytes(value), PUBKEY_LENGTH);
|
|
218
|
+
}
|
|
219
|
+
throw new Error(`Must be provided as hex string or ta-address`);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
var Signature = class _Signature {
|
|
223
|
+
constructor(bytes) {
|
|
224
|
+
this.bytes = bytes;
|
|
225
|
+
}
|
|
226
|
+
static from(value) {
|
|
227
|
+
if (value instanceof _Signature) {
|
|
228
|
+
return value;
|
|
229
|
+
}
|
|
230
|
+
if (value instanceof Uint8Array) {
|
|
231
|
+
return new _Signature(ensureExactLength(value, SIGNATURE_LENGTH));
|
|
232
|
+
}
|
|
233
|
+
if (typeof value === "string") {
|
|
234
|
+
return new _Signature(_Signature.bytesFromString(value));
|
|
235
|
+
}
|
|
236
|
+
throw new Error(
|
|
237
|
+
`Must be provided as Uint8Array, ts-encoded string, hex string, or base64 string`
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
static fromProto(proto) {
|
|
241
|
+
if (!proto?.value) {
|
|
242
|
+
throw new Error(`Proto is missing value`);
|
|
243
|
+
}
|
|
244
|
+
return new _Signature(ensureExactLength(proto.value, SIGNATURE_LENGTH));
|
|
245
|
+
}
|
|
246
|
+
static isThruFmt(value) {
|
|
247
|
+
return value.startsWith("ts") && value.length === TS_SIGNATURE_LENGTH;
|
|
248
|
+
}
|
|
249
|
+
toBytes() {
|
|
250
|
+
return copyBytes2(this.bytes);
|
|
251
|
+
}
|
|
252
|
+
toBytesUnsafe() {
|
|
253
|
+
return this.bytes;
|
|
254
|
+
}
|
|
255
|
+
toThruFmt() {
|
|
256
|
+
return encodeSignature(this.bytes);
|
|
257
|
+
}
|
|
258
|
+
toHex() {
|
|
259
|
+
return bytesToHex(this.bytes);
|
|
260
|
+
}
|
|
261
|
+
equals(other) {
|
|
262
|
+
const candidate = _Signature.from(other);
|
|
263
|
+
return bytesEqual(this.bytes, candidate.bytes);
|
|
264
|
+
}
|
|
265
|
+
toProtoSignature() {
|
|
266
|
+
return create(SignatureSchema, { value: this.toBytes() });
|
|
267
|
+
}
|
|
268
|
+
toProtoTsSignature() {
|
|
269
|
+
return create(TsSignatureSchema, { value: this.toThruFmt() });
|
|
270
|
+
}
|
|
271
|
+
static fromProtoTsSignature(proto) {
|
|
272
|
+
if (!proto?.value) {
|
|
273
|
+
throw new Error(`Proto is missing value`);
|
|
274
|
+
}
|
|
275
|
+
return new _Signature(ensureExactLength(decodeSignature(proto.value), SIGNATURE_LENGTH));
|
|
276
|
+
}
|
|
277
|
+
static fromProtoSignature(proto) {
|
|
278
|
+
if (!proto?.value) {
|
|
279
|
+
throw new Error(`Proto is missing value`);
|
|
280
|
+
}
|
|
281
|
+
return new _Signature(ensureExactLength(proto.value, SIGNATURE_LENGTH));
|
|
282
|
+
}
|
|
283
|
+
static bytesFromString(value) {
|
|
284
|
+
if (_Signature.isThruFmt(value)) {
|
|
285
|
+
return ensureExactLength(decodeSignature(value), SIGNATURE_LENGTH);
|
|
286
|
+
}
|
|
287
|
+
if (isHexString(value)) {
|
|
288
|
+
return ensureExactLength(hexToBytes(value), SIGNATURE_LENGTH);
|
|
289
|
+
}
|
|
290
|
+
throw new Error(`Must be provided as ts-encoded string or hex string`);
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
// thru-ts-client-sdk/wire-format.ts
|
|
295
|
+
var SIGNATURE_SIZE2 = 64;
|
|
296
|
+
var PUBKEY_SIZE2 = 32;
|
|
297
|
+
var HASH_SIZE = 32;
|
|
298
|
+
var BLOCK_HEADER_SIZE = 168;
|
|
299
|
+
var BLOCK_FOOTER_SIZE = 104;
|
|
300
|
+
var BLOCK_VERSION_V1 = 1;
|
|
301
|
+
var TXN_HEADER_SIZE = 176;
|
|
302
|
+
var TXN_VERSION_V1 = 1;
|
|
303
|
+
var TXN_MAX_ACCOUNTS = 1024;
|
|
304
|
+
var STATE_PROOF_HEADER_SIZE = 40;
|
|
305
|
+
var ACCOUNT_META_FOOTPRINT = 64;
|
|
306
|
+
var TXN_FLAG_HAS_FEE_PAYER_PROOF = 1 << 0;
|
|
307
|
+
var STATE_PROOF_TYPE_EXISTING = 0;
|
|
308
|
+
var STATE_PROOF_TYPE_UPDATING = 1;
|
|
309
|
+
var STATE_PROOF_TYPE_CREATION = 2;
|
|
310
|
+
|
|
311
|
+
// thru-ts-client-sdk/domain/transactions/Transaction.ts
|
|
312
|
+
var DEFAULT_FLAGS = 0;
|
|
313
|
+
var SIGNATURE_PREFIX_SIZE = SIGNATURE_SIZE2;
|
|
314
|
+
var MAX_INSTRUCTION_DATA_LENGTH = 65535;
|
|
315
|
+
var BYTE_POPCOUNT = new Uint8Array(256).map((_value, index) => {
|
|
316
|
+
let v = index;
|
|
317
|
+
let count = 0;
|
|
318
|
+
while (v !== 0) {
|
|
319
|
+
count += v & 1;
|
|
320
|
+
v >>= 1;
|
|
321
|
+
}
|
|
322
|
+
return count;
|
|
323
|
+
});
|
|
324
|
+
var Transaction = class _Transaction {
|
|
325
|
+
constructor(params) {
|
|
326
|
+
this.version = params.version ?? TXN_VERSION_V1;
|
|
327
|
+
this.feePayer = Pubkey.from(params.feePayer);
|
|
328
|
+
this.program = Pubkey.from(params.program);
|
|
329
|
+
this.fee = params.header.fee;
|
|
330
|
+
this.nonce = params.header.nonce;
|
|
331
|
+
this.startSlot = params.header.startSlot;
|
|
332
|
+
this.expiryAfter = params.header.expiryAfter ?? 0;
|
|
333
|
+
this.requestedComputeUnits = params.header.computeUnits ?? 0;
|
|
334
|
+
this.requestedStateUnits = params.header.stateUnits ?? 0;
|
|
335
|
+
this.requestedMemoryUnits = params.header.memoryUnits ?? 0;
|
|
336
|
+
this.flags = params.header.flags ?? DEFAULT_FLAGS;
|
|
337
|
+
this.readWriteAccounts = params.accounts?.readWriteAccounts ? params.accounts.readWriteAccounts.map(Pubkey.from) : [];
|
|
338
|
+
this.readOnlyAccounts = params.accounts?.readOnlyAccounts ? params.accounts.readOnlyAccounts.map(Pubkey.from) : [];
|
|
339
|
+
this.instructionData = params.instructionData ? new Uint8Array(params.instructionData) : void 0;
|
|
340
|
+
if (this.instructionData && this.instructionData.length > MAX_INSTRUCTION_DATA_LENGTH) {
|
|
341
|
+
throw new Error(`Instruction data exceeds maximum length (${MAX_INSTRUCTION_DATA_LENGTH} bytes)`);
|
|
342
|
+
}
|
|
343
|
+
this.instructionDataSize = params.instructionDataSize;
|
|
344
|
+
this.feePayerStateProof = params.proofs?.feePayerStateProof ? new Uint8Array(params.proofs.feePayerStateProof) : void 0;
|
|
345
|
+
this.feePayerAccountMetaRaw = params.proofs?.feePayerAccountMetaRaw ? new Uint8Array(params.proofs.feePayerAccountMetaRaw) : void 0;
|
|
346
|
+
}
|
|
347
|
+
static fromWire(data) {
|
|
348
|
+
const { transaction, size } = _Transaction.parseWire(data, { strict: true });
|
|
349
|
+
if (size !== data.length) {
|
|
350
|
+
throw new Error(
|
|
351
|
+
`Transaction body has trailing bytes: expected ${size} bytes but found ${data.length}`
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
return transaction;
|
|
355
|
+
}
|
|
356
|
+
static parseWire(data, options = {}) {
|
|
357
|
+
if (data.length < TXN_HEADER_SIZE) {
|
|
358
|
+
throw new Error(`Transaction data too short: ${data.length} bytes (expected at least ${TXN_HEADER_SIZE})`);
|
|
359
|
+
}
|
|
360
|
+
const strict = options.strict ?? false;
|
|
361
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
362
|
+
let offset = 0;
|
|
363
|
+
const signatureBytes = data.slice(offset, offset + SIGNATURE_SIZE2);
|
|
364
|
+
const hasSignature = hasNonZeroBytes(signatureBytes);
|
|
365
|
+
offset += SIGNATURE_SIZE2;
|
|
366
|
+
const version = view.getUint8(offset);
|
|
367
|
+
offset += 1;
|
|
368
|
+
if (strict && version !== TXN_VERSION_V1) {
|
|
369
|
+
throw new Error(`Unsupported transaction version: ${version}`);
|
|
370
|
+
}
|
|
371
|
+
const flags = view.getUint8(offset);
|
|
372
|
+
offset += 1;
|
|
373
|
+
const invalidFlags = flags & -4;
|
|
374
|
+
if (strict && invalidFlags !== 0) {
|
|
375
|
+
throw new Error(`Unsupported transaction flags: 0x${invalidFlags.toString(16).padStart(2, "0")}`);
|
|
376
|
+
}
|
|
377
|
+
const readwriteAccountsCount = view.getUint16(offset, true);
|
|
378
|
+
offset += 2;
|
|
379
|
+
const readonlyAccountsCount = view.getUint16(offset, true);
|
|
380
|
+
offset += 2;
|
|
381
|
+
const instructionDataSize = view.getUint16(offset, true);
|
|
382
|
+
offset += 2;
|
|
383
|
+
const requestedComputeUnits = view.getUint32(offset, true);
|
|
384
|
+
offset += 4;
|
|
385
|
+
const requestedStateUnits = view.getUint16(offset, true);
|
|
386
|
+
offset += 2;
|
|
387
|
+
const requestedMemoryUnits = view.getUint16(offset, true);
|
|
388
|
+
offset += 2;
|
|
389
|
+
const fee = view.getBigUint64(offset, true);
|
|
390
|
+
offset += 8;
|
|
391
|
+
const nonce = view.getBigUint64(offset, true);
|
|
392
|
+
offset += 8;
|
|
393
|
+
const startSlot = view.getBigUint64(offset, true);
|
|
394
|
+
offset += 8;
|
|
395
|
+
const expiryAfter = view.getUint32(offset, true);
|
|
396
|
+
offset += 4;
|
|
397
|
+
offset += 4;
|
|
398
|
+
_Transaction.ensureAvailable(data.length, offset, PUBKEY_SIZE2, "fee payer account");
|
|
399
|
+
const feePayer = data.slice(offset, offset + PUBKEY_SIZE2);
|
|
400
|
+
offset += PUBKEY_SIZE2;
|
|
401
|
+
_Transaction.ensureAvailable(data.length, offset, PUBKEY_SIZE2, "program account");
|
|
402
|
+
const program = data.slice(offset, offset + PUBKEY_SIZE2);
|
|
403
|
+
offset += PUBKEY_SIZE2;
|
|
404
|
+
if (offset !== TXN_HEADER_SIZE) {
|
|
405
|
+
throw new Error(`Transaction header parsing mismatch (expected offset ${TXN_HEADER_SIZE}, got ${offset})`);
|
|
406
|
+
}
|
|
407
|
+
const totalAccountCount = Number(readwriteAccountsCount + readonlyAccountsCount);
|
|
408
|
+
if (strict && totalAccountCount > TXN_MAX_ACCOUNTS) {
|
|
409
|
+
throw new Error(
|
|
410
|
+
`Transaction references ${totalAccountCount} accounts (maximum allowed ${TXN_MAX_ACCOUNTS})`
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
const readWriteAccounts = [];
|
|
414
|
+
for (let i = 0; i < readwriteAccountsCount; i++) {
|
|
415
|
+
_Transaction.ensureAvailable(data.length, offset, PUBKEY_SIZE2, "read-write accounts");
|
|
416
|
+
readWriteAccounts.push(data.slice(offset, offset + PUBKEY_SIZE2));
|
|
417
|
+
offset += PUBKEY_SIZE2;
|
|
418
|
+
}
|
|
419
|
+
const readOnlyAccounts = [];
|
|
420
|
+
for (let i = 0; i < readonlyAccountsCount; i++) {
|
|
421
|
+
_Transaction.ensureAvailable(data.length, offset, PUBKEY_SIZE2, "read-only accounts");
|
|
422
|
+
readOnlyAccounts.push(data.slice(offset, offset + PUBKEY_SIZE2));
|
|
423
|
+
offset += PUBKEY_SIZE2;
|
|
424
|
+
}
|
|
425
|
+
let instructionData;
|
|
426
|
+
if (instructionDataSize > 0) {
|
|
427
|
+
_Transaction.ensureAvailable(data.length, offset, instructionDataSize, "instruction data");
|
|
428
|
+
instructionData = data.slice(offset, offset + instructionDataSize);
|
|
429
|
+
offset += instructionDataSize;
|
|
430
|
+
}
|
|
431
|
+
let feePayerStateProof;
|
|
432
|
+
let feePayerAccountMetaRaw;
|
|
433
|
+
if ((flags & TXN_FLAG_HAS_FEE_PAYER_PROOF) !== 0) {
|
|
434
|
+
const { proofBytes, footprint, proofType } = _Transaction.parseStateProof(data.subarray(offset));
|
|
435
|
+
feePayerStateProof = proofBytes;
|
|
436
|
+
offset += footprint;
|
|
437
|
+
if (proofType === STATE_PROOF_TYPE_EXISTING) {
|
|
438
|
+
_Transaction.ensureAvailable(data.length, offset, ACCOUNT_META_FOOTPRINT, "fee payer account metadata");
|
|
439
|
+
feePayerAccountMetaRaw = data.slice(offset, offset + ACCOUNT_META_FOOTPRINT);
|
|
440
|
+
offset += ACCOUNT_META_FOOTPRINT;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
const transaction = new _Transaction({
|
|
444
|
+
version,
|
|
445
|
+
feePayer: Pubkey.from(feePayer),
|
|
446
|
+
program: Pubkey.from(program),
|
|
447
|
+
header: {
|
|
448
|
+
fee,
|
|
449
|
+
nonce,
|
|
450
|
+
startSlot,
|
|
451
|
+
expiryAfter,
|
|
452
|
+
computeUnits: requestedComputeUnits,
|
|
453
|
+
stateUnits: requestedStateUnits,
|
|
454
|
+
memoryUnits: requestedMemoryUnits,
|
|
455
|
+
flags
|
|
456
|
+
},
|
|
457
|
+
accounts: {
|
|
458
|
+
readWriteAccounts,
|
|
459
|
+
readOnlyAccounts
|
|
460
|
+
},
|
|
461
|
+
instructionData,
|
|
462
|
+
instructionDataSize,
|
|
463
|
+
proofs: feePayerStateProof || feePayerAccountMetaRaw ? {
|
|
464
|
+
feePayerStateProof,
|
|
465
|
+
feePayerAccountMetaRaw
|
|
466
|
+
} : void 0
|
|
467
|
+
});
|
|
468
|
+
if (hasSignature) {
|
|
469
|
+
transaction.setSignature(Signature.from(signatureBytes));
|
|
470
|
+
}
|
|
471
|
+
return { transaction, size: offset };
|
|
472
|
+
}
|
|
473
|
+
static fromProto(proto) {
|
|
474
|
+
if (!proto.header) {
|
|
475
|
+
throw new Error("Transaction proto missing header");
|
|
476
|
+
}
|
|
477
|
+
const header = proto.header;
|
|
478
|
+
const body = proto.body ? new Uint8Array(proto.body) : void 0;
|
|
479
|
+
let transaction;
|
|
480
|
+
if (body && body.length > 0) {
|
|
481
|
+
try {
|
|
482
|
+
const { transaction: parsed } = this.parseWire(body, { strict: false });
|
|
483
|
+
transaction = parsed;
|
|
484
|
+
} catch (err) {
|
|
485
|
+
transaction = void 0;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
if (!transaction) {
|
|
489
|
+
let parsed;
|
|
490
|
+
if (body && body.length > 0) {
|
|
491
|
+
try {
|
|
492
|
+
parsed = this.parseBodySections(
|
|
493
|
+
body,
|
|
494
|
+
header.readwriteAccountsCount ?? 0,
|
|
495
|
+
header.readonlyAccountsCount ?? 0,
|
|
496
|
+
header.instructionDataSize ?? 0,
|
|
497
|
+
header.flags ?? DEFAULT_FLAGS
|
|
498
|
+
);
|
|
499
|
+
} catch (sectionErr) {
|
|
500
|
+
if (body.length >= TXN_HEADER_SIZE) {
|
|
501
|
+
parsed = this.parseBodySections(
|
|
502
|
+
body.slice(TXN_HEADER_SIZE),
|
|
503
|
+
header.readwriteAccountsCount ?? 0,
|
|
504
|
+
header.readonlyAccountsCount ?? 0,
|
|
505
|
+
header.instructionDataSize ?? 0,
|
|
506
|
+
header.flags ?? DEFAULT_FLAGS
|
|
507
|
+
);
|
|
508
|
+
} else {
|
|
509
|
+
throw sectionErr;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
if (!parsed) {
|
|
514
|
+
parsed = {
|
|
515
|
+
readWriteAccounts: [],
|
|
516
|
+
readOnlyAccounts: [],
|
|
517
|
+
instructionData: void 0,
|
|
518
|
+
feePayerStateProof: void 0,
|
|
519
|
+
feePayerAccountMetaRaw: void 0
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
transaction = new _Transaction({
|
|
523
|
+
version: header.version ?? TXN_VERSION_V1,
|
|
524
|
+
feePayer: Pubkey.fromProtoPubkey(header.feePayerPubkey),
|
|
525
|
+
program: Pubkey.fromProtoPubkey(header.programPubkey),
|
|
526
|
+
header: {
|
|
527
|
+
fee: header.fee ?? 0n,
|
|
528
|
+
nonce: header.nonce ?? 0n,
|
|
529
|
+
startSlot: header.startSlot ?? 0n,
|
|
530
|
+
expiryAfter: header.expiryAfter ?? 0,
|
|
531
|
+
computeUnits: header.requestedComputeUnits ?? 0,
|
|
532
|
+
stateUnits: header.requestedStateUnits ?? 0,
|
|
533
|
+
memoryUnits: header.requestedMemoryUnits ?? 0,
|
|
534
|
+
flags: header.flags ?? DEFAULT_FLAGS
|
|
535
|
+
},
|
|
536
|
+
accounts: {
|
|
537
|
+
readWriteAccounts: parsed.readWriteAccounts,
|
|
538
|
+
readOnlyAccounts: parsed.readOnlyAccounts
|
|
539
|
+
},
|
|
540
|
+
instructionData: parsed.instructionData,
|
|
541
|
+
instructionDataSize: header.instructionDataSize,
|
|
542
|
+
proofs: parsed.feePayerStateProof || parsed.feePayerAccountMetaRaw ? {
|
|
543
|
+
feePayerStateProof: parsed.feePayerStateProof,
|
|
544
|
+
feePayerAccountMetaRaw: parsed.feePayerAccountMetaRaw
|
|
545
|
+
} : void 0
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
const signatureBytes = proto.signature?.value ?? header.feePayerSignature?.value ?? void 0;
|
|
549
|
+
if (signatureBytes && signatureBytes.length === SIGNATURE_SIZE2 && hasNonZeroBytes(signatureBytes)) {
|
|
550
|
+
transaction.setSignature(Signature.from(signatureBytes));
|
|
551
|
+
}
|
|
552
|
+
if (proto.executionResult) {
|
|
553
|
+
transaction.executionResult = _Transaction.executionResultFromProto(proto.executionResult);
|
|
554
|
+
}
|
|
555
|
+
if (proto.slot !== void 0) {
|
|
556
|
+
transaction.slot = proto.slot;
|
|
557
|
+
}
|
|
558
|
+
if (proto.blockOffset !== void 0) {
|
|
559
|
+
transaction.blockOffset = proto.blockOffset;
|
|
560
|
+
}
|
|
561
|
+
return transaction;
|
|
562
|
+
}
|
|
563
|
+
getSignature() {
|
|
564
|
+
return this.signature;
|
|
565
|
+
}
|
|
566
|
+
setSignature(signature) {
|
|
567
|
+
this.signature = signature;
|
|
568
|
+
}
|
|
569
|
+
async sign(privateKey) {
|
|
570
|
+
if (privateKey.length !== 32) {
|
|
571
|
+
throw new Error("Fee payer private key must contain 32 bytes");
|
|
572
|
+
}
|
|
573
|
+
const payload = this.toWireForSigning();
|
|
574
|
+
const publicKey = this.feePayer.toBytes();
|
|
575
|
+
const signature = await signWithDomain(
|
|
576
|
+
payload,
|
|
577
|
+
privateKey,
|
|
578
|
+
publicKey,
|
|
579
|
+
0 /* TXN */
|
|
580
|
+
);
|
|
581
|
+
if (signature.length !== SIGNATURE_SIZE2) {
|
|
582
|
+
throw new Error("ed25519 signing produced an invalid signature");
|
|
583
|
+
}
|
|
584
|
+
this.signature = Signature.from(signature);
|
|
585
|
+
return this.signature;
|
|
586
|
+
}
|
|
587
|
+
toWireForSigning() {
|
|
588
|
+
const header = this.createHeader(void 0);
|
|
589
|
+
const view = new Uint8Array(header);
|
|
590
|
+
return this.buildWirePayload(view.subarray(SIGNATURE_PREFIX_SIZE));
|
|
591
|
+
}
|
|
592
|
+
toWire() {
|
|
593
|
+
const header = this.createHeader(this.signature?.toBytes());
|
|
594
|
+
return this.buildWirePayload(new Uint8Array(header));
|
|
595
|
+
}
|
|
596
|
+
createHeader(signature) {
|
|
597
|
+
const buffer = new ArrayBuffer(TXN_HEADER_SIZE);
|
|
598
|
+
const headerBytes = new Uint8Array(buffer);
|
|
599
|
+
const view = new DataView(buffer);
|
|
600
|
+
if (signature) {
|
|
601
|
+
if (signature.length !== SIGNATURE_SIZE2) {
|
|
602
|
+
throw new Error(`Signature must contain ${SIGNATURE_SIZE2} bytes`);
|
|
603
|
+
}
|
|
604
|
+
headerBytes.set(signature, 0);
|
|
605
|
+
} else {
|
|
606
|
+
headerBytes.fill(0, 0, SIGNATURE_SIZE2);
|
|
607
|
+
}
|
|
608
|
+
let offset = SIGNATURE_PREFIX_SIZE;
|
|
609
|
+
view.setUint8(offset, this.version & 255);
|
|
610
|
+
offset += 1;
|
|
611
|
+
view.setUint8(offset, this.flags & 255);
|
|
612
|
+
offset += 1;
|
|
613
|
+
view.setUint16(offset, this.readWriteAccounts.length, true);
|
|
614
|
+
offset += 2;
|
|
615
|
+
view.setUint16(offset, this.readOnlyAccounts.length, true);
|
|
616
|
+
offset += 2;
|
|
617
|
+
const instructionDataLength = this.instructionData?.length ?? 0;
|
|
618
|
+
if (instructionDataLength > MAX_INSTRUCTION_DATA_LENGTH) {
|
|
619
|
+
throw new Error(`Instruction data exceeds maximum length (${MAX_INSTRUCTION_DATA_LENGTH} bytes)`);
|
|
620
|
+
}
|
|
621
|
+
view.setUint16(offset, instructionDataLength, true);
|
|
622
|
+
offset += 2;
|
|
623
|
+
view.setUint32(offset, ensureUint32(this.requestedComputeUnits), true);
|
|
624
|
+
offset += 4;
|
|
625
|
+
view.setUint16(offset, ensureUint16(this.requestedStateUnits), true);
|
|
626
|
+
offset += 2;
|
|
627
|
+
view.setUint16(offset, ensureUint16(this.requestedMemoryUnits), true);
|
|
628
|
+
offset += 2;
|
|
629
|
+
view.setBigUint64(offset, ensureBigUint64(this.fee), true);
|
|
630
|
+
offset += 8;
|
|
631
|
+
view.setBigUint64(offset, ensureBigUint64(this.nonce), true);
|
|
632
|
+
offset += 8;
|
|
633
|
+
view.setBigUint64(offset, ensureBigUint64(this.startSlot), true);
|
|
634
|
+
offset += 8;
|
|
635
|
+
view.setUint32(offset, ensureUint32(this.expiryAfter), true);
|
|
636
|
+
offset += 4;
|
|
637
|
+
offset += 4;
|
|
638
|
+
headerBytes.set(this.feePayer.toBytes(), offset);
|
|
639
|
+
offset += PUBKEY_SIZE2;
|
|
640
|
+
headerBytes.set(this.program.toBytes(), offset);
|
|
641
|
+
return buffer;
|
|
642
|
+
}
|
|
643
|
+
buildWirePayload(headerPrefix) {
|
|
644
|
+
const dynamicLength = this.readWriteAccounts.length * PUBKEY_SIZE2 + this.readOnlyAccounts.length * PUBKEY_SIZE2 + (this.instructionData?.length ?? 0) + (this.feePayerStateProof?.length ?? 0) + (this.feePayerAccountMetaRaw?.length ?? 0);
|
|
645
|
+
const result = new Uint8Array(headerPrefix.length + dynamicLength);
|
|
646
|
+
result.set(headerPrefix, 0);
|
|
647
|
+
let offset = headerPrefix.length;
|
|
648
|
+
offset = appendAccountList(result, offset, this.readWriteAccounts.map((account) => account.toBytes()));
|
|
649
|
+
offset = appendAccountList(result, offset, this.readOnlyAccounts.map((account) => account.toBytes()));
|
|
650
|
+
if (this.instructionData) {
|
|
651
|
+
result.set(this.instructionData, offset);
|
|
652
|
+
offset += this.instructionData.length;
|
|
653
|
+
}
|
|
654
|
+
if (this.feePayerStateProof) {
|
|
655
|
+
result.set(this.feePayerStateProof, offset);
|
|
656
|
+
offset += this.feePayerStateProof.length;
|
|
657
|
+
}
|
|
658
|
+
if (this.feePayerAccountMetaRaw) {
|
|
659
|
+
result.set(this.feePayerAccountMetaRaw, offset);
|
|
660
|
+
offset += this.feePayerAccountMetaRaw.length;
|
|
661
|
+
}
|
|
662
|
+
return result;
|
|
663
|
+
}
|
|
664
|
+
static parseBodySections(body, readwriteCount, readonlyCount, instructionDataSize, flags) {
|
|
665
|
+
let offset = 0;
|
|
666
|
+
const readWriteAccounts = [];
|
|
667
|
+
for (let i = 0; i < readwriteCount; i++) {
|
|
668
|
+
this.ensureAvailable(body.length, offset, PUBKEY_SIZE2, "read-write accounts");
|
|
669
|
+
readWriteAccounts.push(body.slice(offset, offset + PUBKEY_SIZE2));
|
|
670
|
+
offset += PUBKEY_SIZE2;
|
|
671
|
+
}
|
|
672
|
+
const readOnlyAccounts = [];
|
|
673
|
+
for (let i = 0; i < readonlyCount; i++) {
|
|
674
|
+
this.ensureAvailable(body.length, offset, PUBKEY_SIZE2, "read-only accounts");
|
|
675
|
+
readOnlyAccounts.push(body.slice(offset, offset + PUBKEY_SIZE2));
|
|
676
|
+
offset += PUBKEY_SIZE2;
|
|
677
|
+
}
|
|
678
|
+
let instructionData;
|
|
679
|
+
if (instructionDataSize > 0) {
|
|
680
|
+
this.ensureAvailable(body.length, offset, instructionDataSize, "instruction data");
|
|
681
|
+
instructionData = body.slice(offset, offset + instructionDataSize);
|
|
682
|
+
offset += instructionDataSize;
|
|
683
|
+
}
|
|
684
|
+
let feePayerStateProof;
|
|
685
|
+
let feePayerAccountMetaRaw;
|
|
686
|
+
if ((flags & TXN_FLAG_HAS_FEE_PAYER_PROOF) !== 0) {
|
|
687
|
+
const { proofBytes, footprint, proofType } = this.parseStateProof(body.subarray(offset));
|
|
688
|
+
feePayerStateProof = proofBytes;
|
|
689
|
+
offset += footprint;
|
|
690
|
+
if (proofType === STATE_PROOF_TYPE_EXISTING) {
|
|
691
|
+
this.ensureAvailable(body.length, offset, ACCOUNT_META_FOOTPRINT, "fee payer account metadata");
|
|
692
|
+
feePayerAccountMetaRaw = body.slice(offset, offset + ACCOUNT_META_FOOTPRINT);
|
|
693
|
+
offset += ACCOUNT_META_FOOTPRINT;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
if (offset !== body.length) {
|
|
697
|
+
throw new Error(
|
|
698
|
+
`Transaction body has trailing bytes: expected ${offset} bytes but found ${body.length}`
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
return {
|
|
702
|
+
readWriteAccounts,
|
|
703
|
+
readOnlyAccounts,
|
|
704
|
+
instructionData,
|
|
705
|
+
feePayerStateProof,
|
|
706
|
+
feePayerAccountMetaRaw
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
static ensureAvailable(totalLength, offset, required, context) {
|
|
710
|
+
if (offset + required > totalLength) {
|
|
711
|
+
throw new Error(`Transaction data truncated while parsing ${context}`);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
static parseStateProof(data) {
|
|
715
|
+
if (data.length < STATE_PROOF_HEADER_SIZE) {
|
|
716
|
+
throw new Error("Transaction data truncated while parsing state proof header");
|
|
717
|
+
}
|
|
718
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
719
|
+
const typeSlot = view.getBigUint64(0, true);
|
|
720
|
+
const proofType = Number(typeSlot >> 62n & 0x3n);
|
|
721
|
+
if (proofType !== STATE_PROOF_TYPE_EXISTING && proofType !== STATE_PROOF_TYPE_UPDATING && proofType !== STATE_PROOF_TYPE_CREATION) {
|
|
722
|
+
throw new Error(`Transaction state proof has unknown type: ${proofType}`);
|
|
723
|
+
}
|
|
724
|
+
const pathBitset = data.subarray(8, 40);
|
|
725
|
+
const siblingCount = countSetBits(pathBitset);
|
|
726
|
+
const bodyCount = proofType + siblingCount;
|
|
727
|
+
const totalSize = STATE_PROOF_HEADER_SIZE + bodyCount * HASH_SIZE;
|
|
728
|
+
if (proofType === STATE_PROOF_TYPE_CREATION && bodyCount < 2) {
|
|
729
|
+
throw new Error("Transaction state proof creation entry is truncated");
|
|
730
|
+
}
|
|
731
|
+
if (proofType === STATE_PROOF_TYPE_UPDATING && bodyCount < 1) {
|
|
732
|
+
throw new Error("Transaction state proof updating entry is truncated");
|
|
733
|
+
}
|
|
734
|
+
if (data.length < totalSize) {
|
|
735
|
+
throw new Error("Transaction data truncated while parsing state proof body");
|
|
736
|
+
}
|
|
737
|
+
return {
|
|
738
|
+
proofBytes: data.slice(0, totalSize),
|
|
739
|
+
footprint: totalSize,
|
|
740
|
+
proofType
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
static executionResultFromProto(proto) {
|
|
744
|
+
return {
|
|
745
|
+
consumedComputeUnits: proto.consumedComputeUnits ?? 0,
|
|
746
|
+
consumedMemoryUnits: proto.consumedMemoryUnits ?? 0,
|
|
747
|
+
consumedStateUnits: proto.consumedStateUnits ?? 0,
|
|
748
|
+
userErrorCode: proto.userErrorCode ?? 0n,
|
|
749
|
+
vmError: proto.vmError ?? TransactionVmError.TRANSACTION_VM_EXECUTE_SUCCESS,
|
|
750
|
+
executionResult: proto.executionResult ?? 0n,
|
|
751
|
+
pagesUsed: proto.pagesUsed ?? 0,
|
|
752
|
+
eventsCount: proto.eventsCount ?? 0,
|
|
753
|
+
eventsSize: proto.eventsSize ?? 0,
|
|
754
|
+
readwriteAccounts: proto.readwriteAccounts.map((account) => Pubkey.fromProtoPubkey(account)),
|
|
755
|
+
readonlyAccounts: proto.readonlyAccounts.map((account) => Pubkey.fromProtoPubkey(account)),
|
|
756
|
+
events: proto.events.length ? proto.events.map((event) => ({
|
|
757
|
+
eventId: event.eventId,
|
|
758
|
+
callIdx: event.callIdx,
|
|
759
|
+
programIdx: event.programIdx,
|
|
760
|
+
program: event.program ? Pubkey.fromProtoPubkey(event.program) : void 0,
|
|
761
|
+
payload: new Uint8Array(event.payload ?? new Uint8Array(0))
|
|
762
|
+
})) : void 0
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
function appendAccountList(target, start, accounts) {
|
|
767
|
+
let offset = start;
|
|
768
|
+
for (const account of accounts) {
|
|
769
|
+
target.set(account, offset);
|
|
770
|
+
offset += PUBKEY_SIZE2;
|
|
771
|
+
}
|
|
772
|
+
return offset;
|
|
773
|
+
}
|
|
774
|
+
function ensureUint16(value) {
|
|
775
|
+
if (!Number.isInteger(value) || value < 0 || value > 65535) {
|
|
776
|
+
throw new Error("Value must fit within uint16 range");
|
|
777
|
+
}
|
|
778
|
+
return value;
|
|
779
|
+
}
|
|
780
|
+
function ensureUint32(value) {
|
|
781
|
+
if (!Number.isInteger(value) || value < 0 || value > 4294967295) {
|
|
782
|
+
throw new Error("Value must fit within uint32 range");
|
|
783
|
+
}
|
|
784
|
+
return value;
|
|
785
|
+
}
|
|
786
|
+
function ensureBigUint64(value) {
|
|
787
|
+
if (value < 0n || value > 0xffffffffffffffffn) {
|
|
788
|
+
throw new Error("Value must fit within uint64 range");
|
|
789
|
+
}
|
|
790
|
+
return value;
|
|
791
|
+
}
|
|
792
|
+
function countSetBits(bytes) {
|
|
793
|
+
let total = 0;
|
|
794
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
795
|
+
total += BYTE_POPCOUNT[bytes[i]];
|
|
796
|
+
}
|
|
797
|
+
return total;
|
|
798
|
+
}
|
|
799
|
+
function hasNonZeroBytes(value) {
|
|
800
|
+
for (let i = 0; i < value.length; i++) {
|
|
801
|
+
if (value[i] !== 0) {
|
|
802
|
+
return true;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return false;
|
|
806
|
+
}
|
|
807
|
+
var ACCOUNT_LIMIT = 1024;
|
|
808
|
+
function normalizeAccountList(accounts) {
|
|
809
|
+
if (accounts.length === 0) {
|
|
810
|
+
return [];
|
|
811
|
+
}
|
|
812
|
+
if (accounts.length > ACCOUNT_LIMIT) {
|
|
813
|
+
throw new Error(`Too many accounts provided: ${accounts.length} (max ${ACCOUNT_LIMIT})`);
|
|
814
|
+
}
|
|
815
|
+
const deduped = dedupeAccountList(accounts);
|
|
816
|
+
return deduped;
|
|
817
|
+
}
|
|
818
|
+
function dedupeAccountList(accounts) {
|
|
819
|
+
const pubkeys = accounts.map(Pubkey.from).map((pubkey) => pubkey.toBytes());
|
|
820
|
+
const seen = /* @__PURE__ */ new Map();
|
|
821
|
+
for (const pubkey of pubkeys) {
|
|
822
|
+
if (pubkey.length !== 32) {
|
|
823
|
+
throw new Error("Account addresses must contain 32 bytes");
|
|
824
|
+
}
|
|
825
|
+
const key = toHex(pubkey);
|
|
826
|
+
if (!seen.has(key)) {
|
|
827
|
+
seen.set(key, pubkey);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
return Array.from(seen.values()).sort(compareAccounts);
|
|
831
|
+
}
|
|
832
|
+
function compareAccounts(a, b) {
|
|
833
|
+
for (let i = 0; i < 32; i++) {
|
|
834
|
+
if (a[i] !== b[i]) {
|
|
835
|
+
return a[i] - b[i];
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
return 0;
|
|
839
|
+
}
|
|
840
|
+
function toHex(bytes) {
|
|
841
|
+
let result = "";
|
|
842
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
843
|
+
const hex = bytes[i].toString(16).padStart(2, "0");
|
|
844
|
+
result += hex;
|
|
845
|
+
}
|
|
846
|
+
return result;
|
|
847
|
+
}
|
|
848
|
+
function parseInstructionData(value) {
|
|
849
|
+
if (value === void 0) {
|
|
850
|
+
return void 0;
|
|
851
|
+
}
|
|
852
|
+
if (value instanceof Uint8Array) {
|
|
853
|
+
return new Uint8Array(value);
|
|
854
|
+
}
|
|
855
|
+
if (typeof value === "string") {
|
|
856
|
+
if (value.length === 0) {
|
|
857
|
+
return new Uint8Array();
|
|
858
|
+
}
|
|
859
|
+
if (isHexString(value)) {
|
|
860
|
+
return hexToBytes(value);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
throw new Error("Instruction data must be provided as hex string or Uint8Array");
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// thru-ts-client-sdk/domain/transactions/TransactionBuilder.ts
|
|
867
|
+
var FLAG_HAS_FEE_PAYER_PROOF = 1 << 0;
|
|
868
|
+
var TransactionBuilder = class {
|
|
869
|
+
build(params) {
|
|
870
|
+
const accounts = this.normalizeAccounts(params.accounts);
|
|
871
|
+
const baseFlags = params.header.flags ?? 0;
|
|
872
|
+
const flags = params.proofs?.feePayerStateProof ? baseFlags | FLAG_HAS_FEE_PAYER_PROOF : baseFlags;
|
|
873
|
+
const instructionData = parseInstructionData(params.instructionData);
|
|
874
|
+
return new Transaction({
|
|
875
|
+
feePayer: Pubkey.from(params.feePayer.publicKey),
|
|
876
|
+
program: Pubkey.from(params.program),
|
|
877
|
+
header: {
|
|
878
|
+
...params.header,
|
|
879
|
+
flags
|
|
880
|
+
},
|
|
881
|
+
accounts,
|
|
882
|
+
instructionData,
|
|
883
|
+
proofs: params.proofs
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
normalizeAccounts(accounts) {
|
|
887
|
+
if (!accounts) {
|
|
888
|
+
return void 0;
|
|
889
|
+
}
|
|
890
|
+
return {
|
|
891
|
+
readWriteAccounts: normalizeAccountList(accounts.readWriteAccounts ?? []),
|
|
892
|
+
readOnlyAccounts: normalizeAccountList(accounts.readOnlyAccounts ?? [])
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
async buildAndSign(params) {
|
|
896
|
+
if (!params.feePayer.privateKey) {
|
|
897
|
+
throw new Error("Fee payer private key is required to sign the transaction");
|
|
898
|
+
}
|
|
899
|
+
const transaction = this.build(params);
|
|
900
|
+
const signature = await transaction.sign(params.feePayer.privateKey);
|
|
901
|
+
const rawTransaction = transaction.toWire();
|
|
902
|
+
return { transaction, signature, rawTransaction };
|
|
903
|
+
}
|
|
904
|
+
};
|
|
905
|
+
function isSlotSelector(selector) {
|
|
906
|
+
return "slot" in selector;
|
|
907
|
+
}
|
|
908
|
+
function mergeTransactionHeader(defaults, overrides) {
|
|
909
|
+
if (!overrides) {
|
|
910
|
+
return defaults;
|
|
911
|
+
}
|
|
912
|
+
const sanitized = Object.fromEntries(
|
|
913
|
+
Object.entries(overrides).filter(([, value]) => value !== void 0)
|
|
914
|
+
);
|
|
915
|
+
return {
|
|
916
|
+
...defaults,
|
|
917
|
+
...sanitized
|
|
918
|
+
};
|
|
919
|
+
}
|
|
920
|
+
function timestampToNanoseconds(timestamp) {
|
|
921
|
+
if (!timestamp) {
|
|
922
|
+
return 0n;
|
|
923
|
+
}
|
|
924
|
+
const seconds = BigInt(timestamp.seconds ?? 0);
|
|
925
|
+
const nanos = BigInt(timestamp.nanos ?? 0);
|
|
926
|
+
return seconds * 1000000000n + nanos;
|
|
927
|
+
}
|
|
928
|
+
function nanosecondsToTimestamp(ns) {
|
|
929
|
+
const seconds = ns / 1000000000n;
|
|
930
|
+
const nanos = Number(ns % 1000000000n);
|
|
931
|
+
return { seconds, nanos };
|
|
932
|
+
}
|
|
933
|
+
function consensusStatusToString(status) {
|
|
934
|
+
const lookup = ConsensusStatus;
|
|
935
|
+
return lookup[status] ?? `UNKNOWN(${status})`;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
// thru-ts-client-sdk/domain/transactions/TransactionStatusSnapshot.ts
|
|
939
|
+
var TransactionStatusSnapshot = class _TransactionStatusSnapshot {
|
|
940
|
+
constructor(params) {
|
|
941
|
+
this.signature = copyBytes3(params.signature);
|
|
942
|
+
this.statusCode = params.consensusStatus;
|
|
943
|
+
this.status = params.consensusStatus != null ? consensusStatusToString(params.consensusStatus) : void 0;
|
|
944
|
+
this.executionResult = params.executionResult;
|
|
945
|
+
}
|
|
946
|
+
static fromProto(proto) {
|
|
947
|
+
if (!proto.signature?.value) {
|
|
948
|
+
throw new Error("TransactionStatus proto missing signature");
|
|
949
|
+
}
|
|
950
|
+
return new _TransactionStatusSnapshot({
|
|
951
|
+
signature: proto.signature.value,
|
|
952
|
+
consensusStatus: proto.consensusStatus,
|
|
953
|
+
executionResult: proto.executionResult ? Transaction.executionResultFromProto(proto.executionResult) : void 0
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
function copyBytes3(bytes) {
|
|
958
|
+
const copy = new Uint8Array(bytes.length);
|
|
959
|
+
copy.set(bytes);
|
|
960
|
+
return copy;
|
|
961
|
+
}
|
|
962
|
+
var DEFAULT_HOST = "https://grpc-web.alphanet.thruput.org";
|
|
963
|
+
var DEFAULT_ACCOUNT_VIEW = AccountView.FULL;
|
|
964
|
+
var DEFAULT_BLOCK_VIEW = BlockView.FULL;
|
|
965
|
+
var DEFAULT_TRANSACTION_VIEW = TransactionView.FULL;
|
|
966
|
+
var DEFAULT_MIN_CONSENSUS = ConsensusStatus.UNSPECIFIED;
|
|
967
|
+
var DEFAULT_VERSION_CONTEXT = create(VersionContextSchema, {
|
|
968
|
+
version: {
|
|
969
|
+
case: "current",
|
|
970
|
+
value: create(CurrentVersionSchema, {})
|
|
971
|
+
}
|
|
972
|
+
});
|
|
973
|
+
var DEFAULT_FEE = 1n;
|
|
974
|
+
var DEFAULT_COMPUTE_UNITS = 3e8;
|
|
975
|
+
var DEFAULT_STATE_UNITS = 1e4;
|
|
976
|
+
var DEFAULT_MEMORY_UNITS = 1e4;
|
|
977
|
+
var DEFAULT_EXPIRY_AFTER = 100;
|
|
978
|
+
function createThruClientContext(config = {}) {
|
|
979
|
+
const transportOptions = config.transportOptions ?? {};
|
|
980
|
+
const { baseUrl: optionsBaseUrl, interceptors: optionInterceptors, ...restTransportOptions } = transportOptions;
|
|
981
|
+
const baseUrl = config.baseUrl ?? optionsBaseUrl ?? DEFAULT_HOST;
|
|
982
|
+
const mergedInterceptors = [
|
|
983
|
+
...optionInterceptors ?? [],
|
|
984
|
+
...config.interceptors ?? []
|
|
985
|
+
];
|
|
986
|
+
const transport = config.transport ?? createGrpcWebTransport({
|
|
987
|
+
baseUrl,
|
|
988
|
+
...restTransportOptions,
|
|
989
|
+
interceptors: mergedInterceptors.length > 0 ? mergedInterceptors : void 0
|
|
990
|
+
});
|
|
991
|
+
return {
|
|
992
|
+
baseUrl,
|
|
993
|
+
transport,
|
|
994
|
+
query: createClient(QueryService, transport),
|
|
995
|
+
command: createClient(CommandService, transport),
|
|
996
|
+
streaming: createClient(StreamingService, transport),
|
|
997
|
+
callOptions: config.callOptions
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
function withCallOptions(ctx, overrides) {
|
|
1001
|
+
return mergeCallOptions(ctx.callOptions, overrides);
|
|
1002
|
+
}
|
|
1003
|
+
function mergeCallOptions(defaults, overrides) {
|
|
1004
|
+
if (!defaults) {
|
|
1005
|
+
return overrides;
|
|
1006
|
+
}
|
|
1007
|
+
if (!overrides) {
|
|
1008
|
+
return defaults;
|
|
1009
|
+
}
|
|
1010
|
+
return {
|
|
1011
|
+
...defaults,
|
|
1012
|
+
...overrides,
|
|
1013
|
+
headers: mergeHeaders(defaults.headers, overrides.headers),
|
|
1014
|
+
contextValues: overrides.contextValues ?? defaults.contextValues,
|
|
1015
|
+
onHeader: overrides.onHeader ?? defaults.onHeader,
|
|
1016
|
+
onTrailer: overrides.onTrailer ?? defaults.onTrailer
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
function mergeHeaders(a, b) {
|
|
1020
|
+
const entries = [];
|
|
1021
|
+
const add = (init) => {
|
|
1022
|
+
if (!init) {
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
if (init instanceof Headers) {
|
|
1026
|
+
init.forEach((value, key) => {
|
|
1027
|
+
entries.push([key, value]);
|
|
1028
|
+
});
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
if (Array.isArray(init)) {
|
|
1032
|
+
for (const [key, value] of init) {
|
|
1033
|
+
entries.push([key, value]);
|
|
1034
|
+
}
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
for (const [key, value] of Object.entries(init)) {
|
|
1038
|
+
if (value !== void 0) {
|
|
1039
|
+
entries.push([key, String(value)]);
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
};
|
|
1043
|
+
add(a);
|
|
1044
|
+
add(b);
|
|
1045
|
+
if (entries.length === 0) {
|
|
1046
|
+
return void 0;
|
|
1047
|
+
}
|
|
1048
|
+
return entries;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// thru-ts-client-sdk/domain/accounts/Account.ts
|
|
1052
|
+
var AccountFlags = class _AccountFlags {
|
|
1053
|
+
constructor(flags) {
|
|
1054
|
+
this.isProgram = flags?.isProgram ?? false;
|
|
1055
|
+
this.isPrivileged = flags?.isPrivileged ?? false;
|
|
1056
|
+
this.isUncompressable = flags?.isUncompressable ?? false;
|
|
1057
|
+
this.isEphemeral = flags?.isEphemeral ?? false;
|
|
1058
|
+
this.isDeleted = flags?.isDeleted ?? false;
|
|
1059
|
+
this.isNew = flags?.isNew ?? false;
|
|
1060
|
+
this.isCompressed = flags?.isCompressed ?? false;
|
|
1061
|
+
}
|
|
1062
|
+
static fromProto(flags) {
|
|
1063
|
+
if (!flags) {
|
|
1064
|
+
return new _AccountFlags();
|
|
1065
|
+
}
|
|
1066
|
+
return new _AccountFlags({
|
|
1067
|
+
isProgram: flags.isProgram,
|
|
1068
|
+
isPrivileged: flags.isPrivileged,
|
|
1069
|
+
isUncompressable: flags.isUncompressable,
|
|
1070
|
+
isEphemeral: flags.isEphemeral,
|
|
1071
|
+
isDeleted: flags.isDeleted,
|
|
1072
|
+
isNew: flags.isNew,
|
|
1073
|
+
isCompressed: flags.isCompressed
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
var AccountMeta = class _AccountMeta {
|
|
1078
|
+
constructor(params) {
|
|
1079
|
+
this.version = params.version;
|
|
1080
|
+
this.flags = params.flags ?? new AccountFlags();
|
|
1081
|
+
this.dataSize = params.dataSize;
|
|
1082
|
+
this.seq = params.seq;
|
|
1083
|
+
this.owner = params.owner;
|
|
1084
|
+
this.balance = params.balance;
|
|
1085
|
+
this.nonce = params.nonce;
|
|
1086
|
+
}
|
|
1087
|
+
static fromProto(meta) {
|
|
1088
|
+
if (!meta) {
|
|
1089
|
+
return void 0;
|
|
1090
|
+
}
|
|
1091
|
+
return new _AccountMeta({
|
|
1092
|
+
version: meta.version,
|
|
1093
|
+
flags: AccountFlags.fromProto(meta.flags),
|
|
1094
|
+
dataSize: meta.dataSize,
|
|
1095
|
+
seq: meta.seq ?? 0n,
|
|
1096
|
+
owner: meta.owner ? Pubkey.fromProtoPubkey(meta.owner) : void 0,
|
|
1097
|
+
balance: meta.balance ?? 0n,
|
|
1098
|
+
nonce: meta.nonce
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
var AccountData = class _AccountData {
|
|
1103
|
+
constructor(params) {
|
|
1104
|
+
this.data = params.data ? new Uint8Array(params.data) : void 0;
|
|
1105
|
+
this.compressed = params.compressed ?? false;
|
|
1106
|
+
this.compressionAlgorithm = params.compressionAlgorithm;
|
|
1107
|
+
}
|
|
1108
|
+
static fromProto(data) {
|
|
1109
|
+
if (!data) {
|
|
1110
|
+
return void 0;
|
|
1111
|
+
}
|
|
1112
|
+
return new _AccountData({
|
|
1113
|
+
data: data.data ? new Uint8Array(data.data) : void 0,
|
|
1114
|
+
compressed: data.compressed ?? false,
|
|
1115
|
+
compressionAlgorithm: data.compressionAlgorithm
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
1119
|
+
var Account = class _Account {
|
|
1120
|
+
constructor(params) {
|
|
1121
|
+
this.address = params.address;
|
|
1122
|
+
this.meta = params.meta;
|
|
1123
|
+
this.data = params.data;
|
|
1124
|
+
this.versionContext = params.versionContext;
|
|
1125
|
+
this.consensusStatus = params.consensusStatus;
|
|
1126
|
+
}
|
|
1127
|
+
static fromProto(proto) {
|
|
1128
|
+
if (!proto.address) {
|
|
1129
|
+
throw new Error("Account proto missing address");
|
|
1130
|
+
}
|
|
1131
|
+
return new _Account({
|
|
1132
|
+
address: Pubkey.fromProtoPubkey(proto.address),
|
|
1133
|
+
meta: AccountMeta.fromProto(proto.meta),
|
|
1134
|
+
data: AccountData.fromProto(proto.data ?? void 0),
|
|
1135
|
+
versionContext: convertVersionContext(proto.versionContext),
|
|
1136
|
+
consensusStatus: proto.consensusStatus
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
function convertVersionContext(meta) {
|
|
1141
|
+
if (!meta) {
|
|
1142
|
+
return void 0;
|
|
1143
|
+
}
|
|
1144
|
+
return {
|
|
1145
|
+
slot: meta.slot,
|
|
1146
|
+
blockTimestampNs: timestampToNanoseconds(meta.blockTimestamp)
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
// thru-ts-client-sdk/domain/accounts/streaming.ts
|
|
1151
|
+
function toStreamAccountUpdate(response) {
|
|
1152
|
+
if (!response.message) {
|
|
1153
|
+
return void 0;
|
|
1154
|
+
}
|
|
1155
|
+
if (response.message.case === "snapshot") {
|
|
1156
|
+
return {
|
|
1157
|
+
kind: "snapshot",
|
|
1158
|
+
snapshot: { account: Account.fromProto(response.message.value) }
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
if (response.message.case === "update") {
|
|
1162
|
+
return {
|
|
1163
|
+
kind: "update",
|
|
1164
|
+
update: fromProtoUpdate(response.message.value)
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
return void 0;
|
|
1168
|
+
}
|
|
1169
|
+
function fromProtoUpdate(update) {
|
|
1170
|
+
return {
|
|
1171
|
+
slot: update.slot,
|
|
1172
|
+
meta: AccountMeta.fromProto(update.meta),
|
|
1173
|
+
page: update.page ? fromProtoPage(update.page) : void 0,
|
|
1174
|
+
deleted: update.delete ?? false
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
function fromProtoPage(page) {
|
|
1178
|
+
return {
|
|
1179
|
+
pageIndex: page.pageIdx,
|
|
1180
|
+
pageSize: page.pageSize,
|
|
1181
|
+
data: new Uint8Array(page.pageData),
|
|
1182
|
+
compressed: page.compressed ?? void 0,
|
|
1183
|
+
compressionAlgorithm: page.compressionAlgorithm
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
var PageRequest = class _PageRequest {
|
|
1187
|
+
constructor(params = {}) {
|
|
1188
|
+
if (params.pageSize !== void 0) {
|
|
1189
|
+
if (!Number.isInteger(params.pageSize) || params.pageSize < 0) {
|
|
1190
|
+
throw new Error("PageRequest.pageSize must be a non-negative integer");
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
this.pageSize = params.pageSize;
|
|
1194
|
+
this.pageToken = params.pageToken;
|
|
1195
|
+
this.orderBy = params.orderBy;
|
|
1196
|
+
}
|
|
1197
|
+
static fromProto(proto) {
|
|
1198
|
+
if (!proto) {
|
|
1199
|
+
return void 0;
|
|
1200
|
+
}
|
|
1201
|
+
return new _PageRequest({
|
|
1202
|
+
pageSize: proto.pageSize,
|
|
1203
|
+
pageToken: proto.pageToken,
|
|
1204
|
+
orderBy: proto.orderBy
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
toProto() {
|
|
1208
|
+
return create(PageRequestSchema, {
|
|
1209
|
+
pageSize: this.pageSize,
|
|
1210
|
+
pageToken: this.pageToken,
|
|
1211
|
+
orderBy: this.orderBy
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
withParams(params) {
|
|
1215
|
+
return new _PageRequest({
|
|
1216
|
+
pageSize: params.pageSize ?? this.pageSize,
|
|
1217
|
+
pageToken: params.pageToken ?? this.pageToken,
|
|
1218
|
+
orderBy: params.orderBy ?? this.orderBy
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
};
|
|
1222
|
+
var PageResponse = class _PageResponse {
|
|
1223
|
+
constructor(params = {}) {
|
|
1224
|
+
this.nextPageToken = params.nextPageToken;
|
|
1225
|
+
this.totalSize = params.totalSize;
|
|
1226
|
+
}
|
|
1227
|
+
static fromProto(proto) {
|
|
1228
|
+
if (!proto) {
|
|
1229
|
+
return void 0;
|
|
1230
|
+
}
|
|
1231
|
+
return new _PageResponse({
|
|
1232
|
+
nextPageToken: proto.nextPageToken,
|
|
1233
|
+
totalSize: proto.totalSize
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
toProto() {
|
|
1237
|
+
return create(PageResponseSchema, {
|
|
1238
|
+
nextPageToken: this.nextPageToken,
|
|
1239
|
+
totalSize: this.totalSize
|
|
1240
|
+
});
|
|
1241
|
+
}
|
|
1242
|
+
hasNextPage() {
|
|
1243
|
+
return !!this.nextPageToken;
|
|
1244
|
+
}
|
|
1245
|
+
};
|
|
1246
|
+
|
|
1247
|
+
// thru-ts-client-sdk/domain/proofs/StateProof.ts
|
|
1248
|
+
var StateProof = class _StateProof {
|
|
1249
|
+
constructor(params) {
|
|
1250
|
+
this.proof = copyBytes4(params.proof);
|
|
1251
|
+
this.slot = params.slot;
|
|
1252
|
+
}
|
|
1253
|
+
static fromProto(proto) {
|
|
1254
|
+
return new _StateProof({
|
|
1255
|
+
proof: proto.proof,
|
|
1256
|
+
slot: proto.slot ?? 0n
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
};
|
|
1260
|
+
function copyBytes4(bytes) {
|
|
1261
|
+
const copy = new Uint8Array(bytes.length);
|
|
1262
|
+
copy.set(bytes);
|
|
1263
|
+
return copy;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
// thru-ts-client-sdk/modules/proofs.ts
|
|
1267
|
+
var proofs_exports = {};
|
|
1268
|
+
__export(proofs_exports, {
|
|
1269
|
+
generateStateProof: () => generateStateProof
|
|
1270
|
+
});
|
|
1271
|
+
async function generateStateProof(ctx, options) {
|
|
1272
|
+
const targetSlot = options.targetSlot ?? 0n;
|
|
1273
|
+
const request = create(StateProofRequestSchema, {
|
|
1274
|
+
address: options.address ? Pubkey.from(options.address).toProtoPubkey() : void 0,
|
|
1275
|
+
proofType: options.proofType,
|
|
1276
|
+
targetSlot
|
|
1277
|
+
});
|
|
1278
|
+
const schemaRequest = create(GenerateStateProofRequestSchema, { request });
|
|
1279
|
+
const response = await ctx.query.generateStateProof(
|
|
1280
|
+
schemaRequest,
|
|
1281
|
+
withCallOptions(ctx)
|
|
1282
|
+
);
|
|
1283
|
+
if (!response.proof) {
|
|
1284
|
+
throw new Error("State proof response missing proof");
|
|
1285
|
+
}
|
|
1286
|
+
return StateProof.fromProto(response.proof);
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
// thru-ts-client-sdk/modules/accounts.ts
|
|
1290
|
+
var accounts_exports = {};
|
|
1291
|
+
__export(accounts_exports, {
|
|
1292
|
+
createAccount: () => createAccount,
|
|
1293
|
+
getAccount: () => getAccount,
|
|
1294
|
+
getRawAccount: () => getRawAccount,
|
|
1295
|
+
listAccounts: () => listAccounts
|
|
1296
|
+
});
|
|
1297
|
+
function getAccount(ctx, address, options = {}) {
|
|
1298
|
+
const request = create(GetAccountRequestSchema, {
|
|
1299
|
+
address: Pubkey.from(address).toProtoPubkey(),
|
|
1300
|
+
view: options.view ?? DEFAULT_ACCOUNT_VIEW,
|
|
1301
|
+
versionContext: options.versionContext ?? DEFAULT_VERSION_CONTEXT,
|
|
1302
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS,
|
|
1303
|
+
dataSlice: options.dataSlice
|
|
1304
|
+
});
|
|
1305
|
+
return ctx.query.getAccount(request, withCallOptions(ctx)).then(Account.fromProto);
|
|
1306
|
+
}
|
|
1307
|
+
function getRawAccount(ctx, address, options = {}) {
|
|
1308
|
+
const request = create(GetRawAccountRequestSchema, {
|
|
1309
|
+
address: Pubkey.from(address).toProtoPubkey(),
|
|
1310
|
+
view: options.view ?? DEFAULT_ACCOUNT_VIEW,
|
|
1311
|
+
versionContext: options.versionContext ?? DEFAULT_VERSION_CONTEXT,
|
|
1312
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
1313
|
+
});
|
|
1314
|
+
return ctx.query.getRawAccount(request, withCallOptions(ctx));
|
|
1315
|
+
}
|
|
1316
|
+
function listAccounts(ctx, options) {
|
|
1317
|
+
const request = create(ListAccountsRequestSchema, {
|
|
1318
|
+
view: options.view ?? DEFAULT_ACCOUNT_VIEW,
|
|
1319
|
+
versionContext: options.versionContext ?? DEFAULT_VERSION_CONTEXT,
|
|
1320
|
+
filter: options.filter?.toProto(),
|
|
1321
|
+
page: options.page?.toProto(),
|
|
1322
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
1323
|
+
});
|
|
1324
|
+
return ctx.query.listAccounts(request, withCallOptions(ctx)).then((response) => ({
|
|
1325
|
+
accounts: response.accounts.map((proto) => Account.fromProto(proto)),
|
|
1326
|
+
page: PageResponse.fromProto(response.page)
|
|
1327
|
+
}));
|
|
1328
|
+
}
|
|
1329
|
+
async function createAccount(ctx, options) {
|
|
1330
|
+
const feePayer = Pubkey.from(options.publicKey).toBytes();
|
|
1331
|
+
const proofResponse = await generateStateProof(ctx, {
|
|
1332
|
+
address: options.publicKey,
|
|
1333
|
+
proofType: StateProofType.CREATING
|
|
1334
|
+
// targetSlot omitted - server will auto-select
|
|
1335
|
+
});
|
|
1336
|
+
const proofBytes = proofResponse.proof;
|
|
1337
|
+
if (!proofBytes || proofBytes.length === 0) {
|
|
1338
|
+
throw new Error("State proof generation returned empty proof");
|
|
1339
|
+
}
|
|
1340
|
+
const startSlot = proofResponse.slot;
|
|
1341
|
+
const program = new Uint8Array(32);
|
|
1342
|
+
program[31] = 3;
|
|
1343
|
+
const builder = new TransactionBuilder();
|
|
1344
|
+
const headerDefaults = {
|
|
1345
|
+
fee: 0n,
|
|
1346
|
+
nonce: 0n,
|
|
1347
|
+
startSlot,
|
|
1348
|
+
expiryAfter: 100,
|
|
1349
|
+
computeUnits: 1e4,
|
|
1350
|
+
memoryUnits: 1e4,
|
|
1351
|
+
stateUnits: 1e4
|
|
1352
|
+
};
|
|
1353
|
+
const header = mergeTransactionHeader(headerDefaults, options.header);
|
|
1354
|
+
const transaction = builder.build({
|
|
1355
|
+
feePayer: { publicKey: feePayer },
|
|
1356
|
+
program,
|
|
1357
|
+
header,
|
|
1358
|
+
proofs: { feePayerStateProof: proofBytes }
|
|
1359
|
+
});
|
|
1360
|
+
return transaction;
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
// thru-ts-client-sdk/domain/transactions/streaming.ts
|
|
1364
|
+
function toStreamTransactionUpdate(proto) {
|
|
1365
|
+
const signatureBytes = proto.signature?.value ? new Uint8Array(proto.signature.value) : new Uint8Array();
|
|
1366
|
+
const executionResult = proto.executionResult ? Transaction.executionResultFromProto(proto.executionResult) : void 0;
|
|
1367
|
+
if (!proto.header) {
|
|
1368
|
+
return {
|
|
1369
|
+
kind: "partial",
|
|
1370
|
+
signature: signatureBytes,
|
|
1371
|
+
slot: proto.slot,
|
|
1372
|
+
executionResult
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
return {
|
|
1376
|
+
kind: "full",
|
|
1377
|
+
transaction: Transaction.fromProto(proto)
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
function toTrackTransactionUpdate(response) {
|
|
1381
|
+
const signatureBytes = response.signature?.value ? new Uint8Array(response.signature.value) : void 0;
|
|
1382
|
+
const executionResult = response.executionResult ? Transaction.executionResultFromProto(response.executionResult) : void 0;
|
|
1383
|
+
return {
|
|
1384
|
+
signature: signatureBytes,
|
|
1385
|
+
status: consensusStatusToString(response.consensusStatus),
|
|
1386
|
+
statusCode: response.consensusStatus,
|
|
1387
|
+
executionResult,
|
|
1388
|
+
transaction: void 0
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
var BlockFooter = class _BlockFooter {
|
|
1392
|
+
constructor(params) {
|
|
1393
|
+
this.signature = copyBytes5(params.signature);
|
|
1394
|
+
this.status = params.status;
|
|
1395
|
+
this.consumedComputeUnits = params.consumedComputeUnits;
|
|
1396
|
+
this.consumedStateUnits = params.consumedStateUnits;
|
|
1397
|
+
this.attestorPayment = params.attestorPayment;
|
|
1398
|
+
}
|
|
1399
|
+
static fromProto(proto) {
|
|
1400
|
+
return new _BlockFooter({
|
|
1401
|
+
signature: proto.signature?.value,
|
|
1402
|
+
status: proto.status ?? ExecutionStatus.UNSPECIFIED,
|
|
1403
|
+
consumedComputeUnits: proto.consumedComputeUnits ?? 0n,
|
|
1404
|
+
consumedStateUnits: proto.consumedStateUnits ?? 0,
|
|
1405
|
+
attestorPayment: proto.attestorPayment ?? 0n
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1409
|
+
function copyBytes5(bytes) {
|
|
1410
|
+
if (!bytes) return void 0;
|
|
1411
|
+
const out = new Uint8Array(bytes.length);
|
|
1412
|
+
out.set(bytes);
|
|
1413
|
+
return out;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
// thru-ts-client-sdk/domain/blocks/BlockHeader.ts
|
|
1417
|
+
var BlockHeader = class _BlockHeader {
|
|
1418
|
+
constructor(params) {
|
|
1419
|
+
this.slot = params.slot;
|
|
1420
|
+
this.version = params.version;
|
|
1421
|
+
this.headerSignature = copyBytes6(params.headerSignature);
|
|
1422
|
+
this.producer = copyBytes6(params.producer);
|
|
1423
|
+
this.expiryTimestamp = params.expiryTimestamp;
|
|
1424
|
+
this.startSlot = params.startSlot;
|
|
1425
|
+
this.expiryAfter = params.expiryAfter;
|
|
1426
|
+
this.maxBlockSize = params.maxBlockSize;
|
|
1427
|
+
this.maxComputeUnits = params.maxComputeUnits;
|
|
1428
|
+
this.maxStateUnits = params.maxStateUnits;
|
|
1429
|
+
this.bondAmountLockUp = params.bondAmountLockUp;
|
|
1430
|
+
this.weightSlot = params.weightSlot;
|
|
1431
|
+
this.blockHash = copyBytes6(params.blockHash);
|
|
1432
|
+
}
|
|
1433
|
+
static fromProto(proto) {
|
|
1434
|
+
return new _BlockHeader({
|
|
1435
|
+
slot: proto.slot ?? 0n,
|
|
1436
|
+
version: proto.version ?? 0,
|
|
1437
|
+
headerSignature: proto.headerSignature?.value,
|
|
1438
|
+
producer: proto.producer?.value,
|
|
1439
|
+
expiryTimestamp: proto.expiryTimestamp,
|
|
1440
|
+
startSlot: proto.startSlot ?? 0n,
|
|
1441
|
+
expiryAfter: proto.expiryAfter,
|
|
1442
|
+
maxBlockSize: proto.maxBlockSize,
|
|
1443
|
+
maxComputeUnits: proto.maxComputeUnits,
|
|
1444
|
+
maxStateUnits: proto.maxStateUnits,
|
|
1445
|
+
bondAmountLockUp: proto.bondAmountLockUp,
|
|
1446
|
+
weightSlot: proto.weightSlot,
|
|
1447
|
+
blockHash: proto.blockHash?.value
|
|
1448
|
+
});
|
|
1449
|
+
}
|
|
1450
|
+
withBlockHash(blockHash) {
|
|
1451
|
+
return new _BlockHeader({
|
|
1452
|
+
slot: this.slot,
|
|
1453
|
+
version: this.version,
|
|
1454
|
+
headerSignature: this.headerSignature,
|
|
1455
|
+
producer: this.producer,
|
|
1456
|
+
expiryTimestamp: this.expiryTimestamp,
|
|
1457
|
+
startSlot: this.startSlot,
|
|
1458
|
+
expiryAfter: this.expiryAfter,
|
|
1459
|
+
maxBlockSize: this.maxBlockSize,
|
|
1460
|
+
maxComputeUnits: this.maxComputeUnits,
|
|
1461
|
+
maxStateUnits: this.maxStateUnits,
|
|
1462
|
+
bondAmountLockUp: this.bondAmountLockUp,
|
|
1463
|
+
weightSlot: this.weightSlot,
|
|
1464
|
+
blockHash
|
|
1465
|
+
});
|
|
1466
|
+
}
|
|
1467
|
+
};
|
|
1468
|
+
function copyBytes6(bytes) {
|
|
1469
|
+
if (!bytes) return void 0;
|
|
1470
|
+
const out = new Uint8Array(bytes.length);
|
|
1471
|
+
out.set(bytes);
|
|
1472
|
+
return out;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
// thru-ts-client-sdk/domain/blocks/Block.ts
|
|
1476
|
+
var BLOCK_HASH_SIZE = 32;
|
|
1477
|
+
var RESERVED_FOOTER_PADDING = 0n;
|
|
1478
|
+
var SIGNATURE_PREFIX_SIZE2 = SIGNATURE_SIZE2;
|
|
1479
|
+
var Block = class _Block {
|
|
1480
|
+
constructor(params) {
|
|
1481
|
+
this.header = params.header;
|
|
1482
|
+
this.footer = params.footer;
|
|
1483
|
+
this.body = params.body ? new Uint8Array(params.body) : void 0;
|
|
1484
|
+
this.consensusStatus = params.consensusStatus;
|
|
1485
|
+
}
|
|
1486
|
+
static fromProto(proto) {
|
|
1487
|
+
if (!proto.header) {
|
|
1488
|
+
throw new Error("Block proto missing header");
|
|
1489
|
+
}
|
|
1490
|
+
const rawBody = proto.body ? new Uint8Array(proto.body) : void 0;
|
|
1491
|
+
const transactionBody = _Block.extractTransactionBody(rawBody, !!proto.footer);
|
|
1492
|
+
const block = new _Block({
|
|
1493
|
+
header: BlockHeader.fromProto(proto.header),
|
|
1494
|
+
footer: proto.footer ? BlockFooter.fromProto(proto.footer) : void 0,
|
|
1495
|
+
body: transactionBody,
|
|
1496
|
+
consensusStatus: proto.consensusStatus
|
|
1497
|
+
});
|
|
1498
|
+
block.attestorPayment = block.footer?.attestorPayment ?? 0n;
|
|
1499
|
+
return block;
|
|
1500
|
+
}
|
|
1501
|
+
static fromWire(data) {
|
|
1502
|
+
if (data.length < BLOCK_HEADER_SIZE) {
|
|
1503
|
+
throw new Error(`Block data too short: ${data.length} bytes (expected at least ${BLOCK_HEADER_SIZE})`);
|
|
1504
|
+
}
|
|
1505
|
+
const headerBytes = data.slice(0, BLOCK_HEADER_SIZE);
|
|
1506
|
+
const { header, blockTimeNs } = this.parseHeader(headerBytes);
|
|
1507
|
+
if (header.version !== BLOCK_VERSION_V1) {
|
|
1508
|
+
throw new Error(`Unsupported block version: ${header.version}`);
|
|
1509
|
+
}
|
|
1510
|
+
let finalHeader = header;
|
|
1511
|
+
let footer;
|
|
1512
|
+
let footerInfo;
|
|
1513
|
+
let body;
|
|
1514
|
+
if (data.length >= BLOCK_HEADER_SIZE + BLOCK_FOOTER_SIZE) {
|
|
1515
|
+
const footerOffset = data.length - BLOCK_FOOTER_SIZE;
|
|
1516
|
+
const footerBytes = data.slice(footerOffset);
|
|
1517
|
+
const parsedFooter = this.parseFooter(footerBytes);
|
|
1518
|
+
footer = parsedFooter.footer;
|
|
1519
|
+
footerInfo = { blockHash: parsedFooter.blockHash, attestorPayment: parsedFooter.attestorPayment };
|
|
1520
|
+
finalHeader = header.withBlockHash(parsedFooter.blockHash);
|
|
1521
|
+
body = footerOffset > BLOCK_HEADER_SIZE ? data.slice(BLOCK_HEADER_SIZE, footerOffset) : void 0;
|
|
1522
|
+
} else {
|
|
1523
|
+
body = data.length > BLOCK_HEADER_SIZE ? data.slice(BLOCK_HEADER_SIZE) : void 0;
|
|
1524
|
+
}
|
|
1525
|
+
const block = new _Block({ header: finalHeader, footer, body });
|
|
1526
|
+
block.blockTimeNs = blockTimeNs;
|
|
1527
|
+
block.attestorPayment = footerInfo?.attestorPayment ?? 0n;
|
|
1528
|
+
return block;
|
|
1529
|
+
}
|
|
1530
|
+
toWire() {
|
|
1531
|
+
const headerBytes = this.serializeHeader();
|
|
1532
|
+
const bodyBytes = this.body ?? new Uint8Array(0);
|
|
1533
|
+
const footerBytes = this.footer ? this.serializeFooter() : void 0;
|
|
1534
|
+
const totalLength = headerBytes.length + bodyBytes.length + (footerBytes?.length ?? 0);
|
|
1535
|
+
const result = new Uint8Array(totalLength);
|
|
1536
|
+
result.set(headerBytes, 0);
|
|
1537
|
+
result.set(bodyBytes, headerBytes.length);
|
|
1538
|
+
if (footerBytes) {
|
|
1539
|
+
result.set(footerBytes, headerBytes.length + bodyBytes.length);
|
|
1540
|
+
}
|
|
1541
|
+
return result;
|
|
1542
|
+
}
|
|
1543
|
+
getTransactions() {
|
|
1544
|
+
if (!this.body || this.body.length === 0) {
|
|
1545
|
+
return [];
|
|
1546
|
+
}
|
|
1547
|
+
return _Block.parseTransactionsFromBody(this.body);
|
|
1548
|
+
}
|
|
1549
|
+
static extractTransactionBody(raw, hasFooter) {
|
|
1550
|
+
if (!raw || raw.length <= BLOCK_HEADER_SIZE) {
|
|
1551
|
+
return raw && raw.length > BLOCK_HEADER_SIZE ? raw.slice(BLOCK_HEADER_SIZE) : void 0;
|
|
1552
|
+
}
|
|
1553
|
+
const footerSize = hasFooter && raw.length >= BLOCK_HEADER_SIZE + BLOCK_FOOTER_SIZE ? BLOCK_FOOTER_SIZE : 0;
|
|
1554
|
+
const start = BLOCK_HEADER_SIZE;
|
|
1555
|
+
const end = Math.max(start, raw.length - footerSize);
|
|
1556
|
+
if (end <= start) {
|
|
1557
|
+
return void 0;
|
|
1558
|
+
}
|
|
1559
|
+
return raw.slice(start, end);
|
|
1560
|
+
}
|
|
1561
|
+
serializeHeader() {
|
|
1562
|
+
const buffer = new ArrayBuffer(BLOCK_HEADER_SIZE);
|
|
1563
|
+
const bytes = new Uint8Array(buffer);
|
|
1564
|
+
const view = new DataView(buffer);
|
|
1565
|
+
const signature = normalizeBytes(this.header.headerSignature, SIGNATURE_SIZE2);
|
|
1566
|
+
bytes.set(signature, 0);
|
|
1567
|
+
let offset = SIGNATURE_PREFIX_SIZE2;
|
|
1568
|
+
const version = this.header.version ?? BLOCK_VERSION_V1;
|
|
1569
|
+
view.setUint8(offset, version & 255);
|
|
1570
|
+
offset += 1;
|
|
1571
|
+
bytes.fill(0, offset, offset + 7);
|
|
1572
|
+
offset += 7;
|
|
1573
|
+
const producer = normalizeBytes(this.header.producer, PUBKEY_SIZE2);
|
|
1574
|
+
bytes.set(producer, offset);
|
|
1575
|
+
offset += PUBKEY_SIZE2;
|
|
1576
|
+
const bondAmountLockUp = this.header.bondAmountLockUp ?? 0n;
|
|
1577
|
+
view.setBigUint64(offset, bondAmountLockUp, true);
|
|
1578
|
+
offset += 8;
|
|
1579
|
+
const expiryTimestampNs = timestampToNanoseconds(this.header.expiryTimestamp);
|
|
1580
|
+
view.setBigUint64(offset, expiryTimestampNs, true);
|
|
1581
|
+
offset += 8;
|
|
1582
|
+
const startSlot = this.header.startSlot ?? 0n;
|
|
1583
|
+
view.setBigUint64(offset, startSlot, true);
|
|
1584
|
+
offset += 8;
|
|
1585
|
+
view.setUint32(offset, this.header.expiryAfter ?? 0, true);
|
|
1586
|
+
offset += 4;
|
|
1587
|
+
view.setUint32(offset, this.header.maxBlockSize ?? 0, true);
|
|
1588
|
+
offset += 4;
|
|
1589
|
+
view.setBigUint64(offset, this.header.maxComputeUnits ?? 0n, true);
|
|
1590
|
+
offset += 8;
|
|
1591
|
+
view.setUint32(offset, this.header.maxStateUnits ?? 0, true);
|
|
1592
|
+
offset += 4;
|
|
1593
|
+
bytes.fill(0, offset, offset + 4);
|
|
1594
|
+
offset += 4;
|
|
1595
|
+
const blockTimeNs = this.blockTimeNs ?? 0n;
|
|
1596
|
+
view.setBigUint64(offset, blockTimeNs, true);
|
|
1597
|
+
return bytes;
|
|
1598
|
+
}
|
|
1599
|
+
serializeFooter() {
|
|
1600
|
+
const buffer = new ArrayBuffer(BLOCK_FOOTER_SIZE);
|
|
1601
|
+
const bytes = new Uint8Array(buffer);
|
|
1602
|
+
const view = new DataView(buffer);
|
|
1603
|
+
const attestorPayment = this.footer?.attestorPayment ?? this.attestorPayment ?? RESERVED_FOOTER_PADDING;
|
|
1604
|
+
view.setBigUint64(0, attestorPayment, true);
|
|
1605
|
+
const blockHash = normalizeBytes(this.header.blockHash, BLOCK_HASH_SIZE);
|
|
1606
|
+
bytes.set(blockHash, 8);
|
|
1607
|
+
const signature = normalizeBytes(this.footer?.signature, SIGNATURE_SIZE2);
|
|
1608
|
+
bytes.set(signature, 8 + BLOCK_HASH_SIZE);
|
|
1609
|
+
return bytes;
|
|
1610
|
+
}
|
|
1611
|
+
static parseHeader(bytes) {
|
|
1612
|
+
if (bytes.length !== BLOCK_HEADER_SIZE) {
|
|
1613
|
+
throw new Error(`Invalid block header size: ${bytes.length}`);
|
|
1614
|
+
}
|
|
1615
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
1616
|
+
let offset = 0;
|
|
1617
|
+
const signature = bytes.slice(offset, offset + SIGNATURE_SIZE2);
|
|
1618
|
+
offset += SIGNATURE_SIZE2;
|
|
1619
|
+
const version = view.getUint8(offset);
|
|
1620
|
+
offset += 1;
|
|
1621
|
+
offset += 7;
|
|
1622
|
+
const producer = bytes.slice(offset, offset + PUBKEY_SIZE2);
|
|
1623
|
+
offset += PUBKEY_SIZE2;
|
|
1624
|
+
const bondAmountLockUp = view.getBigUint64(offset, true);
|
|
1625
|
+
offset += 8;
|
|
1626
|
+
const expiryTimestampNs = view.getBigUint64(offset, true);
|
|
1627
|
+
offset += 8;
|
|
1628
|
+
const startSlot = view.getBigUint64(offset, true);
|
|
1629
|
+
offset += 8;
|
|
1630
|
+
const expiryAfter = view.getUint32(offset, true);
|
|
1631
|
+
offset += 4;
|
|
1632
|
+
const maxBlockSize = view.getUint32(offset, true);
|
|
1633
|
+
offset += 4;
|
|
1634
|
+
const maxComputeUnits = view.getBigUint64(offset, true);
|
|
1635
|
+
offset += 8;
|
|
1636
|
+
const maxStateUnits = view.getUint32(offset, true);
|
|
1637
|
+
offset += 4;
|
|
1638
|
+
offset += 4;
|
|
1639
|
+
const blockTimeNs = view.getBigUint64(offset, true);
|
|
1640
|
+
const header = new BlockHeader({
|
|
1641
|
+
slot: startSlot,
|
|
1642
|
+
version,
|
|
1643
|
+
headerSignature: signature,
|
|
1644
|
+
producer,
|
|
1645
|
+
expiryTimestamp: nanosecondsToTimestamp(expiryTimestampNs),
|
|
1646
|
+
startSlot,
|
|
1647
|
+
expiryAfter,
|
|
1648
|
+
maxBlockSize,
|
|
1649
|
+
maxComputeUnits,
|
|
1650
|
+
maxStateUnits,
|
|
1651
|
+
bondAmountLockUp
|
|
1652
|
+
});
|
|
1653
|
+
return { header, blockTimeNs };
|
|
1654
|
+
}
|
|
1655
|
+
static parseFooter(bytes) {
|
|
1656
|
+
if (bytes.length !== BLOCK_FOOTER_SIZE) {
|
|
1657
|
+
throw new Error(`Invalid block footer size: ${bytes.length}`);
|
|
1658
|
+
}
|
|
1659
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
1660
|
+
let offset = 0;
|
|
1661
|
+
const attestorPayment = view.getBigUint64(offset, true);
|
|
1662
|
+
offset += 8;
|
|
1663
|
+
const blockHash = bytes.slice(offset, offset + BLOCK_HASH_SIZE);
|
|
1664
|
+
offset += BLOCK_HASH_SIZE;
|
|
1665
|
+
const signature = bytes.slice(offset, offset + SIGNATURE_SIZE2);
|
|
1666
|
+
const footer = new BlockFooter({
|
|
1667
|
+
signature,
|
|
1668
|
+
status: ExecutionStatus.UNSPECIFIED,
|
|
1669
|
+
consumedComputeUnits: 0n,
|
|
1670
|
+
consumedStateUnits: 0,
|
|
1671
|
+
attestorPayment
|
|
1672
|
+
});
|
|
1673
|
+
return { footer, blockHash, attestorPayment };
|
|
1674
|
+
}
|
|
1675
|
+
static parseTransactionsFromBody(body) {
|
|
1676
|
+
const transactions = [];
|
|
1677
|
+
let offset = 0;
|
|
1678
|
+
while (offset < body.length) {
|
|
1679
|
+
const slice = body.subarray(offset);
|
|
1680
|
+
const { transaction, size } = Transaction.parseWire(slice);
|
|
1681
|
+
transactions.push(transaction);
|
|
1682
|
+
offset += size;
|
|
1683
|
+
}
|
|
1684
|
+
return transactions;
|
|
1685
|
+
}
|
|
1686
|
+
};
|
|
1687
|
+
function normalizeBytes(bytes, size) {
|
|
1688
|
+
if (!bytes || bytes.length !== size) {
|
|
1689
|
+
return new Uint8Array(size);
|
|
1690
|
+
}
|
|
1691
|
+
return bytes;
|
|
1692
|
+
}
|
|
1693
|
+
function toBlockHash(value) {
|
|
1694
|
+
return create(BlockHashSchema, { value: ensureBytes(value, "blockHash") });
|
|
1695
|
+
}
|
|
1696
|
+
function deriveProgramAddress(options) {
|
|
1697
|
+
const programAddress = Pubkey.from(options.programAddress).toBytes();
|
|
1698
|
+
const seed = normalizeSeed(options.seed);
|
|
1699
|
+
const ephemeral = options.ephemeral === true;
|
|
1700
|
+
const derivationInput = new Uint8Array(
|
|
1701
|
+
programAddress.length + 1 + seed.length
|
|
1702
|
+
);
|
|
1703
|
+
derivationInput.set(programAddress, 0);
|
|
1704
|
+
derivationInput[programAddress.length] = ephemeral ? 1 : 0;
|
|
1705
|
+
derivationInput.set(seed, programAddress.length + 1);
|
|
1706
|
+
const hash = sha256(derivationInput);
|
|
1707
|
+
const derivedBytes = new Uint8Array(hash.slice(0, 32));
|
|
1708
|
+
return {
|
|
1709
|
+
bytes: derivedBytes,
|
|
1710
|
+
address: encodeAddress(derivedBytes)
|
|
1711
|
+
};
|
|
1712
|
+
}
|
|
1713
|
+
function deriveAddress(inputs) {
|
|
1714
|
+
if (inputs.length === 0) {
|
|
1715
|
+
throw new Error("At least one input is required");
|
|
1716
|
+
}
|
|
1717
|
+
const normalizedInputs = inputs.map((input) => normalizeToBytes(input));
|
|
1718
|
+
const totalLength = normalizedInputs.reduce(
|
|
1719
|
+
(sum, arr) => sum + arr.length,
|
|
1720
|
+
0
|
|
1721
|
+
);
|
|
1722
|
+
const derivationInput = new Uint8Array(totalLength);
|
|
1723
|
+
let offset = 0;
|
|
1724
|
+
for (const input of normalizedInputs) {
|
|
1725
|
+
derivationInput.set(input, offset);
|
|
1726
|
+
offset += input.length;
|
|
1727
|
+
}
|
|
1728
|
+
const hash = sha256(derivationInput);
|
|
1729
|
+
const derivedBytes = new Uint8Array(hash.slice(0, 32));
|
|
1730
|
+
return {
|
|
1731
|
+
bytes: derivedBytes,
|
|
1732
|
+
address: encodeAddress(derivedBytes)
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1735
|
+
function normalizeToBytes(input) {
|
|
1736
|
+
if (input instanceof Uint8Array) {
|
|
1737
|
+
return input;
|
|
1738
|
+
}
|
|
1739
|
+
return Pubkey.from(input).toBytes();
|
|
1740
|
+
}
|
|
1741
|
+
function normalizeSeed(value) {
|
|
1742
|
+
if (value instanceof Uint8Array) {
|
|
1743
|
+
if (value.length === 0) {
|
|
1744
|
+
throw new Error("Seed cannot be empty");
|
|
1745
|
+
}
|
|
1746
|
+
if (value.length > 32) {
|
|
1747
|
+
throw new Error("Seed cannot exceed 32 bytes");
|
|
1748
|
+
}
|
|
1749
|
+
const seed = new Uint8Array(32);
|
|
1750
|
+
seed.set(value);
|
|
1751
|
+
return seed;
|
|
1752
|
+
}
|
|
1753
|
+
if (typeof value === "string") {
|
|
1754
|
+
if (value.length === 0) {
|
|
1755
|
+
throw new Error("Seed cannot be empty");
|
|
1756
|
+
}
|
|
1757
|
+
if (isHexString(value)) {
|
|
1758
|
+
const bytes = hexToBytes(value);
|
|
1759
|
+
if (bytes.length !== 32) {
|
|
1760
|
+
throw new Error(
|
|
1761
|
+
`Hex seed must decode to 32 bytes, got ${bytes.length}`
|
|
1762
|
+
);
|
|
1763
|
+
}
|
|
1764
|
+
return bytes;
|
|
1765
|
+
}
|
|
1766
|
+
const encoder = new TextEncoder();
|
|
1767
|
+
const utf8 = encoder.encode(value);
|
|
1768
|
+
if (utf8.length > 32) {
|
|
1769
|
+
throw new Error(`UTF-8 seed too long: ${utf8.length} bytes (max 32)`);
|
|
1770
|
+
}
|
|
1771
|
+
const seed = new Uint8Array(32);
|
|
1772
|
+
seed.set(utf8);
|
|
1773
|
+
return seed;
|
|
1774
|
+
}
|
|
1775
|
+
throw new Error("Seed must be provided as Uint8Array or string");
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
// thru-ts-client-sdk/modules/blocks.ts
|
|
1779
|
+
var blocks_exports = {};
|
|
1780
|
+
__export(blocks_exports, {
|
|
1781
|
+
getBlock: () => getBlock,
|
|
1782
|
+
getRawBlock: () => getRawBlock,
|
|
1783
|
+
listBlocks: () => listBlocks
|
|
1784
|
+
});
|
|
1785
|
+
async function getBlock(ctx, selector, options = {}) {
|
|
1786
|
+
const request = create(GetBlockRequestSchema, {
|
|
1787
|
+
selector: isSlotSelector(selector) ? { case: "slot", value: typeof selector.slot === "bigint" ? selector.slot : BigInt(selector.slot) } : { case: "blockHash", value: toBlockHash(selector.blockHash) },
|
|
1788
|
+
view: options.view ?? DEFAULT_BLOCK_VIEW,
|
|
1789
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
1790
|
+
});
|
|
1791
|
+
const proto = await ctx.query.getBlock(request, withCallOptions(ctx));
|
|
1792
|
+
const protoBlock = Block.fromProto(proto);
|
|
1793
|
+
try {
|
|
1794
|
+
const rawBlock = await getRawBlock(ctx, selector);
|
|
1795
|
+
const rawBytes = rawBlock?.rawBlock;
|
|
1796
|
+
if (rawBytes && rawBytes.length >= BLOCK_HEADER_SIZE) {
|
|
1797
|
+
const rawBlockParsed = Block.fromWire(rawBytes);
|
|
1798
|
+
if (rawBlockParsed.blockTimeNs !== void 0) {
|
|
1799
|
+
protoBlock.blockTimeNs = rawBlockParsed.blockTimeNs;
|
|
1800
|
+
}
|
|
1801
|
+
if (rawBlockParsed.attestorPayment !== void 0) {
|
|
1802
|
+
protoBlock.attestorPayment = rawBlockParsed.attestorPayment;
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
} catch (error) {
|
|
1806
|
+
console.debug("blocks.getBlock: failed to enrich with raw block", error);
|
|
1807
|
+
}
|
|
1808
|
+
return protoBlock;
|
|
1809
|
+
}
|
|
1810
|
+
function getRawBlock(ctx, selector, options = {}) {
|
|
1811
|
+
const request = create(GetRawBlockRequestSchema, {
|
|
1812
|
+
selector: isSlotSelector(selector) ? { case: "slot", value: typeof selector.slot === "bigint" ? selector.slot : BigInt(selector.slot) } : { case: "blockHash", value: toBlockHash(selector.blockHash) },
|
|
1813
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
1814
|
+
});
|
|
1815
|
+
return ctx.query.getRawBlock(request, withCallOptions(ctx));
|
|
1816
|
+
}
|
|
1817
|
+
async function listBlocks(ctx, options = {}) {
|
|
1818
|
+
const request = create(ListBlocksRequestSchema, {
|
|
1819
|
+
filter: options.filter?.toProto(),
|
|
1820
|
+
page: options.page?.toProto(),
|
|
1821
|
+
view: options.view ?? DEFAULT_BLOCK_VIEW,
|
|
1822
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
1823
|
+
});
|
|
1824
|
+
const response = await ctx.query.listBlocks(request, withCallOptions(ctx));
|
|
1825
|
+
return {
|
|
1826
|
+
blocks: response.blocks.map((proto) => Block.fromProto(proto)),
|
|
1827
|
+
page: PageResponse.fromProto(response.page)
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
// thru-ts-client-sdk/modules/consensus.ts
|
|
1832
|
+
var consensus_exports = {};
|
|
1833
|
+
__export(consensus_exports, {
|
|
1834
|
+
consensusStatusToString: () => consensusStatusToString,
|
|
1835
|
+
currentOrHistoricalVersionContext: () => currentOrHistoricalVersionContext,
|
|
1836
|
+
currentVersionContext: () => currentVersionContext,
|
|
1837
|
+
seqVersionContext: () => seqVersionContext,
|
|
1838
|
+
slotVersionContext: () => slotVersionContext,
|
|
1839
|
+
timestampVersionContext: () => timestampVersionContext,
|
|
1840
|
+
versionContext: () => versionContext
|
|
1841
|
+
});
|
|
1842
|
+
function currentVersionContext() {
|
|
1843
|
+
return create(VersionContextSchema, {
|
|
1844
|
+
version: { case: "current", value: create(CurrentVersionSchema) }
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1847
|
+
function currentOrHistoricalVersionContext() {
|
|
1848
|
+
return create(VersionContextSchema, {
|
|
1849
|
+
version: { case: "currentOrHistorical", value: create(CurrentOrHistoricalVersionSchema) }
|
|
1850
|
+
});
|
|
1851
|
+
}
|
|
1852
|
+
function slotVersionContext(slot) {
|
|
1853
|
+
return create(VersionContextSchema, {
|
|
1854
|
+
version: { case: "slot", value: toUint64(slot, "slot") }
|
|
1855
|
+
});
|
|
1856
|
+
}
|
|
1857
|
+
function timestampVersionContext(value) {
|
|
1858
|
+
return create(VersionContextSchema, {
|
|
1859
|
+
version: { case: "timestamp", value: normalizeTimestamp(value) }
|
|
1860
|
+
});
|
|
1861
|
+
}
|
|
1862
|
+
function seqVersionContext(seq) {
|
|
1863
|
+
return create(VersionContextSchema, {
|
|
1864
|
+
version: { case: "seq", value: toUint64(seq, "seq") }
|
|
1865
|
+
});
|
|
1866
|
+
}
|
|
1867
|
+
function versionContext(input) {
|
|
1868
|
+
if (!input) {
|
|
1869
|
+
return currentVersionContext();
|
|
1870
|
+
}
|
|
1871
|
+
if ("version" in input) {
|
|
1872
|
+
return input;
|
|
1873
|
+
}
|
|
1874
|
+
if ("current" in input) {
|
|
1875
|
+
return currentVersionContext();
|
|
1876
|
+
}
|
|
1877
|
+
if ("currentOrHistorical" in input) {
|
|
1878
|
+
return currentOrHistoricalVersionContext();
|
|
1879
|
+
}
|
|
1880
|
+
if ("slot" in input) {
|
|
1881
|
+
return slotVersionContext(input.slot);
|
|
1882
|
+
}
|
|
1883
|
+
if ("timestamp" in input) {
|
|
1884
|
+
return timestampVersionContext(input.timestamp);
|
|
1885
|
+
}
|
|
1886
|
+
if ("seq" in input) {
|
|
1887
|
+
return seqVersionContext(input.seq);
|
|
1888
|
+
}
|
|
1889
|
+
throw new Error("Version context input must specify current, slot, timestamp, or seq");
|
|
1890
|
+
}
|
|
1891
|
+
function toUint64(value, field) {
|
|
1892
|
+
if (typeof value === "bigint") {
|
|
1893
|
+
if (value < 0n) {
|
|
1894
|
+
throw new Error(`${field} must be non-negative`);
|
|
1895
|
+
}
|
|
1896
|
+
return value;
|
|
1897
|
+
}
|
|
1898
|
+
if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {
|
|
1899
|
+
throw new Error(`${field} must be a non-negative integer`);
|
|
1900
|
+
}
|
|
1901
|
+
return BigInt(value);
|
|
1902
|
+
}
|
|
1903
|
+
function normalizeTimestamp(value) {
|
|
1904
|
+
if (value instanceof Date) {
|
|
1905
|
+
const ms = value.getTime();
|
|
1906
|
+
return {
|
|
1907
|
+
seconds: BigInt(Math.floor(ms / 1e3)),
|
|
1908
|
+
nanos: ms % 1e3 * 1e6
|
|
1909
|
+
};
|
|
1910
|
+
}
|
|
1911
|
+
if (typeof value === "number") {
|
|
1912
|
+
if (!Number.isFinite(value)) {
|
|
1913
|
+
throw new Error("timestamp must be a finite number");
|
|
1914
|
+
}
|
|
1915
|
+
const ms = Math.trunc(value);
|
|
1916
|
+
return {
|
|
1917
|
+
seconds: BigInt(Math.floor(ms / 1e3)),
|
|
1918
|
+
nanos: ms % 1e3 * 1e6
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1921
|
+
if (typeof value === "object" && value !== null) {
|
|
1922
|
+
return value;
|
|
1923
|
+
}
|
|
1924
|
+
throw new Error("timestamp must be a Date, number, or protobuf Timestamp");
|
|
1925
|
+
}
|
|
1926
|
+
|
|
1927
|
+
// thru-ts-client-sdk/domain/events/ChainEvent.ts
|
|
1928
|
+
var ChainEvent = class _ChainEvent {
|
|
1929
|
+
constructor(params) {
|
|
1930
|
+
if (!params.id) {
|
|
1931
|
+
throw new Error("ChainEvent id is required");
|
|
1932
|
+
}
|
|
1933
|
+
this.id = params.id;
|
|
1934
|
+
this.transactionSignature = copyBytes7(params.transactionSignature);
|
|
1935
|
+
this.program = copyBytes7(params.program);
|
|
1936
|
+
this.payload = copyBytes7(params.payload);
|
|
1937
|
+
this.slot = params.slot;
|
|
1938
|
+
this.callIndex = params.callIndex;
|
|
1939
|
+
this.programIndex = params.programIndex;
|
|
1940
|
+
this.payloadSize = params.payloadSize;
|
|
1941
|
+
this.timestampNs = params.timestampNs;
|
|
1942
|
+
}
|
|
1943
|
+
static fromQuery(proto) {
|
|
1944
|
+
return new _ChainEvent({
|
|
1945
|
+
id: proto.eventId,
|
|
1946
|
+
transactionSignature: proto.transactionSignature?.value,
|
|
1947
|
+
program: proto.program?.value,
|
|
1948
|
+
payload: proto.payload,
|
|
1949
|
+
slot: proto.slot,
|
|
1950
|
+
callIndex: proto.callIdx,
|
|
1951
|
+
programIndex: proto.programIdx,
|
|
1952
|
+
payloadSize: proto.payloadSize
|
|
1953
|
+
});
|
|
1954
|
+
}
|
|
1955
|
+
static fromStream(proto) {
|
|
1956
|
+
const id = normalizeStreamEventId(proto.eventId);
|
|
1957
|
+
return new _ChainEvent({
|
|
1958
|
+
id,
|
|
1959
|
+
transactionSignature: proto.signature?.value,
|
|
1960
|
+
program: proto.program?.value,
|
|
1961
|
+
payload: proto.payload,
|
|
1962
|
+
slot: proto.slot,
|
|
1963
|
+
callIndex: proto.callIdx,
|
|
1964
|
+
timestampNs: timestampToNanoseconds(proto.timestamp)
|
|
1965
|
+
});
|
|
1966
|
+
}
|
|
1967
|
+
};
|
|
1968
|
+
function copyBytes7(input) {
|
|
1969
|
+
if (!input) {
|
|
1970
|
+
return void 0;
|
|
1971
|
+
}
|
|
1972
|
+
const copy = new Uint8Array(input.length);
|
|
1973
|
+
copy.set(input);
|
|
1974
|
+
return copy;
|
|
1975
|
+
}
|
|
1976
|
+
function normalizeStreamEventId(id) {
|
|
1977
|
+
const parts = id.split(":");
|
|
1978
|
+
if (parts.length >= 4) {
|
|
1979
|
+
return parts.slice(0, 4).join(":");
|
|
1980
|
+
}
|
|
1981
|
+
return id;
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
// thru-ts-client-sdk/modules/events.ts
|
|
1985
|
+
var events_exports = {};
|
|
1986
|
+
__export(events_exports, {
|
|
1987
|
+
getEvent: () => getEvent,
|
|
1988
|
+
listEvents: () => listEvents
|
|
1989
|
+
});
|
|
1990
|
+
function getEvent(ctx, eventId, options = {}) {
|
|
1991
|
+
if (!eventId) {
|
|
1992
|
+
throw new Error("eventId is required");
|
|
1993
|
+
}
|
|
1994
|
+
const request = create(GetEventRequestSchema, {
|
|
1995
|
+
eventId,
|
|
1996
|
+
versionContext: options.versionContext ?? DEFAULT_VERSION_CONTEXT
|
|
1997
|
+
});
|
|
1998
|
+
return ctx.query.getEvent(request, withCallOptions(ctx)).then((proto) => ChainEvent.fromQuery(proto));
|
|
1999
|
+
}
|
|
2000
|
+
function listEvents(ctx, options = {}) {
|
|
2001
|
+
const request = create(ListEventsRequestSchema, {
|
|
2002
|
+
filter: options.filter?.toProto(),
|
|
2003
|
+
page: options.page?.toProto(),
|
|
2004
|
+
versionContext: options.versionContext ?? DEFAULT_VERSION_CONTEXT,
|
|
2005
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
2006
|
+
});
|
|
2007
|
+
return ctx.query.listEvents(request, withCallOptions(ctx)).then((response) => ({
|
|
2008
|
+
events: response.events.map((proto) => ChainEvent.fromQuery(proto)),
|
|
2009
|
+
page: PageResponse.fromProto(response.page)
|
|
2010
|
+
}));
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
// thru-ts-client-sdk/domain/height/HeightSnapshot.ts
|
|
2014
|
+
var HeightSnapshot = class _HeightSnapshot {
|
|
2015
|
+
constructor(params) {
|
|
2016
|
+
this.finalized = params.finalized;
|
|
2017
|
+
this.locallyExecuted = params.locallyExecuted;
|
|
2018
|
+
this.clusterExecuted = params.clusterExecuted;
|
|
2019
|
+
}
|
|
2020
|
+
static fromProto(proto) {
|
|
2021
|
+
return new _HeightSnapshot({
|
|
2022
|
+
finalized: proto.finalized ?? 0n,
|
|
2023
|
+
locallyExecuted: proto.locallyExecuted ?? 0n,
|
|
2024
|
+
clusterExecuted: proto.clusterExecuted ?? 0n
|
|
2025
|
+
});
|
|
2026
|
+
}
|
|
2027
|
+
delta(other) {
|
|
2028
|
+
return {
|
|
2029
|
+
finalized: this.finalized - other.finalized,
|
|
2030
|
+
locallyExecuted: this.locallyExecuted - other.locallyExecuted,
|
|
2031
|
+
clusterExecuted: this.clusterExecuted - other.clusterExecuted
|
|
2032
|
+
};
|
|
2033
|
+
}
|
|
2034
|
+
};
|
|
2035
|
+
|
|
2036
|
+
// thru-ts-client-sdk/modules/height.ts
|
|
2037
|
+
var height_exports = {};
|
|
2038
|
+
__export(height_exports, {
|
|
2039
|
+
getBlockHeight: () => getBlockHeight
|
|
2040
|
+
});
|
|
2041
|
+
function getBlockHeight(ctx) {
|
|
2042
|
+
const request = create(GetHeightRequestSchema);
|
|
2043
|
+
return ctx.query.getHeight(request, withCallOptions(ctx)).then((proto) => HeightSnapshot.fromProto(proto));
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
// thru-ts-client-sdk/modules/keys.ts
|
|
2047
|
+
var keys_exports = {};
|
|
2048
|
+
__export(keys_exports, {
|
|
2049
|
+
fromPrivateKey: () => fromPrivateKey,
|
|
2050
|
+
generateKeyPair: () => generateKeyPair
|
|
2051
|
+
});
|
|
2052
|
+
async function generateKeyPair() {
|
|
2053
|
+
const seed = generateSeed();
|
|
2054
|
+
const account = await ThruHDWallet.getAccount(seed, 0);
|
|
2055
|
+
seed.fill(0);
|
|
2056
|
+
return {
|
|
2057
|
+
address: account.address,
|
|
2058
|
+
publicKey: account.publicKey,
|
|
2059
|
+
privateKey: account.privateKey
|
|
2060
|
+
};
|
|
2061
|
+
}
|
|
2062
|
+
async function fromPrivateKey(privateKey) {
|
|
2063
|
+
return new Uint8Array(await getPublicKeyAsync(privateKey));
|
|
2064
|
+
}
|
|
2065
|
+
function generateSeed() {
|
|
2066
|
+
const cryptoObj = getWebCrypto();
|
|
2067
|
+
const bytes = new Uint8Array(64);
|
|
2068
|
+
cryptoObj.getRandomValues(bytes);
|
|
2069
|
+
return bytes;
|
|
2070
|
+
}
|
|
2071
|
+
function copyBytes8(source) {
|
|
2072
|
+
const bytes = new Uint8Array(source.length);
|
|
2073
|
+
bytes.set(source);
|
|
2074
|
+
return bytes;
|
|
2075
|
+
}
|
|
2076
|
+
function toUint(value) {
|
|
2077
|
+
if (typeof value === "bigint") {
|
|
2078
|
+
if (value < 0n) {
|
|
2079
|
+
throw new Error("FilterParamValue.uint requires a non-negative value");
|
|
2080
|
+
}
|
|
2081
|
+
return value;
|
|
2082
|
+
}
|
|
2083
|
+
if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {
|
|
2084
|
+
throw new Error("FilterParamValue.uint requires a non-negative integer");
|
|
2085
|
+
}
|
|
2086
|
+
return BigInt(value);
|
|
2087
|
+
}
|
|
2088
|
+
var FilterParamValue = class _FilterParamValue {
|
|
2089
|
+
constructor(params) {
|
|
2090
|
+
this.case = params.case;
|
|
2091
|
+
if (!params.case) {
|
|
2092
|
+
this.value = void 0;
|
|
2093
|
+
return;
|
|
2094
|
+
}
|
|
2095
|
+
switch (params.case) {
|
|
2096
|
+
case "stringValue":
|
|
2097
|
+
if (typeof params.value !== "string") {
|
|
2098
|
+
throw new Error("FilterParamValue.string requires a string value");
|
|
2099
|
+
}
|
|
2100
|
+
this.value = params.value;
|
|
2101
|
+
return;
|
|
2102
|
+
case "bytesValue":
|
|
2103
|
+
if (!(params.value instanceof Uint8Array)) {
|
|
2104
|
+
throw new Error("FilterParamValue.bytes requires a Uint8Array value");
|
|
2105
|
+
}
|
|
2106
|
+
this.value = copyBytes8(params.value);
|
|
2107
|
+
return;
|
|
2108
|
+
case "boolValue":
|
|
2109
|
+
if (typeof params.value !== "boolean") {
|
|
2110
|
+
throw new Error("FilterParamValue.bool requires a boolean value");
|
|
2111
|
+
}
|
|
2112
|
+
this.value = params.value;
|
|
2113
|
+
return;
|
|
2114
|
+
case "intValue":
|
|
2115
|
+
if (typeof params.value !== "bigint") {
|
|
2116
|
+
throw new Error("FilterParamValue.int requires a bigint value");
|
|
2117
|
+
}
|
|
2118
|
+
this.value = params.value;
|
|
2119
|
+
return;
|
|
2120
|
+
case "doubleValue":
|
|
2121
|
+
if (typeof params.value !== "number") {
|
|
2122
|
+
throw new Error("FilterParamValue.double requires a number value");
|
|
2123
|
+
}
|
|
2124
|
+
this.value = params.value;
|
|
2125
|
+
return;
|
|
2126
|
+
case "uintValue":
|
|
2127
|
+
if (typeof params.value !== "bigint") {
|
|
2128
|
+
throw new Error("FilterParamValue.uint requires a bigint value");
|
|
2129
|
+
}
|
|
2130
|
+
this.value = params.value;
|
|
2131
|
+
return;
|
|
2132
|
+
case "pubkeyValue":
|
|
2133
|
+
if (!(params.value instanceof Uint8Array)) {
|
|
2134
|
+
throw new Error("FilterParamValue.pubkey requires a Uint8Array value");
|
|
2135
|
+
}
|
|
2136
|
+
this.value = copyBytes8(params.value);
|
|
2137
|
+
return;
|
|
2138
|
+
case "signatureValue":
|
|
2139
|
+
if (!(params.value instanceof Uint8Array)) {
|
|
2140
|
+
throw new Error("FilterParamValue.signature requires a Uint8Array value");
|
|
2141
|
+
}
|
|
2142
|
+
this.value = copyBytes8(params.value);
|
|
2143
|
+
return;
|
|
2144
|
+
case "taPubkeyValue":
|
|
2145
|
+
if (typeof params.value !== "string") {
|
|
2146
|
+
throw new Error("FilterParamValue.taPubkey requires a string value");
|
|
2147
|
+
}
|
|
2148
|
+
this.value = params.value;
|
|
2149
|
+
return;
|
|
2150
|
+
case "tsSignatureValue":
|
|
2151
|
+
if (typeof params.value !== "string") {
|
|
2152
|
+
throw new Error("FilterParamValue.tsSignature requires a string value");
|
|
2153
|
+
}
|
|
2154
|
+
this.value = params.value;
|
|
2155
|
+
return;
|
|
2156
|
+
default:
|
|
2157
|
+
this.value = void 0;
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
static none() {
|
|
2161
|
+
return new _FilterParamValue({});
|
|
2162
|
+
}
|
|
2163
|
+
static string(value) {
|
|
2164
|
+
return new _FilterParamValue({ case: "stringValue", value });
|
|
2165
|
+
}
|
|
2166
|
+
static bytes(value) {
|
|
2167
|
+
return new _FilterParamValue({ case: "bytesValue", value });
|
|
2168
|
+
}
|
|
2169
|
+
static bool(value) {
|
|
2170
|
+
return new _FilterParamValue({ case: "boolValue", value });
|
|
2171
|
+
}
|
|
2172
|
+
static int(value) {
|
|
2173
|
+
return new _FilterParamValue({ case: "intValue", value });
|
|
2174
|
+
}
|
|
2175
|
+
static double(value) {
|
|
2176
|
+
if (!Number.isFinite(value)) {
|
|
2177
|
+
throw new Error("FilterParamValue.double requires a finite number");
|
|
2178
|
+
}
|
|
2179
|
+
return new _FilterParamValue({ case: "doubleValue", value });
|
|
2180
|
+
}
|
|
2181
|
+
static uint(value) {
|
|
2182
|
+
return new _FilterParamValue({ case: "uintValue", value: toUint(value) });
|
|
2183
|
+
}
|
|
2184
|
+
static pubkey(value) {
|
|
2185
|
+
return new _FilterParamValue({
|
|
2186
|
+
case: "pubkeyValue",
|
|
2187
|
+
value: Pubkey.from(value).toBytes()
|
|
2188
|
+
});
|
|
2189
|
+
}
|
|
2190
|
+
static signature(value) {
|
|
2191
|
+
return new _FilterParamValue({
|
|
2192
|
+
case: "signatureValue",
|
|
2193
|
+
value: Signature.from(value).toBytes()
|
|
2194
|
+
});
|
|
2195
|
+
}
|
|
2196
|
+
static taPubkey(value) {
|
|
2197
|
+
return new _FilterParamValue({
|
|
2198
|
+
case: "taPubkeyValue",
|
|
2199
|
+
value: Pubkey.from(value).toThruFmt()
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
2202
|
+
static tsSignature(value) {
|
|
2203
|
+
return new _FilterParamValue({
|
|
2204
|
+
case: "tsSignatureValue",
|
|
2205
|
+
value: Signature.from(value).toThruFmt()
|
|
2206
|
+
});
|
|
2207
|
+
}
|
|
2208
|
+
static fromProto(proto) {
|
|
2209
|
+
const kind = proto.kind;
|
|
2210
|
+
if (!kind.case) {
|
|
2211
|
+
return _FilterParamValue.none();
|
|
2212
|
+
}
|
|
2213
|
+
switch (kind.case) {
|
|
2214
|
+
case "stringValue":
|
|
2215
|
+
return _FilterParamValue.string(kind.value);
|
|
2216
|
+
case "bytesValue":
|
|
2217
|
+
return _FilterParamValue.bytes(kind.value);
|
|
2218
|
+
case "boolValue":
|
|
2219
|
+
return _FilterParamValue.bool(kind.value);
|
|
2220
|
+
case "intValue":
|
|
2221
|
+
return _FilterParamValue.int(kind.value);
|
|
2222
|
+
case "doubleValue":
|
|
2223
|
+
return _FilterParamValue.double(kind.value);
|
|
2224
|
+
case "uintValue":
|
|
2225
|
+
return _FilterParamValue.uint(kind.value);
|
|
2226
|
+
case "pubkeyValue":
|
|
2227
|
+
return _FilterParamValue.pubkey(Pubkey.fromProtoPubkey(kind.value).toBytes());
|
|
2228
|
+
case "signatureValue":
|
|
2229
|
+
return _FilterParamValue.signature(Signature.fromProtoSignature(kind.value).toBytes());
|
|
2230
|
+
case "taPubkeyValue":
|
|
2231
|
+
return _FilterParamValue.taPubkey(Pubkey.fromProtoTaPubkey(kind.value).toThruFmt());
|
|
2232
|
+
case "tsSignatureValue":
|
|
2233
|
+
return _FilterParamValue.tsSignature(Signature.fromProtoTsSignature(kind.value).toThruFmt());
|
|
2234
|
+
default:
|
|
2235
|
+
return _FilterParamValue.none();
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
toProto() {
|
|
2239
|
+
if (!this.case) {
|
|
2240
|
+
return create(FilterParamValueSchema);
|
|
2241
|
+
}
|
|
2242
|
+
switch (this.case) {
|
|
2243
|
+
case "stringValue":
|
|
2244
|
+
return create(FilterParamValueSchema, {
|
|
2245
|
+
kind: {
|
|
2246
|
+
case: "stringValue",
|
|
2247
|
+
value: this.value
|
|
2248
|
+
}
|
|
2249
|
+
});
|
|
2250
|
+
case "bytesValue":
|
|
2251
|
+
return create(FilterParamValueSchema, {
|
|
2252
|
+
kind: {
|
|
2253
|
+
case: "bytesValue",
|
|
2254
|
+
value: copyBytes8(this.value)
|
|
2255
|
+
}
|
|
2256
|
+
});
|
|
2257
|
+
case "boolValue":
|
|
2258
|
+
return create(FilterParamValueSchema, {
|
|
2259
|
+
kind: {
|
|
2260
|
+
case: "boolValue",
|
|
2261
|
+
value: this.value
|
|
2262
|
+
}
|
|
2263
|
+
});
|
|
2264
|
+
case "intValue":
|
|
2265
|
+
return create(FilterParamValueSchema, {
|
|
2266
|
+
kind: {
|
|
2267
|
+
case: "intValue",
|
|
2268
|
+
value: this.value
|
|
2269
|
+
}
|
|
2270
|
+
});
|
|
2271
|
+
case "doubleValue":
|
|
2272
|
+
return create(FilterParamValueSchema, {
|
|
2273
|
+
kind: {
|
|
2274
|
+
case: "doubleValue",
|
|
2275
|
+
value: this.value
|
|
2276
|
+
}
|
|
2277
|
+
});
|
|
2278
|
+
case "uintValue":
|
|
2279
|
+
return create(FilterParamValueSchema, {
|
|
2280
|
+
kind: {
|
|
2281
|
+
case: "uintValue",
|
|
2282
|
+
value: this.value
|
|
2283
|
+
}
|
|
2284
|
+
});
|
|
2285
|
+
case "pubkeyValue":
|
|
2286
|
+
return create(FilterParamValueSchema, {
|
|
2287
|
+
kind: {
|
|
2288
|
+
case: "pubkeyValue",
|
|
2289
|
+
value: Pubkey.from(this.value).toProtoPubkey()
|
|
2290
|
+
}
|
|
2291
|
+
});
|
|
2292
|
+
case "signatureValue":
|
|
2293
|
+
return create(FilterParamValueSchema, {
|
|
2294
|
+
kind: {
|
|
2295
|
+
case: "signatureValue",
|
|
2296
|
+
value: Signature.from(this.value).toProtoSignature()
|
|
2297
|
+
}
|
|
2298
|
+
});
|
|
2299
|
+
case "taPubkeyValue":
|
|
2300
|
+
return create(FilterParamValueSchema, {
|
|
2301
|
+
kind: {
|
|
2302
|
+
case: "taPubkeyValue",
|
|
2303
|
+
value: Pubkey.from(this.value).toProtoTaPubkey()
|
|
2304
|
+
}
|
|
2305
|
+
});
|
|
2306
|
+
case "tsSignatureValue":
|
|
2307
|
+
return create(FilterParamValueSchema, {
|
|
2308
|
+
kind: {
|
|
2309
|
+
case: "tsSignatureValue",
|
|
2310
|
+
value: Signature.from(this.value).toProtoTsSignature()
|
|
2311
|
+
}
|
|
2312
|
+
});
|
|
2313
|
+
default:
|
|
2314
|
+
throw new Error("FilterParamValue has an unknown kind");
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
getCase() {
|
|
2318
|
+
return this.case;
|
|
2319
|
+
}
|
|
2320
|
+
getString() {
|
|
2321
|
+
return this.case === "stringValue" ? this.value : void 0;
|
|
2322
|
+
}
|
|
2323
|
+
getBytes() {
|
|
2324
|
+
if (this.case !== "bytesValue" || !(this.value instanceof Uint8Array)) {
|
|
2325
|
+
return void 0;
|
|
2326
|
+
}
|
|
2327
|
+
return copyBytes8(this.value);
|
|
2328
|
+
}
|
|
2329
|
+
getBool() {
|
|
2330
|
+
return this.case === "boolValue" ? this.value : void 0;
|
|
2331
|
+
}
|
|
2332
|
+
getInt() {
|
|
2333
|
+
return this.case === "intValue" ? this.value : void 0;
|
|
2334
|
+
}
|
|
2335
|
+
getUint() {
|
|
2336
|
+
return this.case === "uintValue" ? this.value : void 0;
|
|
2337
|
+
}
|
|
2338
|
+
getDouble() {
|
|
2339
|
+
return this.case === "doubleValue" ? this.value : void 0;
|
|
2340
|
+
}
|
|
2341
|
+
getPubkey() {
|
|
2342
|
+
if (this.case !== "pubkeyValue") {
|
|
2343
|
+
return void 0;
|
|
2344
|
+
}
|
|
2345
|
+
return copyBytes8(this.value);
|
|
2346
|
+
}
|
|
2347
|
+
getSignature() {
|
|
2348
|
+
if (this.case !== "signatureValue") {
|
|
2349
|
+
return void 0;
|
|
2350
|
+
}
|
|
2351
|
+
return copyBytes8(this.value);
|
|
2352
|
+
}
|
|
2353
|
+
getTaPubkey() {
|
|
2354
|
+
return this.case === "taPubkeyValue" ? this.value : void 0;
|
|
2355
|
+
}
|
|
2356
|
+
getTsSignature() {
|
|
2357
|
+
return this.case === "tsSignatureValue" ? this.value : void 0;
|
|
2358
|
+
}
|
|
2359
|
+
};
|
|
2360
|
+
var Filter = class _Filter {
|
|
2361
|
+
constructor(init = {}) {
|
|
2362
|
+
this.expression = init.expression;
|
|
2363
|
+
this.params = /* @__PURE__ */ new Map();
|
|
2364
|
+
if (!init.params) {
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
if (init.params instanceof Map) {
|
|
2368
|
+
for (const [key, value] of init.params.entries()) {
|
|
2369
|
+
this.setParamInternal(key, value);
|
|
2370
|
+
}
|
|
2371
|
+
return;
|
|
2372
|
+
}
|
|
2373
|
+
if (typeof init.params === "object" && !Array.isArray(init.params)) {
|
|
2374
|
+
for (const [key, value] of Object.entries(init.params)) {
|
|
2375
|
+
this.setParamInternal(key, value);
|
|
2376
|
+
}
|
|
2377
|
+
return;
|
|
2378
|
+
}
|
|
2379
|
+
for (const [key, value] of init.params) {
|
|
2380
|
+
this.setParamInternal(key, value);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
static fromProto(proto) {
|
|
2384
|
+
const params = Object.entries(proto.params ?? {}).map(([key, value]) => [key, FilterParamValue.fromProto(value)]);
|
|
2385
|
+
return new _Filter({
|
|
2386
|
+
expression: proto.expression,
|
|
2387
|
+
params
|
|
2388
|
+
});
|
|
2389
|
+
}
|
|
2390
|
+
toProto() {
|
|
2391
|
+
const protoParams = {};
|
|
2392
|
+
for (const [key, value] of this.params.entries()) {
|
|
2393
|
+
protoParams[key] = value.toProto();
|
|
2394
|
+
}
|
|
2395
|
+
return create(FilterSchema, {
|
|
2396
|
+
expression: this.expression,
|
|
2397
|
+
params: protoParams
|
|
2398
|
+
});
|
|
2399
|
+
}
|
|
2400
|
+
hasParam(name) {
|
|
2401
|
+
return this.params.has(name);
|
|
2402
|
+
}
|
|
2403
|
+
getParam(name) {
|
|
2404
|
+
const param = this.params.get(name);
|
|
2405
|
+
return param;
|
|
2406
|
+
}
|
|
2407
|
+
listParams() {
|
|
2408
|
+
return Array.from(this.params.keys());
|
|
2409
|
+
}
|
|
2410
|
+
entries() {
|
|
2411
|
+
return Array.from(this.params.entries());
|
|
2412
|
+
}
|
|
2413
|
+
withExpression(expression) {
|
|
2414
|
+
return new _Filter({ expression, params: this.params });
|
|
2415
|
+
}
|
|
2416
|
+
withParam(name, value) {
|
|
2417
|
+
const params = new Map(this.params);
|
|
2418
|
+
params.set(name, value);
|
|
2419
|
+
return new _Filter({ expression: this.expression, params });
|
|
2420
|
+
}
|
|
2421
|
+
withoutParam(name) {
|
|
2422
|
+
if (!this.params.has(name)) {
|
|
2423
|
+
return this;
|
|
2424
|
+
}
|
|
2425
|
+
const params = new Map(this.params);
|
|
2426
|
+
params.delete(name);
|
|
2427
|
+
return new _Filter({ expression: this.expression, params });
|
|
2428
|
+
}
|
|
2429
|
+
setParamInternal(name, value) {
|
|
2430
|
+
if (!(value instanceof FilterParamValue)) {
|
|
2431
|
+
throw new Error(`Filter parameter "${name}" must be a FilterParamValue`);
|
|
2432
|
+
}
|
|
2433
|
+
this.params.set(name, value);
|
|
2434
|
+
}
|
|
2435
|
+
};
|
|
2436
|
+
|
|
2437
|
+
// thru-ts-client-sdk/modules/streaming.ts
|
|
2438
|
+
var streaming_exports = {};
|
|
2439
|
+
__export(streaming_exports, {
|
|
2440
|
+
collectStream: () => collectStream,
|
|
2441
|
+
firstStreamValue: () => firstStreamValue,
|
|
2442
|
+
forEachStreamValue: () => forEachStreamValue,
|
|
2443
|
+
streamAccountUpdates: () => streamAccountUpdates,
|
|
2444
|
+
streamBlocks: () => streamBlocks,
|
|
2445
|
+
streamEvents: () => streamEvents,
|
|
2446
|
+
streamHeight: () => streamHeight,
|
|
2447
|
+
streamTransactions: () => streamTransactions,
|
|
2448
|
+
trackTransaction: () => trackTransaction
|
|
2449
|
+
});
|
|
2450
|
+
function streamBlocks(ctx, options = {}) {
|
|
2451
|
+
const request = create(StreamBlocksRequestSchema, {
|
|
2452
|
+
startSlot: options.startSlot,
|
|
2453
|
+
filter: options.filter?.toProto(),
|
|
2454
|
+
view: options.view ?? DEFAULT_BLOCK_VIEW,
|
|
2455
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
2456
|
+
});
|
|
2457
|
+
const iterable = ctx.streaming.streamBlocks(request, withCallOptions(ctx, { signal: options.signal }));
|
|
2458
|
+
async function* mapper() {
|
|
2459
|
+
for await (const response of iterable) {
|
|
2460
|
+
if (!response.block) {
|
|
2461
|
+
continue;
|
|
2462
|
+
}
|
|
2463
|
+
yield { block: Block.fromProto(response.block) };
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
return mapper();
|
|
2467
|
+
}
|
|
2468
|
+
function streamAccountUpdates(ctx, address, options = {}) {
|
|
2469
|
+
const addressBytes = Pubkey.from(address).toBytes();
|
|
2470
|
+
const addressFilter = new Filter({
|
|
2471
|
+
expression: "snapshot.address.value == params.address || account_update.address.value == params.address",
|
|
2472
|
+
params: {
|
|
2473
|
+
address: FilterParamValue.bytes(addressBytes)
|
|
2474
|
+
}
|
|
2475
|
+
});
|
|
2476
|
+
let mergedFilter = addressFilter;
|
|
2477
|
+
if (options.filter) {
|
|
2478
|
+
const combinedParams = {};
|
|
2479
|
+
for (const [key, value] of addressFilter.entries()) {
|
|
2480
|
+
combinedParams[key] = value;
|
|
2481
|
+
}
|
|
2482
|
+
for (const [key, value] of options.filter.entries()) {
|
|
2483
|
+
combinedParams[key] = value;
|
|
2484
|
+
}
|
|
2485
|
+
mergedFilter = new Filter({
|
|
2486
|
+
expression: `(${addressFilter.expression}) && (${options.filter.expression})`,
|
|
2487
|
+
params: combinedParams
|
|
2488
|
+
});
|
|
2489
|
+
}
|
|
2490
|
+
const request = create(StreamAccountUpdatesRequestSchema, {
|
|
2491
|
+
view: options.view ?? DEFAULT_ACCOUNT_VIEW,
|
|
2492
|
+
filter: mergedFilter.toProto()
|
|
2493
|
+
});
|
|
2494
|
+
const iterable = ctx.streaming.streamAccountUpdates(request, withCallOptions(ctx, { signal: options.signal }));
|
|
2495
|
+
async function* mapper() {
|
|
2496
|
+
for await (const response of iterable) {
|
|
2497
|
+
const update = toStreamAccountUpdate(response);
|
|
2498
|
+
if (!update) {
|
|
2499
|
+
continue;
|
|
2500
|
+
}
|
|
2501
|
+
yield { update };
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
return mapper();
|
|
2505
|
+
}
|
|
2506
|
+
function streamTransactions(ctx, options = {}) {
|
|
2507
|
+
const request = create(StreamTransactionsRequestSchema, {
|
|
2508
|
+
filter: options.filter?.toProto(),
|
|
2509
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
2510
|
+
});
|
|
2511
|
+
const iterable = ctx.streaming.streamTransactions(request, withCallOptions(ctx, { signal: options.signal }));
|
|
2512
|
+
async function* mapper() {
|
|
2513
|
+
for await (const response of iterable) {
|
|
2514
|
+
if (!response.transaction) {
|
|
2515
|
+
continue;
|
|
2516
|
+
}
|
|
2517
|
+
try {
|
|
2518
|
+
yield toStreamTransactionUpdate(response.transaction);
|
|
2519
|
+
} catch (err) {
|
|
2520
|
+
console.error("streamTransactions: failed to decode transaction update", err);
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
return mapper();
|
|
2525
|
+
}
|
|
2526
|
+
function streamEvents(ctx, options = {}) {
|
|
2527
|
+
const request = create(StreamEventsRequestSchema, {
|
|
2528
|
+
filter: options.filter?.toProto()
|
|
2529
|
+
});
|
|
2530
|
+
const iterable = ctx.streaming.streamEvents(request, withCallOptions(ctx, { signal: options.signal }));
|
|
2531
|
+
async function* mapper() {
|
|
2532
|
+
for await (const response of iterable) {
|
|
2533
|
+
yield { event: ChainEvent.fromStream(response) };
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
return mapper();
|
|
2537
|
+
}
|
|
2538
|
+
function trackTransaction(ctx, signature, options = {}) {
|
|
2539
|
+
const timeoutMs = options.timeoutMs;
|
|
2540
|
+
const request = create(TrackTransactionRequestSchema, {
|
|
2541
|
+
signature: Signature.from(signature).toProtoSignature(),
|
|
2542
|
+
timeout: timeoutMs != null ? {
|
|
2543
|
+
seconds: BigInt(Math.floor(timeoutMs / 1e3)),
|
|
2544
|
+
nanos: timeoutMs % 1e3 * 1e6
|
|
2545
|
+
} : void 0
|
|
2546
|
+
});
|
|
2547
|
+
const iterable = ctx.streaming.trackTransaction(request, withCallOptions(ctx, { signal: options.signal }));
|
|
2548
|
+
async function* mapper() {
|
|
2549
|
+
for await (const response of iterable) {
|
|
2550
|
+
yield toTrackTransactionUpdate(response);
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
return mapper();
|
|
2554
|
+
}
|
|
2555
|
+
function streamHeight(ctx, options = {}) {
|
|
2556
|
+
const request = create(StreamHeightRequestSchema, {});
|
|
2557
|
+
const iterable = ctx.streaming.streamHeight(request, withCallOptions(ctx, { signal: options.signal }));
|
|
2558
|
+
async function* mapper() {
|
|
2559
|
+
for await (const response of iterable) {
|
|
2560
|
+
yield { height: HeightSnapshot.fromProto(response) };
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
return mapper();
|
|
2564
|
+
}
|
|
2565
|
+
async function collectStream(iterable, options = {}) {
|
|
2566
|
+
const { limit, signal } = options;
|
|
2567
|
+
throwIfAborted(signal);
|
|
2568
|
+
if (limit != null && limit <= 0) {
|
|
2569
|
+
return [];
|
|
2570
|
+
}
|
|
2571
|
+
const results = [];
|
|
2572
|
+
let count = 0;
|
|
2573
|
+
for await (const value of iterable) {
|
|
2574
|
+
throwIfAborted(signal);
|
|
2575
|
+
results.push(value);
|
|
2576
|
+
count += 1;
|
|
2577
|
+
if (limit != null && count >= limit) {
|
|
2578
|
+
break;
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
return results;
|
|
2582
|
+
}
|
|
2583
|
+
async function firstStreamValue(iterable, options = {}) {
|
|
2584
|
+
const values = await collectStream(iterable, { ...options, limit: 1 });
|
|
2585
|
+
return values[0];
|
|
2586
|
+
}
|
|
2587
|
+
async function forEachStreamValue(iterable, handler, options = {}) {
|
|
2588
|
+
let index = 0;
|
|
2589
|
+
for await (const value of iterable) {
|
|
2590
|
+
throwIfAborted(options.signal);
|
|
2591
|
+
await handler(value, index++);
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
function throwIfAborted(signal) {
|
|
2595
|
+
if (!signal) {
|
|
2596
|
+
return;
|
|
2597
|
+
}
|
|
2598
|
+
if (signal.aborted) {
|
|
2599
|
+
const reason = signal.reason;
|
|
2600
|
+
if (reason instanceof Error) {
|
|
2601
|
+
throw reason;
|
|
2602
|
+
}
|
|
2603
|
+
if (reason !== void 0) {
|
|
2604
|
+
throw new Error(String(reason));
|
|
2605
|
+
}
|
|
2606
|
+
throw new DOMException("The operation was aborted.", "AbortError");
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
|
|
2610
|
+
// thru-ts-client-sdk/modules/transactions.ts
|
|
2611
|
+
var transactions_exports = {};
|
|
2612
|
+
__export(transactions_exports, {
|
|
2613
|
+
batchSendTransactions: () => batchSendTransactions,
|
|
2614
|
+
buildAndSignTransaction: () => buildAndSignTransaction,
|
|
2615
|
+
buildTransaction: () => buildTransaction,
|
|
2616
|
+
getRawTransaction: () => getRawTransaction,
|
|
2617
|
+
getTransaction: () => getTransaction,
|
|
2618
|
+
getTransactionStatus: () => getTransactionStatus,
|
|
2619
|
+
listTransactions: () => listTransactions,
|
|
2620
|
+
listTransactionsForAccount: () => listTransactionsForAccount,
|
|
2621
|
+
sendTransaction: () => sendTransaction
|
|
2622
|
+
});
|
|
2623
|
+
async function getTransaction(ctx, signature, options = {}) {
|
|
2624
|
+
const request = create(GetTransactionRequestSchema, {
|
|
2625
|
+
signature: Signature.from(signature).toProtoSignature(),
|
|
2626
|
+
view: options.view ?? DEFAULT_TRANSACTION_VIEW,
|
|
2627
|
+
versionContext: options.versionContext ?? DEFAULT_VERSION_CONTEXT,
|
|
2628
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
2629
|
+
});
|
|
2630
|
+
const proto = await ctx.query.getTransaction(request, withCallOptions(ctx));
|
|
2631
|
+
return Transaction.fromProto(proto);
|
|
2632
|
+
}
|
|
2633
|
+
async function getRawTransaction(ctx, signature, options = {}) {
|
|
2634
|
+
const request = create(GetRawTransactionRequestSchema, {
|
|
2635
|
+
signature: Signature.from(signature).toProtoSignature(),
|
|
2636
|
+
versionContext: options.versionContext ?? DEFAULT_VERSION_CONTEXT,
|
|
2637
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
2638
|
+
});
|
|
2639
|
+
return ctx.query.getRawTransaction(request, withCallOptions(ctx));
|
|
2640
|
+
}
|
|
2641
|
+
async function getTransactionStatus(ctx, signature) {
|
|
2642
|
+
const request = create(GetTransactionStatusRequestSchema, {
|
|
2643
|
+
signature: Signature.from(signature).toProtoSignature()
|
|
2644
|
+
});
|
|
2645
|
+
const proto = await ctx.query.getTransactionStatus(request, withCallOptions(ctx));
|
|
2646
|
+
return TransactionStatusSnapshot.fromProto(proto);
|
|
2647
|
+
}
|
|
2648
|
+
async function listTransactionsForAccount(ctx, account, options = {}) {
|
|
2649
|
+
const request = create(ListTransactionsForAccountRequestSchema, {
|
|
2650
|
+
account: Pubkey.from(account).toProtoPubkey(),
|
|
2651
|
+
filter: options.filter?.toProto(),
|
|
2652
|
+
page: options.page?.toProto()
|
|
2653
|
+
});
|
|
2654
|
+
const response = await ctx.query.listTransactionsForAccount(
|
|
2655
|
+
request,
|
|
2656
|
+
withCallOptions(ctx)
|
|
2657
|
+
);
|
|
2658
|
+
const protoTransactionSignatures = (response.transactions ?? []).map((transaction) => transaction.signature);
|
|
2659
|
+
const transactions = await Promise.all(
|
|
2660
|
+
protoTransactionSignatures.map((signature) => {
|
|
2661
|
+
if (!signature) {
|
|
2662
|
+
throw new Error("ListTransactionsForAccount returned an empty signature");
|
|
2663
|
+
}
|
|
2664
|
+
return getTransaction(ctx, signature.value, options.transactionOptions);
|
|
2665
|
+
})
|
|
2666
|
+
);
|
|
2667
|
+
return {
|
|
2668
|
+
transactions,
|
|
2669
|
+
page: PageResponse.fromProto(response.page)
|
|
2670
|
+
};
|
|
2671
|
+
}
|
|
2672
|
+
async function listTransactions(ctx, options = {}) {
|
|
2673
|
+
const request = create(ListTransactionsRequestSchema, {
|
|
2674
|
+
filter: options.filter?.toProto(),
|
|
2675
|
+
page: options.page?.toProto(),
|
|
2676
|
+
returnEvents: options.returnEvents,
|
|
2677
|
+
versionContext: options.versionContext ?? DEFAULT_VERSION_CONTEXT,
|
|
2678
|
+
minConsensus: options.minConsensus ?? DEFAULT_MIN_CONSENSUS
|
|
2679
|
+
});
|
|
2680
|
+
const response = await ctx.query.listTransactions(
|
|
2681
|
+
request,
|
|
2682
|
+
withCallOptions(ctx)
|
|
2683
|
+
);
|
|
2684
|
+
return {
|
|
2685
|
+
transactions: response.transactions.map((proto) => Transaction.fromProto(proto)),
|
|
2686
|
+
page: PageResponse.fromProto(response.page)
|
|
2687
|
+
};
|
|
2688
|
+
}
|
|
2689
|
+
async function buildTransaction(ctx, options) {
|
|
2690
|
+
const builder = createTransactionBuilder();
|
|
2691
|
+
const params = await createBuildParams(ctx, options);
|
|
2692
|
+
return builder.build(params);
|
|
2693
|
+
}
|
|
2694
|
+
async function buildAndSignTransaction(ctx, options) {
|
|
2695
|
+
const builder = createTransactionBuilder();
|
|
2696
|
+
const params = await createBuildParams(ctx, options);
|
|
2697
|
+
if (!params.feePayer.privateKey) {
|
|
2698
|
+
throw new Error("Fee payer private key is required to sign the transaction");
|
|
2699
|
+
}
|
|
2700
|
+
return builder.buildAndSign(params);
|
|
2701
|
+
}
|
|
2702
|
+
async function sendTransaction(ctx, transaction) {
|
|
2703
|
+
const raw = transaction instanceof Uint8Array ? transaction : transaction.toWire();
|
|
2704
|
+
return sendRawTransaction(ctx, raw);
|
|
2705
|
+
}
|
|
2706
|
+
async function batchSendTransactions(ctx, transactions, options = {}) {
|
|
2707
|
+
const rawTransactions = transactions.map(
|
|
2708
|
+
(tx) => tx instanceof Uint8Array ? tx : tx.toWire()
|
|
2709
|
+
);
|
|
2710
|
+
const request = create(BatchSendTransactionsRequestSchema, {
|
|
2711
|
+
rawTransactions,
|
|
2712
|
+
numRetries: options.numRetries ?? 0
|
|
2713
|
+
});
|
|
2714
|
+
return ctx.command.batchSendTransactions(request, withCallOptions(ctx));
|
|
2715
|
+
}
|
|
2716
|
+
async function sendRawTransaction(ctx, rawTransaction) {
|
|
2717
|
+
const request = create(SendTransactionRequestSchema, { rawTransaction });
|
|
2718
|
+
const response = await ctx.command.sendTransaction(request, withCallOptions(ctx));
|
|
2719
|
+
if (!response.signature?.value) {
|
|
2720
|
+
throw new Error("No signature returned from sendTransaction");
|
|
2721
|
+
}
|
|
2722
|
+
return encodeSignature(response.signature.value);
|
|
2723
|
+
}
|
|
2724
|
+
function createTransactionBuilder() {
|
|
2725
|
+
return new TransactionBuilder();
|
|
2726
|
+
}
|
|
2727
|
+
async function createBuildParams(ctx, options) {
|
|
2728
|
+
const feePayerPublicKey = Pubkey.from(options.feePayer.publicKey).toBytes();
|
|
2729
|
+
const program = Pubkey.from(options.program).toBytes();
|
|
2730
|
+
const header = await createTransactionHeader(ctx, options.header ?? {}, feePayerPublicKey);
|
|
2731
|
+
const accounts = parseAccounts(options.accounts);
|
|
2732
|
+
const context = createInstructionContext(feePayerPublicKey, program, accounts);
|
|
2733
|
+
const instructionData = await resolveInstructionData(options.instructionData, context);
|
|
2734
|
+
const proofs = createProofs(options);
|
|
2735
|
+
return {
|
|
2736
|
+
feePayer: {
|
|
2737
|
+
publicKey: feePayerPublicKey,
|
|
2738
|
+
privateKey: options.feePayer.privateKey
|
|
2739
|
+
},
|
|
2740
|
+
program: Pubkey.from(options.program).toBytes(),
|
|
2741
|
+
header,
|
|
2742
|
+
accounts,
|
|
2743
|
+
instructionData,
|
|
2744
|
+
proofs
|
|
2745
|
+
};
|
|
2746
|
+
}
|
|
2747
|
+
async function createTransactionHeader(ctx, header, feePayerPublicKey) {
|
|
2748
|
+
const nonce = header.nonce ?? await fetchFeePayerNonce(ctx, feePayerPublicKey);
|
|
2749
|
+
const startSlot = header.startSlot ?? await fetchFinalizedSlot(ctx);
|
|
2750
|
+
return {
|
|
2751
|
+
fee: header.fee ?? DEFAULT_FEE,
|
|
2752
|
+
nonce,
|
|
2753
|
+
startSlot,
|
|
2754
|
+
expiryAfter: header.expiryAfter ?? DEFAULT_EXPIRY_AFTER,
|
|
2755
|
+
computeUnits: header.computeUnits ?? DEFAULT_COMPUTE_UNITS,
|
|
2756
|
+
stateUnits: header.stateUnits ?? DEFAULT_STATE_UNITS,
|
|
2757
|
+
memoryUnits: header.memoryUnits ?? DEFAULT_MEMORY_UNITS,
|
|
2758
|
+
flags: header.flags
|
|
2759
|
+
};
|
|
2760
|
+
}
|
|
2761
|
+
function parseAccounts(accounts) {
|
|
2762
|
+
if (!accounts) {
|
|
2763
|
+
return void 0;
|
|
2764
|
+
}
|
|
2765
|
+
const readWrite = accounts.readWrite?.map(
|
|
2766
|
+
(value, index) => Pubkey.from(value).toBytes()
|
|
2767
|
+
);
|
|
2768
|
+
const readOnly = accounts.readOnly?.map(
|
|
2769
|
+
(value, index) => Pubkey.from(value).toBytes()
|
|
2770
|
+
);
|
|
2771
|
+
const result = {};
|
|
2772
|
+
if (readWrite && readWrite.length > 0) {
|
|
2773
|
+
result.readWriteAccounts = normalizeAccountList(readWrite);
|
|
2774
|
+
}
|
|
2775
|
+
if (readOnly && readOnly.length > 0) {
|
|
2776
|
+
result.readOnlyAccounts = normalizeAccountList(readOnly);
|
|
2777
|
+
}
|
|
2778
|
+
if (!result.readWriteAccounts && !result.readOnlyAccounts) {
|
|
2779
|
+
return void 0;
|
|
2780
|
+
}
|
|
2781
|
+
return result;
|
|
2782
|
+
}
|
|
2783
|
+
function createInstructionContext(feePayer, program, accounts) {
|
|
2784
|
+
const allAccounts = [
|
|
2785
|
+
Pubkey.from(feePayer),
|
|
2786
|
+
Pubkey.from(program),
|
|
2787
|
+
...accounts?.readWriteAccounts?.map((value) => Pubkey.from(value)) ?? [],
|
|
2788
|
+
...accounts?.readOnlyAccounts?.map((value) => Pubkey.from(value)) ?? []
|
|
2789
|
+
];
|
|
2790
|
+
const getAccountIndex = (pubkey) => {
|
|
2791
|
+
for (let i = 0; i < allAccounts.length; i++) {
|
|
2792
|
+
if (allAccounts[i].equals(Pubkey.from(pubkey))) {
|
|
2793
|
+
return i;
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
throw new Error("Account not found in transaction accounts");
|
|
2797
|
+
};
|
|
2798
|
+
return { accounts: allAccounts, getAccountIndex };
|
|
2799
|
+
}
|
|
2800
|
+
async function resolveInstructionData(value, context) {
|
|
2801
|
+
if (value === void 0) {
|
|
2802
|
+
return void 0;
|
|
2803
|
+
}
|
|
2804
|
+
if (typeof value === "function") {
|
|
2805
|
+
return await value(context);
|
|
2806
|
+
}
|
|
2807
|
+
if (value instanceof Uint8Array) {
|
|
2808
|
+
return value;
|
|
2809
|
+
}
|
|
2810
|
+
return parseInstructionData(value);
|
|
2811
|
+
}
|
|
2812
|
+
function createProofs(options) {
|
|
2813
|
+
const proofs = {};
|
|
2814
|
+
if (options.feePayerStateProof) {
|
|
2815
|
+
proofs.feePayerStateProof = options.feePayerStateProof;
|
|
2816
|
+
}
|
|
2817
|
+
if (options.feePayerAccountMetaRaw) {
|
|
2818
|
+
proofs.feePayerAccountMetaRaw = options.feePayerAccountMetaRaw;
|
|
2819
|
+
}
|
|
2820
|
+
const hasProofs = Boolean(proofs.feePayerStateProof || proofs.feePayerAccountMetaRaw);
|
|
2821
|
+
return hasProofs ? proofs : void 0;
|
|
2822
|
+
}
|
|
2823
|
+
async function fetchFeePayerNonce(ctx, feePayer) {
|
|
2824
|
+
const account = await getAccount(ctx, feePayer, { view: AccountView.FULL });
|
|
2825
|
+
const nonce = account.meta?.nonce;
|
|
2826
|
+
if (nonce === void 0) {
|
|
2827
|
+
throw new Error("Fee payer account nonce is unavailable");
|
|
2828
|
+
}
|
|
2829
|
+
return nonce;
|
|
2830
|
+
}
|
|
2831
|
+
async function fetchFinalizedSlot(ctx) {
|
|
2832
|
+
const height = await getBlockHeight(ctx);
|
|
2833
|
+
return height.finalized;
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
// thru-ts-client-sdk/domain/version/VersionInfo.ts
|
|
2837
|
+
var VersionInfo = class _VersionInfo {
|
|
2838
|
+
constructor(components) {
|
|
2839
|
+
this.components = { ...components };
|
|
2840
|
+
}
|
|
2841
|
+
static fromProto(proto) {
|
|
2842
|
+
return new _VersionInfo(proto.versions ?? {});
|
|
2843
|
+
}
|
|
2844
|
+
get(component) {
|
|
2845
|
+
return this.components[component];
|
|
2846
|
+
}
|
|
2847
|
+
};
|
|
2848
|
+
|
|
2849
|
+
export { Account, Block, ChainEvent, Filter, FilterParamValue, HeightSnapshot, PageRequest, PageResponse, Pubkey, Signature, SignatureDomain, StateProof, Transaction, TransactionBuilder, TransactionStatusSnapshot, VersionInfo, accounts_exports, batchSendTransactions, blocks_exports, buildAndSignTransaction, buildTransaction, collectStream, consensusStatusToString, consensus_exports, createAccount, createThruClientContext, currentOrHistoricalVersionContext, currentVersionContext, deriveAddress, deriveProgramAddress, events_exports, firstStreamValue, forEachStreamValue, fromPrivateKey, generateKeyPair, generateStateProof, getAccount, getBlock, getBlockHeight, getEvent, getRawAccount, getRawBlock, getRawTransaction, getTransaction, getTransactionStatus, height_exports, keys_exports, listAccounts, listBlocks, listEvents, listTransactions, listTransactionsForAccount, proofs_exports, sendTransaction, seqVersionContext, signWithDomain, slotVersionContext, streamAccountUpdates, streamBlocks, streamEvents, streamHeight, streamTransactions, streaming_exports, timestampVersionContext, trackTransaction, transactions_exports, verifyWithDomain, versionContext, withCallOptions };
|
|
2850
|
+
//# sourceMappingURL=chunk-PU2M7EPY.js.map
|
|
2851
|
+
//# sourceMappingURL=chunk-PU2M7EPY.js.map
|