@usearete/sdk 0.32.0 → 0.34.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 -0
- package/dist/index.cjs +655 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +24 -3
- package/dist/index.esm.js +654 -8
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1041,6 +1041,639 @@ const AUTH_ERROR_CODES_BY_WIRE = {
|
|
|
1041
1041
|
'stack-version-unknown': 'STACK_VERSION_UNKNOWN',
|
|
1042
1042
|
};
|
|
1043
1043
|
|
|
1044
|
+
/**
|
|
1045
|
+
* The key from the active `a4` CLI login, for servers and local scripts.
|
|
1046
|
+
*
|
|
1047
|
+
* The `a4` CLI stores the keys it logs in with in a TOML credentials file
|
|
1048
|
+
* (`~/.arete/credentials.toml`, or `ARETE_CREDENTIALS_PATH`), keyed by profile
|
|
1049
|
+
* and API URL. This module mirrors the CLI's lookup (the Rust SDK's
|
|
1050
|
+
* `credentials` module is the reference):
|
|
1051
|
+
*
|
|
1052
|
+
* - Profile: `.arete/auth.toml` in the working directory (may pin only the
|
|
1053
|
+
* `agent` profile), then `ARETE_PROFILE`, then the single profile holding a
|
|
1054
|
+
* key for the API URL. More than one candidate means no key.
|
|
1055
|
+
* - Only the key stored for the default Arete API is used, because that is
|
|
1056
|
+
* where the SDK's default token endpoint sends it. Keys the CLI stored for
|
|
1057
|
+
* another API URL are never sent anywhere else.
|
|
1058
|
+
* - Any problem (no file, unreadable, malformed, ambiguous) means no key.
|
|
1059
|
+
*
|
|
1060
|
+
* Browser safety: nothing here is imported statically from Node. Node builtins
|
|
1061
|
+
* are reached at call time through `process.getBuiltinModule` (Node 20.16+,
|
|
1062
|
+
* 22.3+, Bun), Deno through its own permission-checked APIs, so bundlers see no
|
|
1063
|
+
* `fs` import. Callers must not call this in a browser; `resolveAuthConfig`
|
|
1064
|
+
* returns before reaching it there.
|
|
1065
|
+
*/
|
|
1066
|
+
/** API URL whose key the SDK may use: its default token endpoint's origin. */
|
|
1067
|
+
const DEFAULT_A4_API_URL = 'https://api.arete.run';
|
|
1068
|
+
/**
|
|
1069
|
+
* True when `url` is on the API the `a4` login key was stored for. A key
|
|
1070
|
+
* found in the login is only ever sent there, never to an endpoint a stack
|
|
1071
|
+
* names on another host.
|
|
1072
|
+
*/
|
|
1073
|
+
function isA4LoginKeyDestination(url) {
|
|
1074
|
+
try {
|
|
1075
|
+
const parsed = new URL(url);
|
|
1076
|
+
const host = parsed.hostname.toLowerCase().replace(/\.+$/, '');
|
|
1077
|
+
return parsed.protocol === 'https:'
|
|
1078
|
+
&& host === new URL(DEFAULT_A4_API_URL).hostname
|
|
1079
|
+
&& (parsed.port === '' || parsed.port === '443')
|
|
1080
|
+
&& parsed.username === ''
|
|
1081
|
+
&& parsed.password === '';
|
|
1082
|
+
}
|
|
1083
|
+
catch {
|
|
1084
|
+
return false;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
const PROFILE_ENV = 'ARETE_PROFILE';
|
|
1088
|
+
const CREDENTIALS_PATH_ENV = 'ARETE_CREDENTIALS_PATH';
|
|
1089
|
+
const AGENT_PROFILE = 'agent';
|
|
1090
|
+
const HUMAN_PROFILE = 'human';
|
|
1091
|
+
// ── Minimal TOML reader ─────────────────────────────────────────────────────
|
|
1092
|
+
//
|
|
1093
|
+
// Covers what the CLI writes (`[a.b."c"]` tables and `key = "string"`
|
|
1094
|
+
// pairs) plus one-line scalars. Anything else (arrays, inline tables,
|
|
1095
|
+
// multi-line strings) makes the whole document unreadable, which means
|
|
1096
|
+
// "no key" rather than a guess.
|
|
1097
|
+
/** A one-line non-string value (number, boolean, date); its text is unused. */
|
|
1098
|
+
class TomlScalar {
|
|
1099
|
+
constructor(text) {
|
|
1100
|
+
this.text = text;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
class TomlUnsupported extends Error {
|
|
1104
|
+
}
|
|
1105
|
+
function isTable(value) {
|
|
1106
|
+
return typeof value === 'object' && !(value instanceof TomlScalar);
|
|
1107
|
+
}
|
|
1108
|
+
function readBasicString(line, start) {
|
|
1109
|
+
let out = '';
|
|
1110
|
+
let index = start + 1;
|
|
1111
|
+
while (index < line.length) {
|
|
1112
|
+
const char = line[index];
|
|
1113
|
+
if (char === '"')
|
|
1114
|
+
return [out, index + 1];
|
|
1115
|
+
if (char === '\\') {
|
|
1116
|
+
const next = line[index + 1];
|
|
1117
|
+
const simple = {
|
|
1118
|
+
b: '\b', t: '\t', n: '\n', f: '\f', r: '\r', '"': '"', '\\': '\\',
|
|
1119
|
+
};
|
|
1120
|
+
if (next !== undefined && simple[next] !== undefined) {
|
|
1121
|
+
out += simple[next];
|
|
1122
|
+
index += 2;
|
|
1123
|
+
continue;
|
|
1124
|
+
}
|
|
1125
|
+
if (next === 'u' || next === 'U') {
|
|
1126
|
+
const length = next === 'u' ? 4 : 8;
|
|
1127
|
+
const hex = line.slice(index + 2, index + 2 + length);
|
|
1128
|
+
if (!/^[0-9a-fA-F]+$/.test(hex) || hex.length !== length)
|
|
1129
|
+
throw new TomlUnsupported();
|
|
1130
|
+
out += String.fromCodePoint(parseInt(hex, 16));
|
|
1131
|
+
index += 2 + length;
|
|
1132
|
+
continue;
|
|
1133
|
+
}
|
|
1134
|
+
throw new TomlUnsupported();
|
|
1135
|
+
}
|
|
1136
|
+
out += char;
|
|
1137
|
+
index += 1;
|
|
1138
|
+
}
|
|
1139
|
+
throw new TomlUnsupported();
|
|
1140
|
+
}
|
|
1141
|
+
function readLiteralString(line, start) {
|
|
1142
|
+
const end = line.indexOf("'", start + 1);
|
|
1143
|
+
if (end < 0)
|
|
1144
|
+
throw new TomlUnsupported();
|
|
1145
|
+
return [line.slice(start + 1, end), end + 1];
|
|
1146
|
+
}
|
|
1147
|
+
function skipSpaces(line, index) {
|
|
1148
|
+
while (index < line.length && (line[index] === ' ' || line[index] === '\t'))
|
|
1149
|
+
index += 1;
|
|
1150
|
+
return index;
|
|
1151
|
+
}
|
|
1152
|
+
/** Read a dotted key (`a."b".c`) ending at `terminator`. */
|
|
1153
|
+
function readKey(line, start, terminator) {
|
|
1154
|
+
const parts = [];
|
|
1155
|
+
let index = skipSpaces(line, start);
|
|
1156
|
+
for (;;) {
|
|
1157
|
+
let part;
|
|
1158
|
+
if (line[index] === '"') {
|
|
1159
|
+
[part, index] = readBasicString(line, index);
|
|
1160
|
+
}
|
|
1161
|
+
else if (line[index] === "'") {
|
|
1162
|
+
[part, index] = readLiteralString(line, index);
|
|
1163
|
+
}
|
|
1164
|
+
else {
|
|
1165
|
+
const match = /^[A-Za-z0-9_-]+/.exec(line.slice(index));
|
|
1166
|
+
if (!match)
|
|
1167
|
+
throw new TomlUnsupported();
|
|
1168
|
+
part = match[0];
|
|
1169
|
+
index += part.length;
|
|
1170
|
+
}
|
|
1171
|
+
parts.push(part);
|
|
1172
|
+
index = skipSpaces(line, index);
|
|
1173
|
+
if (line[index] === '.') {
|
|
1174
|
+
index = skipSpaces(line, index + 1);
|
|
1175
|
+
continue;
|
|
1176
|
+
}
|
|
1177
|
+
if (line.startsWith(terminator, index))
|
|
1178
|
+
return [parts, index + terminator.length];
|
|
1179
|
+
throw new TomlUnsupported();
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
function assertRestIsComment(line, index) {
|
|
1183
|
+
const rest = line.slice(index).trim();
|
|
1184
|
+
if (rest !== '' && !rest.startsWith('#'))
|
|
1185
|
+
throw new TomlUnsupported();
|
|
1186
|
+
}
|
|
1187
|
+
function tableAt(root, path) {
|
|
1188
|
+
let table = root;
|
|
1189
|
+
for (const part of path) {
|
|
1190
|
+
const existing = table[part];
|
|
1191
|
+
if (existing === undefined) {
|
|
1192
|
+
const created = Object.create(null);
|
|
1193
|
+
table[part] = created;
|
|
1194
|
+
table = created;
|
|
1195
|
+
}
|
|
1196
|
+
else if (isTable(existing)) {
|
|
1197
|
+
table = existing;
|
|
1198
|
+
}
|
|
1199
|
+
else {
|
|
1200
|
+
throw new TomlUnsupported();
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return table;
|
|
1204
|
+
}
|
|
1205
|
+
/** @internal Parse the subset of TOML described above; throws when unsupported. */
|
|
1206
|
+
function parseSimpleToml(content) {
|
|
1207
|
+
const root = Object.create(null);
|
|
1208
|
+
let current = root;
|
|
1209
|
+
for (const rawLine of content.replace(/^/, '').split(/\r?\n/)) {
|
|
1210
|
+
const line = rawLine.trim();
|
|
1211
|
+
if (line === '' || line.startsWith('#'))
|
|
1212
|
+
continue;
|
|
1213
|
+
if (line.startsWith('[['))
|
|
1214
|
+
throw new TomlUnsupported();
|
|
1215
|
+
if (line.startsWith('[')) {
|
|
1216
|
+
const [path, end] = readKey(line, 1, ']');
|
|
1217
|
+
assertRestIsComment(line, end);
|
|
1218
|
+
current = tableAt(root, path);
|
|
1219
|
+
continue;
|
|
1220
|
+
}
|
|
1221
|
+
const [path, afterEquals] = readKey(line, 0, '=');
|
|
1222
|
+
const valueStart = skipSpaces(line, afterEquals);
|
|
1223
|
+
let value;
|
|
1224
|
+
let end;
|
|
1225
|
+
if (line.startsWith('"""', valueStart) || line.startsWith("'''", valueStart)) {
|
|
1226
|
+
throw new TomlUnsupported();
|
|
1227
|
+
}
|
|
1228
|
+
else if (line[valueStart] === '"') {
|
|
1229
|
+
[value, end] = readBasicString(line, valueStart);
|
|
1230
|
+
}
|
|
1231
|
+
else if (line[valueStart] === "'") {
|
|
1232
|
+
[value, end] = readLiteralString(line, valueStart);
|
|
1233
|
+
}
|
|
1234
|
+
else {
|
|
1235
|
+
const match = /^[A-Za-z0-9_:.+-]+(?:[ T][0-9:.+Z-]+)?/.exec(line.slice(valueStart));
|
|
1236
|
+
if (!match)
|
|
1237
|
+
throw new TomlUnsupported();
|
|
1238
|
+
value = new TomlScalar(match[0]);
|
|
1239
|
+
end = valueStart + match[0].length;
|
|
1240
|
+
}
|
|
1241
|
+
assertRestIsComment(line, end);
|
|
1242
|
+
const key = path[path.length - 1];
|
|
1243
|
+
const table = tableAt(current, path.slice(0, -1));
|
|
1244
|
+
if (Object.prototype.hasOwnProperty.call(table, key))
|
|
1245
|
+
throw new TomlUnsupported();
|
|
1246
|
+
table[key] = value;
|
|
1247
|
+
}
|
|
1248
|
+
return root;
|
|
1249
|
+
}
|
|
1250
|
+
// ── Lookup (mirror of the Rust `lookup_credentials`) ─────────────────────────
|
|
1251
|
+
/** Mirror of the CLI's API URL normalisation for credential lookup. */
|
|
1252
|
+
function normalizeA4ApiUrl(url) {
|
|
1253
|
+
const trimmed = url.trim().replace(/\/+$/, '');
|
|
1254
|
+
const schemeAt = trimmed.indexOf('://');
|
|
1255
|
+
const scheme = schemeAt >= 0 ? trimmed.slice(0, schemeAt).toLowerCase() : '';
|
|
1256
|
+
const rest = schemeAt >= 0 ? trimmed.slice(schemeAt + 3) : trimmed;
|
|
1257
|
+
const authorityEnd = rest.search(/[/?#]/);
|
|
1258
|
+
const authority = authorityEnd >= 0 ? rest.slice(0, authorityEnd) : rest;
|
|
1259
|
+
const tail = authorityEnd >= 0 ? rest.slice(authorityEnd) : '';
|
|
1260
|
+
const hostStart = authority.lastIndexOf('@') + 1;
|
|
1261
|
+
const hostPort = authority.slice(hostStart);
|
|
1262
|
+
let host;
|
|
1263
|
+
let port;
|
|
1264
|
+
if (hostPort.startsWith('[')) {
|
|
1265
|
+
const close = hostPort.indexOf(']');
|
|
1266
|
+
host = close >= 0 ? hostPort.slice(0, close + 1) : hostPort;
|
|
1267
|
+
port = close >= 0 ? hostPort.slice(close + 1) : '';
|
|
1268
|
+
}
|
|
1269
|
+
else {
|
|
1270
|
+
const colon = hostPort.lastIndexOf(':');
|
|
1271
|
+
host = colon >= 0 ? hostPort.slice(0, colon) : hostPort;
|
|
1272
|
+
port = colon >= 0 ? hostPort.slice(colon) : '';
|
|
1273
|
+
}
|
|
1274
|
+
host = host.replace(/\.+$/, '').toLowerCase();
|
|
1275
|
+
return `${scheme ? `${scheme}://` : ''}${authority.slice(0, hostStart)}${host}${port}${tail}`;
|
|
1276
|
+
}
|
|
1277
|
+
function stringMap(value) {
|
|
1278
|
+
if (value === undefined)
|
|
1279
|
+
return undefined;
|
|
1280
|
+
if (!isTable(value))
|
|
1281
|
+
throw new TomlUnsupported();
|
|
1282
|
+
const out = new Map();
|
|
1283
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
1284
|
+
if (typeof entry !== 'string')
|
|
1285
|
+
throw new TomlUnsupported();
|
|
1286
|
+
out.set(key, entry);
|
|
1287
|
+
}
|
|
1288
|
+
return out;
|
|
1289
|
+
}
|
|
1290
|
+
function findUrlKey(keys, apiUrl) {
|
|
1291
|
+
if (!keys)
|
|
1292
|
+
return undefined;
|
|
1293
|
+
const wanted = normalizeA4ApiUrl(apiUrl);
|
|
1294
|
+
const exact = (keys.get(apiUrl) ?? keys.get(wanted))?.trim();
|
|
1295
|
+
if (exact)
|
|
1296
|
+
return exact;
|
|
1297
|
+
return [...keys.entries()]
|
|
1298
|
+
.filter(([url]) => normalizeA4ApiUrl(url) === wanted)
|
|
1299
|
+
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
|
|
1300
|
+
.map(([, key]) => key.trim())
|
|
1301
|
+
.find((key) => key !== '');
|
|
1302
|
+
}
|
|
1303
|
+
function isValidProfileName(profile) {
|
|
1304
|
+
return profile.length > 0 && profile.length <= 64 && /^[A-Za-z0-9_-]+$/.test(profile);
|
|
1305
|
+
}
|
|
1306
|
+
function keyFitsProfile(profile, key) {
|
|
1307
|
+
const agentKey = key.trim().startsWith('a4_ak_');
|
|
1308
|
+
if (profile === AGENT_PROFILE)
|
|
1309
|
+
return agentKey;
|
|
1310
|
+
if (profile === HUMAN_PROFILE)
|
|
1311
|
+
return !agentKey;
|
|
1312
|
+
return true;
|
|
1313
|
+
}
|
|
1314
|
+
/** @internal Mirror of the Rust `lookup_credentials`. */
|
|
1315
|
+
function lookupA4Credentials(content, apiUrl, requestedProfile) {
|
|
1316
|
+
let profiles;
|
|
1317
|
+
let legacyKeys;
|
|
1318
|
+
let legacyApiKey;
|
|
1319
|
+
try {
|
|
1320
|
+
const parsed = parseSimpleToml(content);
|
|
1321
|
+
const profilesValue = parsed['profiles'];
|
|
1322
|
+
if (profilesValue !== undefined && !isTable(profilesValue))
|
|
1323
|
+
return { kind: 'invalid' };
|
|
1324
|
+
profiles = Object.entries(profilesValue ?? {}).map(([name, profile]) => {
|
|
1325
|
+
if (!isTable(profile))
|
|
1326
|
+
throw new TomlUnsupported();
|
|
1327
|
+
return [name, stringMap(profile['keys'])];
|
|
1328
|
+
});
|
|
1329
|
+
legacyKeys = stringMap(parsed['keys']);
|
|
1330
|
+
const apiKey = parsed['api_key'];
|
|
1331
|
+
if (apiKey !== undefined && typeof apiKey !== 'string')
|
|
1332
|
+
return { kind: 'invalid' };
|
|
1333
|
+
legacyApiKey = apiKey?.trim() || undefined;
|
|
1334
|
+
}
|
|
1335
|
+
catch {
|
|
1336
|
+
return { kind: 'invalid' };
|
|
1337
|
+
}
|
|
1338
|
+
const legacy = findUrlKey(legacyKeys, apiUrl) ?? legacyApiKey;
|
|
1339
|
+
if (requestedProfile !== undefined) {
|
|
1340
|
+
if (!isValidProfileName(requestedProfile))
|
|
1341
|
+
return { kind: 'invalid' };
|
|
1342
|
+
const entry = profiles.find(([name]) => name === requestedProfile);
|
|
1343
|
+
const key = findUrlKey(entry?.[1], apiUrl);
|
|
1344
|
+
if (key !== undefined) {
|
|
1345
|
+
return keyFitsProfile(requestedProfile, key) ? { kind: 'key', key } : { kind: 'invalid' };
|
|
1346
|
+
}
|
|
1347
|
+
if (legacy !== undefined) {
|
|
1348
|
+
const compatible = requestedProfile === AGENT_PROFILE
|
|
1349
|
+
? legacy.startsWith('a4_ak_')
|
|
1350
|
+
: requestedProfile === HUMAN_PROFILE && !legacy.startsWith('a4_ak_');
|
|
1351
|
+
if (compatible)
|
|
1352
|
+
return { kind: 'key', key: legacy };
|
|
1353
|
+
}
|
|
1354
|
+
return { kind: 'none' };
|
|
1355
|
+
}
|
|
1356
|
+
const matches = profiles
|
|
1357
|
+
.map(([name, keys]) => [name, findUrlKey(keys, apiUrl)])
|
|
1358
|
+
.filter((entry) => entry[1] !== undefined);
|
|
1359
|
+
if (matches.length > 1)
|
|
1360
|
+
return { kind: 'ambiguous' };
|
|
1361
|
+
if (matches.length === 1) {
|
|
1362
|
+
const [name, key] = matches[0];
|
|
1363
|
+
return keyFitsProfile(name, key) ? { kind: 'key', key } : { kind: 'invalid' };
|
|
1364
|
+
}
|
|
1365
|
+
return legacy !== undefined ? { kind: 'key', key: legacy } : { kind: 'none' };
|
|
1366
|
+
}
|
|
1367
|
+
/** Selected profile: `undefined` for none, `null` when selection is invalid. */
|
|
1368
|
+
function selectProfile(host) {
|
|
1369
|
+
// The project file can pin the agent profile; if it cannot be checked
|
|
1370
|
+
// (unknown working directory, denied or failed read), choose nothing rather
|
|
1371
|
+
// than risk a profile the project excludes.
|
|
1372
|
+
const cwd = host.cwd();
|
|
1373
|
+
if (cwd === undefined)
|
|
1374
|
+
return null;
|
|
1375
|
+
let project;
|
|
1376
|
+
try {
|
|
1377
|
+
project = host.readTextFile(host.joinPath(cwd, '.arete', 'auth.toml'));
|
|
1378
|
+
}
|
|
1379
|
+
catch {
|
|
1380
|
+
return null;
|
|
1381
|
+
}
|
|
1382
|
+
if (project !== null) {
|
|
1383
|
+
try {
|
|
1384
|
+
const profile = parseSimpleToml(project)['default_profile'];
|
|
1385
|
+
return profile === AGENT_PROFILE ? AGENT_PROFILE : null;
|
|
1386
|
+
}
|
|
1387
|
+
catch {
|
|
1388
|
+
return null;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
const profile = host.readEnv(PROFILE_ENV)?.trim();
|
|
1392
|
+
if (profile === undefined)
|
|
1393
|
+
return undefined;
|
|
1394
|
+
return isValidProfileName(profile) ? profile : null;
|
|
1395
|
+
}
|
|
1396
|
+
/**
|
|
1397
|
+
* @internal Key of the active `a4` login for the default Arete API, or
|
|
1398
|
+
* `undefined`. Never throws. The caller checks the key class.
|
|
1399
|
+
*/
|
|
1400
|
+
function readA4ProfileKey(host = systemProfileHost()) {
|
|
1401
|
+
if (!host)
|
|
1402
|
+
return {};
|
|
1403
|
+
try {
|
|
1404
|
+
const profile = selectProfile(host);
|
|
1405
|
+
if (profile === null)
|
|
1406
|
+
return {};
|
|
1407
|
+
const override = host.readEnv(CREDENTIALS_PATH_ENV);
|
|
1408
|
+
let path;
|
|
1409
|
+
if (override) {
|
|
1410
|
+
path = override;
|
|
1411
|
+
}
|
|
1412
|
+
else {
|
|
1413
|
+
const home = host.homeDir();
|
|
1414
|
+
path = home ? host.joinPath(home, '.arete', 'credentials.toml') : undefined;
|
|
1415
|
+
}
|
|
1416
|
+
if (!path)
|
|
1417
|
+
return {};
|
|
1418
|
+
const content = host.readTextFile(path);
|
|
1419
|
+
if (content === null)
|
|
1420
|
+
return {};
|
|
1421
|
+
const lookup = lookupA4Credentials(content, DEFAULT_A4_API_URL, profile);
|
|
1422
|
+
if (lookup.kind === 'key')
|
|
1423
|
+
return { key: lookup.key };
|
|
1424
|
+
if (lookup.kind === 'ambiguous')
|
|
1425
|
+
return { ambiguous: true };
|
|
1426
|
+
return {};
|
|
1427
|
+
}
|
|
1428
|
+
catch {
|
|
1429
|
+
return {};
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
function denoHost(deno) {
|
|
1433
|
+
const granted = (descriptor) => {
|
|
1434
|
+
try {
|
|
1435
|
+
return deno.permissions?.querySync?.(descriptor)?.state === 'granted';
|
|
1436
|
+
}
|
|
1437
|
+
catch {
|
|
1438
|
+
return false;
|
|
1439
|
+
}
|
|
1440
|
+
};
|
|
1441
|
+
const readEnv = (name) => granted({ name: 'env', variable: name }) ? deno.env?.get?.(name) : undefined;
|
|
1442
|
+
const separator = deno.build?.os === 'windows' ? '\\' : '/';
|
|
1443
|
+
return {
|
|
1444
|
+
readEnv,
|
|
1445
|
+
readTextFile(path) {
|
|
1446
|
+
// Without --allow-read Deno would prompt or throw; ask first. Denied
|
|
1447
|
+
// access is not a missing file: callers must not treat it as absent.
|
|
1448
|
+
if (!deno.readTextFileSync)
|
|
1449
|
+
throw new Error('file reads unavailable');
|
|
1450
|
+
if (!granted({ name: 'read', path }))
|
|
1451
|
+
throw new Error('read permission not granted');
|
|
1452
|
+
try {
|
|
1453
|
+
return deno.readTextFileSync(path);
|
|
1454
|
+
}
|
|
1455
|
+
catch (error) {
|
|
1456
|
+
const notFound = deno.errors?.NotFound;
|
|
1457
|
+
if (notFound && error instanceof notFound)
|
|
1458
|
+
return null;
|
|
1459
|
+
throw error;
|
|
1460
|
+
}
|
|
1461
|
+
},
|
|
1462
|
+
cwd() {
|
|
1463
|
+
if (!granted({ name: 'read' }))
|
|
1464
|
+
return undefined;
|
|
1465
|
+
try {
|
|
1466
|
+
return deno.cwd?.();
|
|
1467
|
+
}
|
|
1468
|
+
catch {
|
|
1469
|
+
return undefined;
|
|
1470
|
+
}
|
|
1471
|
+
},
|
|
1472
|
+
homeDir: () => readEnv('HOME') ?? readEnv('USERPROFILE'),
|
|
1473
|
+
joinPath: (...parts) => parts.join(separator),
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1476
|
+
function nodeHost(process) {
|
|
1477
|
+
const load = process.getBuiltinModule;
|
|
1478
|
+
if (typeof load !== 'function')
|
|
1479
|
+
return undefined;
|
|
1480
|
+
const fs = load.call(process, 'fs');
|
|
1481
|
+
const os = load.call(process, 'os');
|
|
1482
|
+
const path = load.call(process, 'path');
|
|
1483
|
+
if (!fs || !os || !path)
|
|
1484
|
+
return undefined;
|
|
1485
|
+
return {
|
|
1486
|
+
readEnv: (name) => process.env?.[name],
|
|
1487
|
+
readTextFile(file) {
|
|
1488
|
+
try {
|
|
1489
|
+
return fs.readFileSync(file, 'utf8');
|
|
1490
|
+
}
|
|
1491
|
+
catch (error) {
|
|
1492
|
+
if (error.code === 'ENOENT')
|
|
1493
|
+
return null;
|
|
1494
|
+
throw error;
|
|
1495
|
+
}
|
|
1496
|
+
},
|
|
1497
|
+
cwd: () => process.cwd?.(),
|
|
1498
|
+
homeDir: () => os.homedir(),
|
|
1499
|
+
joinPath: (...parts) => path.join(...parts),
|
|
1500
|
+
};
|
|
1501
|
+
}
|
|
1502
|
+
/** Host for the current server runtime, or `undefined` where files are unreachable. */
|
|
1503
|
+
function systemProfileHost() {
|
|
1504
|
+
try {
|
|
1505
|
+
const scope = globalThis;
|
|
1506
|
+
if (scope.Deno)
|
|
1507
|
+
return denoHost(scope.Deno);
|
|
1508
|
+
if (scope.process)
|
|
1509
|
+
return nodeHost(scope.process);
|
|
1510
|
+
}
|
|
1511
|
+
catch {
|
|
1512
|
+
// Fall through: no profile support in this runtime.
|
|
1513
|
+
}
|
|
1514
|
+
return undefined;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
/** Environment variable read for a secret-class key outside browsers. */
|
|
1518
|
+
const ARETE_API_KEY_ENV = 'ARETE_API_KEY';
|
|
1519
|
+
const CREATE_PUBLISHABLE_HINT = 'create one with `a4 auth keys create-publishable --origin <scheme://host[:port]>`';
|
|
1520
|
+
const PUBLISHABLE_PREFIXES = ['a4_pk_', 'hspk_'];
|
|
1521
|
+
const SECRET_PREFIXES = ['a4_sk_', 'a4_ak_', 'hsk_'];
|
|
1522
|
+
function classifyApiKey(key) {
|
|
1523
|
+
const trimmed = key.trim();
|
|
1524
|
+
if (PUBLISHABLE_PREFIXES.some((prefix) => trimmed.startsWith(prefix)))
|
|
1525
|
+
return 'publishable';
|
|
1526
|
+
if (SECRET_PREFIXES.some((prefix) => trimmed.startsWith(prefix)))
|
|
1527
|
+
return 'secret';
|
|
1528
|
+
return 'unknown';
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* True in a browser page: both `window` and `document` exist. Web workers,
|
|
1532
|
+
* service workers, edge runtimes, SSR (Node/Bun) and Deno have no `document`
|
|
1533
|
+
* and count as server-side.
|
|
1534
|
+
*/
|
|
1535
|
+
function isBrowserEnvironment() {
|
|
1536
|
+
const scope = globalThis;
|
|
1537
|
+
return typeof scope.window === 'object'
|
|
1538
|
+
&& scope.window !== null
|
|
1539
|
+
&& typeof scope.document === 'object'
|
|
1540
|
+
&& scope.document !== null;
|
|
1541
|
+
}
|
|
1542
|
+
/**
|
|
1543
|
+
* Read an environment variable in Node, Bun or Deno without prompting for or
|
|
1544
|
+
* failing on missing permissions. Browsers have no environment.
|
|
1545
|
+
*/
|
|
1546
|
+
function readEnvironmentVariable(name) {
|
|
1547
|
+
try {
|
|
1548
|
+
const deno = globalThis.Deno;
|
|
1549
|
+
if (deno) {
|
|
1550
|
+
// Reading without --allow-env throws or prompts; ask first.
|
|
1551
|
+
const state = deno.permissions?.querySync?.({ name: 'env', variable: name })?.state;
|
|
1552
|
+
if (state !== 'granted')
|
|
1553
|
+
return undefined;
|
|
1554
|
+
const value = deno.env?.get?.(name);
|
|
1555
|
+
return typeof value === 'string' ? value : undefined;
|
|
1556
|
+
}
|
|
1557
|
+
const value = globalThis
|
|
1558
|
+
.process?.env?.[name];
|
|
1559
|
+
return typeof value === 'string' ? value : undefined;
|
|
1560
|
+
}
|
|
1561
|
+
catch {
|
|
1562
|
+
return undefined;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
const warned$1 = new Set();
|
|
1566
|
+
/**
|
|
1567
|
+
* Marks a resolved config whose `secretKey` came from the `a4` login. It holds
|
|
1568
|
+
* that key, so the mark is carried through object spreads (binding paths copy
|
|
1569
|
+
* the resolved config) and only applies while `secretKey` is still that key:
|
|
1570
|
+
* a copy given another `secretKey` is no longer restricted. Per config, never
|
|
1571
|
+
* process-wide, so the same key passed explicitly elsewhere is unaffected.
|
|
1572
|
+
*/
|
|
1573
|
+
const A4_LOGIN_SECRET_KEY = Symbol('arete.a4LoginSecretKey');
|
|
1574
|
+
/** True when `auth.secretKey` was supplied by the `a4` login fallback. */
|
|
1575
|
+
function secretKeyFromA4Login(auth) {
|
|
1576
|
+
const marked = auth;
|
|
1577
|
+
return marked?.secretKey !== undefined && marked[A4_LOGIN_SECRET_KEY] === marked.secretKey;
|
|
1578
|
+
}
|
|
1579
|
+
function warnOnce$1(id, message) {
|
|
1580
|
+
if (warned$1.has(id))
|
|
1581
|
+
return;
|
|
1582
|
+
warned$1.add(id);
|
|
1583
|
+
console.warn(`[arete] ${message}`);
|
|
1584
|
+
}
|
|
1585
|
+
function hasExplicitAuth(auth) {
|
|
1586
|
+
return auth !== undefined && (auth.token !== undefined
|
|
1587
|
+
|| auth.getToken !== undefined
|
|
1588
|
+
|| auth.tokenEndpoint !== undefined
|
|
1589
|
+
|| auth.publishableKey !== undefined
|
|
1590
|
+
|| auth.secretKey !== undefined);
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Validate the configured API keys and apply the server-side credential chain.
|
|
1594
|
+
*
|
|
1595
|
+
* - `secretKey` is refused in browsers and refuses publishable keys.
|
|
1596
|
+
* - A secret-class key in `publishableKey` is refused in browsers and warned
|
|
1597
|
+
* about elsewhere (it still works server-side, as it always has).
|
|
1598
|
+
* - Outside browsers, when no auth option is set at all, `ARETE_API_KEY`
|
|
1599
|
+
* supplies `secretKey`; without it, the agent or secret key from the active
|
|
1600
|
+
* `a4` CLI login does. Browsers never read either.
|
|
1601
|
+
*
|
|
1602
|
+
* Error and warning text never includes key material.
|
|
1603
|
+
*/
|
|
1604
|
+
function resolveAuthConfig(auth, readProfileKey = readA4ProfileKey) {
|
|
1605
|
+
const browser = isBrowserEnvironment();
|
|
1606
|
+
if (auth?.secretKey !== undefined) {
|
|
1607
|
+
if (browser) {
|
|
1608
|
+
throw new AreteError('auth.secretKey cannot be used in a browser: anything shipped to a browser is public. '
|
|
1609
|
+
+ 'Use auth.publishableKey with a publishable key (a4_pk_...) instead; '
|
|
1610
|
+
+ `${CREATE_PUBLISHABLE_HINT}. Keep secret and agent keys on servers and in local scripts.`, 'INVALID_CONFIG');
|
|
1611
|
+
}
|
|
1612
|
+
if (auth.secretKey.trim() === '') {
|
|
1613
|
+
throw new AreteError('auth.secretKey is empty', 'INVALID_CONFIG');
|
|
1614
|
+
}
|
|
1615
|
+
if (classifyApiKey(auth.secretKey) === 'publishable') {
|
|
1616
|
+
throw new AreteError('auth.secretKey was given a publishable key (a4_pk_...). Pass it as auth.publishableKey '
|
|
1617
|
+
+ 'instead; auth.secretKey takes an agent key (a4_ak_...) or secret key (a4_sk_...).', 'INVALID_CONFIG');
|
|
1618
|
+
}
|
|
1619
|
+
if (auth.publishableKey !== undefined) {
|
|
1620
|
+
throw new AreteError('Set either auth.secretKey (servers and scripts) or auth.publishableKey (browsers), not both.', 'INVALID_CONFIG');
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
if (auth?.publishableKey !== undefined && classifyApiKey(auth.publishableKey) === 'secret') {
|
|
1624
|
+
if (browser) {
|
|
1625
|
+
throw new AreteError('auth.publishableKey was given a secret-class key (a4_sk_... or a4_ak_...). Never ship a '
|
|
1626
|
+
+ 'secret or agent key to a browser. Use a publishable key (a4_pk_...) instead; '
|
|
1627
|
+
+ `${CREATE_PUBLISHABLE_HINT}.`, 'INVALID_CONFIG');
|
|
1628
|
+
}
|
|
1629
|
+
warnOnce$1('secret-in-publishable', 'auth.publishableKey was given a secret-class key (a4_sk_... or a4_ak_...). '
|
|
1630
|
+
+ 'Pass it as auth.secretKey instead (servers and scripts only), or set ARETE_API_KEY.');
|
|
1631
|
+
}
|
|
1632
|
+
if (browser || hasExplicitAuth(auth))
|
|
1633
|
+
return auth;
|
|
1634
|
+
const environmentKey = readEnvironmentVariable(ARETE_API_KEY_ENV)?.trim();
|
|
1635
|
+
if (environmentKey) {
|
|
1636
|
+
if (classifyApiKey(environmentKey) !== 'publishable') {
|
|
1637
|
+
return { ...auth, secretKey: environmentKey };
|
|
1638
|
+
}
|
|
1639
|
+
warnOnce$1('publishable-in-env', `${ARETE_API_KEY_ENV} holds a publishable key (a4_pk_...) and was ignored. Set it to an agent `
|
|
1640
|
+
+ 'key (a4_ak_...) or secret key (a4_sk_...), or pass the publishable key as auth.publishableKey.');
|
|
1641
|
+
}
|
|
1642
|
+
const profile = readProfileKey();
|
|
1643
|
+
if (profile.ambiguous) {
|
|
1644
|
+
warnOnce$1('ambiguous-a4-profile', 'More than one a4 login profile holds a key; not choosing one. Set ARETE_PROFILE '
|
|
1645
|
+
+ `(for example \`agent\`) or ${ARETE_API_KEY_ENV}.`);
|
|
1646
|
+
}
|
|
1647
|
+
if (profile.key && classifyApiKey(profile.key) === 'secret') {
|
|
1648
|
+
const resolved = {
|
|
1649
|
+
...auth,
|
|
1650
|
+
secretKey: profile.key,
|
|
1651
|
+
[A4_LOGIN_SECRET_KEY]: profile.key,
|
|
1652
|
+
};
|
|
1653
|
+
return resolved;
|
|
1654
|
+
}
|
|
1655
|
+
return auth;
|
|
1656
|
+
}
|
|
1657
|
+
/**
|
|
1658
|
+
* Appended to a 401 for a request that carried no API key. It names the
|
|
1659
|
+
* commands and options that supply one, never where credentials are stored.
|
|
1660
|
+
*/
|
|
1661
|
+
const NO_API_KEY_HINT = 'No Arete API key found. Run `a4 auth login` (or `a4 auth signup` for an agent), '
|
|
1662
|
+
+ 'or set ARETE_API_KEY, or pass auth.secretKey.';
|
|
1663
|
+
/**
|
|
1664
|
+
* The key sent as the bearer credential to `endpoint`, if any. A key taken
|
|
1665
|
+
* from the `a4` login is only sent to the Arete API it was stored for.
|
|
1666
|
+
*/
|
|
1667
|
+
function tokenEndpointApiKey(auth, endpoint) {
|
|
1668
|
+
if (secretKeyFromA4Login(auth) && !isA4LoginKeyDestination(endpoint))
|
|
1669
|
+
return undefined;
|
|
1670
|
+
return auth?.secretKey ?? auth?.publishableKey;
|
|
1671
|
+
}
|
|
1672
|
+
/** True when `headers` carries its own `Authorization` header. */
|
|
1673
|
+
function hasAuthorizationHeader(headers) {
|
|
1674
|
+
return Object.keys(headers ?? {}).some((name) => name.toLowerCase() === 'authorization');
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1044
1677
|
const GZIP_MAGIC_0 = 0x1f;
|
|
1045
1678
|
const GZIP_MAGIC_1 = 0x8b;
|
|
1046
1679
|
const FRAME_MODES = new Set(['state', 'append', 'list']);
|
|
@@ -1848,7 +2481,7 @@ class ConnectionManager {
|
|
|
1848
2481
|
this.reconnectIntervals = config.reconnectIntervals ?? DEFAULT_CONFIG.reconnectIntervals;
|
|
1849
2482
|
this.maxReconnectAttempts =
|
|
1850
2483
|
config.maxReconnectAttempts ?? DEFAULT_CONFIG.maxReconnectAttempts;
|
|
1851
|
-
this.authConfig = config.auth;
|
|
2484
|
+
this.authConfig = resolveAuthConfig(config.auth);
|
|
1852
2485
|
this.release = normalizeStackRelease(config.release);
|
|
1853
2486
|
this.authFetch = config.fetch ?? ((input, init) => {
|
|
1854
2487
|
if (typeof globalThis.fetch !== 'function') {
|
|
@@ -2100,12 +2733,11 @@ class ConnectionManager {
|
|
|
2100
2733
|
};
|
|
2101
2734
|
}
|
|
2102
2735
|
async fetchTokenFromEndpoint(tokenEndpoint, request) {
|
|
2736
|
+
const apiKey = tokenEndpointApiKey(this.authConfig, tokenEndpoint);
|
|
2103
2737
|
const response = await this.authFetch(tokenEndpoint, {
|
|
2104
2738
|
method: 'POST',
|
|
2105
2739
|
headers: {
|
|
2106
|
-
...(
|
|
2107
|
-
? { Authorization: `Bearer ${this.authConfig.publishableKey}` }
|
|
2108
|
-
: {}),
|
|
2740
|
+
...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),
|
|
2109
2741
|
...(this.authConfig?.tokenEndpointHeaders ?? {}),
|
|
2110
2742
|
'Content-Type': 'application/json',
|
|
2111
2743
|
},
|
|
@@ -2132,9 +2764,17 @@ class ConnectionManager {
|
|
|
2132
2764
|
: response.status === 429
|
|
2133
2765
|
? 'QUOTA_EXCEEDED'
|
|
2134
2766
|
: 'AUTH_REQUIRED';
|
|
2135
|
-
const
|
|
2767
|
+
const responseMessage = typeof parsedError?.error === 'string' && parsedError.error.length > 0
|
|
2136
2768
|
? parsedError.error
|
|
2137
2769
|
: rawError || response.statusText || 'Authentication request failed';
|
|
2770
|
+
// A server-side 401 for a request that carried no credential at all:
|
|
2771
|
+
// say how to supply one. Custom Authorization headers have their own
|
|
2772
|
+
// advice to give.
|
|
2773
|
+
const sentCredential = Boolean(apiKey)
|
|
2774
|
+
|| hasAuthorizationHeader(this.authConfig?.tokenEndpointHeaders);
|
|
2775
|
+
const errorMessage = response.status === 401 && !sentCredential && !isBrowserEnvironment()
|
|
2776
|
+
? `${responseMessage}. ${NO_API_KEY_HINT}`
|
|
2777
|
+
: responseMessage;
|
|
2138
2778
|
const retryAfterHeader = response.headers.get('Retry-After');
|
|
2139
2779
|
const retryAfterSeconds = retryAfterHeader && /^\d+$/.test(retryAfterHeader)
|
|
2140
2780
|
? Number(retryAfterHeader)
|
|
@@ -5451,7 +6091,10 @@ function hasRuntimeAuthStrategy(auth) {
|
|
|
5451
6091
|
|| auth?.getToken !== undefined
|
|
5452
6092
|
|| auth?.tokenEndpoint !== undefined;
|
|
5453
6093
|
}
|
|
5454
|
-
function bindingAuthConfig(binding,
|
|
6094
|
+
function bindingAuthConfig(binding, configuredAuth) {
|
|
6095
|
+
// Resolve ARETE_API_KEY before the binding endpoint is filled in, so an
|
|
6096
|
+
// otherwise unconfigured client still authenticates.
|
|
6097
|
+
const runtimeAuth = resolveAuthConfig(configuredAuth);
|
|
5455
6098
|
if (hasRuntimeAuthStrategy(runtimeAuth))
|
|
5456
6099
|
return runtimeAuth;
|
|
5457
6100
|
if (!binding.auth.required)
|
|
@@ -7498,7 +8141,10 @@ function parseProgramReadResponse(response, path, body) {
|
|
|
7498
8141
|
throw new AreteError(`Program read '${path}' returned invalid JSON`, 'INVALID_RESPONSE', error);
|
|
7499
8142
|
}
|
|
7500
8143
|
}
|
|
7501
|
-
function hostedAuthConfig(binding,
|
|
8144
|
+
function hostedAuthConfig(binding, configuredAuth) {
|
|
8145
|
+
// Resolve ARETE_API_KEY before the binding endpoint is filled in, so an
|
|
8146
|
+
// otherwise unconfigured client still authenticates.
|
|
8147
|
+
const runtimeAuth = resolveAuthConfig(configuredAuth);
|
|
7502
8148
|
const metadata = binding.auth;
|
|
7503
8149
|
const runtimeStrategyConfigured = runtimeAuth?.token !== undefined
|
|
7504
8150
|
|| runtimeAuth?.getToken !== undefined
|
|
@@ -8972,5 +9618,5 @@ function stringifyBigints(value) {
|
|
|
8972
9618
|
|
|
8973
9619
|
const Arete = Object.assign(Arete$1, { session: createSession });
|
|
8974
9620
|
|
|
8975
|
-
export { API_PROBLEM_SCHEMA_VERSION, ASSOCIATED_TOKEN_PROGRAM_ADDRESS, Arete, AreteError, CLAIM_AGENT_MATERIALIZER_PATH, ConnectionManager, DEFAULT_CONFIG, DEFAULT_INITIAL_DATA_TIMEOUT_MS, DEFAULT_MAX_ENTRIES_PER_VIEW, EXTENSION_API_VERSION, FrameProcessor, InitialDataTimeoutError, InstructionError, MANAGED_SOLANA_CONTRACT_VERSION, MAX_MANAGED_BATCH_ADDRESSES, MAX_MANAGED_PAGE_SIZE, MemoryAdapter, OPERATION_KIND, OperationCallbackError, OperationExecutionError, PROGRAM_KEY_CONFLICT, PROGRAM_OPERATION_EXTENSIONS, ProcessedSlotTimeoutError, QueryStore, ReadRequestError, SPL_TOKEN_PROGRAM_ADDRESS, STACK_RUNTIME_EXTENSIONS, SYSTEM_PROGRAM_ADDRESS, StreamGapError, SubscriptionRegistry, TOKEN_2022_PROGRAM_ADDRESS, TRANSACTION_RESOURCE_OPTION_KEYS, TransactionExecutionError, TransactionOptionsError, TransactionTransportError, account, accountTombstone, appendFlowTransactions, appendTransactionInstructions, applyConnectedStackExtensions, arg, buildInstruction, bytes, canonicalQueryKey, chainAccountLoader, compareProgramIdentity, createChainClient, createEntityStream, createHostedSolanaGatewayTransports, createInstructionExecutor, createInstructionHandler, createPreparedFlow, createPreparedInstruction, createPreparedTransaction, createPreparedTransactionBody, createProgramPdas, createPublicKeySeed, createRichUpdateStream, createSeed, createSession, createSignerRegistry, createSubscriptionId, createTransactionTransport, createTypedListView, createTypedStateView, createTypedViews, createUpdateStream, decodeBase58, defineProgramExtensions, defineStackExtensions, deriveAssociatedTokenAccount, deriveHttpEndpoint, findProgramAddress as derivePda, describePreparedOperation, encodeBase58, executeInstruction, executePreparedOperation, extendProgram, extendPrograms, extendStack, findProgramAddress, findProgramAddressSync, flowOperation, formatPreparedOperation, formatProgramError, formatRawToUi, getMintDecimals, getOperationKind, getProgramRuntimeExtensions, getStackRuntimeExtensions, getTransactionFailureOutcome, hostedWebsocketSuffixes, inspectPreparedOperation, instructionOperation, isClaimAgentRecoveryAction, isEntityFrame, isErrorFrame, isHostedAreteEndpoint, isReplayErrorCode, isSafeClaimActionUrl, isSameProgramSdk, isSnapshotFrame, isStackVersionRefusalCode, isSubscribedFrame, isUnsubscribedFrame, isValidFrame, literal, managedAddress, managedContext, managedDiscovery, managedPage, managedReadOptions, managedU64, normalizeSubscription, normalizeSubscriptionQuery, normalizeSubscriptionRequest, normalizeTransactionError, parseApiProblem, parseFrame, parseFrameFromBlob, parseInstructionError, parseUiAmountToRaw, pda, prependFlowTransactionInstructions, prependTransactionInstructions, programAccountRead, programQuery, resolveAccounts, resolveAmount, resolveAmountToRaw, resolveAmountsToRaw, resolveTokenProgramAddress, resolveTransactionBuildOptions, safeToRawAmount, serializeInstructionData, serializeViewKey, setHostedWebsocketSuffixes, stackQuery, stringifyBigints, toJsonValue, toRawAmount, toWireResourceOptions, transactionOperation, unwrapOperationExecutionError, validateAccountResolution, validateProgramReadDescriptor, validateSubscriptionId, withProgramIdentity, withProgramRead, withPrograms };
|
|
9621
|
+
export { API_PROBLEM_SCHEMA_VERSION, ARETE_API_KEY_ENV, ASSOCIATED_TOKEN_PROGRAM_ADDRESS, Arete, AreteError, CLAIM_AGENT_MATERIALIZER_PATH, ConnectionManager, DEFAULT_CONFIG, DEFAULT_INITIAL_DATA_TIMEOUT_MS, DEFAULT_MAX_ENTRIES_PER_VIEW, EXTENSION_API_VERSION, FrameProcessor, InitialDataTimeoutError, InstructionError, MANAGED_SOLANA_CONTRACT_VERSION, MAX_MANAGED_BATCH_ADDRESSES, MAX_MANAGED_PAGE_SIZE, MemoryAdapter, OPERATION_KIND, OperationCallbackError, OperationExecutionError, PROGRAM_KEY_CONFLICT, PROGRAM_OPERATION_EXTENSIONS, ProcessedSlotTimeoutError, QueryStore, ReadRequestError, SPL_TOKEN_PROGRAM_ADDRESS, STACK_RUNTIME_EXTENSIONS, SYSTEM_PROGRAM_ADDRESS, StreamGapError, SubscriptionRegistry, TOKEN_2022_PROGRAM_ADDRESS, TRANSACTION_RESOURCE_OPTION_KEYS, TransactionExecutionError, TransactionOptionsError, TransactionTransportError, account, accountTombstone, appendFlowTransactions, appendTransactionInstructions, applyConnectedStackExtensions, arg, buildInstruction, bytes, canonicalQueryKey, chainAccountLoader, classifyApiKey, compareProgramIdentity, createChainClient, createEntityStream, createHostedSolanaGatewayTransports, createInstructionExecutor, createInstructionHandler, createPreparedFlow, createPreparedInstruction, createPreparedTransaction, createPreparedTransactionBody, createProgramPdas, createPublicKeySeed, createRichUpdateStream, createSeed, createSession, createSignerRegistry, createSubscriptionId, createTransactionTransport, createTypedListView, createTypedStateView, createTypedViews, createUpdateStream, decodeBase58, defineProgramExtensions, defineStackExtensions, deriveAssociatedTokenAccount, deriveHttpEndpoint, findProgramAddress as derivePda, describePreparedOperation, encodeBase58, executeInstruction, executePreparedOperation, extendProgram, extendPrograms, extendStack, findProgramAddress, findProgramAddressSync, flowOperation, formatPreparedOperation, formatProgramError, formatRawToUi, getMintDecimals, getOperationKind, getProgramRuntimeExtensions, getStackRuntimeExtensions, getTransactionFailureOutcome, hostedWebsocketSuffixes, inspectPreparedOperation, instructionOperation, isClaimAgentRecoveryAction, isEntityFrame, isErrorFrame, isHostedAreteEndpoint, isReplayErrorCode, isSafeClaimActionUrl, isSameProgramSdk, isSnapshotFrame, isStackVersionRefusalCode, isSubscribedFrame, isUnsubscribedFrame, isValidFrame, literal, managedAddress, managedContext, managedDiscovery, managedPage, managedReadOptions, managedU64, normalizeSubscription, normalizeSubscriptionQuery, normalizeSubscriptionRequest, normalizeTransactionError, parseApiProblem, parseFrame, parseFrameFromBlob, parseInstructionError, parseUiAmountToRaw, pda, prependFlowTransactionInstructions, prependTransactionInstructions, programAccountRead, programQuery, resolveAccounts, resolveAmount, resolveAmountToRaw, resolveAmountsToRaw, resolveTokenProgramAddress, resolveTransactionBuildOptions, safeToRawAmount, serializeInstructionData, serializeViewKey, setHostedWebsocketSuffixes, stackQuery, stringifyBigints, toJsonValue, toRawAmount, toWireResourceOptions, transactionOperation, unwrapOperationExecutionError, validateAccountResolution, validateProgramReadDescriptor, validateSubscriptionId, withProgramIdentity, withProgramRead, withPrograms };
|
|
8976
9622
|
//# sourceMappingURL=index.esm.js.map
|