@blockrun/llm 1.0.0 → 1.1.0
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.
- package/README.md +48 -11
- package/dist/{chunk-S7BEMV6T.js → chunk-KRDGCX7W.js} +25914 -25839
- package/dist/{esm-EBZAIN5N.js → esm-PTFDM6PE.js} +159 -6
- package/dist/index.cjs +36896 -38
- package/dist/index.d.cts +112 -2
- package/dist/index.d.ts +112 -2
- package/dist/{index.esm-WP2DIBSK.js → index.esm-SXKIFLA7.js} +3 -2
- package/dist/index.js +332 -2
- package/package.json +71 -71
- package/dist/chunk-2ESYSVXG.js +0 -48
package/dist/index.d.cts
CHANGED
|
@@ -301,7 +301,7 @@ declare class LLMClient {
|
|
|
301
301
|
* ```ts
|
|
302
302
|
* const result = await client.smartChat('What is 2+2?');
|
|
303
303
|
* console.log(result.response); // '4'
|
|
304
|
-
* console.log(result.model); // 'google/gemini-2.5-flash'
|
|
304
|
+
* console.log(result.model); // 'google/gemini-2.5-flash-lite'
|
|
305
305
|
* console.log(result.routing.savings); // 0.78 (78% savings)
|
|
306
306
|
* ```
|
|
307
307
|
*
|
|
@@ -502,6 +502,33 @@ declare class ImageClient {
|
|
|
502
502
|
|
|
503
503
|
declare const BASE_CHAIN_ID = 8453;
|
|
504
504
|
declare const USDC_BASE: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
505
|
+
declare const SOLANA_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
506
|
+
declare const USDC_SOLANA = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
507
|
+
interface CreateSolanaPaymentOptions {
|
|
508
|
+
resourceUrl?: string;
|
|
509
|
+
resourceDescription?: string;
|
|
510
|
+
maxTimeoutSeconds?: number;
|
|
511
|
+
extra?: Record<string, unknown>;
|
|
512
|
+
extensions?: Record<string, unknown>;
|
|
513
|
+
rpcUrl?: string;
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Create a signed Solana x402 v2 payment payload.
|
|
517
|
+
*
|
|
518
|
+
* This creates an SPL TransferChecked transaction for USDC payment
|
|
519
|
+
* that the CDP facilitator can verify and settle.
|
|
520
|
+
*
|
|
521
|
+
* Requires @solana/web3.js and @solana/spl-token dependencies.
|
|
522
|
+
*
|
|
523
|
+
* @param secretKey - Solana secret key (Uint8Array, 64 bytes)
|
|
524
|
+
* @param fromAddress - Sender wallet address (base58)
|
|
525
|
+
* @param recipient - Payment recipient address (base58)
|
|
526
|
+
* @param amount - Amount in micro USDC (6 decimals)
|
|
527
|
+
* @param feePayer - CDP facilitator fee payer address (base58)
|
|
528
|
+
* @param options - Additional options
|
|
529
|
+
* @returns Base64-encoded signed payment payload
|
|
530
|
+
*/
|
|
531
|
+
declare function createSolanaPaymentPayload(secretKey: Uint8Array, fromAddress: string, recipient: string, amount: string, feePayer: string, options?: CreateSolanaPaymentOptions): Promise<string>;
|
|
505
532
|
|
|
506
533
|
/**
|
|
507
534
|
* BlockRun Wallet Management - Auto-create and manage wallets.
|
|
@@ -602,6 +629,89 @@ declare function formatFundingMessageCompact(address: string): string;
|
|
|
602
629
|
declare const WALLET_FILE_PATH: string;
|
|
603
630
|
declare const WALLET_DIR_PATH: string;
|
|
604
631
|
|
|
632
|
+
/**
|
|
633
|
+
* BlockRun Solana LLM Client.
|
|
634
|
+
*
|
|
635
|
+
* Usage:
|
|
636
|
+
* import { SolanaLLMClient } from '@blockrun/llm';
|
|
637
|
+
*
|
|
638
|
+
* // SOLANA_WALLET_KEY env var (bs58-encoded Solana secret key)
|
|
639
|
+
* const client = new SolanaLLMClient();
|
|
640
|
+
*
|
|
641
|
+
* // Or pass key directly
|
|
642
|
+
* const client = new SolanaLLMClient({ privateKey: 'your-bs58-key' });
|
|
643
|
+
*
|
|
644
|
+
* const response = await client.chat('openai/gpt-4o', 'gm Solana');
|
|
645
|
+
*/
|
|
646
|
+
|
|
647
|
+
interface SolanaLLMClientOptions {
|
|
648
|
+
/** bs58-encoded Solana secret key (64 bytes). Optional if SOLANA_WALLET_KEY env var is set. */
|
|
649
|
+
privateKey?: string;
|
|
650
|
+
/** API endpoint URL (default: https://sol.blockrun.ai/api) */
|
|
651
|
+
apiUrl?: string;
|
|
652
|
+
/** Solana RPC URL (default: https://api.mainnet-beta.solana.com) */
|
|
653
|
+
rpcUrl?: string;
|
|
654
|
+
/** Request timeout in milliseconds (default: 60000) */
|
|
655
|
+
timeout?: number;
|
|
656
|
+
}
|
|
657
|
+
declare class SolanaLLMClient {
|
|
658
|
+
static readonly SOLANA_API_URL = "https://sol.blockrun.ai/api";
|
|
659
|
+
private privateKey;
|
|
660
|
+
private apiUrl;
|
|
661
|
+
private rpcUrl;
|
|
662
|
+
private timeout;
|
|
663
|
+
private sessionTotalUsd;
|
|
664
|
+
private sessionCalls;
|
|
665
|
+
private addressCache;
|
|
666
|
+
constructor(options?: SolanaLLMClientOptions);
|
|
667
|
+
/** Get Solana wallet address (public key in base58). */
|
|
668
|
+
getWalletAddress(): Promise<string>;
|
|
669
|
+
/** Simple 1-line chat. */
|
|
670
|
+
chat(model: string, prompt: string, options?: ChatOptions): Promise<string>;
|
|
671
|
+
/** Full chat completion (OpenAI-compatible). */
|
|
672
|
+
chatCompletion(model: string, messages: ChatMessage[], options?: ChatCompletionOptions): Promise<ChatResponse>;
|
|
673
|
+
/** List available models. */
|
|
674
|
+
listModels(): Promise<Model[]>;
|
|
675
|
+
/** Get session spending. */
|
|
676
|
+
getSpending(): Spending;
|
|
677
|
+
/** True if using sol.blockrun.ai. */
|
|
678
|
+
isSolana(): boolean;
|
|
679
|
+
private requestWithPayment;
|
|
680
|
+
private handlePaymentAndRetry;
|
|
681
|
+
private fetchWithTimeout;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Convenience function: create SolanaLLMClient for sol.blockrun.ai.
|
|
685
|
+
*/
|
|
686
|
+
declare function solanaClient(options?: SolanaLLMClientOptions): SolanaLLMClient;
|
|
687
|
+
|
|
688
|
+
declare const SOLANA_WALLET_FILE: string;
|
|
689
|
+
interface SolanaWalletInfo {
|
|
690
|
+
privateKey: string;
|
|
691
|
+
address: string;
|
|
692
|
+
isNew: boolean;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Create a new Solana wallet.
|
|
696
|
+
* Requires @solana/web3.js (optional dep).
|
|
697
|
+
*/
|
|
698
|
+
declare function createSolanaWallet(): {
|
|
699
|
+
address: string;
|
|
700
|
+
privateKey: string;
|
|
701
|
+
};
|
|
702
|
+
/**
|
|
703
|
+
* Convert a bs58 private key string to Uint8Array (64 bytes).
|
|
704
|
+
* Accepts: bs58-encoded 64-byte key (standard Solana format).
|
|
705
|
+
*/
|
|
706
|
+
declare function solanaKeyToBytes(privateKey: string): Promise<Uint8Array>;
|
|
707
|
+
/**
|
|
708
|
+
* Get Solana public key (address) from bs58 private key.
|
|
709
|
+
*/
|
|
710
|
+
declare function solanaPublicKey(privateKey: string): Promise<string>;
|
|
711
|
+
declare function saveSolanaWallet(privateKey: string): string;
|
|
712
|
+
declare function loadSolanaWallet(): string | null;
|
|
713
|
+
declare function getOrCreateSolanaWallet(): Promise<SolanaWalletInfo>;
|
|
714
|
+
|
|
605
715
|
/**
|
|
606
716
|
* OpenAI-compatible API wrapper for BlockRun LLM SDK.
|
|
607
717
|
*
|
|
@@ -741,4 +851,4 @@ declare class OpenAI {
|
|
|
741
851
|
getWalletAddress(): string;
|
|
742
852
|
}
|
|
743
853
|
|
|
744
|
-
export { APIError, BASE_CHAIN_ID, BlockrunError, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatUsage, type FunctionCall, type FunctionDefinition, ImageClient, type ImageClientOptions, type ImageData, type ImageGenerateOptions, type ImageModel, type ImageResponse, LLMClient, type LLMClientOptions, type Model, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PaymentError, type PaymentLinks, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, type SearchParameters, type SearchSource, type SmartChatOptions, type SmartChatResponse, type Spending, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, createWallet, LLMClient as default, formatFundingMessageCompact, formatNeedsFundingMessage, formatWalletCreatedMessage, getEip681Uri, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadWallet, saveWallet, testnetClient };
|
|
854
|
+
export { APIError, BASE_CHAIN_ID, BlockrunError, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatUsage, type FunctionCall, type FunctionDefinition, ImageClient, type ImageClientOptions, type ImageData, type ImageGenerateOptions, type ImageModel, type ImageResponse, LLMClient, type LLMClientOptions, type Model, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PaymentError, type PaymentLinks, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, type SearchParameters, type SearchSource, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type Spending, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, formatFundingMessageCompact, formatNeedsFundingMessage, formatWalletCreatedMessage, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadSolanaWallet, loadWallet, saveSolanaWallet, saveWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, testnetClient };
|
package/dist/index.d.ts
CHANGED
|
@@ -301,7 +301,7 @@ declare class LLMClient {
|
|
|
301
301
|
* ```ts
|
|
302
302
|
* const result = await client.smartChat('What is 2+2?');
|
|
303
303
|
* console.log(result.response); // '4'
|
|
304
|
-
* console.log(result.model); // 'google/gemini-2.5-flash'
|
|
304
|
+
* console.log(result.model); // 'google/gemini-2.5-flash-lite'
|
|
305
305
|
* console.log(result.routing.savings); // 0.78 (78% savings)
|
|
306
306
|
* ```
|
|
307
307
|
*
|
|
@@ -502,6 +502,33 @@ declare class ImageClient {
|
|
|
502
502
|
|
|
503
503
|
declare const BASE_CHAIN_ID = 8453;
|
|
504
504
|
declare const USDC_BASE: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
505
|
+
declare const SOLANA_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
506
|
+
declare const USDC_SOLANA = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
507
|
+
interface CreateSolanaPaymentOptions {
|
|
508
|
+
resourceUrl?: string;
|
|
509
|
+
resourceDescription?: string;
|
|
510
|
+
maxTimeoutSeconds?: number;
|
|
511
|
+
extra?: Record<string, unknown>;
|
|
512
|
+
extensions?: Record<string, unknown>;
|
|
513
|
+
rpcUrl?: string;
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Create a signed Solana x402 v2 payment payload.
|
|
517
|
+
*
|
|
518
|
+
* This creates an SPL TransferChecked transaction for USDC payment
|
|
519
|
+
* that the CDP facilitator can verify and settle.
|
|
520
|
+
*
|
|
521
|
+
* Requires @solana/web3.js and @solana/spl-token dependencies.
|
|
522
|
+
*
|
|
523
|
+
* @param secretKey - Solana secret key (Uint8Array, 64 bytes)
|
|
524
|
+
* @param fromAddress - Sender wallet address (base58)
|
|
525
|
+
* @param recipient - Payment recipient address (base58)
|
|
526
|
+
* @param amount - Amount in micro USDC (6 decimals)
|
|
527
|
+
* @param feePayer - CDP facilitator fee payer address (base58)
|
|
528
|
+
* @param options - Additional options
|
|
529
|
+
* @returns Base64-encoded signed payment payload
|
|
530
|
+
*/
|
|
531
|
+
declare function createSolanaPaymentPayload(secretKey: Uint8Array, fromAddress: string, recipient: string, amount: string, feePayer: string, options?: CreateSolanaPaymentOptions): Promise<string>;
|
|
505
532
|
|
|
506
533
|
/**
|
|
507
534
|
* BlockRun Wallet Management - Auto-create and manage wallets.
|
|
@@ -602,6 +629,89 @@ declare function formatFundingMessageCompact(address: string): string;
|
|
|
602
629
|
declare const WALLET_FILE_PATH: string;
|
|
603
630
|
declare const WALLET_DIR_PATH: string;
|
|
604
631
|
|
|
632
|
+
/**
|
|
633
|
+
* BlockRun Solana LLM Client.
|
|
634
|
+
*
|
|
635
|
+
* Usage:
|
|
636
|
+
* import { SolanaLLMClient } from '@blockrun/llm';
|
|
637
|
+
*
|
|
638
|
+
* // SOLANA_WALLET_KEY env var (bs58-encoded Solana secret key)
|
|
639
|
+
* const client = new SolanaLLMClient();
|
|
640
|
+
*
|
|
641
|
+
* // Or pass key directly
|
|
642
|
+
* const client = new SolanaLLMClient({ privateKey: 'your-bs58-key' });
|
|
643
|
+
*
|
|
644
|
+
* const response = await client.chat('openai/gpt-4o', 'gm Solana');
|
|
645
|
+
*/
|
|
646
|
+
|
|
647
|
+
interface SolanaLLMClientOptions {
|
|
648
|
+
/** bs58-encoded Solana secret key (64 bytes). Optional if SOLANA_WALLET_KEY env var is set. */
|
|
649
|
+
privateKey?: string;
|
|
650
|
+
/** API endpoint URL (default: https://sol.blockrun.ai/api) */
|
|
651
|
+
apiUrl?: string;
|
|
652
|
+
/** Solana RPC URL (default: https://api.mainnet-beta.solana.com) */
|
|
653
|
+
rpcUrl?: string;
|
|
654
|
+
/** Request timeout in milliseconds (default: 60000) */
|
|
655
|
+
timeout?: number;
|
|
656
|
+
}
|
|
657
|
+
declare class SolanaLLMClient {
|
|
658
|
+
static readonly SOLANA_API_URL = "https://sol.blockrun.ai/api";
|
|
659
|
+
private privateKey;
|
|
660
|
+
private apiUrl;
|
|
661
|
+
private rpcUrl;
|
|
662
|
+
private timeout;
|
|
663
|
+
private sessionTotalUsd;
|
|
664
|
+
private sessionCalls;
|
|
665
|
+
private addressCache;
|
|
666
|
+
constructor(options?: SolanaLLMClientOptions);
|
|
667
|
+
/** Get Solana wallet address (public key in base58). */
|
|
668
|
+
getWalletAddress(): Promise<string>;
|
|
669
|
+
/** Simple 1-line chat. */
|
|
670
|
+
chat(model: string, prompt: string, options?: ChatOptions): Promise<string>;
|
|
671
|
+
/** Full chat completion (OpenAI-compatible). */
|
|
672
|
+
chatCompletion(model: string, messages: ChatMessage[], options?: ChatCompletionOptions): Promise<ChatResponse>;
|
|
673
|
+
/** List available models. */
|
|
674
|
+
listModels(): Promise<Model[]>;
|
|
675
|
+
/** Get session spending. */
|
|
676
|
+
getSpending(): Spending;
|
|
677
|
+
/** True if using sol.blockrun.ai. */
|
|
678
|
+
isSolana(): boolean;
|
|
679
|
+
private requestWithPayment;
|
|
680
|
+
private handlePaymentAndRetry;
|
|
681
|
+
private fetchWithTimeout;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Convenience function: create SolanaLLMClient for sol.blockrun.ai.
|
|
685
|
+
*/
|
|
686
|
+
declare function solanaClient(options?: SolanaLLMClientOptions): SolanaLLMClient;
|
|
687
|
+
|
|
688
|
+
declare const SOLANA_WALLET_FILE: string;
|
|
689
|
+
interface SolanaWalletInfo {
|
|
690
|
+
privateKey: string;
|
|
691
|
+
address: string;
|
|
692
|
+
isNew: boolean;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Create a new Solana wallet.
|
|
696
|
+
* Requires @solana/web3.js (optional dep).
|
|
697
|
+
*/
|
|
698
|
+
declare function createSolanaWallet(): {
|
|
699
|
+
address: string;
|
|
700
|
+
privateKey: string;
|
|
701
|
+
};
|
|
702
|
+
/**
|
|
703
|
+
* Convert a bs58 private key string to Uint8Array (64 bytes).
|
|
704
|
+
* Accepts: bs58-encoded 64-byte key (standard Solana format).
|
|
705
|
+
*/
|
|
706
|
+
declare function solanaKeyToBytes(privateKey: string): Promise<Uint8Array>;
|
|
707
|
+
/**
|
|
708
|
+
* Get Solana public key (address) from bs58 private key.
|
|
709
|
+
*/
|
|
710
|
+
declare function solanaPublicKey(privateKey: string): Promise<string>;
|
|
711
|
+
declare function saveSolanaWallet(privateKey: string): string;
|
|
712
|
+
declare function loadSolanaWallet(): string | null;
|
|
713
|
+
declare function getOrCreateSolanaWallet(): Promise<SolanaWalletInfo>;
|
|
714
|
+
|
|
605
715
|
/**
|
|
606
716
|
* OpenAI-compatible API wrapper for BlockRun LLM SDK.
|
|
607
717
|
*
|
|
@@ -741,4 +851,4 @@ declare class OpenAI {
|
|
|
741
851
|
getWalletAddress(): string;
|
|
742
852
|
}
|
|
743
853
|
|
|
744
|
-
export { APIError, BASE_CHAIN_ID, BlockrunError, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatUsage, type FunctionCall, type FunctionDefinition, ImageClient, type ImageClientOptions, type ImageData, type ImageGenerateOptions, type ImageModel, type ImageResponse, LLMClient, type LLMClientOptions, type Model, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PaymentError, type PaymentLinks, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, type SearchParameters, type SearchSource, type SmartChatOptions, type SmartChatResponse, type Spending, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, createWallet, LLMClient as default, formatFundingMessageCompact, formatNeedsFundingMessage, formatWalletCreatedMessage, getEip681Uri, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadWallet, saveWallet, testnetClient };
|
|
854
|
+
export { APIError, BASE_CHAIN_ID, BlockrunError, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatUsage, type FunctionCall, type FunctionDefinition, ImageClient, type ImageClientOptions, type ImageData, type ImageGenerateOptions, type ImageModel, type ImageResponse, LLMClient, type LLMClientOptions, type Model, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PaymentError, type PaymentLinks, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, type SearchParameters, type SearchSource, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type Spending, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, formatFundingMessageCompact, formatNeedsFundingMessage, formatWalletCreatedMessage, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadSolanaWallet, loadWallet, saveSolanaWallet, saveWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, testnetClient };
|
|
@@ -73,10 +73,11 @@ import {
|
|
|
73
73
|
VoteInstruction,
|
|
74
74
|
VoteProgram,
|
|
75
75
|
clusterApiUrl,
|
|
76
|
+
init_index_esm,
|
|
76
77
|
sendAndConfirmRawTransaction,
|
|
77
78
|
sendAndConfirmTransaction
|
|
78
|
-
} from "./chunk-
|
|
79
|
-
|
|
79
|
+
} from "./chunk-KRDGCX7W.js";
|
|
80
|
+
init_index_esm();
|
|
80
81
|
export {
|
|
81
82
|
Account,
|
|
82
83
|
AddressLookupTableAccount,
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
__require,
|
|
3
|
+
__toCommonJS,
|
|
4
|
+
index_esm_exports,
|
|
5
|
+
init_index_esm
|
|
6
|
+
} from "./chunk-KRDGCX7W.js";
|
|
2
7
|
|
|
3
8
|
// src/client.ts
|
|
4
9
|
import { privateKeyToAccount } from "viem/accounts";
|
|
@@ -34,6 +39,10 @@ import { route, DEFAULT_ROUTING_CONFIG } from "@blockrun/clawrouter";
|
|
|
34
39
|
import { signTypedData } from "viem/accounts";
|
|
35
40
|
var BASE_CHAIN_ID = 8453;
|
|
36
41
|
var USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
42
|
+
var SOLANA_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
43
|
+
var USDC_SOLANA = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
44
|
+
var DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;
|
|
45
|
+
var DEFAULT_COMPUTE_UNIT_LIMIT = 8e3;
|
|
37
46
|
var USDC_DOMAIN = {
|
|
38
47
|
name: "USD Coin",
|
|
39
48
|
version: "2",
|
|
@@ -106,6 +115,66 @@ async function createPaymentPayload(privateKey, fromAddress, recipient, amount,
|
|
|
106
115
|
};
|
|
107
116
|
return btoa(JSON.stringify(paymentData));
|
|
108
117
|
}
|
|
118
|
+
async function createSolanaPaymentPayload(secretKey, fromAddress, recipient, amount, feePayer, options = {}) {
|
|
119
|
+
const { Connection, PublicKey, TransactionMessage, VersionedTransaction, ComputeBudgetProgram } = await import("./index.esm-SXKIFLA7.js");
|
|
120
|
+
const { getAssociatedTokenAddress, createTransferCheckedInstruction, getMint } = await import("./esm-PTFDM6PE.js");
|
|
121
|
+
const { Keypair } = await import("./index.esm-SXKIFLA7.js");
|
|
122
|
+
const rpcUrl = options.rpcUrl || "https://api.mainnet-beta.solana.com";
|
|
123
|
+
const connection = new Connection(rpcUrl);
|
|
124
|
+
const keypair = Keypair.fromSecretKey(secretKey);
|
|
125
|
+
const feePayerPubkey = new PublicKey(feePayer);
|
|
126
|
+
const ownerPubkey = keypair.publicKey;
|
|
127
|
+
const tokenMint = new PublicKey(USDC_SOLANA);
|
|
128
|
+
const payToPubkey = new PublicKey(recipient);
|
|
129
|
+
const mintInfo = await getMint(connection, tokenMint);
|
|
130
|
+
const sourceATA = await getAssociatedTokenAddress(tokenMint, ownerPubkey, false);
|
|
131
|
+
const destinationATA = await getAssociatedTokenAddress(tokenMint, payToPubkey, false);
|
|
132
|
+
const { blockhash } = await connection.getLatestBlockhash();
|
|
133
|
+
const setComputeUnitPriceIx = ComputeBudgetProgram.setComputeUnitPrice({
|
|
134
|
+
microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS
|
|
135
|
+
});
|
|
136
|
+
const setComputeUnitLimitIx = ComputeBudgetProgram.setComputeUnitLimit({
|
|
137
|
+
units: DEFAULT_COMPUTE_UNIT_LIMIT
|
|
138
|
+
});
|
|
139
|
+
const transferIx = createTransferCheckedInstruction(
|
|
140
|
+
sourceATA,
|
|
141
|
+
tokenMint,
|
|
142
|
+
destinationATA,
|
|
143
|
+
ownerPubkey,
|
|
144
|
+
BigInt(amount),
|
|
145
|
+
mintInfo.decimals
|
|
146
|
+
);
|
|
147
|
+
const messageV0 = new TransactionMessage({
|
|
148
|
+
payerKey: feePayerPubkey,
|
|
149
|
+
recentBlockhash: blockhash,
|
|
150
|
+
instructions: [setComputeUnitLimitIx, setComputeUnitPriceIx, transferIx]
|
|
151
|
+
}).compileToV0Message();
|
|
152
|
+
const transaction = new VersionedTransaction(messageV0);
|
|
153
|
+
transaction.sign([keypair]);
|
|
154
|
+
const serializedTx = Buffer.from(transaction.serialize()).toString("base64");
|
|
155
|
+
const paymentData = {
|
|
156
|
+
x402Version: 2,
|
|
157
|
+
resource: {
|
|
158
|
+
url: options.resourceUrl || "https://blockrun.ai/api/v1/chat/completions",
|
|
159
|
+
description: options.resourceDescription || "BlockRun AI API call",
|
|
160
|
+
mimeType: "application/json"
|
|
161
|
+
},
|
|
162
|
+
accepted: {
|
|
163
|
+
scheme: "exact",
|
|
164
|
+
network: SOLANA_NETWORK,
|
|
165
|
+
amount,
|
|
166
|
+
asset: USDC_SOLANA,
|
|
167
|
+
payTo: recipient,
|
|
168
|
+
maxTimeoutSeconds: options.maxTimeoutSeconds || 300,
|
|
169
|
+
extra: options.extra || { feePayer }
|
|
170
|
+
},
|
|
171
|
+
payload: {
|
|
172
|
+
transaction: serializedTx
|
|
173
|
+
},
|
|
174
|
+
extensions: options.extensions || {}
|
|
175
|
+
};
|
|
176
|
+
return btoa(JSON.stringify(paymentData));
|
|
177
|
+
}
|
|
109
178
|
function parsePaymentRequired(headerValue) {
|
|
110
179
|
try {
|
|
111
180
|
const decoded = atob(headerValue);
|
|
@@ -304,7 +373,7 @@ var LLMClient = class {
|
|
|
304
373
|
* ```ts
|
|
305
374
|
* const result = await client.smartChat('What is 2+2?');
|
|
306
375
|
* console.log(result.response); // '4'
|
|
307
|
-
* console.log(result.model); // 'google/gemini-2.5-flash'
|
|
376
|
+
* console.log(result.model); // 'google/gemini-2.5-flash-lite'
|
|
308
377
|
* console.log(result.routing.savings); // 0.78 (78% savings)
|
|
309
378
|
* ```
|
|
310
379
|
*
|
|
@@ -947,6 +1016,255 @@ Check my balance: ${links.basescan}`;
|
|
|
947
1016
|
var WALLET_FILE_PATH = WALLET_FILE;
|
|
948
1017
|
var WALLET_DIR_PATH = WALLET_DIR;
|
|
949
1018
|
|
|
1019
|
+
// src/solana-wallet.ts
|
|
1020
|
+
import * as fs2 from "fs";
|
|
1021
|
+
import * as path2 from "path";
|
|
1022
|
+
import * as os2 from "os";
|
|
1023
|
+
var WALLET_DIR2 = path2.join(os2.homedir(), ".blockrun");
|
|
1024
|
+
var SOLANA_WALLET_FILE = path2.join(WALLET_DIR2, ".solana-session");
|
|
1025
|
+
function createSolanaWallet() {
|
|
1026
|
+
const { Keypair } = (init_index_esm(), __toCommonJS(index_esm_exports));
|
|
1027
|
+
const bs58 = __require("bs58");
|
|
1028
|
+
const keypair = Keypair.generate();
|
|
1029
|
+
return {
|
|
1030
|
+
address: keypair.publicKey.toBase58(),
|
|
1031
|
+
privateKey: bs58.default?.encode(keypair.secretKey) ?? bs58.encode(keypair.secretKey)
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
async function solanaKeyToBytes(privateKey) {
|
|
1035
|
+
try {
|
|
1036
|
+
const bs58 = await import("bs58");
|
|
1037
|
+
const bytes = (bs58.default ?? bs58).decode(privateKey);
|
|
1038
|
+
if (bytes.length !== 64) {
|
|
1039
|
+
throw new Error(`Invalid Solana key length: expected 64 bytes, got ${bytes.length}`);
|
|
1040
|
+
}
|
|
1041
|
+
return bytes;
|
|
1042
|
+
} catch (err) {
|
|
1043
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1044
|
+
throw new Error(`Invalid Solana private key: ${msg}`);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
async function solanaPublicKey(privateKey) {
|
|
1048
|
+
const { Keypair } = await import("./index.esm-SXKIFLA7.js");
|
|
1049
|
+
const bytes = await solanaKeyToBytes(privateKey);
|
|
1050
|
+
return Keypair.fromSecretKey(bytes).publicKey.toBase58();
|
|
1051
|
+
}
|
|
1052
|
+
function saveSolanaWallet(privateKey) {
|
|
1053
|
+
if (!fs2.existsSync(WALLET_DIR2)) fs2.mkdirSync(WALLET_DIR2, { recursive: true });
|
|
1054
|
+
fs2.writeFileSync(SOLANA_WALLET_FILE, privateKey, { mode: 384 });
|
|
1055
|
+
return SOLANA_WALLET_FILE;
|
|
1056
|
+
}
|
|
1057
|
+
function loadSolanaWallet() {
|
|
1058
|
+
if (fs2.existsSync(SOLANA_WALLET_FILE)) {
|
|
1059
|
+
const key = fs2.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
|
|
1060
|
+
if (key) return key;
|
|
1061
|
+
}
|
|
1062
|
+
return null;
|
|
1063
|
+
}
|
|
1064
|
+
async function getOrCreateSolanaWallet() {
|
|
1065
|
+
const envKey = typeof process !== "undefined" && process.env ? process.env.SOLANA_WALLET_KEY : void 0;
|
|
1066
|
+
if (envKey) {
|
|
1067
|
+
const address2 = await solanaPublicKey(envKey);
|
|
1068
|
+
return { privateKey: envKey, address: address2, isNew: false };
|
|
1069
|
+
}
|
|
1070
|
+
const fileKey = loadSolanaWallet();
|
|
1071
|
+
if (fileKey) {
|
|
1072
|
+
const address2 = await solanaPublicKey(fileKey);
|
|
1073
|
+
return { privateKey: fileKey, address: address2, isNew: false };
|
|
1074
|
+
}
|
|
1075
|
+
const { address, privateKey } = createSolanaWallet();
|
|
1076
|
+
saveSolanaWallet(privateKey);
|
|
1077
|
+
return { address, privateKey, isNew: true };
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
// src/solana-client.ts
|
|
1081
|
+
var SOLANA_API_URL = "https://sol.blockrun.ai/api";
|
|
1082
|
+
var DEFAULT_MAX_TOKENS2 = 1024;
|
|
1083
|
+
var DEFAULT_TIMEOUT3 = 6e4;
|
|
1084
|
+
var SDK_VERSION2 = "0.3.0";
|
|
1085
|
+
var USER_AGENT2 = `blockrun-ts/${SDK_VERSION2}`;
|
|
1086
|
+
var SolanaLLMClient = class {
|
|
1087
|
+
static SOLANA_API_URL = SOLANA_API_URL;
|
|
1088
|
+
privateKey;
|
|
1089
|
+
apiUrl;
|
|
1090
|
+
rpcUrl;
|
|
1091
|
+
timeout;
|
|
1092
|
+
sessionTotalUsd = 0;
|
|
1093
|
+
sessionCalls = 0;
|
|
1094
|
+
addressCache = null;
|
|
1095
|
+
constructor(options = {}) {
|
|
1096
|
+
const envKey = typeof process !== "undefined" && process.env ? process.env.SOLANA_WALLET_KEY : void 0;
|
|
1097
|
+
const privateKey = options.privateKey || envKey;
|
|
1098
|
+
if (!privateKey) {
|
|
1099
|
+
throw new Error(
|
|
1100
|
+
"Private key required. Pass privateKey in options or set SOLANA_WALLET_KEY environment variable."
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
this.privateKey = privateKey;
|
|
1104
|
+
const apiUrl = options.apiUrl || SOLANA_API_URL;
|
|
1105
|
+
validateApiUrl(apiUrl);
|
|
1106
|
+
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
1107
|
+
this.rpcUrl = options.rpcUrl || "https://api.mainnet-beta.solana.com";
|
|
1108
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT3;
|
|
1109
|
+
}
|
|
1110
|
+
/** Get Solana wallet address (public key in base58). */
|
|
1111
|
+
async getWalletAddress() {
|
|
1112
|
+
if (!this.addressCache) {
|
|
1113
|
+
this.addressCache = await solanaPublicKey(this.privateKey);
|
|
1114
|
+
}
|
|
1115
|
+
return this.addressCache;
|
|
1116
|
+
}
|
|
1117
|
+
/** Simple 1-line chat. */
|
|
1118
|
+
async chat(model, prompt, options) {
|
|
1119
|
+
const messages = [];
|
|
1120
|
+
if (options?.system) messages.push({ role: "system", content: options.system });
|
|
1121
|
+
messages.push({ role: "user", content: prompt });
|
|
1122
|
+
const result = await this.chatCompletion(model, messages, {
|
|
1123
|
+
maxTokens: options?.maxTokens,
|
|
1124
|
+
temperature: options?.temperature,
|
|
1125
|
+
topP: options?.topP,
|
|
1126
|
+
search: options?.search,
|
|
1127
|
+
searchParameters: options?.searchParameters
|
|
1128
|
+
});
|
|
1129
|
+
return result.choices[0].message.content || "";
|
|
1130
|
+
}
|
|
1131
|
+
/** Full chat completion (OpenAI-compatible). */
|
|
1132
|
+
async chatCompletion(model, messages, options) {
|
|
1133
|
+
const body = {
|
|
1134
|
+
model,
|
|
1135
|
+
messages,
|
|
1136
|
+
max_tokens: options?.maxTokens || DEFAULT_MAX_TOKENS2
|
|
1137
|
+
};
|
|
1138
|
+
if (options?.temperature !== void 0) body.temperature = options.temperature;
|
|
1139
|
+
if (options?.topP !== void 0) body.top_p = options.topP;
|
|
1140
|
+
if (options?.searchParameters !== void 0) body.search_parameters = options.searchParameters;
|
|
1141
|
+
else if (options?.search === true) body.search_parameters = { mode: "on" };
|
|
1142
|
+
if (options?.tools !== void 0) body.tools = options.tools;
|
|
1143
|
+
if (options?.toolChoice !== void 0) body.tool_choice = options.toolChoice;
|
|
1144
|
+
return this.requestWithPayment("/v1/chat/completions", body);
|
|
1145
|
+
}
|
|
1146
|
+
/** List available models. */
|
|
1147
|
+
async listModels() {
|
|
1148
|
+
const response = await this.fetchWithTimeout(`${this.apiUrl}/v1/models`, { method: "GET" });
|
|
1149
|
+
if (!response.ok) {
|
|
1150
|
+
throw new APIError(`Failed to list models: ${response.status}`, response.status);
|
|
1151
|
+
}
|
|
1152
|
+
const data = await response.json();
|
|
1153
|
+
return data.data || [];
|
|
1154
|
+
}
|
|
1155
|
+
/** Get session spending. */
|
|
1156
|
+
getSpending() {
|
|
1157
|
+
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
1158
|
+
}
|
|
1159
|
+
/** True if using sol.blockrun.ai. */
|
|
1160
|
+
isSolana() {
|
|
1161
|
+
return this.apiUrl.includes("sol.blockrun.ai");
|
|
1162
|
+
}
|
|
1163
|
+
async requestWithPayment(endpoint, body) {
|
|
1164
|
+
const url = `${this.apiUrl}${endpoint}`;
|
|
1165
|
+
const response = await this.fetchWithTimeout(url, {
|
|
1166
|
+
method: "POST",
|
|
1167
|
+
headers: { "Content-Type": "application/json", "User-Agent": USER_AGENT2 },
|
|
1168
|
+
body: JSON.stringify(body)
|
|
1169
|
+
});
|
|
1170
|
+
if (response.status === 402) {
|
|
1171
|
+
return this.handlePaymentAndRetry(url, body, response);
|
|
1172
|
+
}
|
|
1173
|
+
if (!response.ok) {
|
|
1174
|
+
let errorBody;
|
|
1175
|
+
try {
|
|
1176
|
+
errorBody = await response.json();
|
|
1177
|
+
} catch {
|
|
1178
|
+
errorBody = { error: "Request failed" };
|
|
1179
|
+
}
|
|
1180
|
+
throw new APIError(`API error: ${response.status}`, response.status, sanitizeErrorResponse(errorBody));
|
|
1181
|
+
}
|
|
1182
|
+
return response.json();
|
|
1183
|
+
}
|
|
1184
|
+
async handlePaymentAndRetry(url, body, response) {
|
|
1185
|
+
let paymentHeader = response.headers.get("payment-required");
|
|
1186
|
+
if (!paymentHeader) {
|
|
1187
|
+
try {
|
|
1188
|
+
const respBody = await response.json();
|
|
1189
|
+
if (respBody.accepts || respBody.x402Version) {
|
|
1190
|
+
paymentHeader = btoa(JSON.stringify(respBody));
|
|
1191
|
+
}
|
|
1192
|
+
} catch {
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
if (!paymentHeader) {
|
|
1196
|
+
throw new PaymentError("402 response but no payment requirements found");
|
|
1197
|
+
}
|
|
1198
|
+
const paymentRequired = parsePaymentRequired(paymentHeader);
|
|
1199
|
+
const details = extractPaymentDetails(paymentRequired, SOLANA_NETWORK);
|
|
1200
|
+
if (!details.network?.startsWith("solana:")) {
|
|
1201
|
+
throw new PaymentError(
|
|
1202
|
+
`Expected Solana payment network, got: ${details.network}. Use LLMClient for Base payments.`
|
|
1203
|
+
);
|
|
1204
|
+
}
|
|
1205
|
+
const feePayer = details.extra?.feePayer;
|
|
1206
|
+
if (!feePayer) throw new PaymentError("Missing feePayer in 402 extra field");
|
|
1207
|
+
const fromAddress = await this.getWalletAddress();
|
|
1208
|
+
const secretKey = await solanaKeyToBytes(this.privateKey);
|
|
1209
|
+
const extensions = paymentRequired.extensions;
|
|
1210
|
+
const paymentPayload = await createSolanaPaymentPayload(
|
|
1211
|
+
secretKey,
|
|
1212
|
+
fromAddress,
|
|
1213
|
+
details.recipient,
|
|
1214
|
+
details.amount,
|
|
1215
|
+
feePayer,
|
|
1216
|
+
{
|
|
1217
|
+
resourceUrl: validateResourceUrl(
|
|
1218
|
+
details.resource?.url || `${this.apiUrl}/v1/chat/completions`,
|
|
1219
|
+
this.apiUrl
|
|
1220
|
+
),
|
|
1221
|
+
resourceDescription: details.resource?.description || "BlockRun Solana AI API call",
|
|
1222
|
+
maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
|
|
1223
|
+
extra: details.extra,
|
|
1224
|
+
extensions,
|
|
1225
|
+
rpcUrl: this.rpcUrl
|
|
1226
|
+
}
|
|
1227
|
+
);
|
|
1228
|
+
const retryResponse = await this.fetchWithTimeout(url, {
|
|
1229
|
+
method: "POST",
|
|
1230
|
+
headers: {
|
|
1231
|
+
"Content-Type": "application/json",
|
|
1232
|
+
"User-Agent": USER_AGENT2,
|
|
1233
|
+
"PAYMENT-SIGNATURE": paymentPayload
|
|
1234
|
+
},
|
|
1235
|
+
body: JSON.stringify(body)
|
|
1236
|
+
});
|
|
1237
|
+
if (retryResponse.status === 402) {
|
|
1238
|
+
throw new PaymentError("Payment was rejected. Check your Solana USDC balance.");
|
|
1239
|
+
}
|
|
1240
|
+
if (!retryResponse.ok) {
|
|
1241
|
+
let errorBody;
|
|
1242
|
+
try {
|
|
1243
|
+
errorBody = await retryResponse.json();
|
|
1244
|
+
} catch {
|
|
1245
|
+
errorBody = { error: "Request failed" };
|
|
1246
|
+
}
|
|
1247
|
+
throw new APIError(`API error after payment: ${retryResponse.status}`, retryResponse.status, sanitizeErrorResponse(errorBody));
|
|
1248
|
+
}
|
|
1249
|
+
const costUsd = parseFloat(details.amount) / 1e6;
|
|
1250
|
+
this.sessionCalls += 1;
|
|
1251
|
+
this.sessionTotalUsd += costUsd;
|
|
1252
|
+
return retryResponse.json();
|
|
1253
|
+
}
|
|
1254
|
+
async fetchWithTimeout(url, options) {
|
|
1255
|
+
const controller = new AbortController();
|
|
1256
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
1257
|
+
try {
|
|
1258
|
+
return await fetch(url, { ...options, signal: controller.signal });
|
|
1259
|
+
} finally {
|
|
1260
|
+
clearTimeout(timeoutId);
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
};
|
|
1264
|
+
function solanaClient(options = {}) {
|
|
1265
|
+
return new SolanaLLMClient({ ...options, apiUrl: SOLANA_API_URL });
|
|
1266
|
+
}
|
|
1267
|
+
|
|
950
1268
|
// src/openai-compat.ts
|
|
951
1269
|
var StreamingResponse = class {
|
|
952
1270
|
reader;
|
|
@@ -1124,20 +1442,32 @@ export {
|
|
|
1124
1442
|
LLMClient,
|
|
1125
1443
|
OpenAI,
|
|
1126
1444
|
PaymentError,
|
|
1445
|
+
SOLANA_NETWORK,
|
|
1446
|
+
SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH,
|
|
1447
|
+
SolanaLLMClient,
|
|
1127
1448
|
USDC_BASE,
|
|
1128
1449
|
USDC_BASE_CONTRACT,
|
|
1450
|
+
USDC_SOLANA,
|
|
1129
1451
|
WALLET_DIR_PATH,
|
|
1130
1452
|
WALLET_FILE_PATH,
|
|
1453
|
+
createSolanaPaymentPayload,
|
|
1454
|
+
createSolanaWallet,
|
|
1131
1455
|
createWallet,
|
|
1132
1456
|
client_default as default,
|
|
1133
1457
|
formatFundingMessageCompact,
|
|
1134
1458
|
formatNeedsFundingMessage,
|
|
1135
1459
|
formatWalletCreatedMessage,
|
|
1136
1460
|
getEip681Uri,
|
|
1461
|
+
getOrCreateSolanaWallet,
|
|
1137
1462
|
getOrCreateWallet,
|
|
1138
1463
|
getPaymentLinks,
|
|
1139
1464
|
getWalletAddress,
|
|
1465
|
+
loadSolanaWallet,
|
|
1140
1466
|
loadWallet,
|
|
1467
|
+
saveSolanaWallet,
|
|
1141
1468
|
saveWallet,
|
|
1469
|
+
solanaClient,
|
|
1470
|
+
solanaKeyToBytes,
|
|
1471
|
+
solanaPublicKey,
|
|
1142
1472
|
testnetClient
|
|
1143
1473
|
};
|