@beeperbot/sdk 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @beeper/sdk
1
+ # @beeperbot/sdk
2
2
 
3
3
  TypeScript SDK for [beep.works](https://beep.works) — the attention layer on Base.
4
4
 
@@ -7,7 +7,7 @@ Send paid messages (beeps) to Farcaster users. Look up users, check prices, run
7
7
  ## Install
8
8
 
9
9
  ```bash
10
- npm install @beeper/sdk
10
+ npm install @beeperbot/sdk
11
11
  ```
12
12
 
13
13
  ## Quick Start — AI Agent
@@ -15,7 +15,7 @@ npm install @beeper/sdk
15
15
  The `AgentClient` is the simplest way to integrate beeps into your AI agent or bot.
16
16
 
17
17
  ```typescript
18
- import { AgentClient } from '@beeper/sdk';
18
+ import { AgentClient } from '@beeperbot/sdk';
19
19
 
20
20
  const agent = new AgentClient({
21
21
  apiKey: process.env.BEEPER_API_KEY!, // bpk_live_...
@@ -247,7 +247,7 @@ Use filters with `estimate`, `preview`, and `createBulkIntent`.
247
247
  For the full deposit → execute → receipt flow:
248
248
 
249
249
  ```typescript
250
- import { BeeperClient } from '@beeper/sdk';
250
+ import { BeeperClient } from '@beeperbot/sdk';
251
251
 
252
252
  const client = new BeeperClient({
253
253
  apiKey: process.env.BEEPER_API_KEY!,
@@ -282,7 +282,7 @@ const receipt = await client.pollUntilCompleteByQuoteId(quote.id);
282
282
  ## Error Handling
283
283
 
284
284
  ```typescript
285
- import { BeeperError, ErrorCodes } from '@beeper/sdk';
285
+ import { BeeperError, ErrorCodes } from '@beeperbot/sdk';
286
286
 
287
287
  try {
288
288
  await agent.lookup('nonexistent');
package/dist/index.cjs CHANGED
@@ -908,8 +908,16 @@ var ENDPOINTS = {
908
908
  PREVIEW: "/agent/preview",
909
909
  BULK_INTENT: "/agent/bulk-intent"
910
910
  };
911
- var AgentClient = class {
911
+ var AgentClient = class _AgentClient {
912
912
  http;
913
+ static CHAIN_ID_MAP = {
914
+ base: 8453,
915
+ ethereum: 1,
916
+ mainnet: 1,
917
+ arbitrum: 42161,
918
+ polygon: 137,
919
+ optimism: 10
920
+ };
913
921
  constructor(config) {
914
922
  if (!config.apiKey) {
915
923
  throw BeeperError.validation("API key is required");
@@ -924,6 +932,62 @@ var AgentClient = class {
924
932
  });
925
933
  this.http = new HttpClient(httpConfig);
926
934
  }
935
+ /**
936
+ * Normalize filters for agent endpoints (accepts flexible shapes from other builders)
937
+ */
938
+ normalizeFilters(filters) {
939
+ const normalized = { ...filters };
940
+ const stripEmptyArray = (key) => {
941
+ const val = normalized[key];
942
+ if (Array.isArray(val) && val.length === 0) {
943
+ delete normalized[key];
944
+ }
945
+ };
946
+ const stripZero = (key) => {
947
+ const val = normalized[key];
948
+ if (typeof val === "number" && val === 0) {
949
+ delete normalized[key];
950
+ }
951
+ };
952
+ if (normalized.platform === "all") delete normalized.platform;
953
+ if (normalized.spamLabel === "all") delete normalized.spamLabel;
954
+ stripZero("minFollowers");
955
+ stripZero("maxFollowers");
956
+ stripZero("activeInLastDays");
957
+ stripZero("minBatteryPercentage");
958
+ stripZero("hasRechargedInLastDays");
959
+ stripZero("maxAttentionPriceUsd");
960
+ if (normalized.neynarScoreMin === 0) delete normalized.neynarScoreMin;
961
+ if (normalized.neynarScoreMax === 1) delete normalized.neynarScoreMax;
962
+ if (normalized.quotientScoreMin === 0) delete normalized.quotientScoreMin;
963
+ if (normalized.quotientScoreMax === 1) delete normalized.quotientScoreMax;
964
+ if (Array.isArray(normalized.countries)) {
965
+ normalized.countries = normalized.countries.map((c) => typeof c === "string" ? c : c?.code).filter((c) => typeof c === "string" && c.trim().length > 0).map((c) => c.trim().toUpperCase());
966
+ }
967
+ stripEmptyArray("countries");
968
+ if (Array.isArray(normalized.tokenHolders)) {
969
+ normalized.tokenHolders = normalized.tokenHolders.map((holder) => {
970
+ if (!holder) return null;
971
+ if ("tokenAddress" in holder && "chainId" in holder) return holder;
972
+ const contractAddress = holder.contractAddress;
973
+ const chain = holder.chain;
974
+ const minBalance = holder.minBalance;
975
+ if (!contractAddress || chain == null) return null;
976
+ const chainId = typeof chain === "number" ? chain : _AgentClient.CHAIN_ID_MAP[String(chain).toLowerCase()] ?? Number(chain);
977
+ if (!Number.isFinite(chainId)) return null;
978
+ return {
979
+ tokenAddress: contractAddress,
980
+ chainId,
981
+ ...minBalance ? { minBalance } : {}
982
+ };
983
+ }).filter((holder) => !!holder);
984
+ }
985
+ stripEmptyArray("tokenHolders");
986
+ stripEmptyArray("signalTokens");
987
+ stripEmptyArray("fids");
988
+ stripEmptyArray("userIds");
989
+ return normalized;
990
+ }
927
991
  /**
928
992
  * Look up a user by username, FID, or wallet address
929
993
  *
@@ -1054,7 +1118,7 @@ var AgentClient = class {
1054
1118
  const response = await this.http.post(
1055
1119
  ENDPOINTS.ESTIMATE,
1056
1120
  {
1057
- filters: input.filters,
1121
+ filters: this.normalizeFilters(input.filters),
1058
1122
  budgetUsd: budgetStr,
1059
1123
  message: input.message
1060
1124
  }
@@ -1084,7 +1148,7 @@ var AgentClient = class {
1084
1148
  const response = await this.http.post(
1085
1149
  ENDPOINTS.PREVIEW,
1086
1150
  {
1087
- filters: input.filters,
1151
+ filters: this.normalizeFilters(input.filters),
1088
1152
  limit
1089
1153
  }
1090
1154
  );
@@ -1116,7 +1180,7 @@ var AgentClient = class {
1116
1180
  const response = await this.http.post(
1117
1181
  ENDPOINTS.BULK_INTENT,
1118
1182
  {
1119
- filters: input.filters,
1183
+ filters: this.normalizeFilters(input.filters),
1120
1184
  budgetUsd: budgetStr,
1121
1185
  message: input.message,
1122
1186
  chainId: input.chainId ?? 8453
@@ -1198,6 +1262,7 @@ function maskApiKey(apiKey) {
1198
1262
  }
1199
1263
 
1200
1264
  // src/client/BeeperClient.ts
1265
+ var ALLOWED_REWARD_TYPES = ["guaranteed", "lottery", "fcfs"];
1201
1266
  var QuoteSchema = zod.z.object({
1202
1267
  id: zod.z.string(),
1203
1268
  status: zod.z.enum([
@@ -1404,6 +1469,16 @@ var BeeperClient = class {
1404
1469
  if (input.message.length > 1e3) {
1405
1470
  throw BeeperError.validation("Message must be 1000 characters or less");
1406
1471
  }
1472
+ if (input.rewardType !== void 0) {
1473
+ if (input.rewardType.trim().length === 0) {
1474
+ throw BeeperError.validation("rewardType must be a non-empty string");
1475
+ }
1476
+ if (!ALLOWED_REWARD_TYPES.includes(input.rewardType)) {
1477
+ throw BeeperError.validation(
1478
+ `rewardType must be one of: ${ALLOWED_REWARD_TYPES.join(", ")}`
1479
+ );
1480
+ }
1481
+ }
1407
1482
  if (!input.recipientFids?.length && !input.filter) {
1408
1483
  throw BeeperError.validation("Must provide either recipientFids or filter");
1409
1484
  }
@@ -1422,6 +1497,7 @@ var BeeperClient = class {
1422
1497
  filter: input.filter,
1423
1498
  budgetUSD: input.budgetUSD,
1424
1499
  rewardType: input.rewardType ?? "guaranteed",
1500
+ mode: "attention_marketplace",
1425
1501
  memo: input.memo,
1426
1502
  metadata: input.metadata,
1427
1503
  ttlSeconds: opts?.ttlSeconds ?? 300
@@ -2785,11 +2861,10 @@ var FilterBuilder = class _FilterBuilder {
2785
2861
  throw new Error("minBalance must be a numeric string (wei)");
2786
2862
  }
2787
2863
  }
2788
- const chainNames = { 1: "ethereum", 8453: "base", 42161: "arbitrum", 10: "optimism", 137: "polygon" };
2789
2864
  return new FilterExpression({
2790
2865
  cachedTokenHolders: opts.map((o) => ({
2791
2866
  contractAddress: o.tokenAddress,
2792
- chain: chainNames[o.chainId] ?? String(o.chainId),
2867
+ chain: o.chainId === 8453 ? "base" : "ethereum",
2793
2868
  tokenStandard: o.tokenStandard ?? "ERC20",
2794
2869
  ...o.minBalance !== void 0 ? { minBalance: o.minBalance } : {},
2795
2870
  ...o.tokenId !== void 0 ? { tokenId: o.tokenId } : {}