@thru/thru-sdk 0.2.7 → 0.2.9

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;
@@ -684,628 +1009,294 @@ var Transaction = class _Transaction {
684
1009
  }
685
1010
  if (includeSignature) {
686
1011
  if (this.signature) {
687
- result.set(this.signature.toBytes(), offset);
688
- }
689
- }
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
- errorProgramAccIdx: proto.errorProgramAccIdx ?? 0
792
- };
793
- }
794
- };
795
- function appendAccountList(target, start, accounts) {
796
- let offset = start;
797
- for (const account of accounts) {
798
- target.set(account, offset);
799
- offset += PUBKEY_SIZE2;
800
- }
801
- return offset;
802
- }
803
- function ensureUint16(value) {
804
- if (!Number.isInteger(value) || value < 0 || value > 65535) {
805
- throw new Error("Value must fit within uint16 range");
806
- }
807
- return value;
808
- }
809
- function ensureUint32(value) {
810
- if (!Number.isInteger(value) || value < 0 || value > 4294967295) {
811
- throw new Error("Value must fit within uint32 range");
812
- }
813
- return value;
814
- }
815
- function ensureBigUint64(value) {
816
- if (value < 0n || value > 0xffffffffffffffffn) {
817
- throw new Error("Value must fit within uint64 range");
818
- }
819
- return value;
820
- }
821
- function countSetBits(bytes) {
822
- let total = 0;
823
- for (let i = 0; i < bytes.length; i++) {
824
- total += BYTE_POPCOUNT[bytes[i]];
825
- }
826
- return total;
827
- }
828
- function hasNonZeroBytes(value) {
829
- for (let i = 0; i < value.length; i++) {
830
- if (value[i] !== 0) {
831
- return true;
832
- }
833
- }
834
- return false;
835
- }
836
- var ACCOUNT_LIMIT = 1024;
837
- function normalizeAccountList(accounts) {
838
- if (accounts.length === 0) {
839
- return [];
840
- }
841
- if (accounts.length > ACCOUNT_LIMIT) {
842
- throw new Error(`Too many accounts provided: ${accounts.length} (max ${ACCOUNT_LIMIT})`);
843
- }
844
- const deduped = dedupeAccountList(accounts);
845
- return deduped;
846
- }
847
- function dedupeAccountList(accounts) {
848
- const pubkeys = accounts.map(Pubkey.from).map((pubkey) => pubkey.toBytes());
849
- const seen = /* @__PURE__ */ new Map();
850
- for (const pubkey of pubkeys) {
851
- if (pubkey.length !== 32) {
852
- throw new Error("Account addresses must contain 32 bytes");
853
- }
854
- const key = toHex(pubkey);
855
- if (!seen.has(key)) {
856
- seen.set(key, pubkey);
857
- }
858
- }
859
- return Array.from(seen.values()).sort(compareAccounts);
860
- }
861
- function compareAccounts(a, b) {
862
- for (let i = 0; i < 32; i++) {
863
- if (a[i] !== b[i]) {
864
- return a[i] - b[i];
865
- }
866
- }
867
- return 0;
868
- }
869
- function toHex(bytes) {
870
- let result = "";
871
- for (let i = 0; i < bytes.length; i++) {
872
- const hex = bytes[i].toString(16).padStart(2, "0");
873
- result += hex;
874
- }
875
- return result;
876
- }
877
- function parseInstructionData(value) {
878
- if (value === void 0) {
879
- return void 0;
880
- }
881
- if (value instanceof Uint8Array) {
882
- return new Uint8Array(value);
883
- }
884
- if (typeof value === "string") {
885
- if (value.length === 0) {
886
- return new Uint8Array();
887
- }
888
- if (isHexString(value)) {
889
- return hexToBytes(value);
1012
+ result.set(this.signature.toBytes(), offset);
1013
+ }
890
1014
  }
1015
+ return result;
891
1016
  }
892
- throw new Error("Instruction data must be provided as hex string or Uint8Array");
893
- }
894
- function createInstructionContext(feePayer, program, sortedReadWrite, sortedReadOnly) {
895
- const accounts = [
896
- feePayer,
897
- program,
898
- ...sortedReadWrite.map((bytes) => Pubkey.from(bytes)),
899
- ...sortedReadOnly.map((bytes) => Pubkey.from(bytes))
900
- ];
901
- const indexMap = /* @__PURE__ */ new Map();
902
- for (let i = 0; i < accounts.length; i++) {
903
- const key = toHex(accounts[i].toBytes());
904
- if (!indexMap.has(key)) {
905
- indexMap.set(key, i);
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;
906
1024
  }
907
- }
908
- return {
909
- accounts,
910
- getAccountIndex: (pubkey) => {
911
- const bytes = Pubkey.from(pubkey).toBytes();
912
- const key = toHex(bytes);
913
- const index = indexMap.get(key);
914
- if (index === void 0) {
915
- throw new Error(`Account ${key} not found in transaction accounts`);
916
- }
917
- return index;
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;
918
1030
  }
919
- };
920
- }
921
-
922
- // thru-ts-client-sdk/domain/transactions/TransactionBuilder.ts
923
- var FLAG_HAS_FEE_PAYER_PROOF = 1 << 0;
924
- var TransactionBuilder = class {
925
- build(params) {
926
- const feePayer = Pubkey.from(params.feePayer.publicKey);
927
- const program = Pubkey.from(params.program);
928
- const sortedReadWrite = normalizeAccountList(params.accounts?.readWriteAccounts ?? []);
929
- const sortedReadOnly = normalizeAccountList(params.accounts?.readOnlyAccounts ?? []);
930
1031
  let instructionData;
931
- if (params.buildInstructionData) {
932
- const context = createInstructionContext(feePayer, program, sortedReadWrite, sortedReadOnly);
933
- const result = params.buildInstructionData(context);
934
- instructionData = parseInstructionData(result);
935
- } else {
936
- instructionData = parseInstructionData(params.instructionData);
1032
+ if (instructionDataSize > 0) {
1033
+ this.ensureAvailable(body.length, offset, instructionDataSize, "instruction data");
1034
+ instructionData = body.slice(offset, offset + instructionDataSize);
1035
+ offset += instructionDataSize;
937
1036
  }
938
- const baseFlags = params.header.flags ?? 0;
939
- const flags = params.proofs?.feePayerStateProof ? baseFlags | FLAG_HAS_FEE_PAYER_PROOF : baseFlags;
940
- const accounts = sortedReadWrite.length > 0 || sortedReadOnly.length > 0 ? { readWriteAccounts: sortedReadWrite, readOnlyAccounts: sortedReadOnly } : void 0;
941
- return new Transaction({
942
- feePayer,
943
- program,
944
- header: {
945
- ...params.header,
946
- flags
947
- },
948
- 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;
1047
+ }
1048
+ }
1049
+ if (offset !== body.length) {
1050
+ throw new Error(
1051
+ `Transaction body has trailing bytes: expected ${offset} bytes but found ${body.length}`
1052
+ );
1053
+ }
1054
+ return {
1055
+ readWriteAccounts,
1056
+ readOnlyAccounts,
949
1057
  instructionData,
950
- proofs: params.proofs
951
- });
1058
+ feePayerStateProof,
1059
+ feePayerAccountMetaRaw
1060
+ };
952
1061
  }
953
- async buildAndSign(params) {
954
- if (!params.feePayer.privateKey) {
955
- 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}`);
956
1065
  }
957
- const transaction = this.build(params);
958
- const signature = await transaction.sign(params.feePayer.privateKey);
959
- const rawTransaction = transaction.toWire();
960
- return { transaction, signature, rawTransaction };
961
- }
962
- };
963
- function isSlotSelector(selector) {
964
- return "slot" in selector;
965
- }
966
- function mergeTransactionHeader(defaults, overrides) {
967
- if (!overrides) {
968
- return defaults;
969
- }
970
- const sanitized = Object.fromEntries(
971
- Object.entries(overrides).filter(([, value]) => value !== void 0)
972
- );
973
- return {
974
- ...defaults,
975
- ...sanitized
976
- };
977
- }
978
- function timestampToNanoseconds(timestamp) {
979
- if (!timestamp) {
980
- return 0n;
981
- }
982
- const seconds = BigInt(timestamp.seconds ?? 0);
983
- const nanos = BigInt(timestamp.nanos ?? 0);
984
- return seconds * 1000000000n + nanos;
985
- }
986
- function nanosecondsToTimestamp(ns) {
987
- const seconds = ns / 1000000000n;
988
- const nanos = Number(ns % 1000000000n);
989
- return { seconds, nanos };
990
- }
991
- function consensusStatusToString(status) {
992
- const lookup = ConsensusStatus;
993
- return lookup[status] ?? `UNKNOWN(${status})`;
994
- }
995
-
996
- // thru-ts-client-sdk/domain/transactions/TransactionStatusSnapshot.ts
997
- var TransactionStatusSnapshot = class _TransactionStatusSnapshot {
998
- constructor(params) {
999
- this.signature = copyBytes3(params.signature);
1000
- this.statusCode = params.consensusStatus;
1001
- this.status = params.consensusStatus != null ? consensusStatusToString(params.consensusStatus) : void 0;
1002
- this.executionResult = params.executionResult;
1003
1066
  }
1004
- static fromProto(proto) {
1005
- if (!proto.signature?.value) {
1006
- 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");
1007
1070
  }
1008
- return new _TransactionStatusSnapshot({
1009
- signature: proto.signature.value,
1010
- consensusStatus: proto.consensusStatus,
1011
- executionResult: proto.executionResult ? Transaction.executionResultFromProto(proto.executionResult) : void 0
1012
- });
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
+ };
1013
1118
  }
1014
1119
  };
1015
- function copyBytes3(bytes) {
1016
- const copy = new Uint8Array(bytes.length);
1017
- copy.set(bytes);
1018
- return copy;
1019
- }
1020
- var DEFAULT_HOST = "https://grpc-web.alphanet.thruput.org";
1021
- var DEFAULT_ACCOUNT_VIEW = AccountView.FULL;
1022
- var DEFAULT_BLOCK_VIEW = BlockView.FULL;
1023
- var DEFAULT_TRANSACTION_VIEW = TransactionView.FULL;
1024
- var DEFAULT_MIN_CONSENSUS = ConsensusStatus.UNSPECIFIED;
1025
- var DEFAULT_VERSION_CONTEXT = create(VersionContextSchema, {
1026
- version: {
1027
- case: "current",
1028
- 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;
1029
1125
  }
1030
- });
1031
- var DEFAULT_FEE = 1n;
1032
- var DEFAULT_COMPUTE_UNITS = 3e8;
1033
- var DEFAULT_STATE_UNITS = 1e4;
1034
- var DEFAULT_MEMORY_UNITS = 1e4;
1035
- var DEFAULT_EXPIRY_AFTER = 100;
1036
- function createThruClientContext(config = {}) {
1037
- const transportOptions = config.transportOptions ?? {};
1038
- const { baseUrl: optionsBaseUrl, interceptors: optionInterceptors, ...restTransportOptions } = transportOptions;
1039
- const baseUrl = config.baseUrl ?? optionsBaseUrl ?? DEFAULT_HOST;
1040
- const mergedInterceptors = [
1041
- ...optionInterceptors ?? [],
1042
- ...config.interceptors ?? []
1043
- ];
1044
- const transport = config.transport ?? createGrpcWebTransport({
1045
- baseUrl,
1046
- ...restTransportOptions,
1047
- interceptors: mergedInterceptors.length > 0 ? mergedInterceptors : void 0
1048
- });
1049
- return {
1050
- baseUrl,
1051
- transport,
1052
- query: createClient(QueryService, transport),
1053
- command: createClient(CommandService, transport),
1054
- streaming: createClient(StreamingService, transport),
1055
- callOptions: config.callOptions
1056
- };
1057
- }
1058
- function withCallOptions(ctx, overrides) {
1059
- return mergeCallOptions(ctx.callOptions, overrides);
1126
+ return offset;
1060
1127
  }
1061
- function mergeCallOptions(defaults, overrides) {
1062
- if (!defaults) {
1063
- 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");
1064
1131
  }
1065
- if (!overrides) {
1066
- 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");
1067
1137
  }
1068
- return {
1069
- ...defaults,
1070
- ...overrides,
1071
- headers: mergeHeaders(defaults.headers, overrides.headers),
1072
- contextValues: overrides.contextValues ?? defaults.contextValues,
1073
- onHeader: overrides.onHeader ?? defaults.onHeader,
1074
- onTrailer: overrides.onTrailer ?? defaults.onTrailer
1075
- };
1138
+ return value;
1076
1139
  }
1077
- function mergeHeaders(a, b) {
1078
- const entries = [];
1079
- const add = (init) => {
1080
- if (!init) {
1081
- return;
1082
- }
1083
- if (init instanceof Headers) {
1084
- init.forEach((value, key) => {
1085
- entries.push([key, value]);
1086
- });
1087
- return;
1088
- }
1089
- if (Array.isArray(init)) {
1090
- for (const [key, value] of init) {
1091
- entries.push([key, value]);
1092
- }
1093
- return;
1094
- }
1095
- for (const [key, value] of Object.entries(init)) {
1096
- if (value !== void 0) {
1097
- entries.push([key, String(value)]);
1098
- }
1099
- }
1100
- };
1101
- add(a);
1102
- add(b);
1103
- if (entries.length === 0) {
1104
- return void 0;
1140
+ function ensureBigUint64(value) {
1141
+ if (value < 0n || value > 0xffffffffffffffffn) {
1142
+ throw new Error("Value must fit within uint64 range");
1105
1143
  }
1106
- return entries;
1144
+ return value;
1107
1145
  }
1108
-
1109
- // thru-ts-client-sdk/domain/accounts/Account.ts
1110
- var AccountFlags = class _AccountFlags {
1111
- constructor(flags) {
1112
- this.isProgram = flags?.isProgram ?? false;
1113
- this.isPrivileged = flags?.isPrivileged ?? false;
1114
- this.isUncompressable = flags?.isUncompressable ?? false;
1115
- this.isEphemeral = flags?.isEphemeral ?? false;
1116
- this.isDeleted = flags?.isDeleted ?? false;
1117
- this.isNew = flags?.isNew ?? false;
1118
- 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]];
1119
1150
  }
1120
- static fromProto(flags) {
1121
- if (!flags) {
1122
- 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;
1123
1157
  }
1124
- return new _AccountFlags({
1125
- isProgram: flags.isProgram,
1126
- isPrivileged: flags.isPrivileged,
1127
- isUncompressable: flags.isUncompressable,
1128
- isEphemeral: flags.isEphemeral,
1129
- isDeleted: flags.isDeleted,
1130
- isNew: flags.isNew,
1131
- isCompressed: flags.isCompressed
1132
- });
1133
- }
1134
- };
1135
- var AccountMeta = class _AccountMeta {
1136
- constructor(params) {
1137
- this.version = params.version;
1138
- this.flags = params.flags ?? new AccountFlags();
1139
- this.dataSize = params.dataSize;
1140
- this.seq = params.seq;
1141
- this.owner = params.owner;
1142
- this.balance = params.balance;
1143
- this.nonce = params.nonce;
1144
1158
  }
1145
- static fromProto(meta) {
1146
- if (!meta) {
1147
- return void 0;
1148
- }
1149
- return new _AccountMeta({
1150
- version: meta.version,
1151
- flags: AccountFlags.fromProto(meta.flags),
1152
- dataSize: meta.dataSize,
1153
- seq: meta.seq ?? 0n,
1154
- owner: meta.owner ? Pubkey.fromProtoPubkey(meta.owner) : void 0,
1155
- balance: meta.balance ?? 0n,
1156
- nonce: meta.nonce
1157
- });
1159
+ return false;
1160
+ }
1161
+ var ACCOUNT_LIMIT = 1024;
1162
+ function normalizeAccountList(accounts) {
1163
+ if (accounts.length === 0) {
1164
+ return [];
1158
1165
  }
1159
- };
1160
- var AccountData = class _AccountData {
1161
- constructor(params) {
1162
- this.data = params.data ? new Uint8Array(params.data) : void 0;
1163
- this.compressed = params.compressed ?? false;
1164
- this.compressionAlgorithm = params.compressionAlgorithm;
1166
+ if (accounts.length > ACCOUNT_LIMIT) {
1167
+ throw new Error(`Too many accounts provided: ${accounts.length} (max ${ACCOUNT_LIMIT})`);
1165
1168
  }
1166
- static fromProto(data) {
1167
- if (!data) {
1168
- 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);
1169
1182
  }
1170
- return new _AccountData({
1171
- data: data.data ? new Uint8Array(data.data) : void 0,
1172
- compressed: data.compressed ?? false,
1173
- compressionAlgorithm: data.compressionAlgorithm
1174
- });
1175
- }
1176
- };
1177
- var Account = class _Account {
1178
- constructor(params) {
1179
- this.address = params.address;
1180
- this.meta = params.meta;
1181
- this.data = params.data;
1182
- this.versionContext = params.versionContext;
1183
- this.consensusStatus = params.consensusStatus;
1184
1183
  }
1185
- static fromProto(proto) {
1186
- if (!proto.address) {
1187
- 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];
1188
1190
  }
1189
- return new _Account({
1190
- address: Pubkey.fromProtoPubkey(proto.address),
1191
- meta: AccountMeta.fromProto(proto.meta),
1192
- data: AccountData.fromProto(proto.data ?? void 0),
1193
- versionContext: convertVersionContext(proto.versionContext),
1194
- consensusStatus: proto.consensusStatus
1195
- });
1196
1191
  }
1197
- };
1198
- function convertVersionContext(meta) {
1199
- if (!meta) {
1200
- 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;
1201
1199
  }
1202
- return {
1203
- slot: meta.slot,
1204
- blockTimestampNs: timestampToNanoseconds(meta.blockTimestamp)
1205
- };
1200
+ return result;
1206
1201
  }
1207
-
1208
- // thru-ts-client-sdk/domain/accounts/streaming.ts
1209
- function toStreamAccountUpdate(response) {
1210
- if (!response.message) {
1202
+ function parseInstructionData(value) {
1203
+ if (value === void 0) {
1211
1204
  return void 0;
1212
1205
  }
1213
- if (response.message.case === "snapshot") {
1214
- return {
1215
- kind: "snapshot",
1216
- snapshot: { account: Account.fromProto(response.message.value) }
1217
- };
1206
+ if (value instanceof Uint8Array) {
1207
+ return new Uint8Array(value);
1218
1208
  }
1219
- if (response.message.case === "update") {
1220
- return {
1221
- kind: "update",
1222
- update: fromProtoUpdate(response.message.value)
1223
- };
1209
+ if (typeof value === "string") {
1210
+ if (value.length === 0) {
1211
+ return new Uint8Array();
1212
+ }
1213
+ if (isHexString(value)) {
1214
+ return hexToBytes(value);
1215
+ }
1224
1216
  }
1225
- return void 0;
1226
- }
1227
- function fromProtoUpdate(update) {
1228
- return {
1229
- slot: update.slot,
1230
- meta: AccountMeta.fromProto(update.meta),
1231
- page: update.page ? fromProtoPage(update.page) : void 0,
1232
- deleted: update.delete ?? false
1233
- };
1217
+ throw new Error("Instruction data must be provided as hex string or Uint8Array");
1234
1218
  }
1235
- 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
+ }
1236
1233
  return {
1237
- pageIndex: page.pageIdx,
1238
- pageSize: page.pageSize,
1239
- data: new Uint8Array(page.pageData),
1240
- compressed: page.compressed ?? void 0,
1241
- compressionAlgorithm: page.compressionAlgorithm
1242
- };
1243
- }
1244
- var PageRequest = class _PageRequest {
1245
- constructor(params = {}) {
1246
- if (params.pageSize !== void 0) {
1247
- if (!Number.isInteger(params.pageSize) || params.pageSize < 0) {
1248
- 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`);
1249
1241
  }
1242
+ return index;
1250
1243
  }
1251
- this.pageSize = params.pageSize;
1252
- this.pageToken = params.pageToken;
1253
- this.orderBy = params.orderBy;
1254
- }
1255
- static fromProto(proto) {
1256
- if (!proto) {
1257
- 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);
1258
1262
  }
1259
- return new _PageRequest({
1260
- pageSize: proto.pageSize,
1261
- pageToken: proto.pageToken,
1262
- orderBy: proto.orderBy
1263
- });
1264
- }
1265
- toProto() {
1266
- return create(PageRequestSchema, {
1267
- pageSize: this.pageSize,
1268
- pageToken: this.pageToken,
1269
- orderBy: this.orderBy
1270
- });
1271
- }
1272
- withParams(params) {
1273
- return new _PageRequest({
1274
- pageSize: params.pageSize ?? this.pageSize,
1275
- pageToken: params.pageToken ?? this.pageToken,
1276
- 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
1277
1276
  });
1278
1277
  }
1279
- };
1280
- var PageResponse = class _PageResponse {
1281
- constructor(params = {}) {
1282
- this.nextPageToken = params.nextPageToken;
1283
- this.totalSize = params.totalSize;
1284
- }
1285
- static fromProto(proto) {
1286
- if (!proto) {
1287
- 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");
1288
1281
  }
1289
- return new _PageResponse({
1290
- nextPageToken: proto.nextPageToken,
1291
- totalSize: proto.totalSize
1292
- });
1293
- }
1294
- toProto() {
1295
- return create(PageResponseSchema, {
1296
- nextPageToken: this.nextPageToken,
1297
- totalSize: this.totalSize
1298
- });
1299
- }
1300
- hasNextPage() {
1301
- 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 };
1302
1286
  }
1303
1287
  };
1304
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
+
1305
1296
  // thru-ts-client-sdk/domain/proofs/StateProof.ts
1306
1297
  var StateProof = class _StateProof {
1307
1298
  constructor(params) {
1308
- this.proof = copyBytes4(params.proof);
1299
+ this.proof = copyBytes3(params.proof);
1309
1300
  this.slot = params.slot;
1310
1301
  }
1311
1302
  static fromProto(proto) {
@@ -1315,18 +1306,11 @@ var StateProof = class _StateProof {
1315
1306
  });
1316
1307
  }
1317
1308
  };
1318
- function copyBytes4(bytes) {
1309
+ function copyBytes3(bytes) {
1319
1310
  const copy = new Uint8Array(bytes.length);
1320
1311
  copy.set(bytes);
1321
1312
  return copy;
1322
1313
  }
1323
-
1324
- // thru-ts-client-sdk/modules/proofs.ts
1325
- var proofs_exports = {};
1326
- __export(proofs_exports, {
1327
- generateStateProof: () => generateStateProof,
1328
- getStateRoots: () => getStateRoots
1329
- });
1330
1314
  async function generateStateProof(ctx, options) {
1331
1315
  const targetSlot = options.targetSlot ?? 0n;
1332
1316
  const request = create(StateProofRequestSchema, {
@@ -1352,13 +1336,6 @@ async function getStateRoots(ctx, options = {}) {
1352
1336
  }
1353
1337
 
1354
1338
  // thru-ts-client-sdk/modules/accounts.ts
1355
- var accounts_exports = {};
1356
- __export(accounts_exports, {
1357
- createAccount: () => createAccount,
1358
- getAccount: () => getAccount,
1359
- getRawAccount: () => getRawAccount,
1360
- listAccounts: () => listAccounts
1361
- });
1362
1339
  function getAccount(ctx, address, options = {}) {
1363
1340
  const request = create(GetAccountRequestSchema, {
1364
1341
  address: Pubkey.from(address).toProtoPubkey(),
@@ -1425,6 +1402,14 @@ async function createAccount(ctx, options) {
1425
1402
  return transaction;
1426
1403
  }
1427
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
+
1428
1413
  // thru-ts-client-sdk/domain/transactions/streaming.ts
1429
1414
  function toStreamTransactionUpdate(proto) {
1430
1415
  const signatureBytes = proto.signature?.value ? new Uint8Array(proto.signature.value) : new Uint8Array();
@@ -1453,6 +1438,31 @@ function toTrackTransactionUpdate(response) {
1453
1438
  transaction: void 0
1454
1439
  };
1455
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
+ }
1456
1466
  var BlockFooter = class _BlockFooter {
1457
1467
  constructor(params) {
1458
1468
  this.signature = copyBytes5(params.signature);
@@ -1986,12 +1996,6 @@ function normalizeSeed(value) {
1986
1996
  }
1987
1997
 
1988
1998
  // thru-ts-client-sdk/modules/blocks.ts
1989
- var blocks_exports = {};
1990
- __export(blocks_exports, {
1991
- getBlock: () => getBlock,
1992
- getRawBlock: () => getRawBlock,
1993
- listBlocks: () => listBlocks
1994
- });
1995
1999
  async function getBlock(ctx, selector, options = {}) {
1996
2000
  const request = create(GetBlockRequestSchema, {
1997
2001
  selector: isSlotSelector(selector) ? { case: "slot", value: typeof selector.slot === "bigint" ? selector.slot : BigInt(selector.slot) } : { case: "blockHash", value: toBlockHash(selector.blockHash) },
@@ -2038,21 +2042,6 @@ async function listBlocks(ctx, options = {}) {
2038
2042
  };
2039
2043
  }
2040
2044
 
2041
- // thru-ts-client-sdk/modules/chain.ts
2042
- var chain_exports = {};
2043
- __export(chain_exports, {
2044
- getChainId: () => getChainId,
2045
- getChainInfo: () => getChainInfo
2046
- });
2047
- async function getChainInfo(ctx) {
2048
- const request = create(GetChainInfoRequestSchema);
2049
- return ctx.query.getChainInfo(request, withCallOptions(ctx));
2050
- }
2051
- async function getChainId(ctx) {
2052
- const response = await getChainInfo(ctx);
2053
- return response.chainId;
2054
- }
2055
-
2056
2045
  // thru-ts-client-sdk/modules/consensus.ts
2057
2046
  var consensus_exports = {};
2058
2047
  __export(consensus_exports, {
@@ -2149,6 +2138,13 @@ function normalizeTimestamp(value) {
2149
2138
  throw new Error("timestamp must be a Date, number, or protobuf Timestamp");
2150
2139
  }
2151
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
+
2152
2148
  // thru-ts-client-sdk/domain/events/ChainEvent.ts
2153
2149
  var ChainEvent = class _ChainEvent {
2154
2150
  constructor(params) {
@@ -2205,13 +2201,6 @@ function normalizeStreamEventId(id) {
2205
2201
  }
2206
2202
  return id;
2207
2203
  }
2208
-
2209
- // thru-ts-client-sdk/modules/events.ts
2210
- var events_exports = {};
2211
- __export(events_exports, {
2212
- getEvent: () => getEvent,
2213
- listEvents: () => listEvents
2214
- });
2215
2204
  function getEvent(ctx, eventId, options = {}) {
2216
2205
  if (!eventId) {
2217
2206
  throw new Error("eventId is required");
@@ -2235,6 +2224,12 @@ function listEvents(ctx, options = {}) {
2235
2224
  }));
2236
2225
  }
2237
2226
 
2227
+ // thru-ts-client-sdk/modules/height.ts
2228
+ var height_exports = {};
2229
+ __export(height_exports, {
2230
+ getBlockHeight: () => getBlockHeight
2231
+ });
2232
+
2238
2233
  // thru-ts-client-sdk/domain/height/HeightSnapshot.ts
2239
2234
  var HeightSnapshot = class _HeightSnapshot {
2240
2235
  constructor(params) {
@@ -2257,17 +2252,26 @@ var HeightSnapshot = class _HeightSnapshot {
2257
2252
  };
2258
2253
  }
2259
2254
  };
2260
-
2261
- // thru-ts-client-sdk/modules/height.ts
2262
- var height_exports = {};
2263
- __export(height_exports, {
2264
- getBlockHeight: () => getBlockHeight
2265
- });
2266
2255
  function getBlockHeight(ctx) {
2267
2256
  const request = create(GetHeightRequestSchema);
2268
2257
  return ctx.query.getHeight(request, withCallOptions(ctx)).then((proto) => HeightSnapshot.fromProto(proto));
2269
2258
  }
2270
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
+
2271
2275
  // thru-ts-client-sdk/modules/keys.ts
2272
2276
  var keys_exports = {};
2273
2277
  __export(keys_exports, {
@@ -2327,6 +2331,22 @@ async function listSlotMetrics(ctx, options) {
2327
2331
  });
2328
2332
  return ctx.query.listSlotMetrics(request, withCallOptions(ctx));
2329
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
+ });
2330
2350
  function copyBytes8(source) {
2331
2351
  const bytes = new Uint8Array(source.length);
2332
2352
  bytes.set(source);
@@ -2692,22 +2712,6 @@ var Filter = class _Filter {
2692
2712
  this.params.set(name, value);
2693
2713
  }
2694
2714
  };
2695
-
2696
- // thru-ts-client-sdk/modules/streaming.ts
2697
- var streaming_exports = {};
2698
- __export(streaming_exports, {
2699
- collectStream: () => collectStream,
2700
- firstStreamValue: () => firstStreamValue,
2701
- forEachStreamValue: () => forEachStreamValue,
2702
- streamAccountUpdates: () => streamAccountUpdates,
2703
- streamBlocks: () => streamBlocks,
2704
- streamEvents: () => streamEvents,
2705
- streamHeight: () => streamHeight,
2706
- streamNodeRecords: () => streamNodeRecords,
2707
- streamSlotMetrics: () => streamSlotMetrics,
2708
- streamTransactions: () => streamTransactions,
2709
- trackTransaction: () => trackTransaction
2710
- });
2711
2715
  function streamBlocks(ctx, options = {}) {
2712
2716
  const request = create(StreamBlocksRequestSchema, {
2713
2717
  startSlot: options.startSlot,
@@ -3173,7 +3177,101 @@ var VersionInfo = class _VersionInfo {
3173
3177
  return this.components[component];
3174
3178
  }
3175
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
+ }
3176
3274
 
3177
- 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 };
3178
- //# sourceMappingURL=chunk-DSEDHQB6.js.map
3179
- //# sourceMappingURL=chunk-DSEDHQB6.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