@blockrun/llm 3.7.1 → 3.8.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 CHANGED
@@ -1330,10 +1330,30 @@ belonging to other applications on this system:
1330
1330
  ...
1331
1331
  ```
1332
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.
1333
+ Adopt one deliberately:
1334
+
1335
+ ```typescript
1336
+ import { listDiscoveredWallets, importWallet } from '@blockrun/llm';
1337
+
1338
+ for (const w of listDiscoveredWallets()) {
1339
+ console.log(w.address, 'from', w.source);
1340
+ }
1341
+
1342
+ importWallet('0x88f9B82462f6C4bf4a0Fb15e5c3971559a316e7f');
1343
+ ```
1344
+
1345
+ `importWallet()` writes your current wallet to
1346
+ `~/.blockrun/.session.backup-<timestamp>` before switching, so adopting a wallet
1347
+ never strands funds in the old one. Solana: `listDiscoveredSolanaWallets()` and
1348
+ `importSolanaWallet()`.
1349
+
1350
+ Addresses shown are derived from the discovered key itself, and `importWallet()`
1351
+ matches on that derived address — so a wallet file cannot claim an address it
1352
+ cannot sign for, nor be adopted by one. `listDiscoveredWallets()` never returns
1353
+ private keys.
1354
+
1355
+ For a single run without changing anything, use
1356
+ `export BLOCKRUN_WALLET_KEY=<private-key>`.
1337
1357
 
1338
1358
  ## Response Caching
1339
1359
 
package/dist/index.cjs CHANGED
@@ -84,6 +84,10 @@ __export(index_exports, {
84
84
  getOrCreateWallet: () => getOrCreateWallet,
85
85
  getPaymentLinks: () => getPaymentLinks,
86
86
  getWalletAddress: () => getWalletAddress,
87
+ importSolanaWallet: () => importSolanaWallet,
88
+ importWallet: () => importWallet,
89
+ listDiscoveredSolanaWallets: () => listDiscoveredSolanaWallets,
90
+ listDiscoveredWallets: () => listDiscoveredWallets,
87
91
  loadSolanaWallet: () => loadSolanaWallet,
88
92
  loadWallet: () => loadWallet,
89
93
  logCost: () => logCost,
@@ -4631,7 +4635,7 @@ function scanWallets() {
4631
4635
  const addr = data.address || "";
4632
4636
  if (pk && addr) {
4633
4637
  const mtime = fs2.statSync(walletFile).mtimeMs;
4634
- results.push({ mtime, privateKey: pk, address: addr });
4638
+ results.push({ mtime, privateKey: pk, address: addr, source: walletFile });
4635
4639
  }
4636
4640
  } catch {
4637
4641
  continue;
@@ -4640,7 +4644,46 @@ function scanWallets() {
4640
4644
  } catch {
4641
4645
  }
4642
4646
  results.sort((a, b) => b.mtime - a.mtime);
4643
- return results.map(({ privateKey, address }) => ({ privateKey, address }));
4647
+ return results.map(({ privateKey, address, source }) => ({ privateKey, address, source }));
4648
+ }
4649
+ function listDiscoveredWallets() {
4650
+ const listed = [];
4651
+ for (const entry of scanWallets()) {
4652
+ try {
4653
+ listed.push({
4654
+ address: (0, import_accounts15.privateKeyToAccount)(entry.privateKey).address,
4655
+ source: entry.source
4656
+ });
4657
+ } catch {
4658
+ continue;
4659
+ }
4660
+ }
4661
+ return listed;
4662
+ }
4663
+ function importWallet(address) {
4664
+ const wanted = address.trim().toLowerCase();
4665
+ for (const entry of scanWallets()) {
4666
+ let derived;
4667
+ try {
4668
+ derived = (0, import_accounts15.privateKeyToAccount)(entry.privateKey).address;
4669
+ } catch {
4670
+ continue;
4671
+ }
4672
+ if (derived.toLowerCase() !== wanted) continue;
4673
+ if (fs2.existsSync(WALLET_FILE)) {
4674
+ const current = fs2.readFileSync(WALLET_FILE, "utf-8").trim();
4675
+ if (current && current !== entry.privateKey) {
4676
+ const backup = path2.join(WALLET_DIR, `.session.backup-${Math.floor(Date.now() / 1e3)}`);
4677
+ fs2.writeFileSync(backup, current, { mode: 384 });
4678
+ }
4679
+ }
4680
+ saveWallet(entry.privateKey);
4681
+ return derived;
4682
+ }
4683
+ const available = listDiscoveredWallets().map((w) => w.address);
4684
+ throw new Error(
4685
+ `No discovered wallet controls ${address}. Available: ${available.length ? available.join(", ") : "none"}`
4686
+ );
4644
4687
  }
4645
4688
  function loadWallet() {
4646
4689
  if (fs2.existsSync(WALLET_FILE)) {
@@ -4685,11 +4728,13 @@ Discovered wallets are never adopted automatically \u2014 one may belong to a
4685
4728
  different application, or have been planted to make you fund an address you
4686
4729
  do not control.
4687
4730
 
4688
- If an address above is yours and holds your USDC, import it deliberately:
4731
+ If an address above is yours and holds your USDC, adopt it deliberately:
4689
4732
 
4690
- export BLOCKRUN_WALLET_KEY=<private-key>
4733
+ import { importWallet } from '@blockrun/llm';
4734
+ importWallet("<address-from-the-list-above>");
4691
4735
 
4692
- or write that key to ~/.blockrun/.session
4736
+ Your current wallet is backed up first. You can also set
4737
+ BLOCKRUN_WALLET_KEY=<private-key> for a single run without changing anything.
4693
4738
  `;
4694
4739
  }
4695
4740
  function getOrCreateWallet() {
@@ -4834,7 +4879,7 @@ function scanSolanaWallets() {
4834
4879
  const addr = data.address || "";
4835
4880
  if (pk && addr) {
4836
4881
  const mtime = fs3.statSync(solanaWalletFile).mtimeMs;
4837
- results.push({ mtime, secretKey: pk, publicKey: addr });
4882
+ results.push({ mtime, secretKey: pk, publicKey: addr, source: solanaWalletFile });
4838
4883
  }
4839
4884
  } catch {
4840
4885
  }
@@ -4848,7 +4893,7 @@ function scanSolanaWallets() {
4848
4893
  const addr = data.address || "";
4849
4894
  if (pk && addr) {
4850
4895
  const mtime = fs3.statSync(brccWalletFile).mtimeMs;
4851
- results.push({ mtime, secretKey: pk, publicKey: addr });
4896
+ results.push({ mtime, secretKey: pk, publicKey: addr, source: brccWalletFile });
4852
4897
  }
4853
4898
  } catch {
4854
4899
  }
@@ -4858,7 +4903,7 @@ function scanSolanaWallets() {
4858
4903
  } catch {
4859
4904
  }
4860
4905
  results.sort((a, b) => b.mtime - a.mtime);
4861
- return results.map(({ secretKey, publicKey }) => ({ secretKey, publicKey }));
4906
+ return results.map(({ secretKey, publicKey, source }) => ({ secretKey, publicKey, source }));
4862
4907
  }
4863
4908
  function loadSolanaWallet() {
4864
4909
  if (fs3.existsSync(SOLANA_WALLET_FILE)) {
@@ -4867,6 +4912,45 @@ function loadSolanaWallet() {
4867
4912
  }
4868
4913
  return null;
4869
4914
  }
4915
+ async function listDiscoveredSolanaWallets() {
4916
+ const listed = [];
4917
+ for (const entry of scanSolanaWallets()) {
4918
+ try {
4919
+ listed.push({ address: await solanaPublicKey(entry.secretKey), source: entry.source });
4920
+ } catch {
4921
+ continue;
4922
+ }
4923
+ }
4924
+ return listed;
4925
+ }
4926
+ async function importSolanaWallet(address) {
4927
+ const wanted = address.trim();
4928
+ for (const entry of scanSolanaWallets()) {
4929
+ let derived;
4930
+ try {
4931
+ derived = await solanaPublicKey(entry.secretKey);
4932
+ } catch {
4933
+ continue;
4934
+ }
4935
+ if (derived !== wanted) continue;
4936
+ if (fs3.existsSync(SOLANA_WALLET_FILE)) {
4937
+ const current = fs3.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
4938
+ if (current && current !== entry.secretKey) {
4939
+ const backup = path3.join(
4940
+ WALLET_DIR2,
4941
+ `.solana-session.backup-${Math.floor(Date.now() / 1e3)}`
4942
+ );
4943
+ fs3.writeFileSync(backup, current, { mode: 384 });
4944
+ }
4945
+ }
4946
+ saveSolanaWallet(entry.secretKey);
4947
+ return derived;
4948
+ }
4949
+ const available = (await listDiscoveredSolanaWallets()).map((w) => w.address);
4950
+ throw new Error(
4951
+ `No discovered wallet controls ${address}. Available: ${available.length ? available.join(", ") : "none"}`
4952
+ );
4953
+ }
4870
4954
  async function formatSolanaWalletMigrationNotice(newAddress) {
4871
4955
  let discovered;
4872
4956
  try {
@@ -4898,11 +4982,13 @@ Discovered wallets are never adopted automatically \u2014 one may belong to a
4898
4982
  different application, or have been planted to make you fund an address you
4899
4983
  do not control.
4900
4984
 
4901
- If an address above is yours and holds your USDC, import it deliberately:
4985
+ If an address above is yours and holds your USDC, adopt it deliberately:
4902
4986
 
4903
- export SOLANA_WALLET_KEY=<private-key>
4987
+ import { importSolanaWallet } from '@blockrun/llm';
4988
+ await importSolanaWallet("<address-from-the-list-above>");
4904
4989
 
4905
- or write that key to ~/.blockrun/.solana-session
4990
+ Your current wallet is backed up first. You can also set
4991
+ SOLANA_WALLET_KEY=<private-key> for a single run without changing anything.
4906
4992
  `;
4907
4993
  }
4908
4994
  async function getOrCreateSolanaWallet() {
@@ -6088,6 +6174,10 @@ var AnthropicClient = class {
6088
6174
  getOrCreateWallet,
6089
6175
  getPaymentLinks,
6090
6176
  getWalletAddress,
6177
+ importSolanaWallet,
6178
+ importWallet,
6179
+ listDiscoveredSolanaWallets,
6180
+ listDiscoveredWallets,
6091
6181
  loadSolanaWallet,
6092
6182
  loadWallet,
6093
6183
  logCost,
package/dist/index.d.cts CHANGED
@@ -2539,7 +2539,39 @@ declare function saveWallet(privateKey: string): string;
2539
2539
  declare function scanWallets(): Array<{
2540
2540
  privateKey: string;
2541
2541
  address: string;
2542
+ source: string;
2542
2543
  }>;
2544
+ /**
2545
+ * List wallets from other applications, safe to show to a user.
2546
+ *
2547
+ * Unlike `scanWallets()`, no private key is returned and the address is derived
2548
+ * from the key rather than read from the file, so a wallet file cannot claim an
2549
+ * address it has no key for.
2550
+ *
2551
+ * Nothing here is active. Adopt one deliberately with `importWallet()`.
2552
+ *
2553
+ * @returns Discovered wallets as `{ address, source }`, most recent first
2554
+ */
2555
+ declare function listDiscoveredWallets(): Array<{
2556
+ address: string;
2557
+ source: string;
2558
+ }>;
2559
+ /**
2560
+ * Adopt a discovered wallet by address, making it the active BlockRun wallet.
2561
+ *
2562
+ * This is the deliberate migration path: automatic selection never adopts a
2563
+ * discovered wallet, but you can choose one whose funds you want to spend.
2564
+ * Matching is done against the address *derived from each discovered key*, so a
2565
+ * wallet file claiming someone else's address can never be selected by it.
2566
+ *
2567
+ * The current `~/.blockrun/.session` is backed up beside itself before being
2568
+ * overwritten, so adopting a wallet can't strand the funds in the old one.
2569
+ *
2570
+ * @param address Address to adopt, as shown by `listDiscoveredWallets()`
2571
+ * @returns The adopted address
2572
+ * @throws If no discovered wallet derives to that address
2573
+ */
2574
+ declare function importWallet(address: string): string;
2543
2575
  /**
2544
2576
  * Load wallet private key from file.
2545
2577
  *
@@ -2850,8 +2882,34 @@ declare function saveSolanaWallet(privateKey: string): string;
2850
2882
  declare function scanSolanaWallets(): Array<{
2851
2883
  secretKey: string;
2852
2884
  publicKey: string;
2885
+ source: string;
2853
2886
  }>;
2854
2887
  declare function loadSolanaWallet(): string | null;
2888
+ /**
2889
+ * List Solana wallets from other applications, safe to show to a user.
2890
+ *
2891
+ * Solana counterpart of `listDiscoveredWallets()`: no secret key is returned
2892
+ * and the address is derived from the key rather than trusted from the file.
2893
+ * Nothing here is active — adopt one with `importSolanaWallet()`.
2894
+ *
2895
+ * @returns Discovered wallets as `{ address, source }`, most recent first
2896
+ */
2897
+ declare function listDiscoveredSolanaWallets(): Promise<Array<{
2898
+ address: string;
2899
+ source: string;
2900
+ }>>;
2901
+ /**
2902
+ * Adopt a discovered Solana wallet, making it the active BlockRun wallet.
2903
+ *
2904
+ * Solana counterpart of `importWallet()`. Matching is done against the address
2905
+ * derived from each discovered key, and the current
2906
+ * `~/.blockrun/.solana-session` is backed up before being overwritten.
2907
+ *
2908
+ * @param address Address to adopt, as shown by `listDiscoveredSolanaWallets()`
2909
+ * @returns The adopted address
2910
+ * @throws If no discovered wallet derives to that address
2911
+ */
2912
+ declare function importSolanaWallet(address: string): Promise<string>;
2855
2913
  /**
2856
2914
  * Warn when a new Solana wallet was created while provider wallets exist.
2857
2915
  *
@@ -3133,4 +3191,4 @@ declare function validateTemperature(temperature?: number): void;
3133
3191
  */
3134
3192
  declare function validateTopP(topP?: number): void;
3135
3193
 
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 };
3194
+ 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, importSolanaWallet, importWallet, listDiscoveredSolanaWallets, listDiscoveredWallets, 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
@@ -2539,7 +2539,39 @@ declare function saveWallet(privateKey: string): string;
2539
2539
  declare function scanWallets(): Array<{
2540
2540
  privateKey: string;
2541
2541
  address: string;
2542
+ source: string;
2542
2543
  }>;
2544
+ /**
2545
+ * List wallets from other applications, safe to show to a user.
2546
+ *
2547
+ * Unlike `scanWallets()`, no private key is returned and the address is derived
2548
+ * from the key rather than read from the file, so a wallet file cannot claim an
2549
+ * address it has no key for.
2550
+ *
2551
+ * Nothing here is active. Adopt one deliberately with `importWallet()`.
2552
+ *
2553
+ * @returns Discovered wallets as `{ address, source }`, most recent first
2554
+ */
2555
+ declare function listDiscoveredWallets(): Array<{
2556
+ address: string;
2557
+ source: string;
2558
+ }>;
2559
+ /**
2560
+ * Adopt a discovered wallet by address, making it the active BlockRun wallet.
2561
+ *
2562
+ * This is the deliberate migration path: automatic selection never adopts a
2563
+ * discovered wallet, but you can choose one whose funds you want to spend.
2564
+ * Matching is done against the address *derived from each discovered key*, so a
2565
+ * wallet file claiming someone else's address can never be selected by it.
2566
+ *
2567
+ * The current `~/.blockrun/.session` is backed up beside itself before being
2568
+ * overwritten, so adopting a wallet can't strand the funds in the old one.
2569
+ *
2570
+ * @param address Address to adopt, as shown by `listDiscoveredWallets()`
2571
+ * @returns The adopted address
2572
+ * @throws If no discovered wallet derives to that address
2573
+ */
2574
+ declare function importWallet(address: string): string;
2543
2575
  /**
2544
2576
  * Load wallet private key from file.
2545
2577
  *
@@ -2850,8 +2882,34 @@ declare function saveSolanaWallet(privateKey: string): string;
2850
2882
  declare function scanSolanaWallets(): Array<{
2851
2883
  secretKey: string;
2852
2884
  publicKey: string;
2885
+ source: string;
2853
2886
  }>;
2854
2887
  declare function loadSolanaWallet(): string | null;
2888
+ /**
2889
+ * List Solana wallets from other applications, safe to show to a user.
2890
+ *
2891
+ * Solana counterpart of `listDiscoveredWallets()`: no secret key is returned
2892
+ * and the address is derived from the key rather than trusted from the file.
2893
+ * Nothing here is active — adopt one with `importSolanaWallet()`.
2894
+ *
2895
+ * @returns Discovered wallets as `{ address, source }`, most recent first
2896
+ */
2897
+ declare function listDiscoveredSolanaWallets(): Promise<Array<{
2898
+ address: string;
2899
+ source: string;
2900
+ }>>;
2901
+ /**
2902
+ * Adopt a discovered Solana wallet, making it the active BlockRun wallet.
2903
+ *
2904
+ * Solana counterpart of `importWallet()`. Matching is done against the address
2905
+ * derived from each discovered key, and the current
2906
+ * `~/.blockrun/.solana-session` is backed up before being overwritten.
2907
+ *
2908
+ * @param address Address to adopt, as shown by `listDiscoveredSolanaWallets()`
2909
+ * @returns The adopted address
2910
+ * @throws If no discovered wallet derives to that address
2911
+ */
2912
+ declare function importSolanaWallet(address: string): Promise<string>;
2855
2913
  /**
2856
2914
  * Warn when a new Solana wallet was created while provider wallets exist.
2857
2915
  *
@@ -3133,4 +3191,4 @@ declare function validateTemperature(temperature?: number): void;
3133
3191
  */
3134
3192
  declare function validateTopP(topP?: number): void;
3135
3193
 
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 };
3194
+ 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, importSolanaWallet, importWallet, listDiscoveredSolanaWallets, listDiscoveredWallets, 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
@@ -4522,7 +4522,7 @@ function scanWallets() {
4522
4522
  const addr = data.address || "";
4523
4523
  if (pk && addr) {
4524
4524
  const mtime = fs2.statSync(walletFile).mtimeMs;
4525
- results.push({ mtime, privateKey: pk, address: addr });
4525
+ results.push({ mtime, privateKey: pk, address: addr, source: walletFile });
4526
4526
  }
4527
4527
  } catch {
4528
4528
  continue;
@@ -4531,7 +4531,46 @@ function scanWallets() {
4531
4531
  } catch {
4532
4532
  }
4533
4533
  results.sort((a, b) => b.mtime - a.mtime);
4534
- return results.map(({ privateKey, address }) => ({ privateKey, address }));
4534
+ return results.map(({ privateKey, address, source }) => ({ privateKey, address, source }));
4535
+ }
4536
+ function listDiscoveredWallets() {
4537
+ const listed = [];
4538
+ for (const entry of scanWallets()) {
4539
+ try {
4540
+ listed.push({
4541
+ address: privateKeyToAccount14(entry.privateKey).address,
4542
+ source: entry.source
4543
+ });
4544
+ } catch {
4545
+ continue;
4546
+ }
4547
+ }
4548
+ return listed;
4549
+ }
4550
+ function importWallet(address) {
4551
+ const wanted = address.trim().toLowerCase();
4552
+ for (const entry of scanWallets()) {
4553
+ let derived;
4554
+ try {
4555
+ derived = privateKeyToAccount14(entry.privateKey).address;
4556
+ } catch {
4557
+ continue;
4558
+ }
4559
+ if (derived.toLowerCase() !== wanted) continue;
4560
+ if (fs2.existsSync(WALLET_FILE)) {
4561
+ const current = fs2.readFileSync(WALLET_FILE, "utf-8").trim();
4562
+ if (current && current !== entry.privateKey) {
4563
+ const backup = path2.join(WALLET_DIR, `.session.backup-${Math.floor(Date.now() / 1e3)}`);
4564
+ fs2.writeFileSync(backup, current, { mode: 384 });
4565
+ }
4566
+ }
4567
+ saveWallet(entry.privateKey);
4568
+ return derived;
4569
+ }
4570
+ const available = listDiscoveredWallets().map((w) => w.address);
4571
+ throw new Error(
4572
+ `No discovered wallet controls ${address}. Available: ${available.length ? available.join(", ") : "none"}`
4573
+ );
4535
4574
  }
4536
4575
  function loadWallet() {
4537
4576
  if (fs2.existsSync(WALLET_FILE)) {
@@ -4576,11 +4615,13 @@ Discovered wallets are never adopted automatically \u2014 one may belong to a
4576
4615
  different application, or have been planted to make you fund an address you
4577
4616
  do not control.
4578
4617
 
4579
- If an address above is yours and holds your USDC, import it deliberately:
4618
+ If an address above is yours and holds your USDC, adopt it deliberately:
4580
4619
 
4581
- export BLOCKRUN_WALLET_KEY=<private-key>
4620
+ import { importWallet } from '@blockrun/llm';
4621
+ importWallet("<address-from-the-list-above>");
4582
4622
 
4583
- or write that key to ~/.blockrun/.session
4623
+ Your current wallet is backed up first. You can also set
4624
+ BLOCKRUN_WALLET_KEY=<private-key> for a single run without changing anything.
4584
4625
  `;
4585
4626
  }
4586
4627
  function getOrCreateWallet() {
@@ -4725,7 +4766,7 @@ function scanSolanaWallets() {
4725
4766
  const addr = data.address || "";
4726
4767
  if (pk && addr) {
4727
4768
  const mtime = fs3.statSync(solanaWalletFile).mtimeMs;
4728
- results.push({ mtime, secretKey: pk, publicKey: addr });
4769
+ results.push({ mtime, secretKey: pk, publicKey: addr, source: solanaWalletFile });
4729
4770
  }
4730
4771
  } catch {
4731
4772
  }
@@ -4739,7 +4780,7 @@ function scanSolanaWallets() {
4739
4780
  const addr = data.address || "";
4740
4781
  if (pk && addr) {
4741
4782
  const mtime = fs3.statSync(brccWalletFile).mtimeMs;
4742
- results.push({ mtime, secretKey: pk, publicKey: addr });
4783
+ results.push({ mtime, secretKey: pk, publicKey: addr, source: brccWalletFile });
4743
4784
  }
4744
4785
  } catch {
4745
4786
  }
@@ -4749,7 +4790,7 @@ function scanSolanaWallets() {
4749
4790
  } catch {
4750
4791
  }
4751
4792
  results.sort((a, b) => b.mtime - a.mtime);
4752
- return results.map(({ secretKey, publicKey }) => ({ secretKey, publicKey }));
4793
+ return results.map(({ secretKey, publicKey, source }) => ({ secretKey, publicKey, source }));
4753
4794
  }
4754
4795
  function loadSolanaWallet() {
4755
4796
  if (fs3.existsSync(SOLANA_WALLET_FILE)) {
@@ -4758,6 +4799,45 @@ function loadSolanaWallet() {
4758
4799
  }
4759
4800
  return null;
4760
4801
  }
4802
+ async function listDiscoveredSolanaWallets() {
4803
+ const listed = [];
4804
+ for (const entry of scanSolanaWallets()) {
4805
+ try {
4806
+ listed.push({ address: await solanaPublicKey(entry.secretKey), source: entry.source });
4807
+ } catch {
4808
+ continue;
4809
+ }
4810
+ }
4811
+ return listed;
4812
+ }
4813
+ async function importSolanaWallet(address) {
4814
+ const wanted = address.trim();
4815
+ for (const entry of scanSolanaWallets()) {
4816
+ let derived;
4817
+ try {
4818
+ derived = await solanaPublicKey(entry.secretKey);
4819
+ } catch {
4820
+ continue;
4821
+ }
4822
+ if (derived !== wanted) continue;
4823
+ if (fs3.existsSync(SOLANA_WALLET_FILE)) {
4824
+ const current = fs3.readFileSync(SOLANA_WALLET_FILE, "utf-8").trim();
4825
+ if (current && current !== entry.secretKey) {
4826
+ const backup = path3.join(
4827
+ WALLET_DIR2,
4828
+ `.solana-session.backup-${Math.floor(Date.now() / 1e3)}`
4829
+ );
4830
+ fs3.writeFileSync(backup, current, { mode: 384 });
4831
+ }
4832
+ }
4833
+ saveSolanaWallet(entry.secretKey);
4834
+ return derived;
4835
+ }
4836
+ const available = (await listDiscoveredSolanaWallets()).map((w) => w.address);
4837
+ throw new Error(
4838
+ `No discovered wallet controls ${address}. Available: ${available.length ? available.join(", ") : "none"}`
4839
+ );
4840
+ }
4761
4841
  async function formatSolanaWalletMigrationNotice(newAddress) {
4762
4842
  let discovered;
4763
4843
  try {
@@ -4789,11 +4869,13 @@ Discovered wallets are never adopted automatically \u2014 one may belong to a
4789
4869
  different application, or have been planted to make you fund an address you
4790
4870
  do not control.
4791
4871
 
4792
- If an address above is yours and holds your USDC, import it deliberately:
4872
+ If an address above is yours and holds your USDC, adopt it deliberately:
4793
4873
 
4794
- export SOLANA_WALLET_KEY=<private-key>
4874
+ import { importSolanaWallet } from '@blockrun/llm';
4875
+ await importSolanaWallet("<address-from-the-list-above>");
4795
4876
 
4796
- or write that key to ~/.blockrun/.solana-session
4877
+ Your current wallet is backed up first. You can also set
4878
+ SOLANA_WALLET_KEY=<private-key> for a single run without changing anything.
4797
4879
  `;
4798
4880
  }
4799
4881
  async function getOrCreateSolanaWallet() {
@@ -5979,6 +6061,10 @@ export {
5979
6061
  getOrCreateWallet,
5980
6062
  getPaymentLinks,
5981
6063
  getWalletAddress,
6064
+ importSolanaWallet,
6065
+ importWallet,
6066
+ listDiscoveredSolanaWallets,
6067
+ listDiscoveredWallets,
5982
6068
  loadSolanaWallet,
5983
6069
  loadWallet,
5984
6070
  logCost,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "3.7.1",
3
+ "version": "3.8.0",
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",