@thru/thru-sdk 0.1.19 → 0.1.21

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.
Files changed (88) hide show
  1. package/README.md +19 -0
  2. package/dist/{chunk-PH7P5EEU.js → chunk-SHMREHP5.js} +13 -9
  3. package/dist/chunk-SHMREHP5.js.map +1 -0
  4. package/dist/client.d.ts +2 -1
  5. package/dist/client.js +3 -2
  6. package/dist/client.js.map +1 -1
  7. package/dist/metafile-esm.json +1 -1
  8. package/dist/sdk.d.ts +3 -3
  9. package/dist/sdk.js +1 -1
  10. package/dist/{transactions-BzD9hYlc.d.ts → transactions-CLezIeXO.d.ts} +20 -18
  11. package/package.json +7 -3
  12. package/buf.gen.yaml +0 -12
  13. package/buf.lock +0 -9
  14. package/buf.yaml +0 -15
  15. package/dist/chunk-PH7P5EEU.js.map +0 -1
  16. package/proto/thru/common/v1/consensus.proto +0 -73
  17. package/proto/thru/common/v1/errors.proto +0 -65
  18. package/proto/thru/common/v1/filters.proto +0 -60
  19. package/proto/thru/common/v1/pagination.proto +0 -45
  20. package/proto/thru/core/v1/account.proto +0 -137
  21. package/proto/thru/core/v1/block.proto +0 -80
  22. package/proto/thru/core/v1/state.proto +0 -35
  23. package/proto/thru/core/v1/transaction.proto +0 -136
  24. package/proto/thru/core/v1/types.proto +0 -50
  25. package/proto/thru/services/v1/command_service.proto +0 -70
  26. package/proto/thru/services/v1/query_service.proto +0 -344
  27. package/proto/thru/services/v1/streaming_service.proto +0 -126
  28. package/thru-ts-client-sdk/__tests__/helpers/test-utils.ts +0 -228
  29. package/thru-ts-client-sdk/client.ts +0 -10
  30. package/thru-ts-client-sdk/core/__tests__/bound-client.test.ts +0 -354
  31. package/thru-ts-client-sdk/core/__tests__/client.test.ts +0 -53
  32. package/thru-ts-client-sdk/core/bound-client.ts +0 -156
  33. package/thru-ts-client-sdk/core/client.ts +0 -38
  34. package/thru-ts-client-sdk/defaults.ts +0 -26
  35. package/thru-ts-client-sdk/modules/__tests__/accounts.test.ts +0 -406
  36. package/thru-ts-client-sdk/modules/__tests__/blocks.test.ts +0 -199
  37. package/thru-ts-client-sdk/modules/__tests__/events.test.ts +0 -74
  38. package/thru-ts-client-sdk/modules/__tests__/height.test.ts +0 -39
  39. package/thru-ts-client-sdk/modules/__tests__/helpers.test.ts +0 -288
  40. package/thru-ts-client-sdk/modules/__tests__/keys.test.ts +0 -55
  41. package/thru-ts-client-sdk/modules/__tests__/proofs.test.ts +0 -119
  42. package/thru-ts-client-sdk/modules/__tests__/streaming.test.ts +0 -152
  43. package/thru-ts-client-sdk/modules/__tests__/transactions.test.ts +0 -730
  44. package/thru-ts-client-sdk/modules/__tests__/version.test.ts +0 -40
  45. package/thru-ts-client-sdk/modules/accounts.ts +0 -141
  46. package/thru-ts-client-sdk/modules/blocks.ts +0 -75
  47. package/thru-ts-client-sdk/modules/events.ts +0 -20
  48. package/thru-ts-client-sdk/modules/height.ts +0 -9
  49. package/thru-ts-client-sdk/modules/helpers.ts +0 -131
  50. package/thru-ts-client-sdk/modules/keys.ts +0 -29
  51. package/thru-ts-client-sdk/modules/proofs.ts +0 -20
  52. package/thru-ts-client-sdk/modules/streaming.ts +0 -133
  53. package/thru-ts-client-sdk/modules/transactions.ts +0 -374
  54. package/thru-ts-client-sdk/modules/version.ts +0 -10
  55. package/thru-ts-client-sdk/proto/buf/validate/validate_pb.ts +0 -4761
  56. package/thru-ts-client-sdk/proto/google/api/annotations_pb.ts +0 -39
  57. package/thru-ts-client-sdk/proto/google/api/client_pb.ts +0 -953
  58. package/thru-ts-client-sdk/proto/google/api/field_behavior_pb.ts +0 -157
  59. package/thru-ts-client-sdk/proto/google/api/http_pb.ts +0 -474
  60. package/thru-ts-client-sdk/proto/google/api/launch_stage_pb.ts +0 -118
  61. package/thru-ts-client-sdk/proto/thru/common/v1/consensus_pb.ts +0 -162
  62. package/thru-ts-client-sdk/proto/thru/common/v1/errors_pb.ts +0 -129
  63. package/thru-ts-client-sdk/proto/thru/common/v1/filters_pb.ts +0 -129
  64. package/thru-ts-client-sdk/proto/thru/common/v1/pagination_pb.ts +0 -79
  65. package/thru-ts-client-sdk/proto/thru/core/v1/account_pb.ts +0 -359
  66. package/thru-ts-client-sdk/proto/thru/core/v1/block_pb.ts +0 -259
  67. package/thru-ts-client-sdk/proto/thru/core/v1/state_pb.ts +0 -103
  68. package/thru-ts-client-sdk/proto/thru/core/v1/transaction_pb.ts +0 -528
  69. package/thru-ts-client-sdk/proto/thru/core/v1/types_pb.ts +0 -100
  70. package/thru-ts-client-sdk/proto/thru/services/v1/command_service_pb.ts +0 -146
  71. package/thru-ts-client-sdk/proto/thru/services/v1/query_service_pb.ts +0 -819
  72. package/thru-ts-client-sdk/proto/thru/services/v1/streaming_service_pb.ts +0 -390
  73. package/thru-ts-client-sdk/sdk.ts +0 -42
  74. package/thru-ts-client-sdk/test-scripts/counter.ts +0 -469
  75. package/thru-ts-client-sdk/test-scripts/create-account.ts +0 -74
  76. package/thru-ts-client-sdk/test-scripts/get-height.ts +0 -52
  77. package/thru-ts-client-sdk/transactions/Transaction.ts +0 -240
  78. package/thru-ts-client-sdk/transactions/TransactionBuilder.ts +0 -53
  79. package/thru-ts-client-sdk/transactions/__tests__/TransactionBuilder.test.ts +0 -411
  80. package/thru-ts-client-sdk/transactions/__tests__/utils.test.ts +0 -214
  81. package/thru-ts-client-sdk/transactions/index.ts +0 -3
  82. package/thru-ts-client-sdk/transactions/types.ts +0 -74
  83. package/thru-ts-client-sdk/transactions/utils.ts +0 -132
  84. package/thru-ts-client-sdk/types/types.ts +0 -8
  85. package/thru-ts-client-sdk/utils/utils.ts +0 -27
  86. package/tsconfig.json +0 -9
  87. package/tsup.config.ts +0 -14
  88. package/vitest.config.ts +0 -31
@@ -1,730 +0,0 @@
1
- import { create } from "@bufbuild/protobuf";
2
- import { describe, expect, it, vi } from "vitest";
3
- import {
4
- createMockAccount,
5
- createMockContext,
6
- createMockHeightResponse,
7
- generateTestAddress,
8
- generateTestPubkey,
9
- generateTestSignature,
10
- generateTestSignatureString,
11
- } from "../../__tests__/helpers/test-utils";
12
- import { ConsensusStatus } from "../../proto/thru/common/v1/consensus_pb";
13
- import { FilterSchema } from "../../proto/thru/common/v1/filters_pb";
14
- import { PageRequestSchema } from "../../proto/thru/common/v1/pagination_pb";
15
- import { TransactionSchema, TransactionView } from "../../proto/thru/core/v1/transaction_pb";
16
- import { TransactionStatusSchema } from "../../proto/thru/services/v1/query_service_pb";
17
- import { Transaction } from "../../transactions/Transaction";
18
- import {
19
- batchSendTransactions,
20
- buildAndSignTransaction,
21
- buildTransaction,
22
- getRawTransaction,
23
- getTransaction,
24
- getTransactionStatus,
25
- listTransactionsForAccount,
26
- sendTransaction,
27
- } from "../transactions";
28
-
29
- describe("transactions", () => {
30
- describe("getTransaction", () => {
31
- it("should return transaction with valid signature", async () => {
32
- const ctx = createMockContext();
33
- const mockTransaction = create(TransactionSchema, {
34
- signature: { value: generateTestSignature() },
35
- });
36
- vi.spyOn(ctx.query, "getTransaction").mockResolvedValue(mockTransaction);
37
-
38
- const signature = generateTestSignature();
39
- const result = await getTransaction(ctx, signature);
40
-
41
- expect(result).toBe(mockTransaction);
42
- expect(ctx.query.getTransaction).toHaveBeenCalledTimes(1);
43
- });
44
-
45
- it("should accept signature as Uint8Array", async () => {
46
- const ctx = createMockContext();
47
- const mockTransaction = create(TransactionSchema, {});
48
- vi.spyOn(ctx.query, "getTransaction").mockResolvedValue(mockTransaction);
49
-
50
- const signature = generateTestSignature();
51
- await getTransaction(ctx, signature);
52
-
53
- const callArgs = (ctx.query.getTransaction as any).mock.calls[0][0];
54
- expect(callArgs.signature.value).toEqual(signature);
55
- });
56
-
57
- it("should accept signature as string", async () => {
58
- const ctx = createMockContext();
59
- const mockTransaction = create(TransactionSchema, {});
60
- vi.spyOn(ctx.query, "getTransaction").mockResolvedValue(mockTransaction);
61
-
62
- const signatureString = generateTestSignatureString();
63
- await getTransaction(ctx, signatureString);
64
-
65
- const callArgs = (ctx.query.getTransaction as any).mock.calls[0][0];
66
- expect(callArgs.signature.value.length).toBe(64);
67
- });
68
-
69
- it("should use default view when not provided", async () => {
70
- const ctx = createMockContext();
71
- const mockTransaction = create(TransactionSchema, {});
72
- vi.spyOn(ctx.query, "getTransaction").mockResolvedValue(mockTransaction);
73
-
74
- await getTransaction(ctx, generateTestSignature());
75
-
76
- const callArgs = (ctx.query.getTransaction as any).mock.calls[0][0];
77
- expect(callArgs.view).toBe(TransactionView.FULL);
78
- });
79
-
80
- it("should use custom view when provided", async () => {
81
- const ctx = createMockContext();
82
- const mockTransaction = create(TransactionSchema, {});
83
- vi.spyOn(ctx.query, "getTransaction").mockResolvedValue(mockTransaction);
84
-
85
- await getTransaction(ctx, generateTestSignature(), { view: TransactionView.SIGNATURE_ONLY });
86
-
87
- const callArgs = (ctx.query.getTransaction as any).mock.calls[0][0];
88
- expect(callArgs.view).toBe(TransactionView.SIGNATURE_ONLY);
89
- });
90
-
91
- it("should use default minConsensus", async () => {
92
- const ctx = createMockContext();
93
- const mockTransaction = create(TransactionSchema, {});
94
- vi.spyOn(ctx.query, "getTransaction").mockResolvedValue(mockTransaction);
95
-
96
- await getTransaction(ctx, generateTestSignature());
97
-
98
- const callArgs = (ctx.query.getTransaction as any).mock.calls[0][0];
99
- expect(callArgs.minConsensus).toBe(ConsensusStatus.UNSPECIFIED);
100
- });
101
- });
102
-
103
- describe("getRawTransaction", () => {
104
- it("should return raw transaction", async () => {
105
- const ctx = createMockContext();
106
- const mockRawTransaction = {
107
- signature: { value: generateTestSignature() },
108
- rawTransaction: new Uint8Array([1, 2, 3]),
109
- };
110
- vi.spyOn(ctx.query, "getRawTransaction").mockResolvedValue(mockRawTransaction as any);
111
-
112
- const signature = generateTestSignature();
113
- const result = await getRawTransaction(ctx, signature);
114
-
115
- expect(result).toBe(mockRawTransaction);
116
- expect(ctx.query.getRawTransaction).toHaveBeenCalledTimes(1);
117
- });
118
-
119
- it("should use default version context and minConsensus", async () => {
120
- const ctx = createMockContext();
121
- const mockRawTransaction = { signature: { value: generateTestSignature() } };
122
- vi.spyOn(ctx.query, "getRawTransaction").mockResolvedValue(mockRawTransaction as any);
123
-
124
- await getRawTransaction(ctx, generateTestSignature());
125
-
126
- const callArgs = (ctx.query.getRawTransaction as any).mock.calls[0][0];
127
- expect(callArgs.versionContext).toBeDefined();
128
- expect(callArgs.minConsensus).toBe(ConsensusStatus.UNSPECIFIED);
129
- });
130
- });
131
-
132
- describe("getTransactionStatus", () => {
133
- it("should return transaction status", async () => {
134
- const ctx = createMockContext();
135
- const mockStatus = create(TransactionStatusSchema, {
136
- signature: { value: generateTestSignature() },
137
- consensusStatus: ConsensusStatus.FINALIZED,
138
- });
139
- vi.spyOn(ctx.query, "getTransactionStatus").mockResolvedValue(mockStatus);
140
-
141
- const signature = generateTestSignature();
142
- const result = await getTransactionStatus(ctx, signature);
143
-
144
- expect(result).toBe(mockStatus);
145
- expect(ctx.query.getTransactionStatus).toHaveBeenCalledTimes(1);
146
- });
147
- });
148
-
149
- describe("buildTransaction", () => {
150
- it("should build transaction with minimal options", async () => {
151
- const ctx = createMockContext();
152
- const mockAccount = createMockAccount({
153
- meta: { nonce: 5n },
154
- });
155
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
156
-
157
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount);
158
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
159
-
160
- const publicKey = generateTestPubkey(0x01);
161
- const transaction = await buildTransaction(ctx, {
162
- feePayer: { publicKey },
163
- program: generateTestPubkey(0x02),
164
- });
165
-
166
- expect(transaction).toBeInstanceOf(Transaction);
167
- expect(transaction.feePayer).toEqual(publicKey);
168
- expect(transaction.nonce).toBe(5n);
169
- expect(transaction.startSlot).toBe(1000n);
170
- });
171
-
172
- it("should use provided nonce instead of fetching", async () => {
173
- const ctx = createMockContext();
174
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
175
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
176
-
177
- const publicKey = generateTestPubkey(0x01);
178
- const transaction = await buildTransaction(ctx, {
179
- feePayer: { publicKey },
180
- program: generateTestPubkey(0x02),
181
- header: {
182
- nonce: 10n,
183
- },
184
- });
185
-
186
- expect(transaction.nonce).toBe(10n);
187
- expect(ctx.query.getAccount).not.toHaveBeenCalled();
188
- });
189
-
190
- it("should use provided startSlot instead of fetching", async () => {
191
- const ctx = createMockContext();
192
- const mockAccount = createMockAccount({
193
- meta: { nonce: 5n },
194
- });
195
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount);
196
-
197
- const publicKey = generateTestPubkey(0x01);
198
- const transaction = await buildTransaction(ctx, {
199
- feePayer: { publicKey },
200
- program: generateTestPubkey(0x02),
201
- header: {
202
- startSlot: 2000n,
203
- },
204
- });
205
-
206
- expect(transaction.startSlot).toBe(2000n);
207
- expect(ctx.query.getHeight).not.toHaveBeenCalled();
208
- });
209
-
210
- it("should use default header values when not provided", async () => {
211
- const ctx = createMockContext();
212
- const mockAccount = createMockAccount({
213
- meta: { nonce: 5n },
214
- });
215
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
216
-
217
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount);
218
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
219
-
220
- const publicKey = generateTestPubkey(0x01);
221
- const transaction = await buildTransaction(ctx, {
222
- feePayer: { publicKey },
223
- program: generateTestPubkey(0x02),
224
- });
225
-
226
- expect(transaction.fee).toBe(1n); // DEFAULT_FEE
227
- expect(transaction.expiryAfter).toBe(100); // DEFAULT_EXPIRY_AFTER
228
- expect(transaction.requestedComputeUnits).toBe(300_000_000); // DEFAULT_COMPUTE_UNITS
229
- expect(transaction.requestedStateUnits).toBe(10_000); // DEFAULT_STATE_UNITS
230
- expect(transaction.requestedMemoryUnits).toBe(10_000); // DEFAULT_MEMORY_UNITS
231
- });
232
-
233
- it("should accept program as string", async () => {
234
- const ctx = createMockContext();
235
- const mockAccount = createMockAccount({
236
- meta: { nonce: 5n },
237
- });
238
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
239
-
240
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount);
241
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
242
-
243
- const publicKey = generateTestPubkey(0x01);
244
- const programAddress = generateTestAddress(0x02);
245
- const transaction = await buildTransaction(ctx, {
246
- feePayer: { publicKey },
247
- program: programAddress,
248
- });
249
-
250
- expect(transaction.program.length).toBe(32);
251
- });
252
-
253
- it("should throw error when account nonce is unavailable", async () => {
254
- const ctx = createMockContext();
255
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
256
-
257
- // Mock account with meta that has undefined nonce
258
- // Since nonce is required in protobuf, we need to manually create an object
259
- // that simulates the case where meta.nonce is undefined
260
- const mockAccount = {
261
- address: { value: generateTestPubkey(0x01) },
262
- meta: {
263
- version: 1,
264
- flags: {},
265
- dataSize: 0,
266
- seq: 0n,
267
- owner: { value: generateTestPubkey(0x02) },
268
- balance: 0n,
269
- // nonce is explicitly undefined
270
- nonce: undefined,
271
- },
272
- };
273
-
274
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount as any);
275
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
276
-
277
- const publicKey = generateTestPubkey(0x01);
278
-
279
- await expect(
280
- buildTransaction(ctx, {
281
- feePayer: { publicKey },
282
- program: generateTestPubkey(0x02),
283
- })
284
- ).rejects.toThrow("Fee payer account nonce is unavailable");
285
- });
286
-
287
- it("should accept instruction data as Uint8Array", async () => {
288
- const ctx = createMockContext();
289
- const mockAccount = createMockAccount({
290
- meta: { nonce: 5n },
291
- });
292
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
293
-
294
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount);
295
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
296
-
297
- const instructionData = new Uint8Array([0x01, 0x02, 0x03]);
298
- const transaction = await buildTransaction(ctx, {
299
- feePayer: { publicKey: generateTestPubkey(0x01) },
300
- program: generateTestPubkey(0x02),
301
- instructionData,
302
- });
303
-
304
- expect(transaction.instructionData).toEqual(instructionData);
305
- });
306
-
307
- it("should accept instruction data as function", async () => {
308
- const ctx = createMockContext();
309
- const mockAccount = createMockAccount({
310
- meta: { nonce: 5n },
311
- });
312
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
313
-
314
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount);
315
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
316
-
317
- const instructionDataFn = (context: any) => {
318
- // Function that uses context to generate instruction data
319
- return new Uint8Array([context.accounts.length]);
320
- };
321
-
322
- const transaction = await buildTransaction(ctx, {
323
- feePayer: { publicKey: generateTestPubkey(0x01) },
324
- program: generateTestPubkey(0x02),
325
- instructionData: instructionDataFn,
326
- });
327
-
328
- expect(transaction.instructionData).toBeDefined();
329
- });
330
-
331
- it("should build transaction with instructionData function using context builder", async () => {
332
- const ctx = createMockContext();
333
- const mockAccount = createMockAccount({
334
- meta: { nonce: 5n },
335
- });
336
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
337
-
338
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount);
339
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
340
-
341
- const feePayer = generateTestPubkey(0x01);
342
- const program = generateTestPubkey(0x02);
343
- const readWriteAccount1 = generateTestPubkey(0x03);
344
- const readWriteAccount2 = generateTestPubkey(0x04);
345
- const readOnlyAccount = generateTestPubkey(0x05);
346
-
347
- // Instruction data function that uses the context to:
348
- // 1. Access the accounts array
349
- // 2. Use getAccountIndex to find account positions
350
- // 3. Build instruction data with account indices
351
- const instructionDataFn = (context: {
352
- accounts: Uint8Array[];
353
- getAccountIndex: (pubkey: Uint8Array) => number;
354
- }) => {
355
- // Verify context has all accounts in correct order
356
- expect(context.accounts.length).toBe(5); // feePayer, program, 2 readWrite, 1 readOnly
357
- expect(context.accounts[0]).toEqual(feePayer);
358
- expect(context.accounts[1]).toEqual(program);
359
- expect(context.accounts[2]).toEqual(readWriteAccount1);
360
- expect(context.accounts[3]).toEqual(readWriteAccount2);
361
- expect(context.accounts[4]).toEqual(readOnlyAccount);
362
-
363
- // Use getAccountIndex to find account positions
364
- const feePayerIndex = context.getAccountIndex(feePayer);
365
- const programIndex = context.getAccountIndex(program);
366
- const readWrite1Index = context.getAccountIndex(readWriteAccount1);
367
- const readOnlyIndex = context.getAccountIndex(readOnlyAccount);
368
-
369
- // Verify indices are correct
370
- expect(feePayerIndex).toBe(0);
371
- expect(programIndex).toBe(1);
372
- expect(readWrite1Index).toBe(2);
373
- expect(readOnlyIndex).toBe(4);
374
-
375
- // Build instruction data using account indices (common pattern)
376
- // Example: [instructionDiscriminator, accountIndex1, accountIndex2, ...]
377
- const instructionData = new Uint8Array([
378
- 0x42, // instruction discriminator
379
- feePayerIndex,
380
- programIndex,
381
- readWrite1Index,
382
- readOnlyIndex,
383
- ]);
384
-
385
- return instructionData;
386
- };
387
-
388
- const transaction = await buildTransaction(ctx, {
389
- feePayer: { publicKey: feePayer },
390
- program,
391
- accounts: {
392
- readWrite: [readWriteAccount1, readWriteAccount2],
393
- readOnly: [readOnlyAccount],
394
- },
395
- instructionData: instructionDataFn,
396
- });
397
-
398
- expect(transaction.instructionData).toBeDefined();
399
- expect(transaction.instructionData!.length).toBe(5);
400
- expect(transaction.instructionData![0]).toBe(0x42); // discriminator
401
- expect(transaction.instructionData![1]).toBe(0); // feePayer index
402
- expect(transaction.instructionData![2]).toBe(1); // program index
403
- expect(transaction.instructionData![3]).toBe(2); // readWrite1 index
404
- expect(transaction.instructionData![4]).toBe(4); // readOnly index
405
-
406
- // Verify accounts are in the transaction
407
- expect(transaction.readWriteAccounts).toHaveLength(2);
408
- expect(transaction.readOnlyAccounts).toHaveLength(1);
409
- });
410
-
411
- it("should throw error in instructionData function when account not found via getAccountIndex", async () => {
412
- const ctx = createMockContext();
413
- const mockAccount = createMockAccount({
414
- meta: { nonce: 5n },
415
- });
416
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
417
-
418
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount);
419
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
420
-
421
- const feePayer = generateTestPubkey(0x01);
422
- const program = generateTestPubkey(0x02);
423
- const unknownAccount = generateTestPubkey(0x99); // Not in transaction accounts
424
-
425
- const instructionDataFn = (context: {
426
- accounts: Uint8Array[];
427
- getAccountIndex: (pubkey: Uint8Array) => number;
428
- }) => {
429
- // Try to get index of an account not in the transaction
430
- expect(() => context.getAccountIndex(unknownAccount)).toThrow(
431
- "Account not found in transaction accounts"
432
- );
433
- return new Uint8Array([0x01]);
434
- };
435
-
436
- const transaction = await buildTransaction(ctx, {
437
- feePayer: { publicKey: feePayer },
438
- program,
439
- instructionData: instructionDataFn,
440
- });
441
-
442
- expect(transaction.instructionData).toBeDefined();
443
- });
444
- });
445
-
446
- describe("buildAndSignTransaction", () => {
447
- it("should build and sign transaction", async () => {
448
- const ctx = createMockContext();
449
- const mockAccount = createMockAccount({
450
- meta: { nonce: 5n },
451
- });
452
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
453
-
454
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount);
455
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
456
-
457
- const publicKey = generateTestPubkey(0x01);
458
- const privateKey = new Uint8Array(32);
459
- privateKey.fill(0x42);
460
-
461
- const result = await buildAndSignTransaction(ctx, {
462
- feePayer: {
463
- publicKey,
464
- privateKey,
465
- },
466
- program: generateTestPubkey(0x02),
467
- });
468
-
469
- expect(result.transaction).toBeInstanceOf(Transaction);
470
- expect(result.signature.length).toBe(64);
471
- expect(result.rawTransaction.length).toBeGreaterThan(0);
472
- });
473
-
474
- it("should throw error when private key is missing", async () => {
475
- const ctx = createMockContext();
476
- const mockAccount = createMockAccount({
477
- meta: { nonce: 5n },
478
- });
479
- const mockHeight = createMockHeightResponse({ finalized: 1000n });
480
-
481
- vi.spyOn(ctx.query, "getAccount").mockResolvedValue(mockAccount);
482
- vi.spyOn(ctx.query, "getHeight").mockResolvedValue(mockHeight);
483
-
484
- const publicKey = generateTestPubkey(0x01);
485
-
486
- await expect(
487
- buildAndSignTransaction(ctx, {
488
- feePayer: {
489
- publicKey,
490
- // No privateKey
491
- },
492
- program: generateTestPubkey(0x02),
493
- } as any)
494
- ).rejects.toThrow("Fee payer private key is required to sign the transaction");
495
- });
496
- });
497
-
498
- describe("sendTransaction", () => {
499
- it("should send transaction object", async () => {
500
- const ctx = createMockContext();
501
- const mockSignature = generateTestSignature();
502
- const mockResponse = {
503
- signature: { value: mockSignature },
504
- };
505
- vi.spyOn(ctx.command, "sendTransaction").mockResolvedValue(mockResponse as any);
506
-
507
- const transaction = new Transaction({
508
- feePayer: generateTestPubkey(0x01),
509
- program: generateTestPubkey(0x02),
510
- header: {
511
- fee: 1n,
512
- nonce: 2n,
513
- startSlot: 3n,
514
- },
515
- });
516
-
517
- const result = await sendTransaction(ctx, transaction);
518
-
519
- expect(typeof result).toBe("string");
520
- expect(result.startsWith("ts")).toBe(true);
521
- expect(ctx.command.sendTransaction).toHaveBeenCalledTimes(1);
522
- });
523
-
524
- it("should send raw transaction bytes", async () => {
525
- const ctx = createMockContext();
526
- const mockSignature = generateTestSignature();
527
- const mockResponse = {
528
- signature: { value: mockSignature },
529
- };
530
- vi.spyOn(ctx.command, "sendTransaction").mockResolvedValue(mockResponse as any);
531
-
532
- const rawTransaction = new Uint8Array([1, 2, 3, 4]);
533
- const result = await sendTransaction(ctx, rawTransaction);
534
-
535
- expect(typeof result).toBe("string");
536
- expect(ctx.command.sendTransaction).toHaveBeenCalledTimes(1);
537
- const callArgs = (ctx.command.sendTransaction as any).mock.calls[0][0];
538
- expect(callArgs.rawTransaction).toEqual(rawTransaction);
539
- });
540
-
541
- it("should throw error when signature is missing from response", async () => {
542
- const ctx = createMockContext();
543
- const mockResponse = {
544
- // No signature
545
- };
546
- vi.spyOn(ctx.command, "sendTransaction").mockResolvedValue(mockResponse as any);
547
-
548
- const transaction = new Transaction({
549
- feePayer: generateTestPubkey(0x01),
550
- program: generateTestPubkey(0x02),
551
- header: {
552
- fee: 1n,
553
- nonce: 2n,
554
- startSlot: 3n,
555
- },
556
- });
557
-
558
- await expect(sendTransaction(ctx, transaction)).rejects.toThrow(
559
- "No signature returned from sendTransaction"
560
- );
561
- });
562
- });
563
-
564
- describe("listTransactionsForAccount", () => {
565
- it("should list transactions for account", async () => {
566
- const ctx = createMockContext();
567
- const mockResponse = {
568
- signatures: [
569
- { value: generateTestSignature(0x01) },
570
- { value: generateTestSignature(0x02) },
571
- ],
572
- };
573
- vi.spyOn(ctx.query, "listTransactionsForAccount").mockResolvedValue(mockResponse as any);
574
-
575
- const account = generateTestPubkey();
576
- const result = await listTransactionsForAccount(ctx, account);
577
-
578
- expect(result).toBe(mockResponse);
579
- expect(ctx.query.listTransactionsForAccount).toHaveBeenCalledTimes(1);
580
- const callArgs = (ctx.query.listTransactionsForAccount as any).mock.calls[0][0];
581
- expect(callArgs.account?.value).toEqual(account);
582
- });
583
-
584
- it("should accept account as Uint8Array", async () => {
585
- const ctx = createMockContext();
586
- const mockResponse = { signatures: [] };
587
- vi.spyOn(ctx.query, "listTransactionsForAccount").mockResolvedValue(mockResponse as any);
588
-
589
- const account = generateTestPubkey();
590
- await listTransactionsForAccount(ctx, account);
591
-
592
- const callArgs = (ctx.query.listTransactionsForAccount as any).mock.calls[0][0];
593
- expect(callArgs.account?.value).toEqual(account);
594
- });
595
-
596
- it("should accept account as string", async () => {
597
- const ctx = createMockContext();
598
- const mockResponse = { signatures: [] };
599
- vi.spyOn(ctx.query, "listTransactionsForAccount").mockResolvedValue(mockResponse as any);
600
-
601
- const accountString = generateTestAddress();
602
- await listTransactionsForAccount(ctx, accountString);
603
-
604
- const callArgs = (ctx.query.listTransactionsForAccount as any).mock.calls[0][0];
605
- expect(callArgs.account?.value.length).toBe(32);
606
- });
607
-
608
- it("should pass page options", async () => {
609
- const ctx = createMockContext();
610
- const mockResponse = { signatures: [] };
611
- vi.spyOn(ctx.query, "listTransactionsForAccount").mockResolvedValue(mockResponse as any);
612
-
613
- const account = generateTestPubkey();
614
- const page = create(PageRequestSchema, { pageSize: 20, pageToken: "token123" });
615
- await listTransactionsForAccount(ctx, account, { page });
616
-
617
- const callArgs = (ctx.query.listTransactionsForAccount as any).mock.calls[0][0];
618
- expect(callArgs.page?.pageSize).toBe(20);
619
- expect(callArgs.page?.pageToken).toBe("token123");
620
- });
621
-
622
- it("should pass filter options", async () => {
623
- const ctx = createMockContext();
624
- const mockResponse = { signatures: [] };
625
- vi.spyOn(ctx.query, "listTransactionsForAccount").mockResolvedValue(mockResponse as any);
626
-
627
- const account = generateTestPubkey();
628
- const filter = create(FilterSchema, { expression: "meta.value > 0" });
629
- await listTransactionsForAccount(ctx, account, { filter });
630
-
631
- const callArgs = (ctx.query.listTransactionsForAccount as any).mock.calls[0][0];
632
- expect(callArgs.filter?.expression).toBe("meta.value > 0");
633
- });
634
- });
635
-
636
- describe("batchSendTransactions", () => {
637
- it("should send batch of transactions", async () => {
638
- const ctx = createMockContext();
639
- const mockResponse = {
640
- signatures: [
641
- { value: generateTestSignature(0x01) },
642
- { value: generateTestSignature(0x02) },
643
- ],
644
- };
645
- vi.spyOn(ctx.command, "batchSendTransactions").mockResolvedValue(mockResponse as any);
646
-
647
- const transactions = [
648
- new Uint8Array([1, 2, 3]),
649
- new Uint8Array([4, 5, 6]),
650
- ];
651
- const result = await batchSendTransactions(ctx, transactions);
652
-
653
- expect(result).toBe(mockResponse);
654
- expect(ctx.command.batchSendTransactions).toHaveBeenCalledTimes(1);
655
- const callArgs = (ctx.command.batchSendTransactions as any).mock.calls[0][0];
656
- expect(callArgs.rawTransactions).toHaveLength(2);
657
- expect(callArgs.rawTransactions[0]).toEqual(transactions[0]);
658
- expect(callArgs.rawTransactions[1]).toEqual(transactions[1]);
659
- });
660
-
661
- it("should convert Transaction objects to raw bytes", async () => {
662
- const ctx = createMockContext();
663
- const mockResponse = { signatures: [{ value: generateTestSignature() }] };
664
- vi.spyOn(ctx.command, "batchSendTransactions").mockResolvedValue(mockResponse as any);
665
-
666
- const transaction = new Transaction({
667
- feePayer: generateTestPubkey(0x01),
668
- program: generateTestPubkey(0x02),
669
- header: {
670
- fee: 1n,
671
- nonce: 2n,
672
- startSlot: 3n,
673
- },
674
- });
675
-
676
- await batchSendTransactions(ctx, [transaction]);
677
-
678
- const callArgs = (ctx.command.batchSendTransactions as any).mock.calls[0][0];
679
- expect(callArgs.rawTransactions).toHaveLength(1);
680
- expect(callArgs.rawTransactions[0]).toBeInstanceOf(Uint8Array);
681
- });
682
-
683
- it("should handle mixed Transaction objects and raw bytes", async () => {
684
- const ctx = createMockContext();
685
- const mockResponse = { signatures: [] };
686
- vi.spyOn(ctx.command, "batchSendTransactions").mockResolvedValue(mockResponse as any);
687
-
688
- const transaction = new Transaction({
689
- feePayer: generateTestPubkey(0x01),
690
- program: generateTestPubkey(0x02),
691
- header: {
692
- fee: 1n,
693
- nonce: 2n,
694
- startSlot: 3n,
695
- },
696
- });
697
- const rawBytes = new Uint8Array([1, 2, 3]);
698
-
699
- await batchSendTransactions(ctx, [transaction, rawBytes]);
700
-
701
- const callArgs = (ctx.command.batchSendTransactions as any).mock.calls[0][0];
702
- expect(callArgs.rawTransactions).toHaveLength(2);
703
- expect(callArgs.rawTransactions[0]).toBeInstanceOf(Uint8Array);
704
- expect(callArgs.rawTransactions[1]).toBe(rawBytes);
705
- });
706
-
707
- it("should pass numRetries option", async () => {
708
- const ctx = createMockContext();
709
- const mockResponse = { signatures: [] };
710
- vi.spyOn(ctx.command, "batchSendTransactions").mockResolvedValue(mockResponse as any);
711
-
712
- await batchSendTransactions(ctx, [new Uint8Array([1])], { numRetries: 5 });
713
-
714
- const callArgs = (ctx.command.batchSendTransactions as any).mock.calls[0][0];
715
- expect(callArgs.numRetries).toBe(5);
716
- });
717
-
718
- it("should default numRetries to 0 when not provided", async () => {
719
- const ctx = createMockContext();
720
- const mockResponse = { signatures: [] };
721
- vi.spyOn(ctx.command, "batchSendTransactions").mockResolvedValue(mockResponse as any);
722
-
723
- await batchSendTransactions(ctx, [new Uint8Array([1])]);
724
-
725
- const callArgs = (ctx.command.batchSendTransactions as any).mock.calls[0][0];
726
- expect(callArgs.numRetries).toBe(0);
727
- });
728
- });
729
- });
730
-