@nosana/kit 2.0.19 → 2.0.25

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 (87) hide show
  1. package/README.md +96 -24
  2. package/dist/NosanaClient.d.ts +5 -5
  3. package/dist/NosanaClient.js +7 -5
  4. package/dist/NosanaClient.js.map +1 -1
  5. package/dist/index.d.ts +9 -9
  6. package/dist/index.js +5 -5
  7. package/dist/index.js.map +1 -1
  8. package/dist/services/programs/{JobsProgram.d.ts → jobs/JobsProgram.d.ts} +47 -11
  9. package/dist/services/programs/{JobsProgram.js → jobs/JobsProgram.js} +84 -208
  10. package/dist/services/programs/jobs/JobsProgram.js.map +1 -0
  11. package/dist/services/programs/jobs/index.d.ts +1 -0
  12. package/dist/services/programs/jobs/index.js +2 -0
  13. package/dist/services/programs/jobs/index.js.map +1 -0
  14. package/dist/services/programs/{instructions → jobs/instructions}/delist.d.ts +1 -1
  15. package/dist/services/programs/jobs/instructions/delist.js.map +1 -0
  16. package/dist/services/programs/{instructions → jobs/instructions}/end.d.ts +1 -1
  17. package/dist/services/programs/jobs/instructions/end.js.map +1 -0
  18. package/dist/services/programs/{instructions → jobs/instructions}/extend.d.ts +1 -1
  19. package/dist/services/programs/jobs/instructions/extend.js.map +1 -0
  20. package/dist/services/programs/jobs/instructions/index.js.map +1 -0
  21. package/dist/services/programs/{instructions → jobs/instructions}/post.d.ts +1 -1
  22. package/dist/services/programs/jobs/instructions/post.js.map +1 -0
  23. package/dist/services/programs/jobs/instructions/types.d.ts +16 -0
  24. package/dist/services/programs/jobs/instructions/types.js.map +1 -0
  25. package/dist/services/programs/jobs/monitor/index.d.ts +3 -0
  26. package/dist/services/programs/jobs/monitor/index.js +3 -0
  27. package/dist/services/programs/jobs/monitor/index.js.map +1 -0
  28. package/dist/services/programs/jobs/monitor/monitor.d.ts +22 -0
  29. package/dist/services/programs/jobs/monitor/monitor.js +180 -0
  30. package/dist/services/programs/jobs/monitor/monitor.js.map +1 -0
  31. package/dist/services/programs/jobs/monitor/types.d.ts +27 -0
  32. package/dist/services/programs/jobs/monitor/types.js +9 -0
  33. package/dist/services/programs/jobs/monitor/types.js.map +1 -0
  34. package/dist/services/programs/{MerkleDistributorProgram.d.ts → merkleDistributor/MerkleDistributorProgram.d.ts} +4 -4
  35. package/dist/services/programs/{MerkleDistributorProgram.js → merkleDistributor/MerkleDistributorProgram.js} +3 -3
  36. package/dist/services/programs/merkleDistributor/MerkleDistributorProgram.js.map +1 -0
  37. package/dist/services/programs/merkleDistributor/index.d.ts +1 -0
  38. package/dist/services/programs/merkleDistributor/index.js +2 -0
  39. package/dist/services/programs/merkleDistributor/index.js.map +1 -0
  40. package/dist/services/programs/{StakeProgram.d.ts → stake/StakeProgram.d.ts} +4 -4
  41. package/dist/services/programs/{StakeProgram.js → stake/StakeProgram.js} +2 -2
  42. package/dist/services/programs/stake/StakeProgram.js.map +1 -0
  43. package/dist/services/programs/stake/index.d.ts +1 -0
  44. package/dist/services/programs/stake/index.js +2 -0
  45. package/dist/services/programs/stake/index.js.map +1 -0
  46. package/dist/services/solana/SolanaService.d.ts +150 -0
  47. package/dist/services/{SolanaService.js → solana/SolanaService.js} +191 -9
  48. package/dist/services/solana/SolanaService.js.map +1 -0
  49. package/dist/services/solana/index.d.ts +1 -0
  50. package/dist/services/solana/index.js +2 -0
  51. package/dist/services/solana/index.js.map +1 -0
  52. package/dist/services/token/TokenService.d.ts +65 -0
  53. package/dist/services/{TokenService.js → token/TokenService.js} +82 -4
  54. package/dist/services/token/TokenService.js.map +1 -0
  55. package/dist/services/token/index.d.ts +1 -0
  56. package/dist/services/token/index.js +2 -0
  57. package/dist/services/token/index.js.map +1 -0
  58. package/dist/types.d.ts +3 -1
  59. package/dist/utils/convertHttpToWebSocketUrl.d.ts +28 -0
  60. package/dist/utils/convertHttpToWebSocketUrl.js +37 -0
  61. package/dist/utils/convertHttpToWebSocketUrl.js.map +1 -0
  62. package/dist/utils/getStaticAccounts.d.ts +1 -1
  63. package/dist/utils/index.d.ts +1 -0
  64. package/dist/utils/index.js +1 -0
  65. package/dist/utils/index.js.map +1 -1
  66. package/package.json +4 -4
  67. package/dist/services/SolanaService.d.ts +0 -64
  68. package/dist/services/SolanaService.js.map +0 -1
  69. package/dist/services/TokenService.d.ts +0 -41
  70. package/dist/services/TokenService.js.map +0 -1
  71. package/dist/services/programs/JobsProgram.js.map +0 -1
  72. package/dist/services/programs/MerkleDistributorProgram.js.map +0 -1
  73. package/dist/services/programs/StakeProgram.js.map +0 -1
  74. package/dist/services/programs/instructions/delist.js.map +0 -1
  75. package/dist/services/programs/instructions/end.js.map +0 -1
  76. package/dist/services/programs/instructions/extend.js.map +0 -1
  77. package/dist/services/programs/instructions/index.js.map +0 -1
  78. package/dist/services/programs/instructions/post.js.map +0 -1
  79. package/dist/services/programs/instructions/types.d.ts +0 -16
  80. package/dist/services/programs/instructions/types.js.map +0 -1
  81. /package/dist/services/programs/{instructions → jobs/instructions}/delist.js +0 -0
  82. /package/dist/services/programs/{instructions → jobs/instructions}/end.js +0 -0
  83. /package/dist/services/programs/{instructions → jobs/instructions}/extend.js +0 -0
  84. /package/dist/services/programs/{instructions → jobs/instructions}/index.d.ts +0 -0
  85. /package/dist/services/programs/{instructions → jobs/instructions}/index.js +0 -0
  86. /package/dist/services/programs/{instructions → jobs/instructions}/post.js +0 -0
  87. /package/dist/services/programs/{instructions → jobs/instructions}/types.js +0 -0
@@ -1,8 +1,9 @@
1
- import { createSolanaRpc, createSolanaRpcSubscriptions, address, getProgramDerivedAddress, getAddressEncoder, createTransactionMessage, signTransactionMessageWithSigners, getSignatureFromTransaction, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, sendAndConfirmTransactionFactory, appendTransactionMessageInstructions, pipe, assertIsSendableTransaction, } from '@solana/kit';
1
+ import { createSolanaRpc, createSolanaRpcSubscriptions, address, getProgramDerivedAddress, getAddressEncoder, createTransactionMessage, signTransactionMessageWithSigners, partiallySignTransactionMessageWithSigners, getSignatureFromTransaction, setTransactionMessageFeePayer, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, sendAndConfirmTransactionFactory, appendTransactionMessageInstructions, pipe, assertIsSendableTransaction, getTransactionDecoder, getBase64Encoder, getBase64EncodedWireTransaction, isTransactionSigner, decompileTransactionMessage, getCompiledTransactionMessageDecoder, } from '@solana/kit';
2
2
  import { estimateComputeUnitLimitFactory, getSetComputeUnitLimitInstruction, } from '@solana-program/compute-budget';
3
3
  import { getCreateAssociatedTokenIdempotentInstructionAsync, TOKEN_PROGRAM_ADDRESS, } from '@solana-program/token';
4
- import { SYSTEM_PROGRAM_ADDRESS } from '@solana-program/system';
5
- import { NosanaError, ErrorCodes } from '../errors/NosanaError.js';
4
+ import { SYSTEM_PROGRAM_ADDRESS, getTransferSolInstruction } from '@solana-program/system';
5
+ import { NosanaError, ErrorCodes } from '../../errors/NosanaError.js';
6
+ import { convertHttpToWebSocketUrl } from '../../utils/convertHttpToWebSocketUrl.js';
6
7
  /**
7
8
  * Factory function to create an estimateAndSetComputeUnitLimit function
8
9
  * that estimates compute units and adds the set compute unit limit instruction
@@ -22,8 +23,9 @@ export function createSolanaService(deps, config) {
22
23
  throw new NosanaError('RPC URL is required', ErrorCodes.INVALID_CONFIG);
23
24
  }
24
25
  const rpc = createSolanaRpc(config.rpcEndpoint);
25
- // Use wsEndpoint if provided, otherwise fall back to rpcEndpoint
26
- const rpcSubscriptions = createSolanaRpcSubscriptions(config.wsEndpoint ?? config.rpcEndpoint);
26
+ // Use wsEndpoint if provided, otherwise convert rpcEndpoint from http(s) to ws(s)
27
+ const wsUrl = config.wsEndpoint ?? convertHttpToWebSocketUrl(config.rpcEndpoint);
28
+ const rpcSubscriptions = createSolanaRpcSubscriptions(wsUrl);
27
29
  const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({
28
30
  rpc,
29
31
  rpcSubscriptions,
@@ -90,7 +92,7 @@ export function createSolanaService(deps, config) {
90
92
  }
91
93
  deps.logger.debug(`Getting balance for address: ${addr}`);
92
94
  const balance = await rpc.getBalance(addr).send();
93
- return balance.value;
95
+ return Number(balance.value);
94
96
  }
95
97
  catch (error) {
96
98
  if (error instanceof NosanaError) {
@@ -106,11 +108,14 @@ export function createSolanaService(deps, config) {
106
108
  * - Fee payer set to the provided feePayer, service feePayer, or wallet (in that order)
107
109
  * - Latest blockhash for lifetime
108
110
  * - Provided instructions
109
- * - Estimated compute unit limit
111
+ * - Optionally: estimated compute unit limit
110
112
  *
111
113
  * @param instructions Single instruction or array of instructions
112
114
  * @param options Optional configuration
113
- * @param options.feePayer Optional custom fee payer. Takes precedence over service feePayer and wallet.
115
+ * @param options.feePayer Optional custom fee payer. Can be a TransactionSigner (for full signing)
116
+ * or an Address/string (for partial signing where feepayer signs later).
117
+ * Takes precedence over service feePayer and wallet.
118
+ * @param options.estimateComputeUnits If true, estimates and sets the compute unit limit. Default: false.
114
119
  * @returns An unsigned transaction message ready to be signed
115
120
  */
116
121
  async buildTransaction(instructions, options) {
@@ -124,8 +129,22 @@ export function createSolanaService(deps, config) {
124
129
  const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
125
130
  // Normalize instructions to array
126
131
  const instructionsArray = Array.isArray(instructions) ? instructions : [instructions];
132
+ // Helper to check if the feePayer is a TransactionSigner
133
+ const isSigner = (value) => typeof value === 'object' && isTransactionSigner(value);
127
134
  // Build transaction message using pipe
128
- const transactionMessage = await pipe(createTransactionMessage({ version: 0 }), (tx) => setTransactionMessageFeePayerSigner(transactionFeePayer, tx), (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) => appendTransactionMessageInstructions(instructionsArray, tx), (tx) => estimateAndSetComputeUnitLimit(tx));
135
+ // Use setTransactionMessageFeePayerSigner for TransactionSigner, setTransactionMessageFeePayer for Address
136
+ const transactionMessage = await pipe(createTransactionMessage({ version: 0 }), (tx) => {
137
+ if (isSigner(transactionFeePayer)) {
138
+ return setTransactionMessageFeePayerSigner(transactionFeePayer, tx);
139
+ }
140
+ else {
141
+ // It's a string address, convert to Address type
142
+ const feePayerAddress = address(transactionFeePayer);
143
+ return setTransactionMessageFeePayer(feePayerAddress, tx);
144
+ }
145
+ }, (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) => appendTransactionMessageInstructions(instructionsArray, tx),
146
+ // Optionally estimate and set compute unit limit
147
+ (tx) => (options?.estimateComputeUnits ? estimateAndSetComputeUnitLimit(tx) : tx));
129
148
  return transactionMessage;
130
149
  }
131
150
  catch (error) {
@@ -190,15 +209,54 @@ export function createSolanaService(deps, config) {
190
209
  * @param options Optional configuration
191
210
  * @param options.feePayer Optional custom fee payer. If not provided, uses the wallet.
192
211
  * @param options.commitment Commitment level for confirmation (takes precedence over config, then falls back to config.commitment, then 'confirmed')
212
+ * @param options.estimateComputeUnits If true, estimates and sets the compute unit limit. Default: false.
193
213
  * @returns The transaction signature
194
214
  */
195
215
  async buildSignAndSend(instructions, options) {
196
216
  const transactionMessage = await this.buildTransaction(instructions, {
197
217
  feePayer: options?.feePayer,
218
+ estimateComputeUnits: options?.estimateComputeUnits,
198
219
  });
199
220
  const signedTransaction = await this.signTransaction(transactionMessage);
200
221
  return await this.sendTransaction(signedTransaction, { commitment: options?.commitment });
201
222
  },
223
+ /**
224
+ * Get an instruction to transfer SOL from one address to another.
225
+ *
226
+ * @param params Transfer parameters
227
+ * @param params.to Recipient address
228
+ * @param params.amount Amount in lamports (number or bigint)
229
+ * @param params.from Optional sender TransactionSigner. If not provided, uses wallet from client.
230
+ * @returns An instruction to transfer SOL
231
+ */
232
+ async transfer(params) {
233
+ try {
234
+ // Determine sender: use params.from if provided, otherwise get from wallet
235
+ const sender = params.from ?? deps.getWallet();
236
+ if (!sender) {
237
+ throw new NosanaError('No wallet found and no from parameter provided', ErrorCodes.NO_WALLET);
238
+ }
239
+ // Convert amount to bigint if it's a number
240
+ const amountBigInt = typeof params.amount === 'bigint' ? params.amount : BigInt(params.amount);
241
+ // Convert recipient to Address
242
+ const recipient = typeof params.to === 'string' ? address(params.to) : params.to;
243
+ deps.logger.debug(`Creating SOL transfer instruction: ${amountBigInt} lamports from ${sender.address} to ${recipient}`);
244
+ // Create and return transfer instruction
245
+ const instruction = getTransferSolInstruction({
246
+ source: sender,
247
+ destination: recipient,
248
+ amount: amountBigInt,
249
+ });
250
+ return instruction;
251
+ }
252
+ catch (error) {
253
+ if (error instanceof NosanaError) {
254
+ throw error;
255
+ }
256
+ deps.logger.error(`Failed to get transfer SOL instruction: ${error}`);
257
+ throw new NosanaError('Failed to get transfer SOL instruction', ErrorCodes.TRANSACTION_ERROR, error);
258
+ }
259
+ },
202
260
  /**
203
261
  * Get an instruction to create an associated token account if it doesn't exist.
204
262
  * Checks if the ATA exists, and if not, returns an instruction to create it.
@@ -239,6 +297,130 @@ export function createSolanaService(deps, config) {
239
297
  throw new NosanaError('Failed to get create ATA instruction', ErrorCodes.RPC_ERROR, error);
240
298
  }
241
299
  },
300
+ /**
301
+ * Partially sign a transaction message with the signers embedded in the transaction.
302
+ * The transaction message must already have a fee payer address set (via buildTransaction with an address).
303
+ * Signers are extracted from instructions in the message (e.g., transfer source signer).
304
+ * Use this when building transactions where the fee payer will sign later.
305
+ *
306
+ * @param transactionMessage The transaction message to sign (must have fee payer address set and signers embedded in instructions)
307
+ * @returns A partially signed transaction
308
+ */
309
+ async partiallySignTransaction(transactionMessage) {
310
+ try {
311
+ deps.logger.debug('Partially signing transaction with embedded signers');
312
+ // Use partiallySignTransactionMessageWithSigners to sign with signers embedded in the message
313
+ const partiallySignedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);
314
+ return partiallySignedTransaction;
315
+ }
316
+ catch (error) {
317
+ deps.logger.error(`Failed to partially sign transaction: ${error}`);
318
+ throw new NosanaError('Failed to partially sign transaction', ErrorCodes.TRANSACTION_ERROR, error);
319
+ }
320
+ },
321
+ /**
322
+ * Serialize a transaction to a base64 string.
323
+ * Works with both partially signed and fully signed transactions.
324
+ * Use this to transmit transactions to other parties (e.g., for fee payer signing).
325
+ *
326
+ * @param transaction The transaction to serialize
327
+ * @returns Base64 encoded wire transaction string
328
+ */
329
+ serializeTransaction(transaction) {
330
+ try {
331
+ deps.logger.debug('Serializing transaction to base64');
332
+ // Use getBase64EncodedWireTransaction to encode the transaction
333
+ const base64String = getBase64EncodedWireTransaction(transaction);
334
+ return base64String;
335
+ }
336
+ catch (error) {
337
+ deps.logger.error(`Failed to serialize transaction: ${error}`);
338
+ throw new NosanaError('Failed to serialize transaction', ErrorCodes.TRANSACTION_ERROR, error);
339
+ }
340
+ },
341
+ /**
342
+ * Deserialize a base64 string back to a transaction.
343
+ * Use this to receive transactions from other parties.
344
+ *
345
+ * @param base64 The base64 encoded transaction string
346
+ * @returns The deserialized transaction
347
+ */
348
+ deserializeTransaction(base64) {
349
+ try {
350
+ deps.logger.debug('Deserializing transaction from base64');
351
+ // Decode the base64 string to bytes, then to transaction
352
+ const transactionBytes = getBase64Encoder().encode(base64);
353
+ const transaction = getTransactionDecoder().decode(transactionBytes);
354
+ return transaction;
355
+ }
356
+ catch (error) {
357
+ deps.logger.error(`Failed to deserialize transaction: ${error}`);
358
+ throw new NosanaError('Failed to deserialize transaction', ErrorCodes.TRANSACTION_ERROR, error);
359
+ }
360
+ },
361
+ /**
362
+ * Sign a transaction with the provided signers.
363
+ * Use this when receiving a partially signed transaction that needs additional signatures.
364
+ * This adds signatures from the provided signers to the transaction.
365
+ *
366
+ * @param transaction The transaction to sign (typically partially signed, received from another party)
367
+ * @param signers Array of TransactionPartialSigners to sign with
368
+ * @returns The signed transaction with additional signatures
369
+ */
370
+ async signTransactionWithSigners(transaction, signers) {
371
+ try {
372
+ deps.logger.debug(`Signing transaction with ${signers.length} signer(s): ${signers.map((s) => s.address).join(', ')}`);
373
+ // Sign with each signer and merge signatures into the transaction
374
+ // TransactionPartialSigner.signTransactions returns SignatureDictionary[] (not transactions)
375
+ // We need to merge these signatures into the transaction's signatures map
376
+ let updatedSignatures = { ...transaction.signatures };
377
+ for (const signer of signers) {
378
+ // signTransactions returns an array of SignatureDictionary (one per transaction)
379
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
380
+ const [signatureDict] = await signer.signTransactions([transaction]);
381
+ // Merge the new signatures into our accumulated signatures
382
+ updatedSignatures = { ...updatedSignatures, ...signatureDict };
383
+ }
384
+ // Create a new transaction with the merged signatures
385
+ const signedTransaction = {
386
+ ...transaction,
387
+ signatures: updatedSignatures,
388
+ };
389
+ return signedTransaction;
390
+ }
391
+ catch (error) {
392
+ if (error instanceof NosanaError) {
393
+ throw error;
394
+ }
395
+ deps.logger.error(`Failed to sign transaction: ${error}`);
396
+ throw new NosanaError('Failed to sign transaction', ErrorCodes.TRANSACTION_ERROR, error);
397
+ }
398
+ },
399
+ /**
400
+ * Decompile a transaction back to a transaction message.
401
+ * Use this to inspect/verify the content of a deserialized transaction before signing.
402
+ *
403
+ * Note: Decompilation is lossy - some information like lastValidBlockHeight may not be fully
404
+ * reconstructed. The returned message is suitable for inspection but may not be suitable
405
+ * for re-signing without additional context.
406
+ *
407
+ * @param transaction The compiled transaction to decompile
408
+ * @returns The decompiled transaction message (with either blockhash or durable nonce lifetime)
409
+ */
410
+ decompileTransaction(transaction) {
411
+ try {
412
+ deps.logger.debug('Decompiling transaction to transaction message');
413
+ // First decode the compiled transaction message from the transaction bytes
414
+ const compiledMessage = getCompiledTransactionMessageDecoder().decode(transaction.messageBytes);
415
+ // Then decompile to get the transaction message
416
+ const transactionMessage = decompileTransactionMessage(compiledMessage);
417
+ return transactionMessage;
418
+ }
419
+ catch (error) {
420
+ deps.logger.error(`Failed to decompile transaction: ${error}`);
421
+ throw new NosanaError('Failed to decompile transaction', ErrorCodes.TRANSACTION_ERROR, error);
422
+ }
423
+ },
242
424
  };
243
425
  }
244
426
  //# sourceMappingURL=SolanaService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SolanaService.js","sourceRoot":"","sources":["../../../src/services/solana/SolanaService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from './SolanaService.js';
@@ -0,0 +1,2 @@
1
+ export * from './SolanaService.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/solana/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { Address, Instruction, TransactionSigner } from '@solana/kit';
2
+ import { Logger } from '../../logger/Logger.js';
3
+ import { Wallet } from '../../types.js';
4
+ export interface TokenAccount {
5
+ pubkey: Address;
6
+ owner: Address;
7
+ mint: Address;
8
+ amount: bigint;
9
+ decimals: number;
10
+ }
11
+ export interface TokenAccountWithBalance extends TokenAccount {
12
+ uiAmount: number;
13
+ }
14
+ import type { SolanaService } from '../solana/index.js';
15
+ /**
16
+ * Dependencies for TokenService
17
+ */
18
+ export interface TokenServiceDeps {
19
+ logger: Logger;
20
+ solana: SolanaService;
21
+ getWallet: () => Wallet | undefined;
22
+ }
23
+ /**
24
+ * Config for TokenService
25
+ */
26
+ export interface TokenServiceConfig {
27
+ tokenAddress: Address;
28
+ }
29
+ /**
30
+ * TokenService interface
31
+ */
32
+ export interface TokenService {
33
+ getAllTokenHolders(options?: {
34
+ includeZeroBalance?: boolean;
35
+ excludePdaAccounts?: boolean;
36
+ }): Promise<TokenAccountWithBalance[]>;
37
+ getTokenAccountForAddress(owner: string | Address): Promise<TokenAccountWithBalance | null>;
38
+ getBalance(owner?: string | Address): Promise<number>;
39
+ /**
40
+ * Get the associated token account address for a given owner.
41
+ *
42
+ * @param owner The owner address
43
+ * @returns The associated token account address
44
+ */
45
+ getATA(owner: Address | string): Promise<Address>;
46
+ /**
47
+ * Get instruction(s) to transfer SPL tokens from one address to another.
48
+ * May return 1 or 2 instructions depending on whether the recipient's associated token account needs to be created.
49
+ *
50
+ * @param params Transfer parameters
51
+ * @param params.to Recipient address
52
+ * @param params.amount Amount in token base units (number or bigint)
53
+ * @param params.from Optional sender TransactionSigner. If not provided, uses wallet from client.
54
+ * @returns Array of instructions (create ATA instruction if needed, then transfer instruction)
55
+ */
56
+ transfer(params: {
57
+ to: Address | string;
58
+ amount: number | bigint;
59
+ from?: TransactionSigner;
60
+ }): Promise<Instruction[]>;
61
+ }
62
+ /**
63
+ * Creates a TokenService instance.
64
+ */
65
+ export declare function createTokenService(deps: TokenServiceDeps, config: TokenServiceConfig): TokenService;
@@ -1,6 +1,6 @@
1
1
  import { address } from '@solana/kit';
2
- import { NosanaError, ErrorCodes } from '../errors/NosanaError.js';
3
- import { TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';
2
+ import { NosanaError, ErrorCodes } from '../../errors/NosanaError.js';
3
+ import { TOKEN_PROGRAM_ADDRESS, getTransferInstruction, findAssociatedTokenPda, } from '@solana-program/token';
4
4
  // Standard SPL token account size
5
5
  const TOKEN_ACCOUNT_SIZE = 165;
6
6
  // Offset of mint address in token account data structure
@@ -124,13 +124,91 @@ export function createTokenService(deps, config) {
124
124
  * Get the token balance for a specific owner address
125
125
  * Convenience method that returns just the balance
126
126
  *
127
- * @param owner - The owner address to query
127
+ * @param owner - Optional owner address to query. If not provided, uses the wallet address.
128
128
  * @returns The token balance as a UI amount (with decimals), or 0 if no account exists
129
+ * @throws {NosanaError} If neither owner nor wallet is provided
129
130
  */
130
131
  async getBalance(owner) {
131
- const account = await this.getTokenAccountForAddress(owner);
132
+ let ownerAddr;
133
+ if (owner) {
134
+ ownerAddr = typeof owner === 'string' ? address(owner) : owner;
135
+ }
136
+ else {
137
+ const wallet = deps.getWallet();
138
+ if (!wallet) {
139
+ throw new NosanaError('No wallet found and no owner address provided', ErrorCodes.NO_WALLET);
140
+ }
141
+ ownerAddr = wallet.address;
142
+ }
143
+ const account = await this.getTokenAccountForAddress(ownerAddr);
132
144
  return account ? account.uiAmount : 0;
133
145
  },
146
+ /**
147
+ * Get the associated token account address for a given owner.
148
+ *
149
+ * @param owner The owner address
150
+ * @returns The associated token account address
151
+ */
152
+ async getATA(owner) {
153
+ const ownerAddr = typeof owner === 'string' ? address(owner) : owner;
154
+ const tokenMint = config.tokenAddress;
155
+ const [ata] = await findAssociatedTokenPda({
156
+ mint: tokenMint,
157
+ owner: ownerAddr,
158
+ tokenProgram: TOKEN_PROGRAM_ADDRESS,
159
+ });
160
+ return ata;
161
+ },
162
+ /**
163
+ * Get instruction(s) to transfer SPL tokens from one address to another.
164
+ * May return 1 or 2 instructions depending on whether the recipient's associated token account needs to be created.
165
+ *
166
+ * @param params Transfer parameters
167
+ * @param params.to Recipient address
168
+ * @param params.amount Amount in token base units (number or bigint)
169
+ * @param params.from Optional sender TransactionSigner. If not provided, uses wallet from client.
170
+ * @returns Array of instructions (create ATA instruction if needed, then transfer instruction)
171
+ */
172
+ async transfer(params) {
173
+ try {
174
+ // Determine sender: use params.from if provided, otherwise use wallet
175
+ const sender = params.from ?? deps.getWallet();
176
+ if (!sender) {
177
+ throw new NosanaError('No wallet found and no from parameter provided', ErrorCodes.NO_WALLET);
178
+ }
179
+ // Convert amount to bigint if it's a number
180
+ const amountBigInt = typeof params.amount === 'bigint' ? params.amount : BigInt(params.amount);
181
+ // Convert recipient to Address
182
+ const recipient = typeof params.to === 'string' ? address(params.to) : params.to;
183
+ const tokenMint = config.tokenAddress;
184
+ deps.logger.debug(`Creating SPL token transfer instruction: ${amountBigInt} tokens from ${sender.address} to ${recipient}`);
185
+ // Find sender's ATA
186
+ const senderAta = await this.getATA(sender.address);
187
+ // Find recipient's ATA
188
+ const recipientAta = await this.getATA(recipient);
189
+ // Check if recipient ATA exists and get create instruction if needed
190
+ const createAtaInstruction = await deps.solana.getCreateATAInstructionIfNeeded(recipientAta, tokenMint, recipient, sender);
191
+ // Create transfer instruction
192
+ const transferIx = getTransferInstruction({
193
+ source: senderAta,
194
+ destination: recipientAta,
195
+ authority: sender.address,
196
+ amount: amountBigInt,
197
+ });
198
+ // Return array of instructions - either 1 or 2 instructions
199
+ if (createAtaInstruction) {
200
+ return [createAtaInstruction, transferIx];
201
+ }
202
+ return [transferIx];
203
+ }
204
+ catch (error) {
205
+ if (error instanceof NosanaError) {
206
+ throw error;
207
+ }
208
+ deps.logger.error(`Failed to get transfer instruction: ${error}`);
209
+ throw new NosanaError('Failed to get transfer instruction', ErrorCodes.TRANSACTION_ERROR, error);
210
+ }
211
+ },
134
212
  };
135
213
  }
136
214
  //# sourceMappingURL=TokenService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenService.js","sourceRoot":"","sources":["../../../src/services/token/TokenService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from './TokenService.js';
@@ -0,0 +1,2 @@
1
+ export * from './TokenService.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/token/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
package/dist/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { TransactionSigner, MessageSigner } from '@solana/kit';
2
- import type { SolanaService } from './services/SolanaService.js';
2
+ import type { SolanaService } from './services/solana/index.js';
3
+ import type { TokenService } from './services/token/index.js';
3
4
  import { Logger } from './logger/Logger.js';
4
5
  /**
5
6
  * A wallet that can sign both messages and transactions.
@@ -13,5 +14,6 @@ export type Wallet = MessageSigner & TransactionSigner;
13
14
  export interface ProgramDeps {
14
15
  logger: Logger;
15
16
  solana: SolanaService;
17
+ nos: TokenService;
16
18
  getWallet: () => Wallet | undefined;
17
19
  }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * URL protocol constants
3
+ */
4
+ export declare const PROTOCOL: {
5
+ readonly HTTP: "http";
6
+ readonly HTTPS: "https";
7
+ readonly WS: "ws";
8
+ readonly WSS: "wss";
9
+ };
10
+ /**
11
+ * Converts an HTTP/HTTPS URL to a WebSocket URL (ws/wss).
12
+ * Replaces the protocol: http -> ws, https -> wss
13
+ *
14
+ * @param httpUrl The HTTP or HTTPS URL to convert
15
+ * @returns The WebSocket URL with the protocol replaced
16
+ * @throws NosanaError if the URL doesn't use HTTP/HTTPS protocol
17
+ * @throws TypeError if the URL is invalid
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * convertHttpToWebSocketUrl('https://api.mainnet-beta.solana.com')
22
+ * // Returns: 'wss://api.mainnet-beta.solana.com'
23
+ *
24
+ * convertHttpToWebSocketUrl('http://localhost:8899')
25
+ * // Returns: 'ws://localhost:8899'
26
+ * ```
27
+ */
28
+ export declare function convertHttpToWebSocketUrl(httpUrl: string): string;
@@ -0,0 +1,37 @@
1
+ import { NosanaError, ErrorCodes } from '../errors/NosanaError.js';
2
+ /**
3
+ * URL protocol constants
4
+ */
5
+ export const PROTOCOL = {
6
+ HTTP: 'http',
7
+ HTTPS: 'https',
8
+ WS: 'ws',
9
+ WSS: 'wss',
10
+ };
11
+ /**
12
+ * Converts an HTTP/HTTPS URL to a WebSocket URL (ws/wss).
13
+ * Replaces the protocol: http -> ws, https -> wss
14
+ *
15
+ * @param httpUrl The HTTP or HTTPS URL to convert
16
+ * @returns The WebSocket URL with the protocol replaced
17
+ * @throws NosanaError if the URL doesn't use HTTP/HTTPS protocol
18
+ * @throws TypeError if the URL is invalid
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * convertHttpToWebSocketUrl('https://api.mainnet-beta.solana.com')
23
+ * // Returns: 'wss://api.mainnet-beta.solana.com'
24
+ *
25
+ * convertHttpToWebSocketUrl('http://localhost:8899')
26
+ * // Returns: 'ws://localhost:8899'
27
+ * ```
28
+ */
29
+ export function convertHttpToWebSocketUrl(httpUrl) {
30
+ const url = new URL(httpUrl);
31
+ if (!url.protocol.match(/^https?:$/i)) {
32
+ throw new NosanaError(`Unsupported protocol: ${url.protocol}. Only HTTP and HTTPS are supported.`, ErrorCodes.VALIDATION_ERROR);
33
+ }
34
+ url.protocol = url.protocol.replace(PROTOCOL.HTTP, PROTOCOL.WS);
35
+ return url.toString();
36
+ }
37
+ //# sourceMappingURL=convertHttpToWebSocketUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convertHttpToWebSocketUrl.js","sourceRoot":"","sources":["../../src/utils/convertHttpToWebSocketUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEnE;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,EAAE,EAAE,IAAI;IACR,GAAG,EAAE,KAAK;CACF,CAAC;AAEX;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAe;IACvD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,WAAW,CACnB,yBAAyB,GAAG,CAAC,QAAQ,sCAAsC,EAC3E,UAAU,CAAC,gBAAgB,CAC5B,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IAChE,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { Address } from '@solana/kit';
2
- import type { SolanaService } from '../services/SolanaService.js';
2
+ import type { SolanaService } from '../services/solana/index.js';
3
3
  import type { ProgramConfig } from '../config/types.js';
4
4
  export type StaticAccounts = {
5
5
  rewardsReflection: Address;
@@ -1,3 +1,4 @@
1
1
  export * from './convertBigIntToNumber.js';
2
+ export * from './convertHttpToWebSocketUrl.js';
2
3
  export * from './getStaticAccounts.js';
3
4
  export * from './walletToAuthorizationSigner.js';
@@ -1,5 +1,6 @@
1
1
  // Barrel export file - exports all utility functions and types
2
2
  export * from './convertBigIntToNumber.js';
3
+ export * from './convertHttpToWebSocketUrl.js';
3
4
  export * from './getStaticAccounts.js';
4
5
  export * from './walletToAuthorizationSigner.js';
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC"}
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@nosana/kit",
3
- "version": "2.0.19",
3
+ "version": "2.0.25",
4
4
  "description": "Nosana KIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
9
  "build": "tsc",
10
- "test": "vitest run",
11
- "test:coverage": "vitest run --coverage",
12
- "test:watch": "vitest",
10
+ "test": "NODE_NO_WARNINGS=1 vitest run",
11
+ "test:coverage": "NODE_NO_WARNINGS=1 vitest run --coverage",
12
+ "test:watch": "NODE_NO_WARNINGS=1 vitest",
13
13
  "generate-clients": "npx tsx scripts/generate-clients.ts",
14
14
  "lint": "eslint .",
15
15
  "lint:fix": "eslint . --fix",