@thru/thru-sdk 0.2.6 → 0.2.8

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.
@@ -1,9 +1,9 @@
1
- import { utils, etc, Point, CURVE, getPublicKeyAsync } from '@noble/ed25519';
2
1
  import { create } from '@bufbuild/protobuf';
3
2
  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, GetStateRootsRequestSchema, GetAccountRequestSchema, GetRawAccountRequestSchema, ListAccountsRequestSchema, StateProofType, ExecutionStatus, GetBlockRequestSchema, GetRawBlockRequestSchema, ListBlocksRequestSchema, GetChainInfoRequestSchema, CurrentOrHistoricalVersionSchema, GetEventRequestSchema, ListEventsRequestSchema, GetHeightRequestSchema, GetNodePubkeyRequestSchema, GetNodeRecordsRequestSchema, GetSlotMetricsRequestSchema, ListSlotMetricsRequestSchema, FilterParamValueSchema, FilterSchema, StreamBlocksRequestSchema, StreamAccountUpdatesRequestSchema, StreamTransactionsRequestSchema, StreamEventsRequestSchema, TrackTransactionRequestSchema, StreamHeightRequestSchema, StreamSlotMetricsRequestSchema, StreamNodeRecordsRequestSchema, GetTransactionRequestSchema, GetRawTransactionRequestSchema, GetTransactionStatusRequestSchema, ListTransactionsForAccountRequestSchema, ListTransactionsRequestSchema, BatchSendTransactionsRequestSchema, SendAndTrackTxnRequestSchema, SendTransactionRequestSchema, BlockHashSchema } from '@thru/proto';
3
+ import { AccountView, BlockView, TransactionView, ConsensusStatus, VersionContextSchema, CurrentVersionSchema, PubkeySchema, TaPubkeySchema, SignatureSchema, TsSignatureSchema, PageRequestSchema, PageResponseSchema, TransactionVmError, StateProofRequestSchema, GenerateStateProofRequestSchema, GetStateRootsRequestSchema, GetAccountRequestSchema, GetRawAccountRequestSchema, ListAccountsRequestSchema, StateProofType, ExecutionStatus, GetBlockRequestSchema, GetRawBlockRequestSchema, ListBlocksRequestSchema, CurrentOrHistoricalVersionSchema, GetEventRequestSchema, ListEventsRequestSchema, GetHeightRequestSchema, GetChainInfoRequestSchema, GetNodePubkeyRequestSchema, GetNodeRecordsRequestSchema, GetSlotMetricsRequestSchema, ListSlotMetricsRequestSchema, FilterParamValueSchema, FilterSchema, StreamBlocksRequestSchema, StreamAccountUpdatesRequestSchema, StreamTransactionsRequestSchema, StreamEventsRequestSchema, TrackTransactionRequestSchema, StreamHeightRequestSchema, StreamSlotMetricsRequestSchema, StreamNodeRecordsRequestSchema, GetTransactionRequestSchema, GetRawTransactionRequestSchema, GetTransactionStatusRequestSchema, ListTransactionsForAccountRequestSchema, ListTransactionsRequestSchema, BatchSendTransactionsRequestSchema, SendAndTrackTxnRequestSchema, SendTransactionRequestSchema, BlockHashSchema, StreamingService, CommandService, QueryService, GetVersionRequestSchema } from '@thru/proto';
5
4
  import { createClient } from '@connectrpc/connect';
6
5
  import { createGrpcWebTransport } from '@connectrpc/connect-web';
6
+ import { utils, etc, Point, CURVE, getPublicKeyAsync } from '@noble/ed25519';
7
7
  import { sha256 } from '@noble/hashes/sha2';
8
8
  import { ThruHDWallet, getWebCrypto } from '@thru/crypto';
9
9
 
@@ -12,112 +12,9 @@ var __export = (target, all) => {
12
12
  for (var name in all)
13
13
  __defProp(target, name, { get: all[name], enumerable: true });
14
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
15
 
119
16
  // thru-ts-client-sdk/domain/primitives/byte-utils.ts
120
- function copyBytes2(source) {
17
+ function copyBytes(source) {
121
18
  const bytes = new Uint8Array(source.length);
122
19
  bytes.set(source);
123
20
  return bytes;
@@ -126,7 +23,7 @@ function ensureExactLength(bytes, expected) {
126
23
  if (bytes.length !== expected) {
127
24
  throw new Error(`Must contain ${expected} bytes`);
128
25
  }
129
- return copyBytes2(bytes);
26
+ return copyBytes(bytes);
130
27
  }
131
28
  function bytesEqual(a, b) {
132
29
  if (a.length !== b.length) {
@@ -176,7 +73,7 @@ var Pubkey = class _Pubkey {
176
73
  return value.startsWith("ta") && value.length === TA_ADDRESS_LENGTH;
177
74
  }
178
75
  toBytes() {
179
- return copyBytes2(this.bytes);
76
+ return copyBytes(this.bytes);
180
77
  }
181
78
  toBytesUnsafe() {
182
79
  return this.bytes;
@@ -247,7 +144,7 @@ var Signature = class _Signature {
247
144
  return value.startsWith("ts") && value.length === TS_SIGNATURE_LENGTH;
248
145
  }
249
146
  toBytes() {
250
- return copyBytes2(this.bytes);
147
+ return copyBytes(this.bytes);
251
148
  }
252
149
  toBytesUnsafe() {
253
150
  return this.bytes;
@@ -291,92 +188,520 @@ var Signature = class _Signature {
291
188
  }
292
189
  };
293
190
 
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_HEADER_SIZE_LEGACY = 160;
300
- var BLOCK_FOOTER_SIZE = 104;
301
- var BLOCK_VERSION_V1 = 1;
302
- var TXN_HEADER_BODY_SIZE = 112;
303
- var TXN_VERSION_V1 = 1;
304
- var TXN_MAX_ACCOUNTS = 1024;
305
- var STATE_PROOF_HEADER_SIZE = 40;
306
- var ACCOUNT_META_FOOTPRINT = 64;
307
- var TXN_FLAG_HAS_FEE_PAYER_PROOF = 1 << 0;
308
- var STATE_PROOF_TYPE_EXISTING = 0;
309
- var STATE_PROOF_TYPE_UPDATING = 1;
310
- var STATE_PROOF_TYPE_CREATION = 2;
311
-
312
- // thru-ts-client-sdk/domain/transactions/Transaction.ts
313
- var DEFAULT_FLAGS = 0;
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;
191
+ // thru-ts-client-sdk/modules/accounts.ts
192
+ var accounts_exports = {};
193
+ __export(accounts_exports, {
194
+ createAccount: () => createAccount,
195
+ getAccount: () => getAccount,
196
+ getRawAccount: () => getRawAccount,
197
+ listAccounts: () => listAccounts
198
+ });
199
+ var DEFAULT_HOST = "https://grpc-web.alphanet.thruput.org";
200
+ var DEFAULT_ACCOUNT_VIEW = AccountView.FULL;
201
+ var DEFAULT_BLOCK_VIEW = BlockView.FULL;
202
+ var DEFAULT_TRANSACTION_VIEW = TransactionView.FULL;
203
+ var DEFAULT_MIN_CONSENSUS = ConsensusStatus.UNSPECIFIED;
204
+ var DEFAULT_VERSION_CONTEXT = create(VersionContextSchema, {
205
+ version: {
206
+ case: "current",
207
+ value: create(CurrentVersionSchema, {})
321
208
  }
322
- return count;
323
209
  });
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.chainId = params.header.chainId ?? 1;
334
- this.requestedComputeUnits = params.header.computeUnits ?? 0;
335
- this.requestedStateUnits = params.header.stateUnits ?? 0;
336
- this.requestedMemoryUnits = params.header.memoryUnits ?? 0;
337
- this.flags = params.header.flags ?? DEFAULT_FLAGS;
338
- this.readWriteAccounts = params.accounts?.readWriteAccounts ? params.accounts.readWriteAccounts.map(Pubkey.from) : [];
339
- this.readOnlyAccounts = params.accounts?.readOnlyAccounts ? params.accounts.readOnlyAccounts.map(Pubkey.from) : [];
340
- this.instructionData = params.instructionData ? new Uint8Array(params.instructionData) : void 0;
341
- if (this.instructionData && this.instructionData.length > MAX_INSTRUCTION_DATA_LENGTH) {
342
- throw new Error(`Instruction data exceeds maximum length (${MAX_INSTRUCTION_DATA_LENGTH} bytes)`);
343
- }
344
- this.instructionDataSize = params.instructionDataSize;
345
- this.feePayerStateProof = params.proofs?.feePayerStateProof ? new Uint8Array(params.proofs.feePayerStateProof) : void 0;
346
- this.feePayerAccountMetaRaw = params.proofs?.feePayerAccountMetaRaw ? new Uint8Array(params.proofs.feePayerAccountMetaRaw) : void 0;
210
+ var DEFAULT_FEE = 1n;
211
+ var DEFAULT_COMPUTE_UNITS = 3e8;
212
+ var DEFAULT_STATE_UNITS = 1e4;
213
+ var DEFAULT_MEMORY_UNITS = 1e4;
214
+ var DEFAULT_EXPIRY_AFTER = 100;
215
+ function createThruClientContext(config = {}) {
216
+ const transportOptions = config.transportOptions ?? {};
217
+ const { baseUrl: optionsBaseUrl, interceptors: optionInterceptors, ...restTransportOptions } = transportOptions;
218
+ const baseUrl = config.baseUrl ?? optionsBaseUrl ?? DEFAULT_HOST;
219
+ const mergedInterceptors = [
220
+ ...optionInterceptors ?? [],
221
+ ...config.interceptors ?? []
222
+ ];
223
+ const transport = config.transport ?? createGrpcWebTransport({
224
+ baseUrl,
225
+ ...restTransportOptions,
226
+ interceptors: mergedInterceptors.length > 0 ? mergedInterceptors : void 0
227
+ });
228
+ return {
229
+ baseUrl,
230
+ transport,
231
+ query: createClient(QueryService, transport),
232
+ command: createClient(CommandService, transport),
233
+ streaming: createClient(StreamingService, transport),
234
+ callOptions: config.callOptions
235
+ };
236
+ }
237
+ function withCallOptions(ctx, overrides) {
238
+ return mergeCallOptions(ctx.callOptions, overrides);
239
+ }
240
+ function mergeCallOptions(defaults, overrides) {
241
+ if (!defaults) {
242
+ return overrides;
347
243
  }
348
- static fromWire(data) {
349
- const { transaction, size } = _Transaction.parseWire(data, { strict: true });
350
- if (size !== data.length) {
351
- throw new Error(
352
- `Transaction body has trailing bytes: expected ${size} bytes but found ${data.length}`
353
- );
354
- }
355
- return transaction;
244
+ if (!overrides) {
245
+ return defaults;
356
246
  }
357
- static parseWire(data, options = {}) {
358
- const strict = options.strict ?? false;
359
- const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
360
- if (data.length < TXN_HEADER_BODY_SIZE) {
361
- throw new Error(`Transaction data too short: ${data.length} bytes (minimum ${TXN_HEADER_BODY_SIZE})`);
247
+ return {
248
+ ...defaults,
249
+ ...overrides,
250
+ headers: mergeHeaders(defaults.headers, overrides.headers),
251
+ contextValues: overrides.contextValues ?? defaults.contextValues,
252
+ onHeader: overrides.onHeader ?? defaults.onHeader,
253
+ onTrailer: overrides.onTrailer ?? defaults.onTrailer
254
+ };
255
+ }
256
+ function mergeHeaders(a, b) {
257
+ const entries = [];
258
+ const add = (init) => {
259
+ if (!init) {
260
+ return;
362
261
  }
363
- let offset = 0;
364
- const version = view.getUint8(offset);
365
- offset += 1;
366
- if (strict && version !== TXN_VERSION_V1) {
367
- throw new Error(`Unsupported transaction version: ${version}`);
262
+ if (init instanceof Headers) {
263
+ init.forEach((value, key) => {
264
+ entries.push([key, value]);
265
+ });
266
+ return;
368
267
  }
369
- const flags = view.getUint8(offset);
370
- offset += 1;
371
- const invalidFlags = flags & -4;
372
- if (strict && invalidFlags !== 0) {
373
- throw new Error(`Unsupported transaction flags: 0x${invalidFlags.toString(16).padStart(2, "0")}`);
268
+ if (Array.isArray(init)) {
269
+ for (const [key, value] of init) {
270
+ entries.push([key, value]);
271
+ }
272
+ return;
374
273
  }
375
- const readwriteAccountsCount = view.getUint16(offset, true);
376
- offset += 2;
377
- const readonlyAccountsCount = view.getUint16(offset, true);
378
- offset += 2;
379
- const instructionDataSize = view.getUint16(offset, true);
274
+ for (const [key, value] of Object.entries(init)) {
275
+ if (value !== void 0) {
276
+ entries.push([key, String(value)]);
277
+ }
278
+ }
279
+ };
280
+ add(a);
281
+ add(b);
282
+ if (entries.length === 0) {
283
+ return void 0;
284
+ }
285
+ return entries;
286
+ }
287
+ function isSlotSelector(selector) {
288
+ return "slot" in selector;
289
+ }
290
+ function mergeTransactionHeader(defaults, overrides) {
291
+ if (!overrides) {
292
+ return defaults;
293
+ }
294
+ const sanitized = Object.fromEntries(
295
+ Object.entries(overrides).filter(([, value]) => value !== void 0)
296
+ );
297
+ return {
298
+ ...defaults,
299
+ ...sanitized
300
+ };
301
+ }
302
+ function timestampToNanoseconds(timestamp) {
303
+ if (!timestamp) {
304
+ return 0n;
305
+ }
306
+ const seconds = BigInt(timestamp.seconds ?? 0);
307
+ const nanos = BigInt(timestamp.nanos ?? 0);
308
+ return seconds * 1000000000n + nanos;
309
+ }
310
+ function nanosecondsToTimestamp(ns) {
311
+ const seconds = ns / 1000000000n;
312
+ const nanos = Number(ns % 1000000000n);
313
+ return { seconds, nanos };
314
+ }
315
+ function consensusStatusToString(status) {
316
+ const lookup = ConsensusStatus;
317
+ return lookup[status] ?? `UNKNOWN(${status})`;
318
+ }
319
+
320
+ // thru-ts-client-sdk/domain/accounts/Account.ts
321
+ var AccountFlags = class _AccountFlags {
322
+ constructor(flags) {
323
+ this.isProgram = flags?.isProgram ?? false;
324
+ this.isPrivileged = flags?.isPrivileged ?? false;
325
+ this.isUncompressable = flags?.isUncompressable ?? false;
326
+ this.isEphemeral = flags?.isEphemeral ?? false;
327
+ this.isDeleted = flags?.isDeleted ?? false;
328
+ this.isNew = flags?.isNew ?? false;
329
+ this.isCompressed = flags?.isCompressed ?? false;
330
+ }
331
+ static fromProto(flags) {
332
+ if (!flags) {
333
+ return new _AccountFlags();
334
+ }
335
+ return new _AccountFlags({
336
+ isProgram: flags.isProgram,
337
+ isPrivileged: flags.isPrivileged,
338
+ isUncompressable: flags.isUncompressable,
339
+ isEphemeral: flags.isEphemeral,
340
+ isDeleted: flags.isDeleted,
341
+ isNew: flags.isNew,
342
+ isCompressed: flags.isCompressed
343
+ });
344
+ }
345
+ };
346
+ var AccountMeta = class _AccountMeta {
347
+ constructor(params) {
348
+ this.version = params.version;
349
+ this.flags = params.flags ?? new AccountFlags();
350
+ this.dataSize = params.dataSize;
351
+ this.seq = params.seq;
352
+ this.owner = params.owner;
353
+ this.balance = params.balance;
354
+ this.nonce = params.nonce;
355
+ }
356
+ static fromProto(meta) {
357
+ if (!meta) {
358
+ return void 0;
359
+ }
360
+ return new _AccountMeta({
361
+ version: meta.version,
362
+ flags: AccountFlags.fromProto(meta.flags),
363
+ dataSize: meta.dataSize,
364
+ seq: meta.seq ?? 0n,
365
+ owner: meta.owner ? Pubkey.fromProtoPubkey(meta.owner) : void 0,
366
+ balance: meta.balance ?? 0n,
367
+ nonce: meta.nonce
368
+ });
369
+ }
370
+ };
371
+ var AccountData = class _AccountData {
372
+ constructor(params) {
373
+ this.data = params.data ? new Uint8Array(params.data) : void 0;
374
+ this.compressed = params.compressed ?? false;
375
+ this.compressionAlgorithm = params.compressionAlgorithm;
376
+ }
377
+ static fromProto(data) {
378
+ if (!data) {
379
+ return void 0;
380
+ }
381
+ return new _AccountData({
382
+ data: data.data ? new Uint8Array(data.data) : void 0,
383
+ compressed: data.compressed ?? false,
384
+ compressionAlgorithm: data.compressionAlgorithm
385
+ });
386
+ }
387
+ };
388
+ var Account = class _Account {
389
+ constructor(params) {
390
+ this.address = params.address;
391
+ this.meta = params.meta;
392
+ this.data = params.data;
393
+ this.versionContext = params.versionContext;
394
+ this.consensusStatus = params.consensusStatus;
395
+ }
396
+ static fromProto(proto) {
397
+ if (!proto.address) {
398
+ throw new Error("Account proto missing address");
399
+ }
400
+ return new _Account({
401
+ address: Pubkey.fromProtoPubkey(proto.address),
402
+ meta: AccountMeta.fromProto(proto.meta),
403
+ data: AccountData.fromProto(proto.data ?? void 0),
404
+ versionContext: convertVersionContext(proto.versionContext),
405
+ consensusStatus: proto.consensusStatus
406
+ });
407
+ }
408
+ };
409
+ function convertVersionContext(meta) {
410
+ if (!meta) {
411
+ return void 0;
412
+ }
413
+ return {
414
+ slot: meta.slot,
415
+ blockTimestampNs: timestampToNanoseconds(meta.blockTimestamp)
416
+ };
417
+ }
418
+
419
+ // thru-ts-client-sdk/domain/accounts/streaming.ts
420
+ function toStreamAccountUpdate(response) {
421
+ if (!response.message) {
422
+ return void 0;
423
+ }
424
+ if (response.message.case === "snapshot") {
425
+ return {
426
+ kind: "snapshot",
427
+ snapshot: { account: Account.fromProto(response.message.value) }
428
+ };
429
+ }
430
+ if (response.message.case === "update") {
431
+ return {
432
+ kind: "update",
433
+ update: fromProtoUpdate(response.message.value)
434
+ };
435
+ }
436
+ return void 0;
437
+ }
438
+ function fromProtoUpdate(update) {
439
+ return {
440
+ slot: update.slot,
441
+ meta: AccountMeta.fromProto(update.meta),
442
+ page: update.page ? fromProtoPage(update.page) : void 0,
443
+ deleted: update.delete ?? false
444
+ };
445
+ }
446
+ function fromProtoPage(page) {
447
+ return {
448
+ pageIndex: page.pageIdx,
449
+ pageSize: page.pageSize,
450
+ data: new Uint8Array(page.pageData),
451
+ compressed: page.compressed ?? void 0,
452
+ compressionAlgorithm: page.compressionAlgorithm
453
+ };
454
+ }
455
+ var PageRequest = class _PageRequest {
456
+ constructor(params = {}) {
457
+ if (params.pageSize !== void 0) {
458
+ if (!Number.isInteger(params.pageSize) || params.pageSize < 0) {
459
+ throw new Error("PageRequest.pageSize must be a non-negative integer");
460
+ }
461
+ }
462
+ this.pageSize = params.pageSize;
463
+ this.pageToken = params.pageToken;
464
+ this.orderBy = params.orderBy;
465
+ }
466
+ static fromProto(proto) {
467
+ if (!proto) {
468
+ return void 0;
469
+ }
470
+ return new _PageRequest({
471
+ pageSize: proto.pageSize,
472
+ pageToken: proto.pageToken,
473
+ orderBy: proto.orderBy
474
+ });
475
+ }
476
+ toProto() {
477
+ return create(PageRequestSchema, {
478
+ pageSize: this.pageSize,
479
+ pageToken: this.pageToken,
480
+ orderBy: this.orderBy
481
+ });
482
+ }
483
+ withParams(params) {
484
+ return new _PageRequest({
485
+ pageSize: params.pageSize ?? this.pageSize,
486
+ pageToken: params.pageToken ?? this.pageToken,
487
+ orderBy: params.orderBy ?? this.orderBy
488
+ });
489
+ }
490
+ };
491
+ var PageResponse = class _PageResponse {
492
+ constructor(params = {}) {
493
+ this.nextPageToken = params.nextPageToken;
494
+ this.totalSize = params.totalSize;
495
+ }
496
+ static fromProto(proto) {
497
+ if (!proto) {
498
+ return void 0;
499
+ }
500
+ return new _PageResponse({
501
+ nextPageToken: proto.nextPageToken,
502
+ totalSize: proto.totalSize
503
+ });
504
+ }
505
+ toProto() {
506
+ return create(PageResponseSchema, {
507
+ nextPageToken: this.nextPageToken,
508
+ totalSize: this.totalSize
509
+ });
510
+ }
511
+ hasNextPage() {
512
+ return !!this.nextPageToken;
513
+ }
514
+ };
515
+ var SignatureDomain = /* @__PURE__ */ ((SignatureDomain2) => {
516
+ SignatureDomain2[SignatureDomain2["TXN"] = 0] = "TXN";
517
+ SignatureDomain2[SignatureDomain2["BLOCK_HEADER"] = 1] = "BLOCK_HEADER";
518
+ SignatureDomain2[SignatureDomain2["BLOCK"] = 2] = "BLOCK";
519
+ SignatureDomain2[SignatureDomain2["GOSSIP"] = 3] = "GOSSIP";
520
+ return SignatureDomain2;
521
+ })(SignatureDomain || {});
522
+ var DOMAIN_TAGS = {
523
+ [0 /* TXN */]: 1n,
524
+ [1 /* BLOCK_HEADER */]: 2n,
525
+ [2 /* BLOCK */]: 3n,
526
+ [3 /* GOSSIP */]: 4n
527
+ };
528
+ var DOMAIN_BLOCK_SIZE = 128;
529
+ var SIGNATURE_SIZE = 64;
530
+ var PUBKEY_SIZE = 32;
531
+ function createDomainBlock(domain) {
532
+ const block = new Uint8Array(DOMAIN_BLOCK_SIZE);
533
+ block.fill(0);
534
+ const tag = DOMAIN_TAGS[domain];
535
+ if (tag === void 0) {
536
+ throw new Error(`Invalid signature domain: ${domain}`);
537
+ }
538
+ const view = new DataView(block.buffer, block.byteOffset, block.byteLength);
539
+ view.setBigUint64(0, tag, false);
540
+ return block;
541
+ }
542
+ function copyBytes2(bytes) {
543
+ const out = new Uint8Array(bytes.length);
544
+ out.set(bytes);
545
+ return out;
546
+ }
547
+ function concatBytes(...arrays) {
548
+ return etc.concatBytes(...arrays);
549
+ }
550
+ function bytesToNumberLE(bytes) {
551
+ let value = 0n;
552
+ for (let i = 0; i < bytes.length; i++) {
553
+ value += BigInt(bytes[i]) << 8n * BigInt(i);
554
+ }
555
+ return value;
556
+ }
557
+ function modOrder(value) {
558
+ const modulus = CURVE.n;
559
+ const result = value % modulus;
560
+ return result >= 0n ? result : result + modulus;
561
+ }
562
+ function numberToBytesLE(value, length) {
563
+ const out = new Uint8Array(length);
564
+ let current = value;
565
+ for (let i = 0; i < length; i++) {
566
+ out[i] = Number(current & 0xffn);
567
+ current >>= 8n;
568
+ }
569
+ return out;
570
+ }
571
+ async function signWithDomain(message, privateKey, publicKey, domain = 0 /* TXN */) {
572
+ if (privateKey.length !== PUBKEY_SIZE) {
573
+ throw new Error("Private key must contain 32 bytes");
574
+ }
575
+ const domainBlock = createDomainBlock(domain);
576
+ const messageBytes = copyBytes2(message);
577
+ const extended = await utils.getExtendedPublicKeyAsync(privateKey);
578
+ const publicKeyBytes = publicKey ? copyBytes2(publicKey) : extended.pointBytes;
579
+ if (publicKeyBytes.length !== PUBKEY_SIZE) {
580
+ throw new Error("Public key must contain 32 bytes");
581
+ }
582
+ const rInput = concatBytes(domainBlock, extended.prefix, messageBytes);
583
+ const r = modOrder(bytesToNumberLE(await etc.sha512Async(rInput)));
584
+ const R = Point.BASE.multiply(r).toBytes();
585
+ const kInput = concatBytes(domainBlock, R, publicKeyBytes, messageBytes);
586
+ const k = modOrder(bytesToNumberLE(await etc.sha512Async(kInput)));
587
+ const s = modOrder(r + k * extended.scalar);
588
+ const signature = new Uint8Array(SIGNATURE_SIZE);
589
+ signature.set(R, 0);
590
+ signature.set(numberToBytesLE(s, PUBKEY_SIZE), PUBKEY_SIZE);
591
+ return signature;
592
+ }
593
+ async function verifyWithDomain(signature, message, publicKey, domain = 0 /* TXN */) {
594
+ if (signature.length !== SIGNATURE_SIZE || publicKey.length !== PUBKEY_SIZE) {
595
+ return false;
596
+ }
597
+ const domainBlock = createDomainBlock(domain);
598
+ const messageBytes = copyBytes2(message);
599
+ const rBytes = signature.subarray(0, PUBKEY_SIZE);
600
+ const s = bytesToNumberLE(signature.subarray(PUBKEY_SIZE));
601
+ if (s >= CURVE.n) {
602
+ return false;
603
+ }
604
+ let R;
605
+ let A;
606
+ try {
607
+ R = Point.fromHex(rBytes);
608
+ A = Point.fromHex(publicKey);
609
+ } catch {
610
+ return false;
611
+ }
612
+ const kInput = concatBytes(domainBlock, rBytes, publicKey, messageBytes);
613
+ const k = modOrder(bytesToNumberLE(await etc.sha512Async(kInput)));
614
+ const lhs = Point.BASE.multiply(s);
615
+ const rhs = R.add(A.multiply(k));
616
+ return lhs.add(rhs.negate()).clearCofactor().is0();
617
+ }
618
+
619
+ // thru-ts-client-sdk/wire-format.ts
620
+ var SIGNATURE_SIZE2 = 64;
621
+ var PUBKEY_SIZE2 = 32;
622
+ var HASH_SIZE = 32;
623
+ var BLOCK_HEADER_SIZE = 168;
624
+ var BLOCK_HEADER_SIZE_LEGACY = 160;
625
+ var BLOCK_FOOTER_SIZE = 104;
626
+ var BLOCK_VERSION_V1 = 1;
627
+ var TXN_HEADER_BODY_SIZE = 112;
628
+ var TXN_VERSION_V1 = 1;
629
+ var TXN_MAX_ACCOUNTS = 1024;
630
+ var STATE_PROOF_HEADER_SIZE = 40;
631
+ var ACCOUNT_META_FOOTPRINT = 64;
632
+ var TXN_FLAG_HAS_FEE_PAYER_PROOF = 1 << 0;
633
+ var STATE_PROOF_TYPE_EXISTING = 0;
634
+ var STATE_PROOF_TYPE_UPDATING = 1;
635
+ var STATE_PROOF_TYPE_CREATION = 2;
636
+
637
+ // thru-ts-client-sdk/domain/transactions/Transaction.ts
638
+ var DEFAULT_FLAGS = 0;
639
+ var MAX_INSTRUCTION_DATA_LENGTH = 65535;
640
+ var BYTE_POPCOUNT = new Uint8Array(256).map((_value, index) => {
641
+ let v = index;
642
+ let count = 0;
643
+ while (v !== 0) {
644
+ count += v & 1;
645
+ v >>= 1;
646
+ }
647
+ return count;
648
+ });
649
+ var Transaction = class _Transaction {
650
+ constructor(params) {
651
+ this.version = params.version ?? TXN_VERSION_V1;
652
+ this.feePayer = Pubkey.from(params.feePayer);
653
+ this.program = Pubkey.from(params.program);
654
+ this.fee = params.header.fee;
655
+ this.nonce = params.header.nonce;
656
+ this.startSlot = params.header.startSlot;
657
+ this.expiryAfter = params.header.expiryAfter ?? 0;
658
+ this.chainId = params.header.chainId ?? 1;
659
+ this.requestedComputeUnits = params.header.computeUnits ?? 0;
660
+ this.requestedStateUnits = params.header.stateUnits ?? 0;
661
+ this.requestedMemoryUnits = params.header.memoryUnits ?? 0;
662
+ this.flags = params.header.flags ?? DEFAULT_FLAGS;
663
+ this.readWriteAccounts = params.accounts?.readWriteAccounts ? params.accounts.readWriteAccounts.map(Pubkey.from) : [];
664
+ this.readOnlyAccounts = params.accounts?.readOnlyAccounts ? params.accounts.readOnlyAccounts.map(Pubkey.from) : [];
665
+ this.instructionData = params.instructionData ? new Uint8Array(params.instructionData) : void 0;
666
+ if (this.instructionData && this.instructionData.length > MAX_INSTRUCTION_DATA_LENGTH) {
667
+ throw new Error(`Instruction data exceeds maximum length (${MAX_INSTRUCTION_DATA_LENGTH} bytes)`);
668
+ }
669
+ this.instructionDataSize = params.instructionDataSize;
670
+ this.feePayerStateProof = params.proofs?.feePayerStateProof ? new Uint8Array(params.proofs.feePayerStateProof) : void 0;
671
+ this.feePayerAccountMetaRaw = params.proofs?.feePayerAccountMetaRaw ? new Uint8Array(params.proofs.feePayerAccountMetaRaw) : void 0;
672
+ }
673
+ static fromWire(data) {
674
+ const { transaction, size } = _Transaction.parseWire(data, { strict: true });
675
+ if (size !== data.length) {
676
+ throw new Error(
677
+ `Transaction body has trailing bytes: expected ${size} bytes but found ${data.length}`
678
+ );
679
+ }
680
+ return transaction;
681
+ }
682
+ static parseWire(data, options = {}) {
683
+ const strict = options.strict ?? false;
684
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
685
+ if (data.length < TXN_HEADER_BODY_SIZE) {
686
+ throw new Error(`Transaction data too short: ${data.length} bytes (minimum ${TXN_HEADER_BODY_SIZE})`);
687
+ }
688
+ let offset = 0;
689
+ const version = view.getUint8(offset);
690
+ offset += 1;
691
+ if (strict && version !== TXN_VERSION_V1) {
692
+ throw new Error(`Unsupported transaction version: ${version}`);
693
+ }
694
+ const flags = view.getUint8(offset);
695
+ offset += 1;
696
+ const invalidFlags = flags & -4;
697
+ if (strict && invalidFlags !== 0) {
698
+ throw new Error(`Unsupported transaction flags: 0x${invalidFlags.toString(16).padStart(2, "0")}`);
699
+ }
700
+ const readwriteAccountsCount = view.getUint16(offset, true);
701
+ offset += 2;
702
+ const readonlyAccountsCount = view.getUint16(offset, true);
703
+ offset += 2;
704
+ const instructionDataSize = view.getUint16(offset, true);
380
705
  offset += 2;
381
706
  const requestedComputeUnits = view.getUint32(offset, true);
382
707
  offset += 4;
@@ -687,624 +1012,291 @@ var Transaction = class _Transaction {
687
1012
  result.set(this.signature.toBytes(), offset);
688
1013
  }
689
1014
  }
690
- return result;
691
- }
692
- static parseBodySections(body, readwriteCount, readonlyCount, instructionDataSize, flags) {
693
- let offset = 0;
694
- const readWriteAccounts = [];
695
- for (let i = 0; i < readwriteCount; i++) {
696
- this.ensureAvailable(body.length, offset, PUBKEY_SIZE2, "read-write accounts");
697
- readWriteAccounts.push(body.slice(offset, offset + PUBKEY_SIZE2));
698
- offset += PUBKEY_SIZE2;
699
- }
700
- const readOnlyAccounts = [];
701
- for (let i = 0; i < readonlyCount; i++) {
702
- this.ensureAvailable(body.length, offset, PUBKEY_SIZE2, "read-only accounts");
703
- readOnlyAccounts.push(body.slice(offset, offset + PUBKEY_SIZE2));
704
- offset += PUBKEY_SIZE2;
705
- }
706
- let instructionData;
707
- if (instructionDataSize > 0) {
708
- this.ensureAvailable(body.length, offset, instructionDataSize, "instruction data");
709
- instructionData = body.slice(offset, offset + instructionDataSize);
710
- offset += instructionDataSize;
711
- }
712
- let feePayerStateProof;
713
- let feePayerAccountMetaRaw;
714
- if ((flags & TXN_FLAG_HAS_FEE_PAYER_PROOF) !== 0) {
715
- const { proofBytes, footprint, proofType } = this.parseStateProof(body.subarray(offset));
716
- feePayerStateProof = proofBytes;
717
- offset += footprint;
718
- if (proofType === STATE_PROOF_TYPE_EXISTING) {
719
- this.ensureAvailable(body.length, offset, ACCOUNT_META_FOOTPRINT, "fee payer account metadata");
720
- feePayerAccountMetaRaw = body.slice(offset, offset + ACCOUNT_META_FOOTPRINT);
721
- offset += ACCOUNT_META_FOOTPRINT;
722
- }
723
- }
724
- if (offset !== body.length) {
725
- throw new Error(
726
- `Transaction body has trailing bytes: expected ${offset} bytes but found ${body.length}`
727
- );
728
- }
729
- return {
730
- readWriteAccounts,
731
- readOnlyAccounts,
732
- instructionData,
733
- feePayerStateProof,
734
- feePayerAccountMetaRaw
735
- };
736
- }
737
- static ensureAvailable(totalLength, offset, required, context) {
738
- if (offset + required > totalLength) {
739
- throw new Error(`Transaction data truncated while parsing ${context}`);
740
- }
741
- }
742
- static parseStateProof(data) {
743
- if (data.length < STATE_PROOF_HEADER_SIZE) {
744
- throw new Error("Transaction data truncated while parsing state proof header");
745
- }
746
- const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
747
- const typeSlot = view.getBigUint64(0, true);
748
- const proofType = Number(typeSlot >> 62n & 0x3n);
749
- if (proofType !== STATE_PROOF_TYPE_EXISTING && proofType !== STATE_PROOF_TYPE_UPDATING && proofType !== STATE_PROOF_TYPE_CREATION) {
750
- throw new Error(`Transaction state proof has unknown type: ${proofType}`);
751
- }
752
- const pathBitset = data.subarray(8, 40);
753
- const siblingCount = countSetBits(pathBitset);
754
- const bodyCount = proofType + siblingCount;
755
- const totalSize = STATE_PROOF_HEADER_SIZE + bodyCount * HASH_SIZE;
756
- if (proofType === STATE_PROOF_TYPE_CREATION && bodyCount < 2) {
757
- throw new Error("Transaction state proof creation entry is truncated");
758
- }
759
- if (proofType === STATE_PROOF_TYPE_UPDATING && bodyCount < 1) {
760
- throw new Error("Transaction state proof updating entry is truncated");
761
- }
762
- if (data.length < totalSize) {
763
- throw new Error("Transaction data truncated while parsing state proof body");
764
- }
765
- return {
766
- proofBytes: data.slice(0, totalSize),
767
- footprint: totalSize,
768
- proofType
769
- };
770
- }
771
- static executionResultFromProto(proto) {
772
- return {
773
- consumedComputeUnits: proto.consumedComputeUnits ?? 0,
774
- consumedMemoryUnits: proto.consumedMemoryUnits ?? 0,
775
- consumedStateUnits: proto.consumedStateUnits ?? 0,
776
- userErrorCode: proto.userErrorCode ?? 0n,
777
- vmError: proto.vmError ?? TransactionVmError.TRANSACTION_VM_EXECUTE_SUCCESS,
778
- executionResult: proto.executionResult ?? 0n,
779
- pagesUsed: proto.pagesUsed ?? 0,
780
- eventsCount: proto.eventsCount ?? 0,
781
- eventsSize: proto.eventsSize ?? 0,
782
- readwriteAccounts: proto.readwriteAccounts.map((account) => Pubkey.fromProtoPubkey(account)),
783
- readonlyAccounts: proto.readonlyAccounts.map((account) => Pubkey.fromProtoPubkey(account)),
784
- events: proto.events.length ? proto.events.map((event) => ({
785
- eventId: event.eventId,
786
- callIdx: event.callIdx,
787
- programIdx: event.programIdx,
788
- program: event.program ? Pubkey.fromProtoPubkey(event.program) : void 0,
789
- payload: new Uint8Array(event.payload ?? new Uint8Array(0))
790
- })) : void 0
791
- };
792
- }
793
- };
794
- function appendAccountList(target, start, accounts) {
795
- let offset = start;
796
- for (const account of accounts) {
797
- target.set(account, offset);
798
- offset += PUBKEY_SIZE2;
799
- }
800
- return offset;
801
- }
802
- function ensureUint16(value) {
803
- if (!Number.isInteger(value) || value < 0 || value > 65535) {
804
- throw new Error("Value must fit within uint16 range");
805
- }
806
- return value;
807
- }
808
- function ensureUint32(value) {
809
- if (!Number.isInteger(value) || value < 0 || value > 4294967295) {
810
- throw new Error("Value must fit within uint32 range");
811
- }
812
- return value;
813
- }
814
- function ensureBigUint64(value) {
815
- if (value < 0n || value > 0xffffffffffffffffn) {
816
- throw new Error("Value must fit within uint64 range");
817
- }
818
- return value;
819
- }
820
- function countSetBits(bytes) {
821
- let total = 0;
822
- for (let i = 0; i < bytes.length; i++) {
823
- total += BYTE_POPCOUNT[bytes[i]];
824
- }
825
- return total;
826
- }
827
- function hasNonZeroBytes(value) {
828
- for (let i = 0; i < value.length; i++) {
829
- if (value[i] !== 0) {
830
- return true;
831
- }
832
- }
833
- return false;
834
- }
835
- var ACCOUNT_LIMIT = 1024;
836
- function normalizeAccountList(accounts) {
837
- if (accounts.length === 0) {
838
- return [];
839
- }
840
- if (accounts.length > ACCOUNT_LIMIT) {
841
- throw new Error(`Too many accounts provided: ${accounts.length} (max ${ACCOUNT_LIMIT})`);
842
- }
843
- const deduped = dedupeAccountList(accounts);
844
- return deduped;
845
- }
846
- function dedupeAccountList(accounts) {
847
- const pubkeys = accounts.map(Pubkey.from).map((pubkey) => pubkey.toBytes());
848
- const seen = /* @__PURE__ */ new Map();
849
- for (const pubkey of pubkeys) {
850
- if (pubkey.length !== 32) {
851
- throw new Error("Account addresses must contain 32 bytes");
852
- }
853
- const key = toHex(pubkey);
854
- if (!seen.has(key)) {
855
- seen.set(key, pubkey);
856
- }
857
- }
858
- return Array.from(seen.values()).sort(compareAccounts);
859
- }
860
- function compareAccounts(a, b) {
861
- for (let i = 0; i < 32; i++) {
862
- if (a[i] !== b[i]) {
863
- return a[i] - b[i];
864
- }
865
- }
866
- return 0;
867
- }
868
- function toHex(bytes) {
869
- let result = "";
870
- for (let i = 0; i < bytes.length; i++) {
871
- const hex = bytes[i].toString(16).padStart(2, "0");
872
- result += hex;
873
- }
874
- return result;
875
- }
876
- function parseInstructionData(value) {
877
- if (value === void 0) {
878
- return void 0;
879
- }
880
- if (value instanceof Uint8Array) {
881
- return new Uint8Array(value);
1015
+ return result;
882
1016
  }
883
- if (typeof value === "string") {
884
- if (value.length === 0) {
885
- return new Uint8Array();
1017
+ static parseBodySections(body, readwriteCount, readonlyCount, instructionDataSize, flags) {
1018
+ let offset = 0;
1019
+ const readWriteAccounts = [];
1020
+ for (let i = 0; i < readwriteCount; i++) {
1021
+ this.ensureAvailable(body.length, offset, PUBKEY_SIZE2, "read-write accounts");
1022
+ readWriteAccounts.push(body.slice(offset, offset + PUBKEY_SIZE2));
1023
+ offset += PUBKEY_SIZE2;
886
1024
  }
887
- if (isHexString(value)) {
888
- return hexToBytes(value);
1025
+ const readOnlyAccounts = [];
1026
+ for (let i = 0; i < readonlyCount; i++) {
1027
+ this.ensureAvailable(body.length, offset, PUBKEY_SIZE2, "read-only accounts");
1028
+ readOnlyAccounts.push(body.slice(offset, offset + PUBKEY_SIZE2));
1029
+ offset += PUBKEY_SIZE2;
889
1030
  }
890
- }
891
- throw new Error("Instruction data must be provided as hex string or Uint8Array");
892
- }
893
- function createInstructionContext(feePayer, program, sortedReadWrite, sortedReadOnly) {
894
- const accounts = [
895
- feePayer,
896
- program,
897
- ...sortedReadWrite.map((bytes) => Pubkey.from(bytes)),
898
- ...sortedReadOnly.map((bytes) => Pubkey.from(bytes))
899
- ];
900
- const indexMap = /* @__PURE__ */ new Map();
901
- for (let i = 0; i < accounts.length; i++) {
902
- const key = toHex(accounts[i].toBytes());
903
- if (!indexMap.has(key)) {
904
- indexMap.set(key, i);
1031
+ let instructionData;
1032
+ if (instructionDataSize > 0) {
1033
+ this.ensureAvailable(body.length, offset, instructionDataSize, "instruction data");
1034
+ instructionData = body.slice(offset, offset + instructionDataSize);
1035
+ offset += instructionDataSize;
905
1036
  }
906
- }
907
- return {
908
- accounts,
909
- getAccountIndex: (pubkey) => {
910
- const bytes = Pubkey.from(pubkey).toBytes();
911
- const key = toHex(bytes);
912
- const index = indexMap.get(key);
913
- if (index === void 0) {
914
- throw new Error(`Account ${key} not found in transaction accounts`);
1037
+ let feePayerStateProof;
1038
+ let feePayerAccountMetaRaw;
1039
+ if ((flags & TXN_FLAG_HAS_FEE_PAYER_PROOF) !== 0) {
1040
+ const { proofBytes, footprint, proofType } = this.parseStateProof(body.subarray(offset));
1041
+ feePayerStateProof = proofBytes;
1042
+ offset += footprint;
1043
+ if (proofType === STATE_PROOF_TYPE_EXISTING) {
1044
+ this.ensureAvailable(body.length, offset, ACCOUNT_META_FOOTPRINT, "fee payer account metadata");
1045
+ feePayerAccountMetaRaw = body.slice(offset, offset + ACCOUNT_META_FOOTPRINT);
1046
+ offset += ACCOUNT_META_FOOTPRINT;
915
1047
  }
916
- return index;
917
1048
  }
918
- };
919
- }
920
-
921
- // thru-ts-client-sdk/domain/transactions/TransactionBuilder.ts
922
- var FLAG_HAS_FEE_PAYER_PROOF = 1 << 0;
923
- var TransactionBuilder = class {
924
- build(params) {
925
- const feePayer = Pubkey.from(params.feePayer.publicKey);
926
- const program = Pubkey.from(params.program);
927
- const sortedReadWrite = normalizeAccountList(params.accounts?.readWriteAccounts ?? []);
928
- const sortedReadOnly = normalizeAccountList(params.accounts?.readOnlyAccounts ?? []);
929
- let instructionData;
930
- if (params.buildInstructionData) {
931
- const context = createInstructionContext(feePayer, program, sortedReadWrite, sortedReadOnly);
932
- const result = params.buildInstructionData(context);
933
- instructionData = parseInstructionData(result);
934
- } else {
935
- instructionData = parseInstructionData(params.instructionData);
1049
+ if (offset !== body.length) {
1050
+ throw new Error(
1051
+ `Transaction body has trailing bytes: expected ${offset} bytes but found ${body.length}`
1052
+ );
936
1053
  }
937
- const baseFlags = params.header.flags ?? 0;
938
- const flags = params.proofs?.feePayerStateProof ? baseFlags | FLAG_HAS_FEE_PAYER_PROOF : baseFlags;
939
- const accounts = sortedReadWrite.length > 0 || sortedReadOnly.length > 0 ? { readWriteAccounts: sortedReadWrite, readOnlyAccounts: sortedReadOnly } : void 0;
940
- return new Transaction({
941
- feePayer,
942
- program,
943
- header: {
944
- ...params.header,
945
- flags
946
- },
947
- accounts,
1054
+ return {
1055
+ readWriteAccounts,
1056
+ readOnlyAccounts,
948
1057
  instructionData,
949
- proofs: params.proofs
950
- });
1058
+ feePayerStateProof,
1059
+ feePayerAccountMetaRaw
1060
+ };
951
1061
  }
952
- async buildAndSign(params) {
953
- if (!params.feePayer.privateKey) {
954
- throw new Error("Fee payer private key is required to sign the transaction");
1062
+ static ensureAvailable(totalLength, offset, required, context) {
1063
+ if (offset + required > totalLength) {
1064
+ throw new Error(`Transaction data truncated while parsing ${context}`);
955
1065
  }
956
- const transaction = this.build(params);
957
- const signature = await transaction.sign(params.feePayer.privateKey);
958
- const rawTransaction = transaction.toWire();
959
- return { transaction, signature, rawTransaction };
960
- }
961
- };
962
- function isSlotSelector(selector) {
963
- return "slot" in selector;
964
- }
965
- function mergeTransactionHeader(defaults, overrides) {
966
- if (!overrides) {
967
- return defaults;
968
- }
969
- const sanitized = Object.fromEntries(
970
- Object.entries(overrides).filter(([, value]) => value !== void 0)
971
- );
972
- return {
973
- ...defaults,
974
- ...sanitized
975
- };
976
- }
977
- function timestampToNanoseconds(timestamp) {
978
- if (!timestamp) {
979
- return 0n;
980
- }
981
- const seconds = BigInt(timestamp.seconds ?? 0);
982
- const nanos = BigInt(timestamp.nanos ?? 0);
983
- return seconds * 1000000000n + nanos;
984
- }
985
- function nanosecondsToTimestamp(ns) {
986
- const seconds = ns / 1000000000n;
987
- const nanos = Number(ns % 1000000000n);
988
- return { seconds, nanos };
989
- }
990
- function consensusStatusToString(status) {
991
- const lookup = ConsensusStatus;
992
- return lookup[status] ?? `UNKNOWN(${status})`;
993
- }
994
-
995
- // thru-ts-client-sdk/domain/transactions/TransactionStatusSnapshot.ts
996
- var TransactionStatusSnapshot = class _TransactionStatusSnapshot {
997
- constructor(params) {
998
- this.signature = copyBytes3(params.signature);
999
- this.statusCode = params.consensusStatus;
1000
- this.status = params.consensusStatus != null ? consensusStatusToString(params.consensusStatus) : void 0;
1001
- this.executionResult = params.executionResult;
1002
1066
  }
1003
- static fromProto(proto) {
1004
- if (!proto.signature?.value) {
1005
- throw new Error("TransactionStatus proto missing signature");
1067
+ static parseStateProof(data) {
1068
+ if (data.length < STATE_PROOF_HEADER_SIZE) {
1069
+ throw new Error("Transaction data truncated while parsing state proof header");
1006
1070
  }
1007
- return new _TransactionStatusSnapshot({
1008
- signature: proto.signature.value,
1009
- consensusStatus: proto.consensusStatus,
1010
- executionResult: proto.executionResult ? Transaction.executionResultFromProto(proto.executionResult) : void 0
1011
- });
1071
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
1072
+ const typeSlot = view.getBigUint64(0, true);
1073
+ const proofType = Number(typeSlot >> 62n & 0x3n);
1074
+ if (proofType !== STATE_PROOF_TYPE_EXISTING && proofType !== STATE_PROOF_TYPE_UPDATING && proofType !== STATE_PROOF_TYPE_CREATION) {
1075
+ throw new Error(`Transaction state proof has unknown type: ${proofType}`);
1076
+ }
1077
+ const pathBitset = data.subarray(8, 40);
1078
+ const siblingCount = countSetBits(pathBitset);
1079
+ const bodyCount = proofType + siblingCount;
1080
+ const totalSize = STATE_PROOF_HEADER_SIZE + bodyCount * HASH_SIZE;
1081
+ if (proofType === STATE_PROOF_TYPE_CREATION && bodyCount < 2) {
1082
+ throw new Error("Transaction state proof creation entry is truncated");
1083
+ }
1084
+ if (proofType === STATE_PROOF_TYPE_UPDATING && bodyCount < 1) {
1085
+ throw new Error("Transaction state proof updating entry is truncated");
1086
+ }
1087
+ if (data.length < totalSize) {
1088
+ throw new Error("Transaction data truncated while parsing state proof body");
1089
+ }
1090
+ return {
1091
+ proofBytes: data.slice(0, totalSize),
1092
+ footprint: totalSize,
1093
+ proofType
1094
+ };
1095
+ }
1096
+ static executionResultFromProto(proto) {
1097
+ return {
1098
+ consumedComputeUnits: proto.consumedComputeUnits ?? 0,
1099
+ consumedMemoryUnits: proto.consumedMemoryUnits ?? 0,
1100
+ consumedStateUnits: proto.consumedStateUnits ?? 0,
1101
+ userErrorCode: proto.userErrorCode ?? 0n,
1102
+ vmError: proto.vmError ?? TransactionVmError.TRANSACTION_VM_EXECUTE_SUCCESS,
1103
+ executionResult: proto.executionResult ?? 0n,
1104
+ pagesUsed: proto.pagesUsed ?? 0,
1105
+ eventsCount: proto.eventsCount ?? 0,
1106
+ eventsSize: proto.eventsSize ?? 0,
1107
+ readwriteAccounts: proto.readwriteAccounts.map((account) => Pubkey.fromProtoPubkey(account)),
1108
+ readonlyAccounts: proto.readonlyAccounts.map((account) => Pubkey.fromProtoPubkey(account)),
1109
+ events: proto.events.length ? proto.events.map((event) => ({
1110
+ eventId: event.eventId,
1111
+ callIdx: event.callIdx,
1112
+ programIdx: event.programIdx,
1113
+ program: event.program ? Pubkey.fromProtoPubkey(event.program) : void 0,
1114
+ payload: new Uint8Array(event.payload ?? new Uint8Array(0))
1115
+ })) : void 0,
1116
+ errorProgramAccIdx: proto.errorProgramAccIdx ?? 0
1117
+ };
1012
1118
  }
1013
1119
  };
1014
- function copyBytes3(bytes) {
1015
- const copy = new Uint8Array(bytes.length);
1016
- copy.set(bytes);
1017
- return copy;
1018
- }
1019
- var DEFAULT_HOST = "https://grpc-web.alphanet.thruput.org";
1020
- var DEFAULT_ACCOUNT_VIEW = AccountView.FULL;
1021
- var DEFAULT_BLOCK_VIEW = BlockView.FULL;
1022
- var DEFAULT_TRANSACTION_VIEW = TransactionView.FULL;
1023
- var DEFAULT_MIN_CONSENSUS = ConsensusStatus.UNSPECIFIED;
1024
- var DEFAULT_VERSION_CONTEXT = create(VersionContextSchema, {
1025
- version: {
1026
- case: "current",
1027
- value: create(CurrentVersionSchema, {})
1120
+ function appendAccountList(target, start, accounts) {
1121
+ let offset = start;
1122
+ for (const account of accounts) {
1123
+ target.set(account, offset);
1124
+ offset += PUBKEY_SIZE2;
1028
1125
  }
1029
- });
1030
- var DEFAULT_FEE = 1n;
1031
- var DEFAULT_COMPUTE_UNITS = 3e8;
1032
- var DEFAULT_STATE_UNITS = 1e4;
1033
- var DEFAULT_MEMORY_UNITS = 1e4;
1034
- var DEFAULT_EXPIRY_AFTER = 100;
1035
- function createThruClientContext(config = {}) {
1036
- const transportOptions = config.transportOptions ?? {};
1037
- const { baseUrl: optionsBaseUrl, interceptors: optionInterceptors, ...restTransportOptions } = transportOptions;
1038
- const baseUrl = config.baseUrl ?? optionsBaseUrl ?? DEFAULT_HOST;
1039
- const mergedInterceptors = [
1040
- ...optionInterceptors ?? [],
1041
- ...config.interceptors ?? []
1042
- ];
1043
- const transport = config.transport ?? createGrpcWebTransport({
1044
- baseUrl,
1045
- ...restTransportOptions,
1046
- interceptors: mergedInterceptors.length > 0 ? mergedInterceptors : void 0
1047
- });
1048
- return {
1049
- baseUrl,
1050
- transport,
1051
- query: createClient(QueryService, transport),
1052
- command: createClient(CommandService, transport),
1053
- streaming: createClient(StreamingService, transport),
1054
- callOptions: config.callOptions
1055
- };
1056
- }
1057
- function withCallOptions(ctx, overrides) {
1058
- return mergeCallOptions(ctx.callOptions, overrides);
1126
+ return offset;
1059
1127
  }
1060
- function mergeCallOptions(defaults, overrides) {
1061
- if (!defaults) {
1062
- return overrides;
1128
+ function ensureUint16(value) {
1129
+ if (!Number.isInteger(value) || value < 0 || value > 65535) {
1130
+ throw new Error("Value must fit within uint16 range");
1063
1131
  }
1064
- if (!overrides) {
1065
- return defaults;
1132
+ return value;
1133
+ }
1134
+ function ensureUint32(value) {
1135
+ if (!Number.isInteger(value) || value < 0 || value > 4294967295) {
1136
+ throw new Error("Value must fit within uint32 range");
1066
1137
  }
1067
- return {
1068
- ...defaults,
1069
- ...overrides,
1070
- headers: mergeHeaders(defaults.headers, overrides.headers),
1071
- contextValues: overrides.contextValues ?? defaults.contextValues,
1072
- onHeader: overrides.onHeader ?? defaults.onHeader,
1073
- onTrailer: overrides.onTrailer ?? defaults.onTrailer
1074
- };
1138
+ return value;
1075
1139
  }
1076
- function mergeHeaders(a, b) {
1077
- const entries = [];
1078
- const add = (init) => {
1079
- if (!init) {
1080
- return;
1081
- }
1082
- if (init instanceof Headers) {
1083
- init.forEach((value, key) => {
1084
- entries.push([key, value]);
1085
- });
1086
- return;
1087
- }
1088
- if (Array.isArray(init)) {
1089
- for (const [key, value] of init) {
1090
- entries.push([key, value]);
1091
- }
1092
- return;
1093
- }
1094
- for (const [key, value] of Object.entries(init)) {
1095
- if (value !== void 0) {
1096
- entries.push([key, String(value)]);
1097
- }
1098
- }
1099
- };
1100
- add(a);
1101
- add(b);
1102
- if (entries.length === 0) {
1103
- return void 0;
1140
+ function ensureBigUint64(value) {
1141
+ if (value < 0n || value > 0xffffffffffffffffn) {
1142
+ throw new Error("Value must fit within uint64 range");
1104
1143
  }
1105
- return entries;
1144
+ return value;
1106
1145
  }
1107
-
1108
- // thru-ts-client-sdk/domain/accounts/Account.ts
1109
- var AccountFlags = class _AccountFlags {
1110
- constructor(flags) {
1111
- this.isProgram = flags?.isProgram ?? false;
1112
- this.isPrivileged = flags?.isPrivileged ?? false;
1113
- this.isUncompressable = flags?.isUncompressable ?? false;
1114
- this.isEphemeral = flags?.isEphemeral ?? false;
1115
- this.isDeleted = flags?.isDeleted ?? false;
1116
- this.isNew = flags?.isNew ?? false;
1117
- this.isCompressed = flags?.isCompressed ?? false;
1146
+ function countSetBits(bytes) {
1147
+ let total = 0;
1148
+ for (let i = 0; i < bytes.length; i++) {
1149
+ total += BYTE_POPCOUNT[bytes[i]];
1118
1150
  }
1119
- static fromProto(flags) {
1120
- if (!flags) {
1121
- return new _AccountFlags();
1151
+ return total;
1152
+ }
1153
+ function hasNonZeroBytes(value) {
1154
+ for (let i = 0; i < value.length; i++) {
1155
+ if (value[i] !== 0) {
1156
+ return true;
1122
1157
  }
1123
- return new _AccountFlags({
1124
- isProgram: flags.isProgram,
1125
- isPrivileged: flags.isPrivileged,
1126
- isUncompressable: flags.isUncompressable,
1127
- isEphemeral: flags.isEphemeral,
1128
- isDeleted: flags.isDeleted,
1129
- isNew: flags.isNew,
1130
- isCompressed: flags.isCompressed
1131
- });
1132
- }
1133
- };
1134
- var AccountMeta = class _AccountMeta {
1135
- constructor(params) {
1136
- this.version = params.version;
1137
- this.flags = params.flags ?? new AccountFlags();
1138
- this.dataSize = params.dataSize;
1139
- this.seq = params.seq;
1140
- this.owner = params.owner;
1141
- this.balance = params.balance;
1142
- this.nonce = params.nonce;
1143
1158
  }
1144
- static fromProto(meta) {
1145
- if (!meta) {
1146
- return void 0;
1147
- }
1148
- return new _AccountMeta({
1149
- version: meta.version,
1150
- flags: AccountFlags.fromProto(meta.flags),
1151
- dataSize: meta.dataSize,
1152
- seq: meta.seq ?? 0n,
1153
- owner: meta.owner ? Pubkey.fromProtoPubkey(meta.owner) : void 0,
1154
- balance: meta.balance ?? 0n,
1155
- nonce: meta.nonce
1156
- });
1159
+ return false;
1160
+ }
1161
+ var ACCOUNT_LIMIT = 1024;
1162
+ function normalizeAccountList(accounts) {
1163
+ if (accounts.length === 0) {
1164
+ return [];
1157
1165
  }
1158
- };
1159
- var AccountData = class _AccountData {
1160
- constructor(params) {
1161
- this.data = params.data ? new Uint8Array(params.data) : void 0;
1162
- this.compressed = params.compressed ?? false;
1163
- this.compressionAlgorithm = params.compressionAlgorithm;
1166
+ if (accounts.length > ACCOUNT_LIMIT) {
1167
+ throw new Error(`Too many accounts provided: ${accounts.length} (max ${ACCOUNT_LIMIT})`);
1164
1168
  }
1165
- static fromProto(data) {
1166
- if (!data) {
1167
- return void 0;
1169
+ const deduped = dedupeAccountList(accounts);
1170
+ return deduped;
1171
+ }
1172
+ function dedupeAccountList(accounts) {
1173
+ const pubkeys = accounts.map(Pubkey.from).map((pubkey) => pubkey.toBytes());
1174
+ const seen = /* @__PURE__ */ new Map();
1175
+ for (const pubkey of pubkeys) {
1176
+ if (pubkey.length !== 32) {
1177
+ throw new Error("Account addresses must contain 32 bytes");
1178
+ }
1179
+ const key = toHex(pubkey);
1180
+ if (!seen.has(key)) {
1181
+ seen.set(key, pubkey);
1168
1182
  }
1169
- return new _AccountData({
1170
- data: data.data ? new Uint8Array(data.data) : void 0,
1171
- compressed: data.compressed ?? false,
1172
- compressionAlgorithm: data.compressionAlgorithm
1173
- });
1174
- }
1175
- };
1176
- var Account = class _Account {
1177
- constructor(params) {
1178
- this.address = params.address;
1179
- this.meta = params.meta;
1180
- this.data = params.data;
1181
- this.versionContext = params.versionContext;
1182
- this.consensusStatus = params.consensusStatus;
1183
1183
  }
1184
- static fromProto(proto) {
1185
- if (!proto.address) {
1186
- throw new Error("Account proto missing address");
1184
+ return Array.from(seen.values()).sort(compareAccounts);
1185
+ }
1186
+ function compareAccounts(a, b) {
1187
+ for (let i = 0; i < 32; i++) {
1188
+ if (a[i] !== b[i]) {
1189
+ return a[i] - b[i];
1187
1190
  }
1188
- return new _Account({
1189
- address: Pubkey.fromProtoPubkey(proto.address),
1190
- meta: AccountMeta.fromProto(proto.meta),
1191
- data: AccountData.fromProto(proto.data ?? void 0),
1192
- versionContext: convertVersionContext(proto.versionContext),
1193
- consensusStatus: proto.consensusStatus
1194
- });
1195
1191
  }
1196
- };
1197
- function convertVersionContext(meta) {
1198
- if (!meta) {
1199
- return void 0;
1192
+ return 0;
1193
+ }
1194
+ function toHex(bytes) {
1195
+ let result = "";
1196
+ for (let i = 0; i < bytes.length; i++) {
1197
+ const hex = bytes[i].toString(16).padStart(2, "0");
1198
+ result += hex;
1200
1199
  }
1201
- return {
1202
- slot: meta.slot,
1203
- blockTimestampNs: timestampToNanoseconds(meta.blockTimestamp)
1204
- };
1200
+ return result;
1205
1201
  }
1206
-
1207
- // thru-ts-client-sdk/domain/accounts/streaming.ts
1208
- function toStreamAccountUpdate(response) {
1209
- if (!response.message) {
1202
+ function parseInstructionData(value) {
1203
+ if (value === void 0) {
1210
1204
  return void 0;
1211
1205
  }
1212
- if (response.message.case === "snapshot") {
1213
- return {
1214
- kind: "snapshot",
1215
- snapshot: { account: Account.fromProto(response.message.value) }
1216
- };
1206
+ if (value instanceof Uint8Array) {
1207
+ return new Uint8Array(value);
1217
1208
  }
1218
- if (response.message.case === "update") {
1219
- return {
1220
- kind: "update",
1221
- update: fromProtoUpdate(response.message.value)
1222
- };
1209
+ if (typeof value === "string") {
1210
+ if (value.length === 0) {
1211
+ return new Uint8Array();
1212
+ }
1213
+ if (isHexString(value)) {
1214
+ return hexToBytes(value);
1215
+ }
1223
1216
  }
1224
- return void 0;
1225
- }
1226
- function fromProtoUpdate(update) {
1227
- return {
1228
- slot: update.slot,
1229
- meta: AccountMeta.fromProto(update.meta),
1230
- page: update.page ? fromProtoPage(update.page) : void 0,
1231
- deleted: update.delete ?? false
1232
- };
1217
+ throw new Error("Instruction data must be provided as hex string or Uint8Array");
1233
1218
  }
1234
- function fromProtoPage(page) {
1219
+ function createInstructionContext(feePayer, program, sortedReadWrite, sortedReadOnly) {
1220
+ const accounts = [
1221
+ feePayer,
1222
+ program,
1223
+ ...sortedReadWrite.map((bytes) => Pubkey.from(bytes)),
1224
+ ...sortedReadOnly.map((bytes) => Pubkey.from(bytes))
1225
+ ];
1226
+ const indexMap = /* @__PURE__ */ new Map();
1227
+ for (let i = 0; i < accounts.length; i++) {
1228
+ const key = toHex(accounts[i].toBytes());
1229
+ if (!indexMap.has(key)) {
1230
+ indexMap.set(key, i);
1231
+ }
1232
+ }
1235
1233
  return {
1236
- pageIndex: page.pageIdx,
1237
- pageSize: page.pageSize,
1238
- data: new Uint8Array(page.pageData),
1239
- compressed: page.compressed ?? void 0,
1240
- compressionAlgorithm: page.compressionAlgorithm
1241
- };
1242
- }
1243
- var PageRequest = class _PageRequest {
1244
- constructor(params = {}) {
1245
- if (params.pageSize !== void 0) {
1246
- if (!Number.isInteger(params.pageSize) || params.pageSize < 0) {
1247
- throw new Error("PageRequest.pageSize must be a non-negative integer");
1234
+ accounts,
1235
+ getAccountIndex: (pubkey) => {
1236
+ const bytes = Pubkey.from(pubkey).toBytes();
1237
+ const key = toHex(bytes);
1238
+ const index = indexMap.get(key);
1239
+ if (index === void 0) {
1240
+ throw new Error(`Account ${key} not found in transaction accounts`);
1248
1241
  }
1242
+ return index;
1249
1243
  }
1250
- this.pageSize = params.pageSize;
1251
- this.pageToken = params.pageToken;
1252
- this.orderBy = params.orderBy;
1253
- }
1254
- static fromProto(proto) {
1255
- if (!proto) {
1256
- return void 0;
1244
+ };
1245
+ }
1246
+
1247
+ // thru-ts-client-sdk/domain/transactions/TransactionBuilder.ts
1248
+ var FLAG_HAS_FEE_PAYER_PROOF = 1 << 0;
1249
+ var TransactionBuilder = class {
1250
+ build(params) {
1251
+ const feePayer = Pubkey.from(params.feePayer.publicKey);
1252
+ const program = Pubkey.from(params.program);
1253
+ const sortedReadWrite = normalizeAccountList(params.accounts?.readWriteAccounts ?? []);
1254
+ const sortedReadOnly = normalizeAccountList(params.accounts?.readOnlyAccounts ?? []);
1255
+ let instructionData;
1256
+ if (params.buildInstructionData) {
1257
+ const context = createInstructionContext(feePayer, program, sortedReadWrite, sortedReadOnly);
1258
+ const result = params.buildInstructionData(context);
1259
+ instructionData = parseInstructionData(result);
1260
+ } else {
1261
+ instructionData = parseInstructionData(params.instructionData);
1257
1262
  }
1258
- return new _PageRequest({
1259
- pageSize: proto.pageSize,
1260
- pageToken: proto.pageToken,
1261
- orderBy: proto.orderBy
1262
- });
1263
- }
1264
- toProto() {
1265
- return create(PageRequestSchema, {
1266
- pageSize: this.pageSize,
1267
- pageToken: this.pageToken,
1268
- orderBy: this.orderBy
1269
- });
1270
- }
1271
- withParams(params) {
1272
- return new _PageRequest({
1273
- pageSize: params.pageSize ?? this.pageSize,
1274
- pageToken: params.pageToken ?? this.pageToken,
1275
- orderBy: params.orderBy ?? this.orderBy
1263
+ const baseFlags = params.header.flags ?? 0;
1264
+ const flags = params.proofs?.feePayerStateProof ? baseFlags | FLAG_HAS_FEE_PAYER_PROOF : baseFlags;
1265
+ const accounts = sortedReadWrite.length > 0 || sortedReadOnly.length > 0 ? { readWriteAccounts: sortedReadWrite, readOnlyAccounts: sortedReadOnly } : void 0;
1266
+ return new Transaction({
1267
+ feePayer,
1268
+ program,
1269
+ header: {
1270
+ ...params.header,
1271
+ flags
1272
+ },
1273
+ accounts,
1274
+ instructionData,
1275
+ proofs: params.proofs
1276
1276
  });
1277
1277
  }
1278
- };
1279
- var PageResponse = class _PageResponse {
1280
- constructor(params = {}) {
1281
- this.nextPageToken = params.nextPageToken;
1282
- this.totalSize = params.totalSize;
1283
- }
1284
- static fromProto(proto) {
1285
- if (!proto) {
1286
- return void 0;
1278
+ async buildAndSign(params) {
1279
+ if (!params.feePayer.privateKey) {
1280
+ throw new Error("Fee payer private key is required to sign the transaction");
1287
1281
  }
1288
- return new _PageResponse({
1289
- nextPageToken: proto.nextPageToken,
1290
- totalSize: proto.totalSize
1291
- });
1292
- }
1293
- toProto() {
1294
- return create(PageResponseSchema, {
1295
- nextPageToken: this.nextPageToken,
1296
- totalSize: this.totalSize
1297
- });
1298
- }
1299
- hasNextPage() {
1300
- return !!this.nextPageToken;
1282
+ const transaction = this.build(params);
1283
+ const signature = await transaction.sign(params.feePayer.privateKey);
1284
+ const rawTransaction = transaction.toWire();
1285
+ return { transaction, signature, rawTransaction };
1301
1286
  }
1302
1287
  };
1303
1288
 
1289
+ // thru-ts-client-sdk/modules/proofs.ts
1290
+ var proofs_exports = {};
1291
+ __export(proofs_exports, {
1292
+ generateStateProof: () => generateStateProof,
1293
+ getStateRoots: () => getStateRoots
1294
+ });
1295
+
1304
1296
  // thru-ts-client-sdk/domain/proofs/StateProof.ts
1305
1297
  var StateProof = class _StateProof {
1306
1298
  constructor(params) {
1307
- this.proof = copyBytes4(params.proof);
1299
+ this.proof = copyBytes3(params.proof);
1308
1300
  this.slot = params.slot;
1309
1301
  }
1310
1302
  static fromProto(proto) {
@@ -1314,18 +1306,11 @@ var StateProof = class _StateProof {
1314
1306
  });
1315
1307
  }
1316
1308
  };
1317
- function copyBytes4(bytes) {
1309
+ function copyBytes3(bytes) {
1318
1310
  const copy = new Uint8Array(bytes.length);
1319
1311
  copy.set(bytes);
1320
1312
  return copy;
1321
1313
  }
1322
-
1323
- // thru-ts-client-sdk/modules/proofs.ts
1324
- var proofs_exports = {};
1325
- __export(proofs_exports, {
1326
- generateStateProof: () => generateStateProof,
1327
- getStateRoots: () => getStateRoots
1328
- });
1329
1314
  async function generateStateProof(ctx, options) {
1330
1315
  const targetSlot = options.targetSlot ?? 0n;
1331
1316
  const request = create(StateProofRequestSchema, {
@@ -1351,13 +1336,6 @@ async function getStateRoots(ctx, options = {}) {
1351
1336
  }
1352
1337
 
1353
1338
  // thru-ts-client-sdk/modules/accounts.ts
1354
- var accounts_exports = {};
1355
- __export(accounts_exports, {
1356
- createAccount: () => createAccount,
1357
- getAccount: () => getAccount,
1358
- getRawAccount: () => getRawAccount,
1359
- listAccounts: () => listAccounts
1360
- });
1361
1339
  function getAccount(ctx, address, options = {}) {
1362
1340
  const request = create(GetAccountRequestSchema, {
1363
1341
  address: Pubkey.from(address).toProtoPubkey(),
@@ -1424,6 +1402,14 @@ async function createAccount(ctx, options) {
1424
1402
  return transaction;
1425
1403
  }
1426
1404
 
1405
+ // thru-ts-client-sdk/modules/blocks.ts
1406
+ var blocks_exports = {};
1407
+ __export(blocks_exports, {
1408
+ getBlock: () => getBlock,
1409
+ getRawBlock: () => getRawBlock,
1410
+ listBlocks: () => listBlocks
1411
+ });
1412
+
1427
1413
  // thru-ts-client-sdk/domain/transactions/streaming.ts
1428
1414
  function toStreamTransactionUpdate(proto) {
1429
1415
  const signatureBytes = proto.signature?.value ? new Uint8Array(proto.signature.value) : new Uint8Array();
@@ -1452,6 +1438,31 @@ function toTrackTransactionUpdate(response) {
1452
1438
  transaction: void 0
1453
1439
  };
1454
1440
  }
1441
+
1442
+ // thru-ts-client-sdk/domain/transactions/TransactionStatusSnapshot.ts
1443
+ var TransactionStatusSnapshot = class _TransactionStatusSnapshot {
1444
+ constructor(params) {
1445
+ this.signature = copyBytes4(params.signature);
1446
+ this.statusCode = params.consensusStatus;
1447
+ this.status = params.consensusStatus != null ? consensusStatusToString(params.consensusStatus) : void 0;
1448
+ this.executionResult = params.executionResult;
1449
+ }
1450
+ static fromProto(proto) {
1451
+ if (!proto.signature?.value) {
1452
+ throw new Error("TransactionStatus proto missing signature");
1453
+ }
1454
+ return new _TransactionStatusSnapshot({
1455
+ signature: proto.signature.value,
1456
+ consensusStatus: proto.consensusStatus,
1457
+ executionResult: proto.executionResult ? Transaction.executionResultFromProto(proto.executionResult) : void 0
1458
+ });
1459
+ }
1460
+ };
1461
+ function copyBytes4(bytes) {
1462
+ const copy = new Uint8Array(bytes.length);
1463
+ copy.set(bytes);
1464
+ return copy;
1465
+ }
1455
1466
  var BlockFooter = class _BlockFooter {
1456
1467
  constructor(params) {
1457
1468
  this.signature = copyBytes5(params.signature);
@@ -1985,12 +1996,6 @@ function normalizeSeed(value) {
1985
1996
  }
1986
1997
 
1987
1998
  // thru-ts-client-sdk/modules/blocks.ts
1988
- var blocks_exports = {};
1989
- __export(blocks_exports, {
1990
- getBlock: () => getBlock,
1991
- getRawBlock: () => getRawBlock,
1992
- listBlocks: () => listBlocks
1993
- });
1994
1999
  async function getBlock(ctx, selector, options = {}) {
1995
2000
  const request = create(GetBlockRequestSchema, {
1996
2001
  selector: isSlotSelector(selector) ? { case: "slot", value: typeof selector.slot === "bigint" ? selector.slot : BigInt(selector.slot) } : { case: "blockHash", value: toBlockHash(selector.blockHash) },
@@ -2037,21 +2042,6 @@ async function listBlocks(ctx, options = {}) {
2037
2042
  };
2038
2043
  }
2039
2044
 
2040
- // thru-ts-client-sdk/modules/chain.ts
2041
- var chain_exports = {};
2042
- __export(chain_exports, {
2043
- getChainId: () => getChainId,
2044
- getChainInfo: () => getChainInfo
2045
- });
2046
- async function getChainInfo(ctx) {
2047
- const request = create(GetChainInfoRequestSchema);
2048
- return ctx.query.getChainInfo(request, withCallOptions(ctx));
2049
- }
2050
- async function getChainId(ctx) {
2051
- const response = await getChainInfo(ctx);
2052
- return response.chainId;
2053
- }
2054
-
2055
2045
  // thru-ts-client-sdk/modules/consensus.ts
2056
2046
  var consensus_exports = {};
2057
2047
  __export(consensus_exports, {
@@ -2148,6 +2138,13 @@ function normalizeTimestamp(value) {
2148
2138
  throw new Error("timestamp must be a Date, number, or protobuf Timestamp");
2149
2139
  }
2150
2140
 
2141
+ // thru-ts-client-sdk/modules/events.ts
2142
+ var events_exports = {};
2143
+ __export(events_exports, {
2144
+ getEvent: () => getEvent,
2145
+ listEvents: () => listEvents
2146
+ });
2147
+
2151
2148
  // thru-ts-client-sdk/domain/events/ChainEvent.ts
2152
2149
  var ChainEvent = class _ChainEvent {
2153
2150
  constructor(params) {
@@ -2204,13 +2201,6 @@ function normalizeStreamEventId(id) {
2204
2201
  }
2205
2202
  return id;
2206
2203
  }
2207
-
2208
- // thru-ts-client-sdk/modules/events.ts
2209
- var events_exports = {};
2210
- __export(events_exports, {
2211
- getEvent: () => getEvent,
2212
- listEvents: () => listEvents
2213
- });
2214
2204
  function getEvent(ctx, eventId, options = {}) {
2215
2205
  if (!eventId) {
2216
2206
  throw new Error("eventId is required");
@@ -2234,6 +2224,12 @@ function listEvents(ctx, options = {}) {
2234
2224
  }));
2235
2225
  }
2236
2226
 
2227
+ // thru-ts-client-sdk/modules/height.ts
2228
+ var height_exports = {};
2229
+ __export(height_exports, {
2230
+ getBlockHeight: () => getBlockHeight
2231
+ });
2232
+
2237
2233
  // thru-ts-client-sdk/domain/height/HeightSnapshot.ts
2238
2234
  var HeightSnapshot = class _HeightSnapshot {
2239
2235
  constructor(params) {
@@ -2256,17 +2252,26 @@ var HeightSnapshot = class _HeightSnapshot {
2256
2252
  };
2257
2253
  }
2258
2254
  };
2259
-
2260
- // thru-ts-client-sdk/modules/height.ts
2261
- var height_exports = {};
2262
- __export(height_exports, {
2263
- getBlockHeight: () => getBlockHeight
2264
- });
2265
2255
  function getBlockHeight(ctx) {
2266
2256
  const request = create(GetHeightRequestSchema);
2267
2257
  return ctx.query.getHeight(request, withCallOptions(ctx)).then((proto) => HeightSnapshot.fromProto(proto));
2268
2258
  }
2269
2259
 
2260
+ // thru-ts-client-sdk/modules/chain.ts
2261
+ var chain_exports = {};
2262
+ __export(chain_exports, {
2263
+ getChainId: () => getChainId,
2264
+ getChainInfo: () => getChainInfo
2265
+ });
2266
+ async function getChainInfo(ctx) {
2267
+ const request = create(GetChainInfoRequestSchema);
2268
+ return ctx.query.getChainInfo(request, withCallOptions(ctx));
2269
+ }
2270
+ async function getChainId(ctx) {
2271
+ const response = await getChainInfo(ctx);
2272
+ return response.chainId;
2273
+ }
2274
+
2270
2275
  // thru-ts-client-sdk/modules/keys.ts
2271
2276
  var keys_exports = {};
2272
2277
  __export(keys_exports, {
@@ -2326,6 +2331,22 @@ async function listSlotMetrics(ctx, options) {
2326
2331
  });
2327
2332
  return ctx.query.listSlotMetrics(request, withCallOptions(ctx));
2328
2333
  }
2334
+
2335
+ // thru-ts-client-sdk/modules/streaming.ts
2336
+ var streaming_exports = {};
2337
+ __export(streaming_exports, {
2338
+ collectStream: () => collectStream,
2339
+ firstStreamValue: () => firstStreamValue,
2340
+ forEachStreamValue: () => forEachStreamValue,
2341
+ streamAccountUpdates: () => streamAccountUpdates,
2342
+ streamBlocks: () => streamBlocks,
2343
+ streamEvents: () => streamEvents,
2344
+ streamHeight: () => streamHeight,
2345
+ streamNodeRecords: () => streamNodeRecords,
2346
+ streamSlotMetrics: () => streamSlotMetrics,
2347
+ streamTransactions: () => streamTransactions,
2348
+ trackTransaction: () => trackTransaction
2349
+ });
2329
2350
  function copyBytes8(source) {
2330
2351
  const bytes = new Uint8Array(source.length);
2331
2352
  bytes.set(source);
@@ -2691,22 +2712,6 @@ var Filter = class _Filter {
2691
2712
  this.params.set(name, value);
2692
2713
  }
2693
2714
  };
2694
-
2695
- // thru-ts-client-sdk/modules/streaming.ts
2696
- var streaming_exports = {};
2697
- __export(streaming_exports, {
2698
- collectStream: () => collectStream,
2699
- firstStreamValue: () => firstStreamValue,
2700
- forEachStreamValue: () => forEachStreamValue,
2701
- streamAccountUpdates: () => streamAccountUpdates,
2702
- streamBlocks: () => streamBlocks,
2703
- streamEvents: () => streamEvents,
2704
- streamHeight: () => streamHeight,
2705
- streamNodeRecords: () => streamNodeRecords,
2706
- streamSlotMetrics: () => streamSlotMetrics,
2707
- streamTransactions: () => streamTransactions,
2708
- trackTransaction: () => trackTransaction
2709
- });
2710
2715
  function streamBlocks(ctx, options = {}) {
2711
2716
  const request = create(StreamBlocksRequestSchema, {
2712
2717
  startSlot: options.startSlot,
@@ -3172,7 +3177,101 @@ var VersionInfo = class _VersionInfo {
3172
3177
  return this.components[component];
3173
3178
  }
3174
3179
  };
3180
+ function getVersion(ctx) {
3181
+ const request = create(GetVersionRequestSchema);
3182
+ return ctx.query.getVersion(request, withCallOptions(ctx)).then((response) => VersionInfo.fromProto(response));
3183
+ }
3184
+
3185
+ // thru-ts-client-sdk/core/bound-client.ts
3186
+ function bind(ctx, fn) {
3187
+ return ((...args) => fn(ctx, ...args));
3188
+ }
3189
+ function createBoundThruClient(ctx) {
3190
+ return {
3191
+ ctx,
3192
+ blocks: {
3193
+ get: bind(ctx, getBlock),
3194
+ getRaw: bind(ctx, getRawBlock),
3195
+ list: bind(ctx, listBlocks),
3196
+ stream: bind(ctx, streamBlocks),
3197
+ getBlockHeight: bind(ctx, getBlockHeight),
3198
+ streamHeight: bind(ctx, streamHeight)
3199
+ },
3200
+ accounts: {
3201
+ get: bind(ctx, getAccount),
3202
+ getRaw: bind(ctx, getRawAccount),
3203
+ list: bind(ctx, listAccounts),
3204
+ stream: bind(ctx, streamAccountUpdates),
3205
+ create: bind(ctx, createAccount)
3206
+ },
3207
+ transactions: {
3208
+ get: bind(ctx, getTransaction),
3209
+ getRaw: bind(ctx, getRawTransaction),
3210
+ getStatus: bind(ctx, getTransactionStatus),
3211
+ list: bind(ctx, listTransactions),
3212
+ listForAccount: bind(ctx, listTransactionsForAccount),
3213
+ stream: bind(ctx, streamTransactions),
3214
+ build: bind(ctx, buildTransaction),
3215
+ buildAndSign: bind(ctx, buildAndSignTransaction),
3216
+ send: bind(ctx, sendTransaction),
3217
+ batchSend: bind(ctx, batchSendTransactions),
3218
+ sendAndTrack: bind(ctx, sendAndTrackTxn),
3219
+ track: bind(ctx, trackTransaction)
3220
+ },
3221
+ helpers: {
3222
+ createSignature: Signature.from,
3223
+ createPubkey: Pubkey.from,
3224
+ deriveProgramAddress,
3225
+ deriveAddress
3226
+ },
3227
+ keys: {
3228
+ generateKeyPair,
3229
+ fromPrivateKey
3230
+ },
3231
+ events: {
3232
+ get: bind(ctx, getEvent),
3233
+ list: bind(ctx, listEvents),
3234
+ stream: bind(ctx, streamEvents)
3235
+ },
3236
+ slots: {
3237
+ getMetrics: bind(ctx, getSlotMetrics),
3238
+ listMetrics: bind(ctx, listSlotMetrics),
3239
+ streamMetrics: bind(ctx, streamSlotMetrics)
3240
+ },
3241
+ proofs: {
3242
+ generate: bind(ctx, generateStateProof),
3243
+ getStateRoots: bind(ctx, getStateRoots)
3244
+ },
3245
+ node: {
3246
+ getPubkey: bind(ctx, getNodePubkey),
3247
+ getRecords: bind(ctx, getNodeRecords),
3248
+ streamRecords: bind(ctx, streamNodeRecords)
3249
+ },
3250
+ chain: {
3251
+ getChainInfo: bind(ctx, getChainInfo),
3252
+ getChainId: bind(ctx, getChainId)
3253
+ },
3254
+ version: {
3255
+ get: bind(ctx, getVersion)
3256
+ },
3257
+ consensus: {
3258
+ statusToString: consensusStatusToString,
3259
+ versionContext,
3260
+ currentVersionContext,
3261
+ currentOrHistoricalVersionContext,
3262
+ slotVersionContext,
3263
+ timestampVersionContext,
3264
+ seqVersionContext
3265
+ }
3266
+ };
3267
+ }
3268
+
3269
+ // thru-ts-client-sdk/client.ts
3270
+ function createThruClient(config = {}) {
3271
+ const ctx = createThruClientContext(config);
3272
+ return createBoundThruClient(ctx);
3273
+ }
3175
3274
 
3176
- export { Account, Block, ChainEvent, Filter, FilterParamValue, HeightSnapshot, PageRequest, PageResponse, Pubkey, Signature, SignatureDomain, StateProof, Transaction, TransactionBuilder, TransactionStatusSnapshot, VersionInfo, accounts_exports, batchSendTransactions, blocks_exports, buildAndSignTransaction, buildTransaction, chain_exports, collectStream, consensusStatusToString, consensus_exports, createAccount, createThruClientContext, currentOrHistoricalVersionContext, currentVersionContext, deriveAddress, deriveProgramAddress, events_exports, firstStreamValue, forEachStreamValue, fromPrivateKey, generateKeyPair, generateStateProof, getAccount, getBlock, getBlockHeight, getChainId, getChainInfo, getEvent, getNodePubkey, getNodeRecords, getRawAccount, getRawBlock, getRawTransaction, getSlotMetrics, getStateRoots, getTransaction, getTransactionStatus, height_exports, keys_exports, listAccounts, listBlocks, listEvents, listSlotMetrics, listTransactions, listTransactionsForAccount, node_exports, proofs_exports, sendAndTrackTxn, sendTransaction, seqVersionContext, signWithDomain, slotVersionContext, slots_exports, streamAccountUpdates, streamBlocks, streamEvents, streamHeight, streamNodeRecords, streamSlotMetrics, streamTransactions, streaming_exports, timestampVersionContext, trackTransaction, transactions_exports, verifyWithDomain, versionContext, withCallOptions };
3177
- //# sourceMappingURL=chunk-ZMDQDIE5.js.map
3178
- //# sourceMappingURL=chunk-ZMDQDIE5.js.map
3275
+ export { Account, Block, ChainEvent, Filter, FilterParamValue, HeightSnapshot, PageRequest, PageResponse, Pubkey, Signature, SignatureDomain, StateProof, Transaction, TransactionBuilder, TransactionStatusSnapshot, VersionInfo, accounts_exports, blocks_exports, chain_exports, collectStream, consensus_exports, createThruClient, deriveAddress, deriveProgramAddress, events_exports, firstStreamValue, forEachStreamValue, height_exports, keys_exports, node_exports, proofs_exports, signWithDomain, slots_exports, streaming_exports, transactions_exports, verifyWithDomain };
3276
+ //# sourceMappingURL=chunk-7YBVSFCS.js.map
3277
+ //# sourceMappingURL=chunk-7YBVSFCS.js.map