hookr-sdk 0.2.1 → 1.0.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/LICENSE +21 -0
  3. package/MIGRATING.md +89 -0
  4. package/README.md +286 -105
  5. package/dist/core/abi.d.ts +10930 -0
  6. package/dist/core/abi.js +455 -0
  7. package/dist/core/advisories.d.ts +184 -0
  8. package/dist/core/advisories.js +291 -0
  9. package/dist/core/client.d.ts +55 -0
  10. package/dist/core/client.js +107 -0
  11. package/dist/core/generated.d.ts +14295 -0
  12. package/dist/core/generated.js +1058 -0
  13. package/dist/core/index.d.ts +17 -0
  14. package/dist/core/index.js +17 -0
  15. package/dist/core/launch.d.ts +200 -0
  16. package/dist/core/launch.js +427 -0
  17. package/dist/core/pair.d.ts +64 -0
  18. package/dist/core/pair.js +136 -0
  19. package/dist/core/params.d.ts +415 -0
  20. package/dist/core/params.js +1235 -0
  21. package/dist/core/policies.d.ts +136 -0
  22. package/dist/core/policies.js +125 -0
  23. package/dist/core/proofs.d.ts +25 -0
  24. package/dist/core/proofs.js +118 -0
  25. package/dist/core/quotes.d.ts +185 -0
  26. package/dist/core/quotes.js +550 -0
  27. package/dist/core/referrals.d.ts +32 -0
  28. package/dist/core/referrals.js +36 -0
  29. package/dist/core/registry.d.ts +357 -0
  30. package/dist/core/registry.js +378 -0
  31. package/dist/core/rules.d.ts +675 -0
  32. package/dist/core/rules.js +1049 -0
  33. package/dist/core/schema.d.ts +358 -0
  34. package/dist/core/schema.js +105 -0
  35. package/dist/core/stocks.generated.d.ts +11 -0
  36. package/dist/core/stocks.generated.js +1228 -0
  37. package/dist/core/vault.d.ts +59 -0
  38. package/dist/core/vault.js +112 -0
  39. package/dist/core/wallet.d.ts +142 -0
  40. package/dist/core/wallet.js +304 -0
  41. package/dist/deployments.d.ts +8 -0
  42. package/dist/deployments.js +26 -0
  43. package/dist/index.d.ts +6 -15
  44. package/dist/index.js +6 -15
  45. package/dist/releases.d.ts +172 -0
  46. package/dist/releases.js +268 -0
  47. package/package.json +46 -10
  48. package/provenance.json +31 -0
  49. package/dist/abi.d.ts +0 -6404
  50. package/dist/abi.js +0 -8300
  51. package/dist/chain.d.ts +0 -87
  52. package/dist/chain.js +0 -86
  53. package/dist/claims.d.ts +0 -32
  54. package/dist/claims.js +0 -31
  55. package/dist/fees.d.ts +0 -59
  56. package/dist/fees.js +0 -142
  57. package/dist/links.d.ts +0 -48
  58. package/dist/links.js +0 -93
  59. package/dist/market.d.ts +0 -264
  60. package/dist/market.js +0 -310
  61. package/dist/reads.d.ts +0 -136
  62. package/dist/reads.js +0 -219
  63. package/dist/rules.d.ts +0 -84
  64. package/dist/rules.js +0 -296
  65. package/dist/swap.d.ts +0 -108
  66. package/dist/swap.js +0 -144
@@ -0,0 +1,358 @@
1
+ export type Address = `0x${string}`;
2
+ export type Hash = `0x${string}`;
3
+ export type Raw = string;
4
+ export declare const ZERO: Address;
5
+ export declare const ZERO_HASH: Hash;
6
+ export declare function assert(ok: unknown, message: string): asserts ok;
7
+ export declare function address(value: unknown, zero?: boolean): Address;
8
+ export declare function hash(value: unknown): Hash;
9
+ export declare function uint(value: unknown, bits?: number): bigint;
10
+ export declare function canonical(value: unknown): string;
11
+ /** Every manifest source role. `root` and `rules` may repeat; every other role is a singleton. */
12
+ export declare const CONTRACT_ROLES: readonly ["poolManager", "registry", "root", "rules", "router", "quoter", "launcher", "treasury", "programs", "referrals", "commissions", "forwarder", "positionManager", "rootFactory", "feeAdvisory", "sessionAdvisory", "liquidityVault"];
13
+ export type ContractRole = (typeof CONTRACT_ROLES)[number];
14
+ export interface ContractPin {
15
+ role: ContractRole;
16
+ address: Address;
17
+ runtimeHash: Hash;
18
+ startBlock: Raw;
19
+ }
20
+ export interface DeploymentManifest {
21
+ schema: "hookr.engagement.sources.v1";
22
+ releaseId: string;
23
+ chainId: Raw;
24
+ startBlock: Raw;
25
+ parentHash: Hash;
26
+ contracts: ContractPin[];
27
+ tokens?: {
28
+ address: Address;
29
+ symbol: string;
30
+ decimals: number;
31
+ }[];
32
+ commissionAuthorities?: {
33
+ rules: Address;
34
+ feeSource: 0 | 1;
35
+ creators: Address[];
36
+ }[];
37
+ /**
38
+ * Reviewed smart-wallet runtime keccak hashes whose accounts may earn referral commission and cashback as payers.
39
+ * Any other contract payer, or EIP-7702 delegate, is excluded because a third party may be able to bind it.
40
+ */
41
+ payerCodeHashes?: Hash[];
42
+ qualification: {
43
+ status: "verified";
44
+ evidenceHash: Hash;
45
+ sourceCommit: string;
46
+ };
47
+ }
48
+ export declare function deployment(value: unknown): DeploymentManifest;
49
+ export interface Coverage {
50
+ schema: "hookr.coverage.v1";
51
+ chainId: Raw;
52
+ manifestHash: Hash;
53
+ fromBlock: Raw;
54
+ throughBlock: Raw | null;
55
+ throughHash: Hash | null;
56
+ throughTimestamp: Raw | null;
57
+ observedFinalizedBlock: Raw | null;
58
+ contiguous: boolean;
59
+ generation: number;
60
+ status: "empty" | "indexed" | "stale" | "error";
61
+ error: string | null;
62
+ sourceTrust: "configured-rpc-and-reviewed-code";
63
+ }
64
+ export interface Scope {
65
+ root: Address;
66
+ poolId: Hash;
67
+ configHash: Hash;
68
+ quoteAsset: Address;
69
+ numerator: Raw;
70
+ denominator: Raw;
71
+ subjectNumerator: Raw;
72
+ subjectDenominator: Raw;
73
+ }
74
+ export interface Terms {
75
+ mode: number;
76
+ globalBux: boolean;
77
+ start: Raw;
78
+ end: Raw;
79
+ pointBudget: Raw;
80
+ walletPointCap: Raw;
81
+ pointNumerator: Raw;
82
+ pointDenominator: Raw;
83
+ dailyPointBudget: Raw;
84
+ rewardToken: Address;
85
+ cashBudget: Raw;
86
+ walletCashCap: Raw;
87
+ cashNumerator: Raw;
88
+ cashDenominator: Raw;
89
+ dailyCashBudget: Raw;
90
+ attestor: Address;
91
+ reviewer: Address;
92
+ reviewDelay: Raw;
93
+ sourcePolicyHash: Hash;
94
+ name: string;
95
+ metadataURI: string;
96
+ pointDecimals: number;
97
+ referralRegistry: Address;
98
+ baseProgramId: Raw;
99
+ }
100
+ export interface Program {
101
+ id: Raw;
102
+ address: Address;
103
+ creator: Address;
104
+ termsHash: Hash;
105
+ terms: Terms;
106
+ scopes: Scope[];
107
+ }
108
+ export interface Award {
109
+ beneficiary: Address;
110
+ weight: Raw;
111
+ points: Raw;
112
+ cash: Raw;
113
+ proof: Hash[];
114
+ }
115
+ export interface DayAllocation {
116
+ schema: "hookr.day-allocation.v1";
117
+ status: "draft" | "reviewed";
118
+ chainId: Raw;
119
+ distributor: Address;
120
+ programId: Raw;
121
+ termsHash: Hash;
122
+ day: Raw;
123
+ epochStart: Raw;
124
+ epochEnd: Raw;
125
+ sourcePolicyHash: Hash;
126
+ coverageHash: Hash;
127
+ evidenceHash: Hash;
128
+ root: Hash;
129
+ totalWeight: Raw;
130
+ generation: number;
131
+ awards: Award[];
132
+ rounding: {
133
+ pointUnallocated: Raw;
134
+ cashUnallocated: Raw;
135
+ };
136
+ review?: {
137
+ reviewer: Address;
138
+ reviewedAt: string;
139
+ artifactHash: Hash;
140
+ signature: Hash;
141
+ };
142
+ }
143
+ export interface Call {
144
+ chainId: number;
145
+ to: Address;
146
+ data: Hash;
147
+ value: bigint;
148
+ }
149
+ /** Cursor for list routes. `next` is null only when the list is complete. */
150
+ export interface ApiPage {
151
+ limit: number;
152
+ next: string | null;
153
+ scanned: number;
154
+ }
155
+ export interface ApiEnvelope<T> {
156
+ schema: "hookr.api.v1";
157
+ releaseId: string;
158
+ coverage: Coverage;
159
+ data: T;
160
+ page?: ApiPage;
161
+ }
162
+ /** A listed program or campaign carries the service's qualification verdict and its reasons. */
163
+ export interface Qualification {
164
+ qualified: boolean;
165
+ unqualifiedReasons: string[];
166
+ }
167
+ export type ProgramListing = (Program & {
168
+ buxApproved: boolean;
169
+ } & Qualification) | ({
170
+ id: Raw;
171
+ } & Qualification);
172
+ /**
173
+ * A buy of a family member pool that its creator made at launch. `devBuy` is the launchWithBuy dev buy
174
+ * (DevBuyExecuted), the only buy the Launcher's 5% cap binds. `sameTransaction` is any other buy of a member pool
175
+ * inside the FamilyLaunched transaction that a family owner paid (`payer`, the HookrRouter SwapExecuted paired with
176
+ * the Swap), sent (`sender`, the PoolManager Swap sender) or originated (`origin`, the transaction sender). Values
177
+ * the logs do not carry are null: a direct PoolManager buy has no `quoteIn` or `subjectOut`, only its Swap's raw
178
+ * pool-side amounts.
179
+ */
180
+ export interface CreatorBuyView {
181
+ kind: "devBuy" | "sameTransaction";
182
+ member: number;
183
+ poolId: Hash;
184
+ tx: Hash;
185
+ block: Raw;
186
+ logIndex: number;
187
+ matchedBy: ("devBuy" | "payer" | "sender" | "origin")[];
188
+ buyer: Address;
189
+ payer: Address | null;
190
+ recipient: Address | null;
191
+ sender: Address | null;
192
+ origin: Address | null;
193
+ quoteIn: Raw | null;
194
+ subjectOut: Raw | null;
195
+ swap: {
196
+ amount0: Raw;
197
+ amount1: Raw;
198
+ } | null;
199
+ sqrtPriceX96: Raw | null;
200
+ sqrtPriceAfterX96: Raw | null;
201
+ lockedUntil: Raw | null;
202
+ /** The buy's member quote, as the family's `members[].quoteAsset`. */
203
+ quoteAsset: QuoteAssetView | null;
204
+ /**
205
+ * The USD value of `quoteIn` at the buy's block, an 18-place decimal string, when the index proves the rate (USDG is
206
+ * one dollar; any other quote through tracked Hookr pools against USDG, or against ETH and then ETH/USDG); else null.
207
+ */
208
+ quoteInUsd: string | null;
209
+ }
210
+ /**
211
+ * A family member's quote as the service reports it: symbol, decimals and class from reviewed sources only (native
212
+ * ETH, the manifest's tokens, the SDK catalog, the stock scan). `decimals` is null when none names it: raw amounts
213
+ * in that quote cannot be formatted.
214
+ */
215
+ export interface QuoteAssetView {
216
+ address: Address;
217
+ symbol: string | null;
218
+ decimals: number | null;
219
+ class: "native" | "weth" | "stable" | "hookr" | "listed" | "rwa" | "erc20";
220
+ source: "native" | "manifest" | "catalog" | "stock-scan" | "unknown";
221
+ }
222
+ export interface FamilyView {
223
+ id: Hash;
224
+ launcher: Address;
225
+ owner: Address;
226
+ creator: Address;
227
+ subject: Address;
228
+ root: Address;
229
+ launchedAt: Raw;
230
+ launchBlock: Raw;
231
+ launchTx: Hash;
232
+ members: {
233
+ member: number;
234
+ poolId: Hash;
235
+ quote: Address;
236
+ liquidity: Raw;
237
+ quoteAsset: QuoteAssetView;
238
+ }[];
239
+ /** Null when the index holds no PoolManager logs for the family's pools; `creatorBuysUnavailable` says why. */
240
+ creatorBuys: CreatorBuyView[] | null;
241
+ /**
242
+ * Why `creatorBuys` is null, else null. `root-not-pinned`: the family's root is not a manifest root pin covering its
243
+ * launch block (a root the registry admitted after the manifest was reviewed). `pool-not-tracked`: a member pool's
244
+ * Initialize was not indexed. Either way the launch transaction's Swaps were never stored.
245
+ */
246
+ creatorBuysUnavailable: "root-not-pinned" | "pool-not-tracked" | null;
247
+ }
248
+ export interface AccountProgramView {
249
+ id: Raw;
250
+ issuer: Address;
251
+ globalBux: boolean;
252
+ name: string;
253
+ pointDecimals: number;
254
+ points: Raw;
255
+ cashAllocated: Raw;
256
+ cashClaimable: Raw;
257
+ rewardToken: Address;
258
+ /** False when a scope names an unpinned root, display text exceeds service bounds or the policy is unknown. */
259
+ qualified?: boolean;
260
+ days: {
261
+ day: Raw;
262
+ status: string;
263
+ reviewStatus: "draft" | "reviewed";
264
+ weight: Raw;
265
+ nominalPoints: Raw;
266
+ nominalCash: Raw;
267
+ payer: Address;
268
+ proof: Hash[];
269
+ coverageHash: Hash;
270
+ root: Hash;
271
+ award: Record<string, unknown>;
272
+ }[];
273
+ nfts: {
274
+ milestone: Raw;
275
+ tokenId: Raw;
276
+ delivered: boolean;
277
+ }[];
278
+ }
279
+ export interface CommissionDayView {
280
+ day: Raw;
281
+ status: string;
282
+ reviewStatus: "draft" | "reviewed";
283
+ eligibleFees: Raw;
284
+ commission: Raw;
285
+ cashback: Raw;
286
+ payer: Address;
287
+ referrer: Address;
288
+ firstActivityBlock: Raw;
289
+ proof: Hash[];
290
+ coverageHash: Hash;
291
+ collectionsHash: Hash;
292
+ root: Hash;
293
+ }
294
+ export interface AccountView {
295
+ address: Address;
296
+ coverage: Coverage;
297
+ /** Only programs this account has indexed activity or an allocation award in. */
298
+ programs: AccountProgramView[];
299
+ /** Programs this account took part in whose definition the service does not serve, with the reason. */
300
+ unavailablePrograms?: {
301
+ id: Raw;
302
+ reason: string;
303
+ }[];
304
+ /** Lists cut to the most recent entries ("programs", "campaigns", "bindings"); totals stay complete. */
305
+ truncated?: string[];
306
+ referrals: {
307
+ bindings: Record<string, unknown>[];
308
+ bindingCount?: number;
309
+ campaigns: {
310
+ id: Raw;
311
+ distributor: Address;
312
+ programKey: Hash;
313
+ currency: Address;
314
+ qualified?: boolean;
315
+ commissionEarned: Raw;
316
+ cashbackEarned: Raw;
317
+ days: CommissionDayView[];
318
+ }[];
319
+ unavailableCampaigns?: {
320
+ id: Raw;
321
+ reason: string;
322
+ }[];
323
+ claimables: {
324
+ distributor: Address;
325
+ currency: Address;
326
+ allocated: Raw;
327
+ paid: Raw;
328
+ claimable: Raw;
329
+ }[];
330
+ };
331
+ }
332
+ export type ClaimAction = {
333
+ type: "claimDay" | "claimReferralDay";
334
+ programId: Raw;
335
+ day: Raw;
336
+ beneficiary: Address | null;
337
+ payer: Address | null;
338
+ referrer: Address | null;
339
+ firstActivityBlock: Raw | null;
340
+ weight: Raw;
341
+ proof: Hash[];
342
+ } | {
343
+ type: "creditDay";
344
+ campaignId: Raw;
345
+ day: Raw;
346
+ payer: Address;
347
+ referrer: Address;
348
+ firstActivityBlock: Raw;
349
+ eligibleFees: Raw;
350
+ proof: Hash[];
351
+ };
352
+ export interface ProofView {
353
+ allocation: Record<string, unknown>;
354
+ award: Record<string, unknown>;
355
+ onchainStatus: string;
356
+ localReview: boolean;
357
+ action: ClaimAction | null;
358
+ }
@@ -0,0 +1,105 @@
1
+ export const ZERO = "0x0000000000000000000000000000000000000000";
2
+ export const ZERO_HASH = `0x${"0".repeat(64)}`;
3
+ export function assert(ok, message) {
4
+ if (!ok)
5
+ throw new Error(message);
6
+ }
7
+ export function address(value, zero = false) {
8
+ assert(typeof value === "string" && /^0x[\da-fA-F]{40}$/.test(value), "Invalid address");
9
+ assert(zero || value.toLowerCase() !== ZERO, "Zero address");
10
+ return value.toLowerCase();
11
+ }
12
+ export function hash(value) {
13
+ assert(typeof value === "string" && /^0x[\da-fA-F]{64}$/.test(value), "Invalid hash");
14
+ return value.toLowerCase();
15
+ }
16
+ export function uint(value, bits = 256) {
17
+ assert((typeof value === "string" && /^(0|[1-9]\d*)$/.test(value)) || typeof value === "bigint", "Expected raw integer string");
18
+ const n = BigInt(value);
19
+ assert(n >= 0n && n < 1n << BigInt(bits), "Integer overflow");
20
+ return n;
21
+ }
22
+ export function canonical(value) {
23
+ if (typeof value === "bigint")
24
+ return JSON.stringify(value.toString());
25
+ if (value === null || typeof value !== "object") {
26
+ const result = JSON.stringify(value);
27
+ assert(result !== undefined, "Undefined is not canonical");
28
+ return result;
29
+ }
30
+ if (Array.isArray(value))
31
+ return `[${value.map(canonical).join(",")}]`;
32
+ return `{${Object.keys(value)
33
+ .sort()
34
+ .map((k) => `${JSON.stringify(k)}:${canonical(value[k])}`)
35
+ .join(",")}}`;
36
+ }
37
+ /** Every manifest source role. `root` and `rules` may repeat; every other role is a singleton. */
38
+ export const CONTRACT_ROLES = [
39
+ "poolManager",
40
+ "registry",
41
+ "root",
42
+ "rules",
43
+ "router",
44
+ "quoter",
45
+ "launcher",
46
+ "treasury",
47
+ "programs",
48
+ "referrals",
49
+ "commissions",
50
+ "forwarder",
51
+ "positionManager",
52
+ "rootFactory",
53
+ "feeAdvisory",
54
+ "sessionAdvisory",
55
+ "liquidityVault",
56
+ ];
57
+ export function deployment(value) {
58
+ const m = value;
59
+ assert(m?.schema === "hookr.engagement.sources.v1", "Unknown manifest schema");
60
+ uint(m.chainId);
61
+ assert(uint(m.chainId) > 0n && uint(m.startBlock) > 0n, "Invalid chain/start block");
62
+ hash(m.parentHash);
63
+ assert(uint(m.startBlock) <= BigInt(Number.MAX_SAFE_INTEGER), "Block height overflow");
64
+ assert(typeof m.releaseId === "string" && /^[a-z0-9-]{1,80}$/.test(m.releaseId), "Invalid releaseId");
65
+ assert(m.qualification?.status === "verified" && /^[\da-f]{40}$/.test(m.qualification.sourceCommit), "Unqualified release");
66
+ hash(m.qualification.evidenceHash);
67
+ assert(Array.isArray(m.contracts) && m.contracts.length > 0 && m.contracts.length <= 64, "Invalid sources");
68
+ const seen = new Set();
69
+ for (const role of CONTRACT_ROLES.filter((r) => r !== "root" && r !== "rules"))
70
+ assert(m.contracts.filter((c) => c.role === role).length <= 1, `Duplicate singleton ${role}`);
71
+ for (const token of m.tokens ?? []) {
72
+ address(token.address, true);
73
+ assert(typeof token.symbol === "string" &&
74
+ token.symbol.length <= 32 &&
75
+ Number.isInteger(token.decimals) &&
76
+ token.decimals >= 0 &&
77
+ token.decimals <= 255, "Invalid token metadata");
78
+ }
79
+ for (const c of m.contracts) {
80
+ assert(CONTRACT_ROLES.includes(c.role), "Unknown source role");
81
+ assert(c.address === address(c.address), "Manifest source addresses must be lowercase");
82
+ hash(c.runtimeHash);
83
+ assert(c.runtimeHash !== ZERO_HASH, "Missing runtime hash");
84
+ assert(uint(c.startBlock) >= uint(m.startBlock) && uint(c.startBlock) <= BigInt(Number.MAX_SAFE_INTEGER), "Source coverage height invalid");
85
+ assert(!seen.has(c.address), "Duplicate source");
86
+ seen.add(c.address);
87
+ }
88
+ for (const rule of m.commissionAuthorities ?? []) {
89
+ address(rule.rules);
90
+ assert(rule.feeSource === 0 || rule.feeSource === 1, "Invalid fee authority source");
91
+ assert(m.contracts.some((c) => c.role === "rules" && c.address === rule.rules.toLowerCase()), "Unpinned fee authority");
92
+ assert(Array.isArray(rule.creators) && rule.creators.length > 0 && rule.creators.length <= 32, "Invalid fee authority creators");
93
+ rule.creators.forEach((c) => address(c));
94
+ }
95
+ if (m.payerCodeHashes !== undefined) {
96
+ assert(Array.isArray(m.payerCodeHashes) && m.payerCodeHashes.length <= 32, "Invalid payer code allow-list");
97
+ for (const h of m.payerCodeHashes) {
98
+ hash(h);
99
+ assert(h === h.toLowerCase() && h !== ZERO_HASH, "Invalid payer code hash");
100
+ }
101
+ }
102
+ for (const role of ["poolManager", "root", "router", "launcher", "programs"])
103
+ assert(m.contracts.some((c) => c.role === role), `Missing ${role}`);
104
+ return m;
105
+ }
@@ -0,0 +1,11 @@
1
+ import type { Address } from "./schema.js";
2
+ /** One Robinhood stock token: its address, onchain symbol and name, and the block its proxy was created in. */
3
+ export interface StockToken {
4
+ address: Address;
5
+ symbol: string;
6
+ name: string;
7
+ createdBlock: number;
8
+ }
9
+ /** The last block the stock scan read. A proxy created after it is still classified by its beacon slot. */
10
+ export declare const ROBINHOOD_STOCK_SCAN_BLOCK = 73819564;
11
+ export declare const ROBINHOOD_STOCK_TOKENS: readonly StockToken[];