@blockrun/llm 2.7.0 → 2.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 +31 -2
- package/dist/index.cjs +195 -37
- package/dist/index.d.cts +128 -2
- package/dist/index.d.ts +128 -2
- package/dist/index.js +192 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,8 +84,8 @@ Four call shapes cover every endpoint type:
|
|
|
84
84
|
- `stream<T>(path, body?)` — async iterator over SSE chunks (chat)
|
|
85
85
|
|
|
86
86
|
The per-API client classes (`LLMClient`, `ImageClient`, `VideoClient`,
|
|
87
|
-
`VoiceClient`, `MusicClient`, `SearchClient`, `XClient`,
|
|
88
|
-
`SurfClient`) all remain — they will be soft-deprecated in 2.6 (rewritten as
|
|
87
|
+
`PortraitClient`, `VoiceClient`, `MusicClient`, `SearchClient`, `XClient`,
|
|
88
|
+
`PriceClient`, `SurfClient`) all remain — they will be soft-deprecated in 2.6 (rewritten as
|
|
89
89
|
shims over `BlockrunClient`) and removed in 3.0.
|
|
90
90
|
|
|
91
91
|
### Try It Free (No USDC Required)
|
|
@@ -441,6 +441,35 @@ const r3 = await client.generate('aerial drone shot over a snowy mountain', {
|
|
|
441
441
|
});
|
|
442
442
|
```
|
|
443
443
|
|
|
444
|
+
### Virtual Portraits
|
|
445
|
+
|
|
446
|
+
`PortraitClient` wraps `POST /v1/portrait/enroll` (paid, flat **$0.01** promo,
|
|
447
|
+
no KYC). Enroll a face image by URL and get back a Token360 asset id (`ta_xxxxxx`).
|
|
448
|
+
Pass that id as `realFaceAssetId` on a Seedance 2.0 video generation to keep the
|
|
449
|
+
same AI character across clips. Payment settles only after Token360 confirms the
|
|
450
|
+
enrollment, so a failed enrollment never charges your wallet. The returned
|
|
451
|
+
`image_url` is a gateway-mirrored copy of your source image (see `mirrored` /
|
|
452
|
+
`source_image_url`). (Real-person likeness is not supported on BlockRun —
|
|
453
|
+
enrolled portraits are AI characters.)
|
|
454
|
+
|
|
455
|
+
```ts
|
|
456
|
+
import { PortraitClient, VideoClient } from '@blockrun/llm';
|
|
457
|
+
|
|
458
|
+
const portraits = new PortraitClient();
|
|
459
|
+
const { asset_id } = await portraits.enroll({
|
|
460
|
+
name: 'Spokesperson',
|
|
461
|
+
imageUrl: 'https://example.com/face.jpg', // public https JPG/PNG/WEBP, ≤10 MB
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
// Reuse the same character across Seedance 2.0 clips
|
|
465
|
+
const video = new VideoClient();
|
|
466
|
+
const clip = await video.generate('she waves and smiles', {
|
|
467
|
+
model: 'bytedance/seedance-2.0-fast',
|
|
468
|
+
realFaceAssetId: asset_id,
|
|
469
|
+
});
|
|
470
|
+
console.log(clip.data[0].url);
|
|
471
|
+
```
|
|
472
|
+
|
|
444
473
|
### Voice Calls
|
|
445
474
|
|
|
446
475
|
`VoiceClient` wraps `POST /v1/voice/call` (paid, $0.54/call) and
|
package/dist/index.cjs
CHANGED
|
@@ -41,8 +41,10 @@ __export(index_exports, {
|
|
|
41
41
|
MusicClient: () => MusicClient,
|
|
42
42
|
OpenAI: () => OpenAI,
|
|
43
43
|
PHONE_PRICES: () => PHONE_PRICES,
|
|
44
|
+
PORTRAIT_ENROLLMENT_PRICE_USD: () => PORTRAIT_ENROLLMENT_PRICE_USD,
|
|
44
45
|
PaymentError: () => PaymentError,
|
|
45
46
|
PhoneClient: () => PhoneClient,
|
|
47
|
+
PortraitClient: () => PortraitClient,
|
|
46
48
|
PriceClient: () => PriceClient,
|
|
47
49
|
SOLANA_NETWORK: () => SOLANA_NETWORK,
|
|
48
50
|
SOLANA_WALLET_FILE_PATH: () => SOLANA_WALLET_FILE,
|
|
@@ -2999,15 +3001,18 @@ var PhoneClient = class {
|
|
|
2999
3001
|
}
|
|
3000
3002
|
};
|
|
3001
3003
|
|
|
3002
|
-
// src/
|
|
3004
|
+
// src/portrait.ts
|
|
3003
3005
|
var import_accounts8 = require("viem/accounts");
|
|
3004
3006
|
var DEFAULT_API_URL7 = "https://blockrun.ai/api";
|
|
3005
3007
|
var DEFAULT_TIMEOUT7 = 6e4;
|
|
3006
|
-
var
|
|
3008
|
+
var PORTRAIT_ENROLLMENT_PRICE_USD = 0.01;
|
|
3009
|
+
var PortraitClient = class {
|
|
3007
3010
|
account;
|
|
3008
3011
|
privateKey;
|
|
3009
3012
|
apiUrl;
|
|
3010
3013
|
timeout;
|
|
3014
|
+
sessionTotalUsd = 0;
|
|
3015
|
+
sessionCalls = 0;
|
|
3011
3016
|
constructor(options = {}) {
|
|
3012
3017
|
const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
|
|
3013
3018
|
const privateKey = options.privateKey || envKey;
|
|
@@ -3024,6 +3029,157 @@ var SearchClient = class {
|
|
|
3024
3029
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3025
3030
|
this.timeout = options.timeout || DEFAULT_TIMEOUT7;
|
|
3026
3031
|
}
|
|
3032
|
+
/** EVM wallet address used for payments. */
|
|
3033
|
+
getWalletAddress() {
|
|
3034
|
+
return this.account.address;
|
|
3035
|
+
}
|
|
3036
|
+
/** Session-cumulative USD spend + call count across this client instance. */
|
|
3037
|
+
getSpending() {
|
|
3038
|
+
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
3039
|
+
}
|
|
3040
|
+
/**
|
|
3041
|
+
* Enroll a Virtual Portrait from a face image URL. $0.01 (promo).
|
|
3042
|
+
*
|
|
3043
|
+
* Payment is settled only after Token360 confirms the enrollment, so failed
|
|
3044
|
+
* enrollments never charge your wallet.
|
|
3045
|
+
*
|
|
3046
|
+
* @param options.name Display name (1–64 chars).
|
|
3047
|
+
* @param options.imageUrl Public HTTPS URL to a JPG/PNG/WEBP image (≤10 MB).
|
|
3048
|
+
* @returns The enrollment record, including `asset_id` (`ta_xxxxxx`).
|
|
3049
|
+
*/
|
|
3050
|
+
async enroll(options) {
|
|
3051
|
+
const name = typeof options?.name === "string" ? options.name.trim() : "";
|
|
3052
|
+
if (name.length < 1 || name.length > 64) {
|
|
3053
|
+
throw new Error("name is required and must be 1\u201364 characters");
|
|
3054
|
+
}
|
|
3055
|
+
const imageUrl = typeof options?.imageUrl === "string" ? options.imageUrl.trim() : "";
|
|
3056
|
+
if (!/^https?:\/\//i.test(imageUrl)) {
|
|
3057
|
+
throw new Error(
|
|
3058
|
+
"imageUrl must be a public http(s) URL to a JPG/PNG/WEBP image"
|
|
3059
|
+
);
|
|
3060
|
+
}
|
|
3061
|
+
const data = await this.request({
|
|
3062
|
+
name,
|
|
3063
|
+
image_url: imageUrl
|
|
3064
|
+
});
|
|
3065
|
+
return data;
|
|
3066
|
+
}
|
|
3067
|
+
// ─── Internals ─────────────────────────────────────────────────────────
|
|
3068
|
+
async request(body) {
|
|
3069
|
+
const url = `${this.apiUrl}/v1/portrait/enroll`;
|
|
3070
|
+
const response = await this.fetchWithTimeout(url, {
|
|
3071
|
+
method: "POST",
|
|
3072
|
+
headers: { "Content-Type": "application/json" },
|
|
3073
|
+
body: JSON.stringify(body)
|
|
3074
|
+
});
|
|
3075
|
+
if (response.status === 402) {
|
|
3076
|
+
return this.handlePaymentAndRetry(url, body, response);
|
|
3077
|
+
}
|
|
3078
|
+
return this.unwrap(response, false);
|
|
3079
|
+
}
|
|
3080
|
+
async handlePaymentAndRetry(url, body, response) {
|
|
3081
|
+
let paymentHeader = response.headers.get("payment-required");
|
|
3082
|
+
if (!paymentHeader) {
|
|
3083
|
+
try {
|
|
3084
|
+
const rb = await response.json();
|
|
3085
|
+
if (rb.x402 || rb.accepts) paymentHeader = btoa(JSON.stringify(rb));
|
|
3086
|
+
} catch {
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
if (!paymentHeader) {
|
|
3090
|
+
throw new PaymentError("402 response but no payment requirements found");
|
|
3091
|
+
}
|
|
3092
|
+
const paymentRequired = parsePaymentRequired(paymentHeader);
|
|
3093
|
+
const details = extractPaymentDetails(paymentRequired);
|
|
3094
|
+
const paymentPayload = await createPaymentPayload(
|
|
3095
|
+
this.privateKey,
|
|
3096
|
+
this.account.address,
|
|
3097
|
+
details.recipient,
|
|
3098
|
+
details.amount,
|
|
3099
|
+
details.network || "eip155:8453",
|
|
3100
|
+
{
|
|
3101
|
+
resourceUrl: details.resource?.url || url,
|
|
3102
|
+
resourceDescription: details.resource?.description || "BlockRun Virtual Portrait",
|
|
3103
|
+
maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
|
|
3104
|
+
extra: details.extra
|
|
3105
|
+
}
|
|
3106
|
+
);
|
|
3107
|
+
const retry = await this.fetchWithTimeout(url, {
|
|
3108
|
+
method: "POST",
|
|
3109
|
+
headers: {
|
|
3110
|
+
"Content-Type": "application/json",
|
|
3111
|
+
"PAYMENT-SIGNATURE": paymentPayload
|
|
3112
|
+
},
|
|
3113
|
+
body: JSON.stringify(body)
|
|
3114
|
+
});
|
|
3115
|
+
if (retry.status === 402) {
|
|
3116
|
+
throw new PaymentError("Payment was rejected. Check your wallet balance.");
|
|
3117
|
+
}
|
|
3118
|
+
const data = await this.unwrap(retry, true);
|
|
3119
|
+
const costUsd = Number.parseFloat(details.amount) / 1e6;
|
|
3120
|
+
this.sessionCalls += 1;
|
|
3121
|
+
this.sessionTotalUsd += costUsd;
|
|
3122
|
+
if (data && typeof data === "object" && !("txHash" in data)) {
|
|
3123
|
+
const settlement = data.settlement;
|
|
3124
|
+
if (settlement?.tx_hash) {
|
|
3125
|
+
data.txHash = settlement.tx_hash;
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
return data;
|
|
3129
|
+
}
|
|
3130
|
+
async unwrap(response, afterPayment) {
|
|
3131
|
+
if (response.ok) {
|
|
3132
|
+
return response.json();
|
|
3133
|
+
}
|
|
3134
|
+
let errorBody;
|
|
3135
|
+
try {
|
|
3136
|
+
errorBody = await response.json();
|
|
3137
|
+
} catch {
|
|
3138
|
+
errorBody = { error: "Request failed" };
|
|
3139
|
+
}
|
|
3140
|
+
const prefix = afterPayment ? "API error after payment" : "API error";
|
|
3141
|
+
throw new APIError(
|
|
3142
|
+
`${prefix}: ${response.status}`,
|
|
3143
|
+
response.status,
|
|
3144
|
+
sanitizeErrorResponse(errorBody)
|
|
3145
|
+
);
|
|
3146
|
+
}
|
|
3147
|
+
async fetchWithTimeout(url, init) {
|
|
3148
|
+
const controller = new AbortController();
|
|
3149
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
3150
|
+
try {
|
|
3151
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
3152
|
+
} finally {
|
|
3153
|
+
clearTimeout(timeoutId);
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
};
|
|
3157
|
+
|
|
3158
|
+
// src/search.ts
|
|
3159
|
+
var import_accounts9 = require("viem/accounts");
|
|
3160
|
+
var DEFAULT_API_URL8 = "https://blockrun.ai/api";
|
|
3161
|
+
var DEFAULT_TIMEOUT8 = 6e4;
|
|
3162
|
+
var SearchClient = class {
|
|
3163
|
+
account;
|
|
3164
|
+
privateKey;
|
|
3165
|
+
apiUrl;
|
|
3166
|
+
timeout;
|
|
3167
|
+
constructor(options = {}) {
|
|
3168
|
+
const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
|
|
3169
|
+
const privateKey = options.privateKey || envKey;
|
|
3170
|
+
if (!privateKey) {
|
|
3171
|
+
throw new Error(
|
|
3172
|
+
"Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
|
|
3173
|
+
);
|
|
3174
|
+
}
|
|
3175
|
+
validatePrivateKey(privateKey);
|
|
3176
|
+
this.privateKey = privateKey;
|
|
3177
|
+
this.account = (0, import_accounts9.privateKeyToAccount)(privateKey);
|
|
3178
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL8;
|
|
3179
|
+
validateApiUrl(apiUrl);
|
|
3180
|
+
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3181
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT8;
|
|
3182
|
+
}
|
|
3027
3183
|
async search(query, options) {
|
|
3028
3184
|
if (!query || query.length > 1e3) {
|
|
3029
3185
|
throw new Error("query must be 1-1000 characters");
|
|
@@ -3136,9 +3292,9 @@ var SearchClient = class {
|
|
|
3136
3292
|
};
|
|
3137
3293
|
|
|
3138
3294
|
// src/x-client.ts
|
|
3139
|
-
var
|
|
3140
|
-
var
|
|
3141
|
-
var
|
|
3295
|
+
var import_accounts10 = require("viem/accounts");
|
|
3296
|
+
var DEFAULT_API_URL9 = "https://blockrun.ai/api";
|
|
3297
|
+
var DEFAULT_TIMEOUT9 = 6e4;
|
|
3142
3298
|
var XClient = class _XClient {
|
|
3143
3299
|
account;
|
|
3144
3300
|
privateKey;
|
|
@@ -3161,11 +3317,11 @@ var XClient = class _XClient {
|
|
|
3161
3317
|
}
|
|
3162
3318
|
validatePrivateKey(privateKey);
|
|
3163
3319
|
this.privateKey = privateKey;
|
|
3164
|
-
this.account = (0,
|
|
3165
|
-
const apiUrl = options.apiUrl ||
|
|
3320
|
+
this.account = (0, import_accounts10.privateKeyToAccount)(privateKey);
|
|
3321
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL9;
|
|
3166
3322
|
validateApiUrl(apiUrl);
|
|
3167
3323
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3168
|
-
this.timeout = options.timeout ||
|
|
3324
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT9;
|
|
3169
3325
|
}
|
|
3170
3326
|
// ───────── User endpoints ─────────
|
|
3171
3327
|
userLookup(usernames) {
|
|
@@ -3343,9 +3499,9 @@ var XClient = class _XClient {
|
|
|
3343
3499
|
};
|
|
3344
3500
|
|
|
3345
3501
|
// src/price.ts
|
|
3346
|
-
var
|
|
3347
|
-
var
|
|
3348
|
-
var
|
|
3502
|
+
var import_accounts11 = require("viem/accounts");
|
|
3503
|
+
var DEFAULT_API_URL10 = "https://blockrun.ai/api";
|
|
3504
|
+
var DEFAULT_TIMEOUT10 = 3e4;
|
|
3349
3505
|
var PriceClient = class {
|
|
3350
3506
|
account = null;
|
|
3351
3507
|
privateKey = null;
|
|
@@ -3363,12 +3519,12 @@ var PriceClient = class {
|
|
|
3363
3519
|
if (privateKey) {
|
|
3364
3520
|
validatePrivateKey(privateKey);
|
|
3365
3521
|
this.privateKey = privateKey;
|
|
3366
|
-
this.account = (0,
|
|
3522
|
+
this.account = (0, import_accounts11.privateKeyToAccount)(privateKey);
|
|
3367
3523
|
}
|
|
3368
|
-
const apiUrl = options.apiUrl ||
|
|
3524
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL10;
|
|
3369
3525
|
validateApiUrl(apiUrl);
|
|
3370
3526
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3371
|
-
this.timeout = options.timeout ||
|
|
3527
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT10;
|
|
3372
3528
|
}
|
|
3373
3529
|
async price(category, symbol, options) {
|
|
3374
3530
|
if (!symbol) throw new Error("symbol is required");
|
|
@@ -3547,9 +3703,9 @@ function buildUrl(base, query) {
|
|
|
3547
3703
|
}
|
|
3548
3704
|
|
|
3549
3705
|
// src/surf.ts
|
|
3550
|
-
var
|
|
3551
|
-
var
|
|
3552
|
-
var
|
|
3706
|
+
var import_accounts12 = require("viem/accounts");
|
|
3707
|
+
var DEFAULT_API_URL11 = "https://blockrun.ai/api";
|
|
3708
|
+
var DEFAULT_TIMEOUT11 = 6e4;
|
|
3553
3709
|
var SURF_PREFIX = "/v1/surf";
|
|
3554
3710
|
var SurfClient = class {
|
|
3555
3711
|
account;
|
|
@@ -3566,11 +3722,11 @@ var SurfClient = class {
|
|
|
3566
3722
|
}
|
|
3567
3723
|
validatePrivateKey(privateKey);
|
|
3568
3724
|
this.privateKey = privateKey;
|
|
3569
|
-
this.account = (0,
|
|
3570
|
-
const apiUrl = options.apiUrl ||
|
|
3725
|
+
this.account = (0, import_accounts12.privateKeyToAccount)(privateKey);
|
|
3726
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL11;
|
|
3571
3727
|
validateApiUrl(apiUrl);
|
|
3572
3728
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3573
|
-
this.timeout = options.timeout ||
|
|
3729
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT11;
|
|
3574
3730
|
}
|
|
3575
3731
|
/**
|
|
3576
3732
|
* GET a Surf endpoint. `path` is everything after `/v1/surf` (a leading
|
|
@@ -3702,9 +3858,9 @@ var SurfClient = class {
|
|
|
3702
3858
|
};
|
|
3703
3859
|
|
|
3704
3860
|
// src/blockrun.ts
|
|
3705
|
-
var
|
|
3706
|
-
var
|
|
3707
|
-
var
|
|
3861
|
+
var import_accounts13 = require("viem/accounts");
|
|
3862
|
+
var DEFAULT_API_URL12 = "https://blockrun.ai/api";
|
|
3863
|
+
var DEFAULT_TIMEOUT12 = 6e4;
|
|
3708
3864
|
var DEFAULT_POLL_INTERVAL_MS = 5e3;
|
|
3709
3865
|
var DEFAULT_POLL_BUDGET_MS = 3e5;
|
|
3710
3866
|
var MAX_SIGNED_AUTH_SECONDS = 600;
|
|
@@ -3725,11 +3881,11 @@ var BlockrunClient = class {
|
|
|
3725
3881
|
}
|
|
3726
3882
|
validatePrivateKey(privateKey);
|
|
3727
3883
|
this.privateKey = privateKey;
|
|
3728
|
-
this.account = (0,
|
|
3729
|
-
const apiUrl = options.apiUrl ||
|
|
3884
|
+
this.account = (0, import_accounts13.privateKeyToAccount)(privateKey);
|
|
3885
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL12;
|
|
3730
3886
|
validateApiUrl(apiUrl);
|
|
3731
3887
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3732
|
-
this.timeout = options.timeout ||
|
|
3888
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT12;
|
|
3733
3889
|
}
|
|
3734
3890
|
/**
|
|
3735
3891
|
* GET a BlockRun endpoint. `path` is everything after `/api` (a leading
|
|
@@ -4080,7 +4236,7 @@ function sleep(ms) {
|
|
|
4080
4236
|
}
|
|
4081
4237
|
|
|
4082
4238
|
// src/wallet.ts
|
|
4083
|
-
var
|
|
4239
|
+
var import_accounts14 = require("viem/accounts");
|
|
4084
4240
|
var fs2 = __toESM(require("fs"), 1);
|
|
4085
4241
|
var path2 = __toESM(require("path"), 1);
|
|
4086
4242
|
var os2 = __toESM(require("os"), 1);
|
|
@@ -4089,8 +4245,8 @@ var BASE_CHAIN_ID2 = "8453";
|
|
|
4089
4245
|
var WALLET_DIR = path2.join(os2.homedir(), ".blockrun");
|
|
4090
4246
|
var WALLET_FILE = path2.join(WALLET_DIR, ".session");
|
|
4091
4247
|
function createWallet() {
|
|
4092
|
-
const privateKey = (0,
|
|
4093
|
-
const account = (0,
|
|
4248
|
+
const privateKey = (0, import_accounts14.generatePrivateKey)();
|
|
4249
|
+
const account = (0, import_accounts14.privateKeyToAccount)(privateKey);
|
|
4094
4250
|
return {
|
|
4095
4251
|
address: account.address,
|
|
4096
4252
|
privateKey
|
|
@@ -4146,12 +4302,12 @@ function loadWallet() {
|
|
|
4146
4302
|
function getOrCreateWallet() {
|
|
4147
4303
|
const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
|
|
4148
4304
|
if (envKey) {
|
|
4149
|
-
const account = (0,
|
|
4305
|
+
const account = (0, import_accounts14.privateKeyToAccount)(envKey);
|
|
4150
4306
|
return { address: account.address, privateKey: envKey, isNew: false };
|
|
4151
4307
|
}
|
|
4152
4308
|
const fileKey = loadWallet();
|
|
4153
4309
|
if (fileKey) {
|
|
4154
|
-
const account = (0,
|
|
4310
|
+
const account = (0, import_accounts14.privateKeyToAccount)(fileKey);
|
|
4155
4311
|
return { address: account.address, privateKey: fileKey, isNew: false };
|
|
4156
4312
|
}
|
|
4157
4313
|
const { address, privateKey } = createWallet();
|
|
@@ -4161,11 +4317,11 @@ function getOrCreateWallet() {
|
|
|
4161
4317
|
function getWalletAddress() {
|
|
4162
4318
|
const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
|
|
4163
4319
|
if (envKey) {
|
|
4164
|
-
return (0,
|
|
4320
|
+
return (0, import_accounts14.privateKeyToAccount)(envKey).address;
|
|
4165
4321
|
}
|
|
4166
4322
|
const fileKey = loadWallet();
|
|
4167
4323
|
if (fileKey) {
|
|
4168
|
-
return (0,
|
|
4324
|
+
return (0, import_accounts14.privateKeyToAccount)(fileKey).address;
|
|
4169
4325
|
}
|
|
4170
4326
|
return null;
|
|
4171
4327
|
}
|
|
@@ -4345,7 +4501,7 @@ async function getOrCreateSolanaWallet() {
|
|
|
4345
4501
|
// src/solana-client.ts
|
|
4346
4502
|
var SOLANA_API_URL = "https://sol.blockrun.ai/api";
|
|
4347
4503
|
var DEFAULT_MAX_TOKENS2 = 1024;
|
|
4348
|
-
var
|
|
4504
|
+
var DEFAULT_TIMEOUT13 = 6e4;
|
|
4349
4505
|
var SDK_VERSION2 = "0.3.0";
|
|
4350
4506
|
var USER_AGENT2 = `blockrun-ts/${SDK_VERSION2}`;
|
|
4351
4507
|
var DEFAULT_SOLANA_RPC_URL = "https://sol.blockrun.ai/api/v1/solana/rpc";
|
|
@@ -4395,7 +4551,7 @@ var SolanaLLMClient = class {
|
|
|
4395
4551
|
const rpc = resolveRpcConfig(options.rpcUrl, options.rpcHeaders);
|
|
4396
4552
|
this.rpcUrl = rpc.url;
|
|
4397
4553
|
this.rpcHeaders = rpc.headers;
|
|
4398
|
-
this.timeout = options.timeout ||
|
|
4554
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT13;
|
|
4399
4555
|
}
|
|
4400
4556
|
/** Get Solana wallet address (public key in base58). */
|
|
4401
4557
|
async getWalletAddress() {
|
|
@@ -5305,7 +5461,7 @@ var OpenAI = class {
|
|
|
5305
5461
|
};
|
|
5306
5462
|
|
|
5307
5463
|
// src/anthropic-compat.ts
|
|
5308
|
-
var
|
|
5464
|
+
var import_accounts15 = require("viem/accounts");
|
|
5309
5465
|
var AnthropicClient = class {
|
|
5310
5466
|
_client = null;
|
|
5311
5467
|
_clientPromise = null;
|
|
@@ -5318,7 +5474,7 @@ var AnthropicClient = class {
|
|
|
5318
5474
|
const key = options.privateKey ?? wallet.privateKey;
|
|
5319
5475
|
validatePrivateKey(key);
|
|
5320
5476
|
this._privateKey = key;
|
|
5321
|
-
this._account = (0,
|
|
5477
|
+
this._account = (0, import_accounts15.privateKeyToAccount)(this._privateKey);
|
|
5322
5478
|
const apiUrl = options.apiUrl ?? "https://blockrun.ai/api";
|
|
5323
5479
|
validateApiUrl(apiUrl);
|
|
5324
5480
|
this._apiUrl = apiUrl.replace(/\/$/, "");
|
|
@@ -5425,8 +5581,10 @@ var AnthropicClient = class {
|
|
|
5425
5581
|
MusicClient,
|
|
5426
5582
|
OpenAI,
|
|
5427
5583
|
PHONE_PRICES,
|
|
5584
|
+
PORTRAIT_ENROLLMENT_PRICE_USD,
|
|
5428
5585
|
PaymentError,
|
|
5429
5586
|
PhoneClient,
|
|
5587
|
+
PortraitClient,
|
|
5430
5588
|
PriceClient,
|
|
5431
5589
|
SOLANA_NETWORK,
|
|
5432
5590
|
SOLANA_WALLET_FILE_PATH,
|
package/dist/index.d.cts
CHANGED
|
@@ -497,7 +497,7 @@ interface VideoGenerateOptions {
|
|
|
497
497
|
/**
|
|
498
498
|
* Virtual Portrait asset ID (`ta_xxxxxx`) — keeps the same AI character
|
|
499
499
|
* across multiple Seedance videos. Enroll via `POST /v1/portrait/enroll`
|
|
500
|
-
* ($0.
|
|
500
|
+
* ($0.01 USDC promo, no KYC). **Seedance 2.0 fast/pro only.** Mutually exclusive
|
|
501
501
|
* with `imageUrl`. Real-person likeness is not supported on BlockRun.
|
|
502
502
|
*/
|
|
503
503
|
realFaceAssetId?: string;
|
|
@@ -867,6 +867,63 @@ interface PhoneReleaseResponse {
|
|
|
867
867
|
phone_number: string;
|
|
868
868
|
txHash?: string;
|
|
869
869
|
}
|
|
870
|
+
interface PortraitClientOptions {
|
|
871
|
+
/** EVM wallet private key (hex string starting with 0x) */
|
|
872
|
+
privateKey?: `0x${string}` | string;
|
|
873
|
+
/** API endpoint URL (default: https://blockrun.ai/api) */
|
|
874
|
+
apiUrl?: string;
|
|
875
|
+
/** Request timeout in milliseconds (default: 60000) */
|
|
876
|
+
timeout?: number;
|
|
877
|
+
}
|
|
878
|
+
interface PortraitEnrollOptions {
|
|
879
|
+
/** Display name for the portrait (1–64 chars). */
|
|
880
|
+
name: string;
|
|
881
|
+
/**
|
|
882
|
+
* Public HTTPS URL to a JPG/PNG/WEBP face image (≤10 MB). The gateway fetches
|
|
883
|
+
* it server-side and forwards it to Token360 as multipart — only the URL is sent.
|
|
884
|
+
*/
|
|
885
|
+
imageUrl: string;
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Response from `POST /v1/portrait/enroll`. The `asset_id` (`ta_xxxxxx`) is what
|
|
889
|
+
* you pass as `realFaceAssetId` on a Seedance 2.0 video generation to keep the
|
|
890
|
+
* same AI character across clips.
|
|
891
|
+
*/
|
|
892
|
+
interface PortraitEnrollResponse {
|
|
893
|
+
object: "virtual_portrait";
|
|
894
|
+
/** Token360 asset id (`ta_xxxxxx`) — pass as `realFaceAssetId` in VideoGenerateOptions. */
|
|
895
|
+
asset_id: string;
|
|
896
|
+
/** Token360 asset-group id (internal/debugging). */
|
|
897
|
+
group_id: string;
|
|
898
|
+
name: string;
|
|
899
|
+
/**
|
|
900
|
+
* Persisted thumbnail URL. The gateway mirrors your source image to its own
|
|
901
|
+
* storage when possible (so the listing thumbnail survives a dead source
|
|
902
|
+
* host); falls back to the original URL if mirroring fails. See `mirrored`.
|
|
903
|
+
*/
|
|
904
|
+
image_url: string;
|
|
905
|
+
/** The original URL you supplied (before any mirroring). */
|
|
906
|
+
source_image_url?: string;
|
|
907
|
+
/** Whether `image_url` is the gateway-mirrored copy (true) or your original (false). */
|
|
908
|
+
mirrored?: boolean;
|
|
909
|
+
/** ISO-8601 creation timestamp. */
|
|
910
|
+
created_at: string;
|
|
911
|
+
usage: {
|
|
912
|
+
compatible_models: string[];
|
|
913
|
+
how_to_use: string;
|
|
914
|
+
};
|
|
915
|
+
price: {
|
|
916
|
+
amount: string;
|
|
917
|
+
currency: string;
|
|
918
|
+
};
|
|
919
|
+
settlement: {
|
|
920
|
+
success: boolean;
|
|
921
|
+
tx_hash: string | null;
|
|
922
|
+
network: string;
|
|
923
|
+
};
|
|
924
|
+
/** On-chain payment receipt (tx hash), surfaced from the response header. */
|
|
925
|
+
txHash?: string;
|
|
926
|
+
}
|
|
870
927
|
interface BlockrunClientOptions {
|
|
871
928
|
privateKey?: `0x${string}` | string;
|
|
872
929
|
apiUrl?: string;
|
|
@@ -1774,6 +1831,75 @@ declare class PhoneClient {
|
|
|
1774
1831
|
private fetchWithTimeout;
|
|
1775
1832
|
}
|
|
1776
1833
|
|
|
1834
|
+
/**
|
|
1835
|
+
* BlockRun Portrait Client — enroll a Virtual Portrait via x402.
|
|
1836
|
+
*
|
|
1837
|
+
* Wraps `POST /v1/portrait/enroll` ($0.01 USDC promo, no KYC). You upload a face image
|
|
1838
|
+
* by URL and get back a Token360 asset id (`ta_xxxxxx`). Pass that id as
|
|
1839
|
+
* `realFaceAssetId` on a Seedance 2.0 video generation (VideoClient.generate)
|
|
1840
|
+
* to keep the same AI character across clips.
|
|
1841
|
+
*
|
|
1842
|
+
* SECURITY NOTE — your private key never leaves your machine. Only EIP-712
|
|
1843
|
+
* signatures are sent in the PAYMENT-SIGNATURE header.
|
|
1844
|
+
*
|
|
1845
|
+
* @example
|
|
1846
|
+
* import { PortraitClient, VideoClient } from '@blockrun/llm';
|
|
1847
|
+
*
|
|
1848
|
+
* const portraits = new PortraitClient({ privateKey: '0x...' });
|
|
1849
|
+
* const { asset_id } = await portraits.enroll({
|
|
1850
|
+
* name: 'Spokesperson',
|
|
1851
|
+
* imageUrl: 'https://example.com/face.jpg',
|
|
1852
|
+
* });
|
|
1853
|
+
*
|
|
1854
|
+
* const video = new VideoClient({ privateKey: '0x...' });
|
|
1855
|
+
* const clip = await video.generate('she waves and smiles', {
|
|
1856
|
+
* model: 'bytedance/seedance-2.0-fast',
|
|
1857
|
+
* realFaceAssetId: asset_id,
|
|
1858
|
+
* });
|
|
1859
|
+
*/
|
|
1860
|
+
|
|
1861
|
+
/**
|
|
1862
|
+
* Flat enrollment price in USD — mirrors the backend's `ENROLLMENT_PRICE_USD`.
|
|
1863
|
+
* Currently $0.01 (promotional, parity with RealFace). The authoritative price
|
|
1864
|
+
* is whatever the gateway quotes in the 402; this constant is informational.
|
|
1865
|
+
*/
|
|
1866
|
+
declare const PORTRAIT_ENROLLMENT_PRICE_USD = 0.01;
|
|
1867
|
+
/**
|
|
1868
|
+
* BlockRun Portrait Client.
|
|
1869
|
+
*
|
|
1870
|
+
* Enrolls a Virtual Portrait from a face image URL and returns the `ta_xxxxxx`
|
|
1871
|
+
* asset id consumed by Seedance 2.0 video generation. Real-person likeness is
|
|
1872
|
+
* not supported on BlockRun — enrolled portraits are AI characters.
|
|
1873
|
+
*/
|
|
1874
|
+
declare class PortraitClient {
|
|
1875
|
+
private account;
|
|
1876
|
+
private privateKey;
|
|
1877
|
+
private apiUrl;
|
|
1878
|
+
private timeout;
|
|
1879
|
+
private sessionTotalUsd;
|
|
1880
|
+
private sessionCalls;
|
|
1881
|
+
constructor(options?: PortraitClientOptions);
|
|
1882
|
+
/** EVM wallet address used for payments. */
|
|
1883
|
+
getWalletAddress(): string;
|
|
1884
|
+
/** Session-cumulative USD spend + call count across this client instance. */
|
|
1885
|
+
getSpending(): Spending;
|
|
1886
|
+
/**
|
|
1887
|
+
* Enroll a Virtual Portrait from a face image URL. $0.01 (promo).
|
|
1888
|
+
*
|
|
1889
|
+
* Payment is settled only after Token360 confirms the enrollment, so failed
|
|
1890
|
+
* enrollments never charge your wallet.
|
|
1891
|
+
*
|
|
1892
|
+
* @param options.name Display name (1–64 chars).
|
|
1893
|
+
* @param options.imageUrl Public HTTPS URL to a JPG/PNG/WEBP image (≤10 MB).
|
|
1894
|
+
* @returns The enrollment record, including `asset_id` (`ta_xxxxxx`).
|
|
1895
|
+
*/
|
|
1896
|
+
enroll(options: PortraitEnrollOptions): Promise<PortraitEnrollResponse>;
|
|
1897
|
+
private request;
|
|
1898
|
+
private handlePaymentAndRetry;
|
|
1899
|
+
private unwrap;
|
|
1900
|
+
private fetchWithTimeout;
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1777
1903
|
/**
|
|
1778
1904
|
* BlockRun Search Client - Standalone Grok Live Search via x402 micropayments.
|
|
1779
1905
|
*
|
|
@@ -2762,4 +2888,4 @@ declare function validateTemperature(temperature?: number): void;
|
|
|
2762
2888
|
*/
|
|
2763
2889
|
declare function validateTopP(topP?: number): void;
|
|
2764
2890
|
|
|
2765
|
-
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, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, 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 VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XArticlesRisingResponse, type XAuthorAnalyticsResponse, XClient, type XClientOptions, type XCompareAuthorsResponse, type XFollower, type XFollowersResponse, type XFollowingsResponse, type XMentionsOptions, type XMentionsResponse, type XSearchOptions, type XSearchResponse, type XSearchSource, type XTrendingResponse, type XTweet, type XTweetLookupResponse, type XTweetRepliesOptions, type XTweetRepliesResponse, type XTweetThreadResponse, type XTweetsResponse, type XUser, type XUserInfoResponse, type XUserLookupResponse, type XUserTweetsOptions, type XVerifiedFollowersResponse, 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 };
|
|
2891
|
+
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, 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, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, 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 VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XArticlesRisingResponse, type XAuthorAnalyticsResponse, XClient, type XClientOptions, type XCompareAuthorsResponse, type XFollower, type XFollowersResponse, type XFollowingsResponse, type XMentionsOptions, type XMentionsResponse, type XSearchOptions, type XSearchResponse, type XSearchSource, type XTrendingResponse, type XTweet, type XTweetLookupResponse, type XTweetRepliesOptions, type XTweetRepliesResponse, type XTweetThreadResponse, type XTweetsResponse, type XUser, type XUserInfoResponse, type XUserLookupResponse, type XUserTweetsOptions, type XVerifiedFollowersResponse, 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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -497,7 +497,7 @@ interface VideoGenerateOptions {
|
|
|
497
497
|
/**
|
|
498
498
|
* Virtual Portrait asset ID (`ta_xxxxxx`) — keeps the same AI character
|
|
499
499
|
* across multiple Seedance videos. Enroll via `POST /v1/portrait/enroll`
|
|
500
|
-
* ($0.
|
|
500
|
+
* ($0.01 USDC promo, no KYC). **Seedance 2.0 fast/pro only.** Mutually exclusive
|
|
501
501
|
* with `imageUrl`. Real-person likeness is not supported on BlockRun.
|
|
502
502
|
*/
|
|
503
503
|
realFaceAssetId?: string;
|
|
@@ -867,6 +867,63 @@ interface PhoneReleaseResponse {
|
|
|
867
867
|
phone_number: string;
|
|
868
868
|
txHash?: string;
|
|
869
869
|
}
|
|
870
|
+
interface PortraitClientOptions {
|
|
871
|
+
/** EVM wallet private key (hex string starting with 0x) */
|
|
872
|
+
privateKey?: `0x${string}` | string;
|
|
873
|
+
/** API endpoint URL (default: https://blockrun.ai/api) */
|
|
874
|
+
apiUrl?: string;
|
|
875
|
+
/** Request timeout in milliseconds (default: 60000) */
|
|
876
|
+
timeout?: number;
|
|
877
|
+
}
|
|
878
|
+
interface PortraitEnrollOptions {
|
|
879
|
+
/** Display name for the portrait (1–64 chars). */
|
|
880
|
+
name: string;
|
|
881
|
+
/**
|
|
882
|
+
* Public HTTPS URL to a JPG/PNG/WEBP face image (≤10 MB). The gateway fetches
|
|
883
|
+
* it server-side and forwards it to Token360 as multipart — only the URL is sent.
|
|
884
|
+
*/
|
|
885
|
+
imageUrl: string;
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Response from `POST /v1/portrait/enroll`. The `asset_id` (`ta_xxxxxx`) is what
|
|
889
|
+
* you pass as `realFaceAssetId` on a Seedance 2.0 video generation to keep the
|
|
890
|
+
* same AI character across clips.
|
|
891
|
+
*/
|
|
892
|
+
interface PortraitEnrollResponse {
|
|
893
|
+
object: "virtual_portrait";
|
|
894
|
+
/** Token360 asset id (`ta_xxxxxx`) — pass as `realFaceAssetId` in VideoGenerateOptions. */
|
|
895
|
+
asset_id: string;
|
|
896
|
+
/** Token360 asset-group id (internal/debugging). */
|
|
897
|
+
group_id: string;
|
|
898
|
+
name: string;
|
|
899
|
+
/**
|
|
900
|
+
* Persisted thumbnail URL. The gateway mirrors your source image to its own
|
|
901
|
+
* storage when possible (so the listing thumbnail survives a dead source
|
|
902
|
+
* host); falls back to the original URL if mirroring fails. See `mirrored`.
|
|
903
|
+
*/
|
|
904
|
+
image_url: string;
|
|
905
|
+
/** The original URL you supplied (before any mirroring). */
|
|
906
|
+
source_image_url?: string;
|
|
907
|
+
/** Whether `image_url` is the gateway-mirrored copy (true) or your original (false). */
|
|
908
|
+
mirrored?: boolean;
|
|
909
|
+
/** ISO-8601 creation timestamp. */
|
|
910
|
+
created_at: string;
|
|
911
|
+
usage: {
|
|
912
|
+
compatible_models: string[];
|
|
913
|
+
how_to_use: string;
|
|
914
|
+
};
|
|
915
|
+
price: {
|
|
916
|
+
amount: string;
|
|
917
|
+
currency: string;
|
|
918
|
+
};
|
|
919
|
+
settlement: {
|
|
920
|
+
success: boolean;
|
|
921
|
+
tx_hash: string | null;
|
|
922
|
+
network: string;
|
|
923
|
+
};
|
|
924
|
+
/** On-chain payment receipt (tx hash), surfaced from the response header. */
|
|
925
|
+
txHash?: string;
|
|
926
|
+
}
|
|
870
927
|
interface BlockrunClientOptions {
|
|
871
928
|
privateKey?: `0x${string}` | string;
|
|
872
929
|
apiUrl?: string;
|
|
@@ -1774,6 +1831,75 @@ declare class PhoneClient {
|
|
|
1774
1831
|
private fetchWithTimeout;
|
|
1775
1832
|
}
|
|
1776
1833
|
|
|
1834
|
+
/**
|
|
1835
|
+
* BlockRun Portrait Client — enroll a Virtual Portrait via x402.
|
|
1836
|
+
*
|
|
1837
|
+
* Wraps `POST /v1/portrait/enroll` ($0.01 USDC promo, no KYC). You upload a face image
|
|
1838
|
+
* by URL and get back a Token360 asset id (`ta_xxxxxx`). Pass that id as
|
|
1839
|
+
* `realFaceAssetId` on a Seedance 2.0 video generation (VideoClient.generate)
|
|
1840
|
+
* to keep the same AI character across clips.
|
|
1841
|
+
*
|
|
1842
|
+
* SECURITY NOTE — your private key never leaves your machine. Only EIP-712
|
|
1843
|
+
* signatures are sent in the PAYMENT-SIGNATURE header.
|
|
1844
|
+
*
|
|
1845
|
+
* @example
|
|
1846
|
+
* import { PortraitClient, VideoClient } from '@blockrun/llm';
|
|
1847
|
+
*
|
|
1848
|
+
* const portraits = new PortraitClient({ privateKey: '0x...' });
|
|
1849
|
+
* const { asset_id } = await portraits.enroll({
|
|
1850
|
+
* name: 'Spokesperson',
|
|
1851
|
+
* imageUrl: 'https://example.com/face.jpg',
|
|
1852
|
+
* });
|
|
1853
|
+
*
|
|
1854
|
+
* const video = new VideoClient({ privateKey: '0x...' });
|
|
1855
|
+
* const clip = await video.generate('she waves and smiles', {
|
|
1856
|
+
* model: 'bytedance/seedance-2.0-fast',
|
|
1857
|
+
* realFaceAssetId: asset_id,
|
|
1858
|
+
* });
|
|
1859
|
+
*/
|
|
1860
|
+
|
|
1861
|
+
/**
|
|
1862
|
+
* Flat enrollment price in USD — mirrors the backend's `ENROLLMENT_PRICE_USD`.
|
|
1863
|
+
* Currently $0.01 (promotional, parity with RealFace). The authoritative price
|
|
1864
|
+
* is whatever the gateway quotes in the 402; this constant is informational.
|
|
1865
|
+
*/
|
|
1866
|
+
declare const PORTRAIT_ENROLLMENT_PRICE_USD = 0.01;
|
|
1867
|
+
/**
|
|
1868
|
+
* BlockRun Portrait Client.
|
|
1869
|
+
*
|
|
1870
|
+
* Enrolls a Virtual Portrait from a face image URL and returns the `ta_xxxxxx`
|
|
1871
|
+
* asset id consumed by Seedance 2.0 video generation. Real-person likeness is
|
|
1872
|
+
* not supported on BlockRun — enrolled portraits are AI characters.
|
|
1873
|
+
*/
|
|
1874
|
+
declare class PortraitClient {
|
|
1875
|
+
private account;
|
|
1876
|
+
private privateKey;
|
|
1877
|
+
private apiUrl;
|
|
1878
|
+
private timeout;
|
|
1879
|
+
private sessionTotalUsd;
|
|
1880
|
+
private sessionCalls;
|
|
1881
|
+
constructor(options?: PortraitClientOptions);
|
|
1882
|
+
/** EVM wallet address used for payments. */
|
|
1883
|
+
getWalletAddress(): string;
|
|
1884
|
+
/** Session-cumulative USD spend + call count across this client instance. */
|
|
1885
|
+
getSpending(): Spending;
|
|
1886
|
+
/**
|
|
1887
|
+
* Enroll a Virtual Portrait from a face image URL. $0.01 (promo).
|
|
1888
|
+
*
|
|
1889
|
+
* Payment is settled only after Token360 confirms the enrollment, so failed
|
|
1890
|
+
* enrollments never charge your wallet.
|
|
1891
|
+
*
|
|
1892
|
+
* @param options.name Display name (1–64 chars).
|
|
1893
|
+
* @param options.imageUrl Public HTTPS URL to a JPG/PNG/WEBP image (≤10 MB).
|
|
1894
|
+
* @returns The enrollment record, including `asset_id` (`ta_xxxxxx`).
|
|
1895
|
+
*/
|
|
1896
|
+
enroll(options: PortraitEnrollOptions): Promise<PortraitEnrollResponse>;
|
|
1897
|
+
private request;
|
|
1898
|
+
private handlePaymentAndRetry;
|
|
1899
|
+
private unwrap;
|
|
1900
|
+
private fetchWithTimeout;
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1777
1903
|
/**
|
|
1778
1904
|
* BlockRun Search Client - Standalone Grok Live Search via x402 micropayments.
|
|
1779
1905
|
*
|
|
@@ -2762,4 +2888,4 @@ declare function validateTemperature(temperature?: number): void;
|
|
|
2762
2888
|
*/
|
|
2763
2889
|
declare function validateTopP(topP?: number): void;
|
|
2764
2890
|
|
|
2765
|
-
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, type NewsSearchSource, OpenAI, type OpenAIChatCompletionChoice, type OpenAIChatCompletionChunk, type OpenAIChatCompletionParams, type OpenAIChatCompletionResponse, type OpenAIClientOptions, PHONE_PRICES, PaymentError, type PaymentLinks, type PhoneBuyOptions, type PhoneBuyResponse, PhoneClient, type PhoneClientOptions, type PhoneListResponse, type PhoneLookupResponse, type PhoneNumberRecord, type PhoneReleaseResponse, type PhoneRenewResponse, type PollOptions, type PriceBar, type PriceCategory, PriceClient, type PriceClientOptions, type PriceHistoryResponse, type PriceOptions, type PricePoint, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, 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 VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XArticlesRisingResponse, type XAuthorAnalyticsResponse, XClient, type XClientOptions, type XCompareAuthorsResponse, type XFollower, type XFollowersResponse, type XFollowingsResponse, type XMentionsOptions, type XMentionsResponse, type XSearchOptions, type XSearchResponse, type XSearchSource, type XTrendingResponse, type XTweet, type XTweetLookupResponse, type XTweetRepliesOptions, type XTweetRepliesResponse, type XTweetThreadResponse, type XTweetsResponse, type XUser, type XUserInfoResponse, type XUserLookupResponse, type XUserTweetsOptions, type XVerifiedFollowersResponse, 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 };
|
|
2891
|
+
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, 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, type RoutingDecision, type RoutingProfile, type RoutingTier, type RssSearchSource, SOLANA_NETWORK, SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH, SearchClient, type SearchClientOptions, type SearchOptions, type SearchParameters, type SearchResult, type SearchSource, type SearchUsage, type SmartChatOptions, type SmartChatResponse, SolanaLLMClient, type SolanaLLMClientOptions, type SolanaWalletInfo, 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 VoicePreset, WALLET_DIR_PATH, WALLET_FILE_PATH, type WalletInfo, type WebSearchSource, type XArticlesRisingResponse, type XAuthorAnalyticsResponse, XClient, type XClientOptions, type XCompareAuthorsResponse, type XFollower, type XFollowersResponse, type XFollowingsResponse, type XMentionsOptions, type XMentionsResponse, type XSearchOptions, type XSearchResponse, type XSearchSource, type XTrendingResponse, type XTweet, type XTweetLookupResponse, type XTweetRepliesOptions, type XTweetRepliesResponse, type XTweetThreadResponse, type XTweetsResponse, type XUser, type XUserInfoResponse, type XUserLookupResponse, type XUserTweetsOptions, type XVerifiedFollowersResponse, 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 };
|
package/dist/index.js
CHANGED
|
@@ -2898,15 +2898,18 @@ var PhoneClient = class {
|
|
|
2898
2898
|
}
|
|
2899
2899
|
};
|
|
2900
2900
|
|
|
2901
|
-
// src/
|
|
2901
|
+
// src/portrait.ts
|
|
2902
2902
|
import { privateKeyToAccount as privateKeyToAccount7 } from "viem/accounts";
|
|
2903
2903
|
var DEFAULT_API_URL7 = "https://blockrun.ai/api";
|
|
2904
2904
|
var DEFAULT_TIMEOUT7 = 6e4;
|
|
2905
|
-
var
|
|
2905
|
+
var PORTRAIT_ENROLLMENT_PRICE_USD = 0.01;
|
|
2906
|
+
var PortraitClient = class {
|
|
2906
2907
|
account;
|
|
2907
2908
|
privateKey;
|
|
2908
2909
|
apiUrl;
|
|
2909
2910
|
timeout;
|
|
2911
|
+
sessionTotalUsd = 0;
|
|
2912
|
+
sessionCalls = 0;
|
|
2910
2913
|
constructor(options = {}) {
|
|
2911
2914
|
const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
|
|
2912
2915
|
const privateKey = options.privateKey || envKey;
|
|
@@ -2923,6 +2926,157 @@ var SearchClient = class {
|
|
|
2923
2926
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
2924
2927
|
this.timeout = options.timeout || DEFAULT_TIMEOUT7;
|
|
2925
2928
|
}
|
|
2929
|
+
/** EVM wallet address used for payments. */
|
|
2930
|
+
getWalletAddress() {
|
|
2931
|
+
return this.account.address;
|
|
2932
|
+
}
|
|
2933
|
+
/** Session-cumulative USD spend + call count across this client instance. */
|
|
2934
|
+
getSpending() {
|
|
2935
|
+
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
2936
|
+
}
|
|
2937
|
+
/**
|
|
2938
|
+
* Enroll a Virtual Portrait from a face image URL. $0.01 (promo).
|
|
2939
|
+
*
|
|
2940
|
+
* Payment is settled only after Token360 confirms the enrollment, so failed
|
|
2941
|
+
* enrollments never charge your wallet.
|
|
2942
|
+
*
|
|
2943
|
+
* @param options.name Display name (1–64 chars).
|
|
2944
|
+
* @param options.imageUrl Public HTTPS URL to a JPG/PNG/WEBP image (≤10 MB).
|
|
2945
|
+
* @returns The enrollment record, including `asset_id` (`ta_xxxxxx`).
|
|
2946
|
+
*/
|
|
2947
|
+
async enroll(options) {
|
|
2948
|
+
const name = typeof options?.name === "string" ? options.name.trim() : "";
|
|
2949
|
+
if (name.length < 1 || name.length > 64) {
|
|
2950
|
+
throw new Error("name is required and must be 1\u201364 characters");
|
|
2951
|
+
}
|
|
2952
|
+
const imageUrl = typeof options?.imageUrl === "string" ? options.imageUrl.trim() : "";
|
|
2953
|
+
if (!/^https?:\/\//i.test(imageUrl)) {
|
|
2954
|
+
throw new Error(
|
|
2955
|
+
"imageUrl must be a public http(s) URL to a JPG/PNG/WEBP image"
|
|
2956
|
+
);
|
|
2957
|
+
}
|
|
2958
|
+
const data = await this.request({
|
|
2959
|
+
name,
|
|
2960
|
+
image_url: imageUrl
|
|
2961
|
+
});
|
|
2962
|
+
return data;
|
|
2963
|
+
}
|
|
2964
|
+
// ─── Internals ─────────────────────────────────────────────────────────
|
|
2965
|
+
async request(body) {
|
|
2966
|
+
const url = `${this.apiUrl}/v1/portrait/enroll`;
|
|
2967
|
+
const response = await this.fetchWithTimeout(url, {
|
|
2968
|
+
method: "POST",
|
|
2969
|
+
headers: { "Content-Type": "application/json" },
|
|
2970
|
+
body: JSON.stringify(body)
|
|
2971
|
+
});
|
|
2972
|
+
if (response.status === 402) {
|
|
2973
|
+
return this.handlePaymentAndRetry(url, body, response);
|
|
2974
|
+
}
|
|
2975
|
+
return this.unwrap(response, false);
|
|
2976
|
+
}
|
|
2977
|
+
async handlePaymentAndRetry(url, body, response) {
|
|
2978
|
+
let paymentHeader = response.headers.get("payment-required");
|
|
2979
|
+
if (!paymentHeader) {
|
|
2980
|
+
try {
|
|
2981
|
+
const rb = await response.json();
|
|
2982
|
+
if (rb.x402 || rb.accepts) paymentHeader = btoa(JSON.stringify(rb));
|
|
2983
|
+
} catch {
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
if (!paymentHeader) {
|
|
2987
|
+
throw new PaymentError("402 response but no payment requirements found");
|
|
2988
|
+
}
|
|
2989
|
+
const paymentRequired = parsePaymentRequired(paymentHeader);
|
|
2990
|
+
const details = extractPaymentDetails(paymentRequired);
|
|
2991
|
+
const paymentPayload = await createPaymentPayload(
|
|
2992
|
+
this.privateKey,
|
|
2993
|
+
this.account.address,
|
|
2994
|
+
details.recipient,
|
|
2995
|
+
details.amount,
|
|
2996
|
+
details.network || "eip155:8453",
|
|
2997
|
+
{
|
|
2998
|
+
resourceUrl: details.resource?.url || url,
|
|
2999
|
+
resourceDescription: details.resource?.description || "BlockRun Virtual Portrait",
|
|
3000
|
+
maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
|
|
3001
|
+
extra: details.extra
|
|
3002
|
+
}
|
|
3003
|
+
);
|
|
3004
|
+
const retry = await this.fetchWithTimeout(url, {
|
|
3005
|
+
method: "POST",
|
|
3006
|
+
headers: {
|
|
3007
|
+
"Content-Type": "application/json",
|
|
3008
|
+
"PAYMENT-SIGNATURE": paymentPayload
|
|
3009
|
+
},
|
|
3010
|
+
body: JSON.stringify(body)
|
|
3011
|
+
});
|
|
3012
|
+
if (retry.status === 402) {
|
|
3013
|
+
throw new PaymentError("Payment was rejected. Check your wallet balance.");
|
|
3014
|
+
}
|
|
3015
|
+
const data = await this.unwrap(retry, true);
|
|
3016
|
+
const costUsd = Number.parseFloat(details.amount) / 1e6;
|
|
3017
|
+
this.sessionCalls += 1;
|
|
3018
|
+
this.sessionTotalUsd += costUsd;
|
|
3019
|
+
if (data && typeof data === "object" && !("txHash" in data)) {
|
|
3020
|
+
const settlement = data.settlement;
|
|
3021
|
+
if (settlement?.tx_hash) {
|
|
3022
|
+
data.txHash = settlement.tx_hash;
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
return data;
|
|
3026
|
+
}
|
|
3027
|
+
async unwrap(response, afterPayment) {
|
|
3028
|
+
if (response.ok) {
|
|
3029
|
+
return response.json();
|
|
3030
|
+
}
|
|
3031
|
+
let errorBody;
|
|
3032
|
+
try {
|
|
3033
|
+
errorBody = await response.json();
|
|
3034
|
+
} catch {
|
|
3035
|
+
errorBody = { error: "Request failed" };
|
|
3036
|
+
}
|
|
3037
|
+
const prefix = afterPayment ? "API error after payment" : "API error";
|
|
3038
|
+
throw new APIError(
|
|
3039
|
+
`${prefix}: ${response.status}`,
|
|
3040
|
+
response.status,
|
|
3041
|
+
sanitizeErrorResponse(errorBody)
|
|
3042
|
+
);
|
|
3043
|
+
}
|
|
3044
|
+
async fetchWithTimeout(url, init) {
|
|
3045
|
+
const controller = new AbortController();
|
|
3046
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
3047
|
+
try {
|
|
3048
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
3049
|
+
} finally {
|
|
3050
|
+
clearTimeout(timeoutId);
|
|
3051
|
+
}
|
|
3052
|
+
}
|
|
3053
|
+
};
|
|
3054
|
+
|
|
3055
|
+
// src/search.ts
|
|
3056
|
+
import { privateKeyToAccount as privateKeyToAccount8 } from "viem/accounts";
|
|
3057
|
+
var DEFAULT_API_URL8 = "https://blockrun.ai/api";
|
|
3058
|
+
var DEFAULT_TIMEOUT8 = 6e4;
|
|
3059
|
+
var SearchClient = class {
|
|
3060
|
+
account;
|
|
3061
|
+
privateKey;
|
|
3062
|
+
apiUrl;
|
|
3063
|
+
timeout;
|
|
3064
|
+
constructor(options = {}) {
|
|
3065
|
+
const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
|
|
3066
|
+
const privateKey = options.privateKey || envKey;
|
|
3067
|
+
if (!privateKey) {
|
|
3068
|
+
throw new Error(
|
|
3069
|
+
"Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
|
|
3070
|
+
);
|
|
3071
|
+
}
|
|
3072
|
+
validatePrivateKey(privateKey);
|
|
3073
|
+
this.privateKey = privateKey;
|
|
3074
|
+
this.account = privateKeyToAccount8(privateKey);
|
|
3075
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL8;
|
|
3076
|
+
validateApiUrl(apiUrl);
|
|
3077
|
+
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3078
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT8;
|
|
3079
|
+
}
|
|
2926
3080
|
async search(query, options) {
|
|
2927
3081
|
if (!query || query.length > 1e3) {
|
|
2928
3082
|
throw new Error("query must be 1-1000 characters");
|
|
@@ -3035,9 +3189,9 @@ var SearchClient = class {
|
|
|
3035
3189
|
};
|
|
3036
3190
|
|
|
3037
3191
|
// src/x-client.ts
|
|
3038
|
-
import { privateKeyToAccount as
|
|
3039
|
-
var
|
|
3040
|
-
var
|
|
3192
|
+
import { privateKeyToAccount as privateKeyToAccount9 } from "viem/accounts";
|
|
3193
|
+
var DEFAULT_API_URL9 = "https://blockrun.ai/api";
|
|
3194
|
+
var DEFAULT_TIMEOUT9 = 6e4;
|
|
3041
3195
|
var XClient = class _XClient {
|
|
3042
3196
|
account;
|
|
3043
3197
|
privateKey;
|
|
@@ -3060,11 +3214,11 @@ var XClient = class _XClient {
|
|
|
3060
3214
|
}
|
|
3061
3215
|
validatePrivateKey(privateKey);
|
|
3062
3216
|
this.privateKey = privateKey;
|
|
3063
|
-
this.account =
|
|
3064
|
-
const apiUrl = options.apiUrl ||
|
|
3217
|
+
this.account = privateKeyToAccount9(privateKey);
|
|
3218
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL9;
|
|
3065
3219
|
validateApiUrl(apiUrl);
|
|
3066
3220
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3067
|
-
this.timeout = options.timeout ||
|
|
3221
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT9;
|
|
3068
3222
|
}
|
|
3069
3223
|
// ───────── User endpoints ─────────
|
|
3070
3224
|
userLookup(usernames) {
|
|
@@ -3242,9 +3396,9 @@ var XClient = class _XClient {
|
|
|
3242
3396
|
};
|
|
3243
3397
|
|
|
3244
3398
|
// src/price.ts
|
|
3245
|
-
import { privateKeyToAccount as
|
|
3246
|
-
var
|
|
3247
|
-
var
|
|
3399
|
+
import { privateKeyToAccount as privateKeyToAccount10 } from "viem/accounts";
|
|
3400
|
+
var DEFAULT_API_URL10 = "https://blockrun.ai/api";
|
|
3401
|
+
var DEFAULT_TIMEOUT10 = 3e4;
|
|
3248
3402
|
var PriceClient = class {
|
|
3249
3403
|
account = null;
|
|
3250
3404
|
privateKey = null;
|
|
@@ -3262,12 +3416,12 @@ var PriceClient = class {
|
|
|
3262
3416
|
if (privateKey) {
|
|
3263
3417
|
validatePrivateKey(privateKey);
|
|
3264
3418
|
this.privateKey = privateKey;
|
|
3265
|
-
this.account =
|
|
3419
|
+
this.account = privateKeyToAccount10(privateKey);
|
|
3266
3420
|
}
|
|
3267
|
-
const apiUrl = options.apiUrl ||
|
|
3421
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL10;
|
|
3268
3422
|
validateApiUrl(apiUrl);
|
|
3269
3423
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3270
|
-
this.timeout = options.timeout ||
|
|
3424
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT10;
|
|
3271
3425
|
}
|
|
3272
3426
|
async price(category, symbol, options) {
|
|
3273
3427
|
if (!symbol) throw new Error("symbol is required");
|
|
@@ -3446,9 +3600,9 @@ function buildUrl(base, query) {
|
|
|
3446
3600
|
}
|
|
3447
3601
|
|
|
3448
3602
|
// src/surf.ts
|
|
3449
|
-
import { privateKeyToAccount as
|
|
3450
|
-
var
|
|
3451
|
-
var
|
|
3603
|
+
import { privateKeyToAccount as privateKeyToAccount11 } from "viem/accounts";
|
|
3604
|
+
var DEFAULT_API_URL11 = "https://blockrun.ai/api";
|
|
3605
|
+
var DEFAULT_TIMEOUT11 = 6e4;
|
|
3452
3606
|
var SURF_PREFIX = "/v1/surf";
|
|
3453
3607
|
var SurfClient = class {
|
|
3454
3608
|
account;
|
|
@@ -3465,11 +3619,11 @@ var SurfClient = class {
|
|
|
3465
3619
|
}
|
|
3466
3620
|
validatePrivateKey(privateKey);
|
|
3467
3621
|
this.privateKey = privateKey;
|
|
3468
|
-
this.account =
|
|
3469
|
-
const apiUrl = options.apiUrl ||
|
|
3622
|
+
this.account = privateKeyToAccount11(privateKey);
|
|
3623
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL11;
|
|
3470
3624
|
validateApiUrl(apiUrl);
|
|
3471
3625
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3472
|
-
this.timeout = options.timeout ||
|
|
3626
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT11;
|
|
3473
3627
|
}
|
|
3474
3628
|
/**
|
|
3475
3629
|
* GET a Surf endpoint. `path` is everything after `/v1/surf` (a leading
|
|
@@ -3601,9 +3755,9 @@ var SurfClient = class {
|
|
|
3601
3755
|
};
|
|
3602
3756
|
|
|
3603
3757
|
// src/blockrun.ts
|
|
3604
|
-
import { privateKeyToAccount as
|
|
3605
|
-
var
|
|
3606
|
-
var
|
|
3758
|
+
import { privateKeyToAccount as privateKeyToAccount12 } from "viem/accounts";
|
|
3759
|
+
var DEFAULT_API_URL12 = "https://blockrun.ai/api";
|
|
3760
|
+
var DEFAULT_TIMEOUT12 = 6e4;
|
|
3607
3761
|
var DEFAULT_POLL_INTERVAL_MS = 5e3;
|
|
3608
3762
|
var DEFAULT_POLL_BUDGET_MS = 3e5;
|
|
3609
3763
|
var MAX_SIGNED_AUTH_SECONDS = 600;
|
|
@@ -3624,11 +3778,11 @@ var BlockrunClient = class {
|
|
|
3624
3778
|
}
|
|
3625
3779
|
validatePrivateKey(privateKey);
|
|
3626
3780
|
this.privateKey = privateKey;
|
|
3627
|
-
this.account =
|
|
3628
|
-
const apiUrl = options.apiUrl ||
|
|
3781
|
+
this.account = privateKeyToAccount12(privateKey);
|
|
3782
|
+
const apiUrl = options.apiUrl || DEFAULT_API_URL12;
|
|
3629
3783
|
validateApiUrl(apiUrl);
|
|
3630
3784
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
3631
|
-
this.timeout = options.timeout ||
|
|
3785
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT12;
|
|
3632
3786
|
}
|
|
3633
3787
|
/**
|
|
3634
3788
|
* GET a BlockRun endpoint. `path` is everything after `/api` (a leading
|
|
@@ -3979,7 +4133,7 @@ function sleep(ms) {
|
|
|
3979
4133
|
}
|
|
3980
4134
|
|
|
3981
4135
|
// src/wallet.ts
|
|
3982
|
-
import { privateKeyToAccount as
|
|
4136
|
+
import { privateKeyToAccount as privateKeyToAccount13, generatePrivateKey } from "viem/accounts";
|
|
3983
4137
|
import * as fs2 from "fs";
|
|
3984
4138
|
import * as path2 from "path";
|
|
3985
4139
|
import * as os2 from "os";
|
|
@@ -3989,7 +4143,7 @@ var WALLET_DIR = path2.join(os2.homedir(), ".blockrun");
|
|
|
3989
4143
|
var WALLET_FILE = path2.join(WALLET_DIR, ".session");
|
|
3990
4144
|
function createWallet() {
|
|
3991
4145
|
const privateKey = generatePrivateKey();
|
|
3992
|
-
const account =
|
|
4146
|
+
const account = privateKeyToAccount13(privateKey);
|
|
3993
4147
|
return {
|
|
3994
4148
|
address: account.address,
|
|
3995
4149
|
privateKey
|
|
@@ -4045,12 +4199,12 @@ function loadWallet() {
|
|
|
4045
4199
|
function getOrCreateWallet() {
|
|
4046
4200
|
const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
|
|
4047
4201
|
if (envKey) {
|
|
4048
|
-
const account =
|
|
4202
|
+
const account = privateKeyToAccount13(envKey);
|
|
4049
4203
|
return { address: account.address, privateKey: envKey, isNew: false };
|
|
4050
4204
|
}
|
|
4051
4205
|
const fileKey = loadWallet();
|
|
4052
4206
|
if (fileKey) {
|
|
4053
|
-
const account =
|
|
4207
|
+
const account = privateKeyToAccount13(fileKey);
|
|
4054
4208
|
return { address: account.address, privateKey: fileKey, isNew: false };
|
|
4055
4209
|
}
|
|
4056
4210
|
const { address, privateKey } = createWallet();
|
|
@@ -4060,11 +4214,11 @@ function getOrCreateWallet() {
|
|
|
4060
4214
|
function getWalletAddress() {
|
|
4061
4215
|
const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
|
|
4062
4216
|
if (envKey) {
|
|
4063
|
-
return
|
|
4217
|
+
return privateKeyToAccount13(envKey).address;
|
|
4064
4218
|
}
|
|
4065
4219
|
const fileKey = loadWallet();
|
|
4066
4220
|
if (fileKey) {
|
|
4067
|
-
return
|
|
4221
|
+
return privateKeyToAccount13(fileKey).address;
|
|
4068
4222
|
}
|
|
4069
4223
|
return null;
|
|
4070
4224
|
}
|
|
@@ -4244,7 +4398,7 @@ async function getOrCreateSolanaWallet() {
|
|
|
4244
4398
|
// src/solana-client.ts
|
|
4245
4399
|
var SOLANA_API_URL = "https://sol.blockrun.ai/api";
|
|
4246
4400
|
var DEFAULT_MAX_TOKENS2 = 1024;
|
|
4247
|
-
var
|
|
4401
|
+
var DEFAULT_TIMEOUT13 = 6e4;
|
|
4248
4402
|
var SDK_VERSION2 = "0.3.0";
|
|
4249
4403
|
var USER_AGENT2 = `blockrun-ts/${SDK_VERSION2}`;
|
|
4250
4404
|
var DEFAULT_SOLANA_RPC_URL = "https://sol.blockrun.ai/api/v1/solana/rpc";
|
|
@@ -4294,7 +4448,7 @@ var SolanaLLMClient = class {
|
|
|
4294
4448
|
const rpc = resolveRpcConfig(options.rpcUrl, options.rpcHeaders);
|
|
4295
4449
|
this.rpcUrl = rpc.url;
|
|
4296
4450
|
this.rpcHeaders = rpc.headers;
|
|
4297
|
-
this.timeout = options.timeout ||
|
|
4451
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT13;
|
|
4298
4452
|
}
|
|
4299
4453
|
/** Get Solana wallet address (public key in base58). */
|
|
4300
4454
|
async getWalletAddress() {
|
|
@@ -5204,7 +5358,7 @@ var OpenAI = class {
|
|
|
5204
5358
|
};
|
|
5205
5359
|
|
|
5206
5360
|
// src/anthropic-compat.ts
|
|
5207
|
-
import { privateKeyToAccount as
|
|
5361
|
+
import { privateKeyToAccount as privateKeyToAccount14 } from "viem/accounts";
|
|
5208
5362
|
var AnthropicClient = class {
|
|
5209
5363
|
_client = null;
|
|
5210
5364
|
_clientPromise = null;
|
|
@@ -5217,7 +5371,7 @@ var AnthropicClient = class {
|
|
|
5217
5371
|
const key = options.privateKey ?? wallet.privateKey;
|
|
5218
5372
|
validatePrivateKey(key);
|
|
5219
5373
|
this._privateKey = key;
|
|
5220
|
-
this._account =
|
|
5374
|
+
this._account = privateKeyToAccount14(this._privateKey);
|
|
5221
5375
|
const apiUrl = options.apiUrl ?? "https://blockrun.ai/api";
|
|
5222
5376
|
validateApiUrl(apiUrl);
|
|
5223
5377
|
this._apiUrl = apiUrl.replace(/\/$/, "");
|
|
@@ -5323,8 +5477,10 @@ export {
|
|
|
5323
5477
|
MusicClient,
|
|
5324
5478
|
OpenAI,
|
|
5325
5479
|
PHONE_PRICES,
|
|
5480
|
+
PORTRAIT_ENROLLMENT_PRICE_USD,
|
|
5326
5481
|
PaymentError,
|
|
5327
5482
|
PhoneClient,
|
|
5483
|
+
PortraitClient,
|
|
5328
5484
|
PriceClient,
|
|
5329
5485
|
SOLANA_NETWORK,
|
|
5330
5486
|
SOLANA_WALLET_FILE as SOLANA_WALLET_FILE_PATH,
|