Solana Service
General Solana utility service for low-level RPC operations, transactions, and PDA derivations.
Methods
Build, Sign, and Send (Convenience Method)
ts
buildSignAndSend(
instructions: Instruction | Instruction[],
options?: {
feePayer?: TransactionSigner;
commitment?: 'processed' | 'confirmed' | 'finalized';
}
): Promise<Signature>Build Transaction
ts
buildTransaction(
instructions: Instruction | Instruction[],
options?: { feePayer?: TransactionSigner }
): Promise<TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithBlockhashLifetime>Sign Transaction
ts
signTransaction(
transactionMessage: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithBlockhashLifetime
): Promise<SendableTransaction & Transaction & TransactionWithBlockhashLifetime>Send Transaction
ts
sendTransaction(
transaction: SendableTransaction & Transaction & TransactionWithBlockhashLifetime,
options?: { commitment?: 'processed' | 'confirmed' | 'finalized' }
): Promise<Signature>Get Balance
ts
getBalance(address?: Address | string): Promise<bigint>Get Balance Info
ts
getBalanceInfo(address?: Address | string): Promise<SolBalanceInfo>Derive PDA
ts
pda(seeds: Array<Address | string>, programId: Address): Promise<Address>Get NFT From Collection
ts
getNftFromCollection(owner: Address, collection: Address): Promise<Address | undefined>Returns the mint of the first NFT owner holds (at least one token, classic SPL token program) whose Metaplex metadata has collection as its verified collection, or undefined if there is none. Metadata accounts that are missing or cannot be decoded are skipped. Use it to find a market's access-key NFT before calling jobs.work({ market, nft }).
Transfer SOL
ts
transfer(params: {
to: Address | string;
amount: number | bigint;
from?: TransactionSigner;
}): Promise<Instruction> // Returns TransferSolInstructionExamples
ts
import type { type Signature = NominalType<"brand", "Signature"> & NominalType<"stringEncoding", "base58"> & stringA 64-byte Ed25519 signature as a base58-encoded string.Signature } from '@solana/kit';
import type { type Address = NominalType<"brand", "Address"> & NominalType<"stringEncoding", "base58"> & stringRepresents a string that validates as a Solana address or public key.Address } from '@nosana/kit';
// Send a single instruction (convenience method)
const const signature: Signaturesignature: type Signature = NominalType<"brand", "Signature"> & NominalType<"stringEncoding", "base58"> & stringA 64-byte Ed25519 signature as a base58-encoded string.Signature = await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.buildSignAndSend(instructions: Instruction | Instruction[], options?: {
feePayer?: TransactionSigner;
commitment?: "processed" | "confirmed" | "finalized";
estimateComputeUnits?: boolean;
}): Promise<Signature>
buildSignAndSend(const instruction: Instruction<string, readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]>instruction);
// Send multiple instructions atomically
const const signature2: Signaturesignature2: type Signature = NominalType<"brand", "Signature"> & NominalType<"stringEncoding", "base58"> & stringA 64-byte Ed25519 signature as a base58-encoded string.Signature = await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.buildSignAndSend(instructions: Instruction | Instruction[], options?: {
feePayer?: TransactionSigner;
commitment?: "processed" | "confirmed" | "finalized";
estimateComputeUnits?: boolean;
}): Promise<Signature>
buildSignAndSend([const ix1: Instruction<string, readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]>ix1, const ix2: Instruction<string, readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]>ix2, const ix3: Instruction<string, readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]>ix3]);
// Or build, sign, and send separately for more control
const const transactionMessage: TransactionMessage & TransactionMessageWithFeePayer<string> & TransactionMessageWithBlockhashLifetimetransactionMessage = await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.buildTransaction(instructions: Instruction | Instruction[], options?: {
feePayer?: TransactionSigner | Address | string;
estimateComputeUnits?: boolean;
}): Promise<TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithBlockhashLifetime>
Build a transaction message from instructions.
This function creates a transaction message with fee payer, blockhash, and instructions.buildTransaction(const instruction: Instruction<string, readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]>instruction);
const const signedTransaction: FullySignedTransaction & TransactionWithinSizeLimit & Readonly<{
messageBytes: TransactionMessageBytes;
signatures: SignaturesMap;
}> & TransactionWithBlockhashLifetime
signedTransaction = await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.signTransaction(transactionMessage: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithBlockhashLifetime): Promise<SendableTransaction & Transaction & TransactionWithBlockhashLifetime>signTransaction(const transactionMessage: TransactionMessage & TransactionMessageWithFeePayer<string> & TransactionMessageWithBlockhashLifetimetransactionMessage);
const const signature3: Signaturesignature3: type Signature = NominalType<"brand", "Signature"> & NominalType<"stringEncoding", "base58"> & stringA 64-byte Ed25519 signature as a base58-encoded string.Signature = await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.sendTransaction(transaction: SendableTransaction & Transaction & TransactionWithBlockhashLifetime, options?: {
commitment?: "processed" | "confirmed" | "finalized";
}): Promise<Signature>
sendTransaction(const signedTransaction: FullySignedTransaction & TransactionWithinSizeLimit & Readonly<{
messageBytes: TransactionMessageBytes;
signatures: SignaturesMap;
}> & TransactionWithBlockhashLifetime
signedTransaction);
// Check account balance
const const balance: bigintbalance: bigint = await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.getBalance(addressStr?: string | Address): Promise<bigint>Get the SOL balance for a specific address.getBalance(address<"address">(putativeAddress: "address"): Address<"address">Combines _asserting_ that a string is an address with _coercing_ it to the
{@link
Address
}
type.
It's most useful with untrusted input.address('address'));
var console: ConsoleThe `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.log(`Balance: ${const balance: bigintbalance} lamports`);
// Or get exact lamports plus display metadata
const const balanceInfo: SolBalanceInfobalanceInfo = await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.getBalanceInfo(addressStr?: string | Address): Promise<SolBalanceInfo>Get SOL balance metadata for a specific address.getBalanceInfo(address<"address">(putativeAddress: "address"): Address<"address">Combines _asserting_ that a string is an address with _coercing_ it to the
{@link
Address
}
type.
It's most useful with untrusted input.address('address'));
var console: ConsoleThe `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.log(`Balance: ${const balanceInfo: SolBalanceInfobalanceInfo.BalanceInfo.uiAmount: numberuiAmount} SOL`);
// Derive PDA
const const pda: Addresspda: type Address = NominalType<"brand", "Address"> & NominalType<"stringEncoding", "base58"> & stringRepresents a string that validates as a Solana address or public key.Address = await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.pda(seeds: Array<Address | string>, programId: Address): Promise<Address>pda(['seed1', 'seed2'], const programAddress: Address<"program-address">programAddress);
// Find the owner's NFT from a verified collection (e.g. a market access key)
const const nft: Address | undefinednft: type Address = NominalType<"brand", "Address"> & NominalType<"stringEncoding", "base58"> & stringRepresents a string that validates as a Solana address or public key.Address | undefined = await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.getNftFromCollection(owner: Address, collection: Address): Promise<Address | undefined>Find the first NFT of a verified Metaplex collection held by `owner`, e.g. a
market's access key to pass as `nft` to `jobs.work`.
Looks at the owner's SPL token accounts (classic token program) holding at
least one token, decodes each mint's Metaplex metadata account, and returns
the first mint whose metadata has `collection` set to the given address with
`verified: true`. Metadata accounts that are missing or cannot be decoded are
skipped.getNftFromCollection(
address<"owner-address">(putativeAddress: "owner-address"): Address<"owner-address">Combines _asserting_ that a string is an address with _coercing_ it to the
{@link
Address
}
type.
It's most useful with untrusted input.address('owner-address'),
address<"collection-address">(putativeAddress: "collection-address"): Address<"collection-address">Combines _asserting_ that a string is an address with _coercing_ it to the
{@link
Address
}
type.
It's most useful with untrusted input.address('collection-address')
);
// Get instruction to transfer SOL
const const transferSolIx: Instruction<string, readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]>transferSolIx: interface Instruction<TProgramAddress extends string = string, TAccounts extends readonly (AccountLookupMeta | AccountMeta)[] = readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]>An instruction destined for a given program.Instruction = await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.transfer(params: {
to: Address | string;
amount: number | bigint;
from?: TransactionSigner;
}): Promise<ReturnType<typeof getTransferSolInstruction>>
Get an instruction to transfer SOL from one address to another.transfer({
to: string | Addressto: address<"recipient-address">(putativeAddress: "recipient-address"): Address<"recipient-address">Combines _asserting_ that a string is an address with _coercing_ it to the
{@link
Address
}
type.
It's most useful with untrusted input.address('recipient-address'),
amount: number | bigintamount: 1000000, // lamports (can be number or bigint)
// from is optional - uses wallet if not provided
});
// Execute the transfer
await const client: NosanaClientclient.NosanaClient.solana: SolanaServicesolana.SolanaService.buildSignAndSend(instructions: Instruction | Instruction[], options?: {
feePayer?: TransactionSigner;
commitment?: "processed" | "confirmed" | "finalized";
estimateComputeUnits?: boolean;
}): Promise<Signature>
buildSignAndSend(const transferSolIx: Instruction<string, readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]>transferSolIx);