@blockrun/llm 3.7.0 → 3.7.1

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 CHANGED
@@ -1295,9 +1295,10 @@ await status();
1295
1295
  // Balance: $5.30 USDC
1296
1296
  ```
1297
1297
 
1298
- ## Wallet Scanning
1298
+ ## Wallet Discovery and Migration
1299
1299
 
1300
- The SDK auto-detects wallets from any provider on your system:
1300
+ The SDK can discover compatible wallets for an explicit, user-confirmed
1301
+ migration. It never automatically makes a discovered provider wallet active:
1301
1302
 
1302
1303
  ```typescript
1303
1304
  import { scanWallets, scanSolanaWallets } from '@blockrun/llm';
@@ -1309,7 +1310,30 @@ const baseWallets = scanWallets();
1309
1310
  const solWallets = scanSolanaWallets();
1310
1311
  ```
1311
1312
 
1312
- `getOrCreateWallet()` checks scanned wallets first, so if you already have a wallet from another BlockRun tool, it will be reused automatically.
1313
+ `getOrCreateWallet()` always uses `~/.blockrun/.session` (or an explicit
1314
+ wallet environment variable, or the legacy `~/.blockrun/wallet.key`). Review
1315
+ the discovered addresses and import one explicitly if you intend to switch
1316
+ wallets.
1317
+
1318
+ ### Upgrading from a provider wallet
1319
+
1320
+ Earlier versions adopted the most recently written provider wallet
1321
+ automatically. If you relied on that, the first run after upgrading creates a
1322
+ fresh BlockRun wallet and prints the addresses it found, so you can import the
1323
+ one you actually own:
1324
+
1325
+ ```
1326
+ NOTICE: BlockRun created a new wallet, but also found existing wallet(s)
1327
+ belonging to other applications on this system:
1328
+
1329
+ 0x88f9B82462f6C4bf4a0Fb15e5c3971559a316e7f
1330
+ ...
1331
+ ```
1332
+
1333
+ Import it deliberately with `export BLOCKRUN_WALLET_KEY=<private-key>`, or by
1334
+ writing the key to `~/.blockrun/.session`. Addresses in that notice are derived
1335
+ from the discovered key itself, so a wallet file cannot claim an address it
1336
+ cannot sign for.
1313
1337
 
1314
1338
  ## Response Caching
1315
1339
 
package/dist/index.cjs CHANGED
@@ -72,7 +72,9 @@ __export(index_exports, {
72
72
  extractPaymentDetails: () => extractPaymentDetails,
73
73
  formatFundingMessageCompact: () => formatFundingMessageCompact,
74
74
  formatNeedsFundingMessage: () => formatNeedsFundingMessage,
75
+ formatSolanaWalletMigrationNotice: () => formatSolanaWalletMigrationNotice,
75
76
  formatWalletCreatedMessage: () => formatWalletCreatedMessage,
77
+ formatWalletMigrationNotice: () => formatWalletMigrationNotice,
76
78
  getCached: () => getCached,
77
79
  getCachedByRequest: () => getCachedByRequest,
78
80
  getCostLogSummary: () => getCostLogSummary,
@@ -4641,8 +4643,6 @@ function scanWallets() {
4641
4643
  return results.map(({ privateKey, address }) => ({ privateKey, address }));
4642
4644
  }
4643
4645
  function loadWallet() {
4644
- const wallets = scanWallets();
4645
- if (wallets.length > 0) return wallets[0].privateKey;
4646
4646
  if (fs2.existsSync(WALLET_FILE)) {
4647
4647
  const key = fs2.readFileSync(WALLET_FILE, "utf-8").trim();
4648
4648
  if (key) return key;
@@ -4654,6 +4654,44 @@ function loadWallet() {
4654
4654
  }
4655
4655
  return null;
4656
4656
  }
4657
+ function formatWalletMigrationNotice(newAddress) {
4658
+ let discovered;
4659
+ try {
4660
+ discovered = scanWallets();
4661
+ } catch {
4662
+ return null;
4663
+ }
4664
+ const addresses = [];
4665
+ for (const entry of discovered) {
4666
+ try {
4667
+ addresses.push((0, import_accounts15.privateKeyToAccount)(entry.privateKey).address);
4668
+ } catch {
4669
+ continue;
4670
+ }
4671
+ }
4672
+ if (addresses.length === 0) return null;
4673
+ const found = addresses.map((addr) => ` ${addr}`).join("\n");
4674
+ return `
4675
+ NOTICE: BlockRun created a new wallet, but also found existing wallet(s)
4676
+ belonging to other applications on this system:
4677
+
4678
+ ${found}
4679
+
4680
+ BlockRun now uses only its own wallet:
4681
+
4682
+ ${newAddress}
4683
+
4684
+ Discovered wallets are never adopted automatically \u2014 one may belong to a
4685
+ different application, or have been planted to make you fund an address you
4686
+ do not control.
4687
+
4688
+ If an address above is yours and holds your USDC, import it deliberately:
4689
+
4690
+ export BLOCKRUN_WALLET_KEY=<private-key>
4691
+
4692
+ or write that key to ~/.blockrun/.session
4693
+ `;
4694
+ }
4657
4695
  function getOrCreateWallet() {
4658
4696
  const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
4659
4697
  if (envKey) {
@@ -4823,24 +4861,56 @@ function scanSolanaWallets() {
4823
4861
  return results.map(({ secretKey, publicKey }) => ({ secretKey, publicKey }));
4824
4862
  }
4825
4863
  function loadSolanaWallet() {
4826
- const wallets = scanSolanaWallets();
4827
- if (wallets.length > 0) return wallets[0].secretKey;
4828
4864
  if (fs3.existsSync(SOLANA_WALLET_FILE)) {
4829
4865
  const key = fs3.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
4830
4866
  if (key) return key;
4831
4867
  }
4832
4868
  return null;
4833
4869
  }
4870
+ async function formatSolanaWalletMigrationNotice(newAddress) {
4871
+ let discovered;
4872
+ try {
4873
+ discovered = scanSolanaWallets();
4874
+ } catch {
4875
+ return null;
4876
+ }
4877
+ const addresses = [];
4878
+ for (const entry of discovered) {
4879
+ try {
4880
+ addresses.push(await solanaPublicKey(entry.secretKey));
4881
+ } catch {
4882
+ continue;
4883
+ }
4884
+ }
4885
+ if (addresses.length === 0) return null;
4886
+ const found = addresses.map((addr) => ` ${addr}`).join("\n");
4887
+ return `
4888
+ NOTICE: BlockRun created a new Solana wallet, but also found existing
4889
+ wallet(s) belonging to other applications on this system:
4890
+
4891
+ ${found}
4892
+
4893
+ BlockRun now uses only its own wallet:
4894
+
4895
+ ${newAddress}
4896
+
4897
+ Discovered wallets are never adopted automatically \u2014 one may belong to a
4898
+ different application, or have been planted to make you fund an address you
4899
+ do not control.
4900
+
4901
+ If an address above is yours and holds your USDC, import it deliberately:
4902
+
4903
+ export SOLANA_WALLET_KEY=<private-key>
4904
+
4905
+ or write that key to ~/.blockrun/.solana-session
4906
+ `;
4907
+ }
4834
4908
  async function getOrCreateSolanaWallet() {
4835
4909
  const envKey = typeof process !== "undefined" && process.env ? process.env.SOLANA_WALLET_KEY : void 0;
4836
4910
  if (envKey) {
4837
4911
  const address2 = await solanaPublicKey(envKey);
4838
4912
  return { privateKey: envKey, address: address2, isNew: false };
4839
4913
  }
4840
- const wallets = scanSolanaWallets();
4841
- if (wallets.length > 0) {
4842
- return { privateKey: wallets[0].secretKey, address: wallets[0].publicKey, isNew: false };
4843
- }
4844
4914
  if (fs3.existsSync(SOLANA_WALLET_FILE)) {
4845
4915
  const fileKey = fs3.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
4846
4916
  if (fileKey) {
@@ -5665,27 +5735,35 @@ function getCostLogSummary() {
5665
5735
  // src/setup.ts
5666
5736
  function setupAgentWallet(options) {
5667
5737
  const { address, privateKey, isNew } = getOrCreateWallet();
5668
- if (isNew && !options?.silent) {
5669
- console.error(
5670
- `
5738
+ if (isNew) {
5739
+ const notice = formatWalletMigrationNotice(address);
5740
+ if (notice) console.error(notice);
5741
+ if (!options?.silent) {
5742
+ console.error(
5743
+ `
5671
5744
  BlockRun Agent Wallet Created!
5672
5745
  Address: ${address}
5673
5746
  Send USDC on Base to get started.
5674
5747
  `
5675
- );
5748
+ );
5749
+ }
5676
5750
  }
5677
5751
  return new LLMClient({ privateKey });
5678
5752
  }
5679
5753
  async function setupAgentSolanaWallet(options) {
5680
5754
  const result = await getOrCreateSolanaWallet();
5681
- if (result.isNew && !options?.silent) {
5682
- console.error(
5683
- `
5755
+ if (result.isNew) {
5756
+ const notice = await formatSolanaWalletMigrationNotice(result.address);
5757
+ if (notice) console.error(notice);
5758
+ if (!options?.silent) {
5759
+ console.error(
5760
+ `
5684
5761
  BlockRun Solana Agent Wallet Created!
5685
5762
  Address: ${result.address}
5686
5763
  Send USDC on Solana to get started.
5687
5764
  `
5688
- );
5765
+ );
5766
+ }
5689
5767
  }
5690
5768
  return new SolanaLLMClient({ privateKey: result.privateKey });
5691
5769
  }
@@ -5998,7 +6076,9 @@ var AnthropicClient = class {
5998
6076
  extractPaymentDetails,
5999
6077
  formatFundingMessageCompact,
6000
6078
  formatNeedsFundingMessage,
6079
+ formatSolanaWalletMigrationNotice,
6001
6080
  formatWalletCreatedMessage,
6081
+ formatWalletMigrationNotice,
6002
6082
  getCached,
6003
6083
  getCachedByRequest,
6004
6084
  getCostLogSummary,
package/dist/index.d.cts CHANGED
@@ -2527,10 +2527,12 @@ declare function createWallet(): {
2527
2527
  */
2528
2528
  declare function saveWallet(privateKey: string): string;
2529
2529
  /**
2530
- * Scan ~/.<dir>/wallet.json files from any provider (agentcash, etc.).
2530
+ * Discover ~/.<dir>/wallet.json files from other providers.
2531
2531
  *
2532
2532
  * Each file should contain JSON with "privateKey" and "address" fields.
2533
- * Results are sorted by modification time (most recent first).
2533
+ * Results are sorted by modification time (most recent first). Discovery is
2534
+ * intentionally opt-in: a provider wallet must never replace the canonical
2535
+ * BlockRun wallet merely because it was written more recently.
2534
2536
  *
2535
2537
  * @returns Array of wallet objects with privateKey and address
2536
2538
  */
@@ -2542,22 +2544,37 @@ declare function scanWallets(): Array<{
2542
2544
  * Load wallet private key from file.
2543
2545
  *
2544
2546
  * Priority:
2545
- * 1. Scan ~/.* /wallet.json (any provider)
2546
- * 2. Legacy ~/.blockrun/.session
2547
- * 3. Legacy ~/.blockrun/wallet.key
2547
+ * 1. ~/.blockrun/.session
2548
+ * 2. ~/.blockrun/wallet.key (legacy)
2548
2549
  *
2549
2550
  * @returns Private key string or null if not found
2550
2551
  */
2551
2552
  declare function loadWallet(): string | null;
2553
+ /**
2554
+ * Warn when a new wallet was created while other provider wallets exist.
2555
+ *
2556
+ * Automatic selection deliberately ignores wallets discovered in other
2557
+ * applications' directories, so a user who previously relied on that discovery
2558
+ * would otherwise land on an empty wallet with no explanation of where their
2559
+ * funds went. This notice names the discovered addresses and tells them how to
2560
+ * import one on purpose.
2561
+ *
2562
+ * Addresses are derived from the discovered private key rather than read from
2563
+ * the file's "address" field, so a file claiming an address it cannot sign for
2564
+ * cannot trick the user into importing it.
2565
+ *
2566
+ * @param newAddress Address of the wallet that was just created
2567
+ * @returns Formatted notice, or null if nothing was discovered
2568
+ */
2569
+ declare function formatWalletMigrationNotice(newAddress: string): string | null;
2552
2570
  /**
2553
2571
  * Get existing wallet or create new one.
2554
2572
  *
2555
2573
  * Priority:
2556
2574
  * 1. BLOCKRUN_WALLET_KEY environment variable
2557
- * 2. Scan wallet.json files from providers
2558
- * 3. ~/.blockrun/.session file
2559
- * 4. ~/.blockrun/wallet.key file - legacy
2560
- * 5. Create new wallet
2575
+ * 2. ~/.blockrun/.session file
2576
+ * 3. ~/.blockrun/wallet.key file - legacy
2577
+ * 4. Create new wallet
2561
2578
  *
2562
2579
  * @returns WalletInfo with address, privateKey, and isNew flag
2563
2580
  */
@@ -2821,11 +2838,12 @@ declare function solanaKeyToBytes(privateKey: string): Promise<Uint8Array>;
2821
2838
  declare function solanaPublicKey(privateKey: string): Promise<string>;
2822
2839
  declare function saveSolanaWallet(privateKey: string): string;
2823
2840
  /**
2824
- * Scan ~/.<dir>/solana-wallet.json files from any provider.
2841
+ * Discover ~/.<dir>/solana-wallet.json files from other providers.
2825
2842
  *
2826
2843
  * Each file should contain JSON with "privateKey" and "address" fields.
2827
2844
  * Also checks ~/.brcc/wallet.json for BRCC wallets.
2828
- * Results are sorted by modification time (most recent first).
2845
+ * Results are sorted by modification time (most recent first). Discovery is
2846
+ * opt-in and never changes the active BlockRun wallet automatically.
2829
2847
  *
2830
2848
  * @returns Array of wallet objects with secretKey and publicKey
2831
2849
  */
@@ -2834,6 +2852,17 @@ declare function scanSolanaWallets(): Array<{
2834
2852
  publicKey: string;
2835
2853
  }>;
2836
2854
  declare function loadSolanaWallet(): string | null;
2855
+ /**
2856
+ * Warn when a new Solana wallet was created while provider wallets exist.
2857
+ *
2858
+ * Solana counterpart of `formatWalletMigrationNotice`. Addresses are derived
2859
+ * from the discovered secret key rather than trusted from the file's "address"
2860
+ * field.
2861
+ *
2862
+ * @param newAddress Address of the wallet that was just created
2863
+ * @returns Formatted notice, or null if nothing was discovered
2864
+ */
2865
+ declare function formatSolanaWalletMigrationNotice(newAddress: string): Promise<string | null>;
2837
2866
  declare function getOrCreateSolanaWallet(): Promise<SolanaWalletInfo>;
2838
2867
 
2839
2868
  declare function getCached(key: string): unknown | null;
@@ -3104,4 +3133,4 @@ declare function validateTemperature(temperature?: number): void;
3104
3133
  */
3105
3134
  declare function validateTopP(topP?: number): void;
3106
3135
 
3107
- export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, BlockrunClient, type BlockrunClientOptions, BlockrunError, type CallInitiatedResponse, type CallModel, type CallOptions, type CallStatusResponse, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatResponseWithCost, type ChatUsage, type CostEntry, type CostEstimate, type CreatePaymentOptions, type FunctionCall, type FunctionDefinition, type HistoryOptions, ImageClient, type ImageClientOptions, type ImageData, type ImageEditOptions, type ImageGenerateOptions, type ImageModel, type ImageResponse, KNOWN_PROVIDERS, LLMClient, type LLMClientOptions, type ListOptions, type MarketSession, type Model, MusicClient, type MusicClientOptions, type MusicGenerateOptions, type MusicResponse, NETWORK_ALIASES, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PORTRAIT_ENROLLMENT_PRICE_USD, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, PortraitClient, type PortraitClientOptions, type PortraitEnrollOptions, type PortraitEnrollResponse, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, RPC_PRICE_USD, type ResponseFormat, type RoutingDecision, type RoutingProfile, type RoutingTier, type RpcBatchRequest, RpcClient, type RpcClientOptions, type RpcError, type RpcNetwork, type RpcResponse, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SUPPORTED_NETWORKS, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type SoundEffectOptions, type SpeechAudio, SpeechClient, type SpeechClientOptions, type SpeechGenerateOptions, type SpeechModel, type SpeechResponse, type SpeechVoice, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoiceInfo, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatWalletCreatedMessage, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, validateMaxTokens, validateModel, validateTemperature, validateTopP };
3136
+ export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, BlockrunClient, type BlockrunClientOptions, BlockrunError, type CallInitiatedResponse, type CallModel, type CallOptions, type CallStatusResponse, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatResponseWithCost, type ChatUsage, type CostEntry, type CostEstimate, type CreatePaymentOptions, type FunctionCall, type FunctionDefinition, type HistoryOptions, ImageClient, type ImageClientOptions, type ImageData, type ImageEditOptions, type ImageGenerateOptions, type ImageModel, type ImageResponse, KNOWN_PROVIDERS, LLMClient, type LLMClientOptions, type ListOptions, type MarketSession, type Model, MusicClient, type MusicClientOptions, type MusicGenerateOptions, type MusicResponse, NETWORK_ALIASES, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PORTRAIT_ENROLLMENT_PRICE_USD, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, PortraitClient, type PortraitClientOptions, type PortraitEnrollOptions, type PortraitEnrollResponse, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, RPC_PRICE_USD, type ResponseFormat, type RoutingDecision, type RoutingProfile, type RoutingTier, type RpcBatchRequest, RpcClient, type RpcClientOptions, type RpcError, type RpcNetwork, type RpcResponse, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SUPPORTED_NETWORKS, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type SoundEffectOptions, type SpeechAudio, SpeechClient, type SpeechClientOptions, type SpeechGenerateOptions, type SpeechModel, type SpeechResponse, type SpeechVoice, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoiceInfo, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatSolanaWalletMigrationNotice, formatWalletCreatedMessage, formatWalletMigrationNotice, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, validateMaxTokens, validateModel, validateTemperature, validateTopP };
package/dist/index.d.ts CHANGED
@@ -2527,10 +2527,12 @@ declare function createWallet(): {
2527
2527
  */
2528
2528
  declare function saveWallet(privateKey: string): string;
2529
2529
  /**
2530
- * Scan ~/.<dir>/wallet.json files from any provider (agentcash, etc.).
2530
+ * Discover ~/.<dir>/wallet.json files from other providers.
2531
2531
  *
2532
2532
  * Each file should contain JSON with "privateKey" and "address" fields.
2533
- * Results are sorted by modification time (most recent first).
2533
+ * Results are sorted by modification time (most recent first). Discovery is
2534
+ * intentionally opt-in: a provider wallet must never replace the canonical
2535
+ * BlockRun wallet merely because it was written more recently.
2534
2536
  *
2535
2537
  * @returns Array of wallet objects with privateKey and address
2536
2538
  */
@@ -2542,22 +2544,37 @@ declare function scanWallets(): Array<{
2542
2544
  * Load wallet private key from file.
2543
2545
  *
2544
2546
  * Priority:
2545
- * 1. Scan ~/.* /wallet.json (any provider)
2546
- * 2. Legacy ~/.blockrun/.session
2547
- * 3. Legacy ~/.blockrun/wallet.key
2547
+ * 1. ~/.blockrun/.session
2548
+ * 2. ~/.blockrun/wallet.key (legacy)
2548
2549
  *
2549
2550
  * @returns Private key string or null if not found
2550
2551
  */
2551
2552
  declare function loadWallet(): string | null;
2553
+ /**
2554
+ * Warn when a new wallet was created while other provider wallets exist.
2555
+ *
2556
+ * Automatic selection deliberately ignores wallets discovered in other
2557
+ * applications' directories, so a user who previously relied on that discovery
2558
+ * would otherwise land on an empty wallet with no explanation of where their
2559
+ * funds went. This notice names the discovered addresses and tells them how to
2560
+ * import one on purpose.
2561
+ *
2562
+ * Addresses are derived from the discovered private key rather than read from
2563
+ * the file's "address" field, so a file claiming an address it cannot sign for
2564
+ * cannot trick the user into importing it.
2565
+ *
2566
+ * @param newAddress Address of the wallet that was just created
2567
+ * @returns Formatted notice, or null if nothing was discovered
2568
+ */
2569
+ declare function formatWalletMigrationNotice(newAddress: string): string | null;
2552
2570
  /**
2553
2571
  * Get existing wallet or create new one.
2554
2572
  *
2555
2573
  * Priority:
2556
2574
  * 1. BLOCKRUN_WALLET_KEY environment variable
2557
- * 2. Scan wallet.json files from providers
2558
- * 3. ~/.blockrun/.session file
2559
- * 4. ~/.blockrun/wallet.key file - legacy
2560
- * 5. Create new wallet
2575
+ * 2. ~/.blockrun/.session file
2576
+ * 3. ~/.blockrun/wallet.key file - legacy
2577
+ * 4. Create new wallet
2561
2578
  *
2562
2579
  * @returns WalletInfo with address, privateKey, and isNew flag
2563
2580
  */
@@ -2821,11 +2838,12 @@ declare function solanaKeyToBytes(privateKey: string): Promise<Uint8Array>;
2821
2838
  declare function solanaPublicKey(privateKey: string): Promise<string>;
2822
2839
  declare function saveSolanaWallet(privateKey: string): string;
2823
2840
  /**
2824
- * Scan ~/.<dir>/solana-wallet.json files from any provider.
2841
+ * Discover ~/.<dir>/solana-wallet.json files from other providers.
2825
2842
  *
2826
2843
  * Each file should contain JSON with "privateKey" and "address" fields.
2827
2844
  * Also checks ~/.brcc/wallet.json for BRCC wallets.
2828
- * Results are sorted by modification time (most recent first).
2845
+ * Results are sorted by modification time (most recent first). Discovery is
2846
+ * opt-in and never changes the active BlockRun wallet automatically.
2829
2847
  *
2830
2848
  * @returns Array of wallet objects with secretKey and publicKey
2831
2849
  */
@@ -2834,6 +2852,17 @@ declare function scanSolanaWallets(): Array<{
2834
2852
  publicKey: string;
2835
2853
  }>;
2836
2854
  declare function loadSolanaWallet(): string | null;
2855
+ /**
2856
+ * Warn when a new Solana wallet was created while provider wallets exist.
2857
+ *
2858
+ * Solana counterpart of `formatWalletMigrationNotice`. Addresses are derived
2859
+ * from the discovered secret key rather than trusted from the file's "address"
2860
+ * field.
2861
+ *
2862
+ * @param newAddress Address of the wallet that was just created
2863
+ * @returns Formatted notice, or null if nothing was discovered
2864
+ */
2865
+ declare function formatSolanaWalletMigrationNotice(newAddress: string): Promise<string | null>;
2837
2866
  declare function getOrCreateSolanaWallet(): Promise<SolanaWalletInfo>;
2838
2867
 
2839
2868
  declare function getCached(key: string): unknown | null;
@@ -3104,4 +3133,4 @@ declare function validateTemperature(temperature?: number): void;
3104
3133
  */
3105
3134
  declare function validateTopP(topP?: number): void;
3106
3135
 
3107
- export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, BlockrunClient, type BlockrunClientOptions, BlockrunError, type CallInitiatedResponse, type CallModel, type CallOptions, type CallStatusResponse, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatResponseWithCost, type ChatUsage, type CostEntry, type CostEstimate, type CreatePaymentOptions, type FunctionCall, type FunctionDefinition, type HistoryOptions, ImageClient, type ImageClientOptions, type ImageData, type ImageEditOptions, type ImageGenerateOptions, type ImageModel, type ImageResponse, KNOWN_PROVIDERS, LLMClient, type LLMClientOptions, type ListOptions, type MarketSession, type Model, MusicClient, type MusicClientOptions, type MusicGenerateOptions, type MusicResponse, NETWORK_ALIASES, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PORTRAIT_ENROLLMENT_PRICE_USD, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, PortraitClient, type PortraitClientOptions, type PortraitEnrollOptions, type PortraitEnrollResponse, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, RPC_PRICE_USD, type ResponseFormat, type RoutingDecision, type RoutingProfile, type RoutingTier, type RpcBatchRequest, RpcClient, type RpcClientOptions, type RpcError, type RpcNetwork, type RpcResponse, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SUPPORTED_NETWORKS, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type SoundEffectOptions, type SpeechAudio, SpeechClient, type SpeechClientOptions, type SpeechGenerateOptions, type SpeechModel, type SpeechResponse, type SpeechVoice, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoiceInfo, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatWalletCreatedMessage, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, validateMaxTokens, validateModel, validateTemperature, validateTopP };
3136
+ export { APIError, AnthropicClient, type AudioModel, type AudioTrack, BASE_CHAIN_ID, type BarResolution, type BlockRunAnthropicOptions, BlockrunClient, type BlockrunClientOptions, BlockrunError, type CallInitiatedResponse, type CallModel, type CallOptions, type CallStatusResponse, type ChatChoice, type ChatCompletionOptions, type ChatMessage, type ChatOptions, type ChatResponse, type ChatResponseWithCost, type ChatUsage, type CostEntry, type CostEstimate, type CreatePaymentOptions, type FunctionCall, type FunctionDefinition, type HistoryOptions, ImageClient, type ImageClientOptions, type ImageData, type ImageEditOptions, type ImageGenerateOptions, type ImageModel, type ImageResponse, KNOWN_PROVIDERS, LLMClient, type LLMClientOptions, type ListOptions, type MarketSession, type Model, MusicClient, type MusicClientOptions, type MusicGenerateOptions, type MusicResponse, NETWORK_ALIASES, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PORTRAIT_ENROLLMENT_PRICE_USD, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, PortraitClient, type PortraitClientOptions, type PortraitEnrollOptions, type PortraitEnrollResponse, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, RPC_PRICE_USD, type ResponseFormat, type RoutingDecision, type RoutingProfile, type RoutingTier, type RpcBatchRequest, RpcClient, type RpcClientOptions, type RpcError, type RpcNetwork, type RpcResponse, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SUPPORTED_NETWORKS, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, type SoundEffectOptions, type SpeechAudio, SpeechClient, type SpeechClientOptions, type SpeechGenerateOptions, type SpeechModel, type SpeechResponse, type SpeechVoice, type Spending, type SpendingReport, type StockMarket, SurfClient, type SurfClientOptions, type SymbolListResponse, type Tool, type ToolCall, type ToolChoice, USDC_BASE, USDC_BASE_CONTRACT, USDC_SOLANA, VideoClient, type VideoClientOptions, type VideoClip, type VideoGenerateOptions, type VideoModel, type VideoResponse, VoiceClient, type VoiceClientOptions, type VoiceInfo, type VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XSearchSource, clearCache, createPaymentPayload, createSolanaPaymentPayload, createSolanaWallet, createWallet, LLMClient as default, extractPaymentDetails, formatFundingMessageCompact, formatNeedsFundingMessage, formatSolanaWalletMigrationNotice, formatWalletCreatedMessage, formatWalletMigrationNotice, getCached, getCachedByRequest, getCostLogSummary, getCostSummary, getEip681Uri, getOrCreateSolanaWallet, getOrCreateWallet, getPaymentLinks, getWalletAddress, loadSolanaWallet, loadWallet, logCost, parsePaymentRequired, saveSolanaWallet, saveToCache, saveWallet, scanSolanaWallets, scanWallets, setCache, setupAgentSolanaWallet, setupAgentWallet, solanaClient, solanaKeyToBytes, solanaPublicKey, status, validateMaxTokens, validateModel, validateTemperature, validateTopP };
package/dist/index.js CHANGED
@@ -4534,8 +4534,6 @@ function scanWallets() {
4534
4534
  return results.map(({ privateKey, address }) => ({ privateKey, address }));
4535
4535
  }
4536
4536
  function loadWallet() {
4537
- const wallets = scanWallets();
4538
- if (wallets.length > 0) return wallets[0].privateKey;
4539
4537
  if (fs2.existsSync(WALLET_FILE)) {
4540
4538
  const key = fs2.readFileSync(WALLET_FILE, "utf-8").trim();
4541
4539
  if (key) return key;
@@ -4547,6 +4545,44 @@ function loadWallet() {
4547
4545
  }
4548
4546
  return null;
4549
4547
  }
4548
+ function formatWalletMigrationNotice(newAddress) {
4549
+ let discovered;
4550
+ try {
4551
+ discovered = scanWallets();
4552
+ } catch {
4553
+ return null;
4554
+ }
4555
+ const addresses = [];
4556
+ for (const entry of discovered) {
4557
+ try {
4558
+ addresses.push(privateKeyToAccount14(entry.privateKey).address);
4559
+ } catch {
4560
+ continue;
4561
+ }
4562
+ }
4563
+ if (addresses.length === 0) return null;
4564
+ const found = addresses.map((addr) => ` ${addr}`).join("\n");
4565
+ return `
4566
+ NOTICE: BlockRun created a new wallet, but also found existing wallet(s)
4567
+ belonging to other applications on this system:
4568
+
4569
+ ${found}
4570
+
4571
+ BlockRun now uses only its own wallet:
4572
+
4573
+ ${newAddress}
4574
+
4575
+ Discovered wallets are never adopted automatically \u2014 one may belong to a
4576
+ different application, or have been planted to make you fund an address you
4577
+ do not control.
4578
+
4579
+ If an address above is yours and holds your USDC, import it deliberately:
4580
+
4581
+ export BLOCKRUN_WALLET_KEY=<private-key>
4582
+
4583
+ or write that key to ~/.blockrun/.session
4584
+ `;
4585
+ }
4550
4586
  function getOrCreateWallet() {
4551
4587
  const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
4552
4588
  if (envKey) {
@@ -4716,24 +4752,56 @@ function scanSolanaWallets() {
4716
4752
  return results.map(({ secretKey, publicKey }) => ({ secretKey, publicKey }));
4717
4753
  }
4718
4754
  function loadSolanaWallet() {
4719
- const wallets = scanSolanaWallets();
4720
- if (wallets.length > 0) return wallets[0].secretKey;
4721
4755
  if (fs3.existsSync(SOLANA_WALLET_FILE)) {
4722
4756
  const key = fs3.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
4723
4757
  if (key) return key;
4724
4758
  }
4725
4759
  return null;
4726
4760
  }
4761
+ async function formatSolanaWalletMigrationNotice(newAddress) {
4762
+ let discovered;
4763
+ try {
4764
+ discovered = scanSolanaWallets();
4765
+ } catch {
4766
+ return null;
4767
+ }
4768
+ const addresses = [];
4769
+ for (const entry of discovered) {
4770
+ try {
4771
+ addresses.push(await solanaPublicKey(entry.secretKey));
4772
+ } catch {
4773
+ continue;
4774
+ }
4775
+ }
4776
+ if (addresses.length === 0) return null;
4777
+ const found = addresses.map((addr) => ` ${addr}`).join("\n");
4778
+ return `
4779
+ NOTICE: BlockRun created a new Solana wallet, but also found existing
4780
+ wallet(s) belonging to other applications on this system:
4781
+
4782
+ ${found}
4783
+
4784
+ BlockRun now uses only its own wallet:
4785
+
4786
+ ${newAddress}
4787
+
4788
+ Discovered wallets are never adopted automatically \u2014 one may belong to a
4789
+ different application, or have been planted to make you fund an address you
4790
+ do not control.
4791
+
4792
+ If an address above is yours and holds your USDC, import it deliberately:
4793
+
4794
+ export SOLANA_WALLET_KEY=<private-key>
4795
+
4796
+ or write that key to ~/.blockrun/.solana-session
4797
+ `;
4798
+ }
4727
4799
  async function getOrCreateSolanaWallet() {
4728
4800
  const envKey = typeof process !== "undefined" && process.env ? process.env.SOLANA_WALLET_KEY : void 0;
4729
4801
  if (envKey) {
4730
4802
  const address2 = await solanaPublicKey(envKey);
4731
4803
  return { privateKey: envKey, address: address2, isNew: false };
4732
4804
  }
4733
- const wallets = scanSolanaWallets();
4734
- if (wallets.length > 0) {
4735
- return { privateKey: wallets[0].secretKey, address: wallets[0].publicKey, isNew: false };
4736
- }
4737
4805
  if (fs3.existsSync(SOLANA_WALLET_FILE)) {
4738
4806
  const fileKey = fs3.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
4739
4807
  if (fileKey) {
@@ -5558,27 +5626,35 @@ function getCostLogSummary() {
5558
5626
  // src/setup.ts
5559
5627
  function setupAgentWallet(options) {
5560
5628
  const { address, privateKey, isNew } = getOrCreateWallet();
5561
- if (isNew && !options?.silent) {
5562
- console.error(
5563
- `
5629
+ if (isNew) {
5630
+ const notice = formatWalletMigrationNotice(address);
5631
+ if (notice) console.error(notice);
5632
+ if (!options?.silent) {
5633
+ console.error(
5634
+ `
5564
5635
  BlockRun Agent Wallet Created!
5565
5636
  Address: ${address}
5566
5637
  Send USDC on Base to get started.
5567
5638
  `
5568
- );
5639
+ );
5640
+ }
5569
5641
  }
5570
5642
  return new LLMClient({ privateKey });
5571
5643
  }
5572
5644
  async function setupAgentSolanaWallet(options) {
5573
5645
  const result = await getOrCreateSolanaWallet();
5574
- if (result.isNew && !options?.silent) {
5575
- console.error(
5576
- `
5646
+ if (result.isNew) {
5647
+ const notice = await formatSolanaWalletMigrationNotice(result.address);
5648
+ if (notice) console.error(notice);
5649
+ if (!options?.silent) {
5650
+ console.error(
5651
+ `
5577
5652
  BlockRun Solana Agent Wallet Created!
5578
5653
  Address: ${result.address}
5579
5654
  Send USDC on Solana to get started.
5580
5655
  `
5581
- );
5656
+ );
5657
+ }
5582
5658
  }
5583
5659
  return new SolanaLLMClient({ privateKey: result.privateKey });
5584
5660
  }
@@ -5891,7 +5967,9 @@ export {
5891
5967
  extractPaymentDetails,
5892
5968
  formatFundingMessageCompact,
5893
5969
  formatNeedsFundingMessage,
5970
+ formatSolanaWalletMigrationNotice,
5894
5971
  formatWalletCreatedMessage,
5972
+ formatWalletMigrationNotice,
5895
5973
  getCached,
5896
5974
  getCachedByRequest,
5897
5975
  getCostLogSummary,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "3.7.0",
3
+ "version": "3.7.1",
4
4
  "type": "module",
5
5
  "description": "BlockRun SDK - Pay-per-request AI (LLM, Image, Video, Music, Voice) via x402 on Base and Solana",
6
6
  "main": "dist/index.cjs",