@molpha/sdk 0.1.0 → 0.2.0-dev-20260911113923

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/dist/index.d.ts CHANGED
@@ -1,13 +1,70 @@
1
1
  import { Address } from '@solana/kit';
2
2
  import { Wallet, Idl, AnchorProvider } from '@anchor-lang/core';
3
- import { R as RegistrySelectionConfig, S as Signer, N as NodeKeyVerifier, a as Node, A as APIConfig, D as DataUpdateResult, b as SolanaConnection, c as SolanaAddress, d as NodeKeyVerifierArgs, e as SolanaAccountMeta, M as MolphaWallet } from './wallet-CbpYQO4l.js';
4
- export { E as EncKeyBundle, f as SchnorrSignature, g as gatewaySignerFromWallet, s as signerFromKeypair } from './wallet-CbpYQO4l.js';
3
+ import { R as RegistrySelectionConfig, S as Signer, N as NodeKeyVerifier, a as Node, A as APIConfig, D as DataUpdateResult, b as SolanaAccountMeta, c as SolanaConnection, d as SolanaAddress, e as NodeKeyVerifierArgs, M as MolphaWallet } from './wallet-udLZ5Iy0.js';
4
+ export { E as EncKeyBundle, f as SchnorrSignature, g as gatewaySignerFromWallet, s as signerFromKeypair } from './wallet-udLZ5Iy0.js';
5
5
  import BN from 'bn.js';
6
6
 
7
- interface RequestSignedDataOptions {
8
- feedId: string;
7
+ /**
8
+ * Gateway on-chain identity. The request-auth hash binds the Gateway PDA
9
+ * (`["molpha_gateway", gatewayAuthority]`), so the client must know which gateway it is
10
+ * talking to. Kit-only — no `@anchor-lang/core` / web3.js on the gateway path.
11
+ */
12
+
13
+ /** One gateway endpoint plus, optionally, the authority key its `Gateway` PDA derives from. */
14
+ interface GatewayEndpoint {
15
+ /** Base URL, e.g. `https://gateway.example.com` (trailing slash ignored). */
16
+ url: string;
17
+ /**
18
+ * Base58 Solana pubkey of the gateway's signing authority. When omitted the client
19
+ * fetches it once from `GET {url}/v1/info` (`data.gatewayAuthority`) the first time an
20
+ * authenticated request targets this endpoint.
21
+ */
22
+ gatewayAuthority?: string;
23
+ }
24
+ type GatewayEndpointInput = string | GatewayEndpoint;
25
+ /** Payload of `GET /v1/info` (inside the usual `{ status, data }` envelope). */
26
+ interface GatewayInfo {
27
+ gatewayAuthority: string;
28
+ /** Program id the gateway settles against; must match the client's when present. */
29
+ programId?: string;
30
+ }
31
+ declare function normalizeEndpoint(input: GatewayEndpointInput): GatewayEndpoint;
32
+ /** 32-byte form of a base58 address. */
33
+ declare function addressToBytes(value: string): Uint8Array;
34
+ /** `["molpha_gateway", gatewayAuthority]` under `programId`, as a base58 address. */
35
+ declare function deriveGatewayPdaAddress(gatewayAuthority: string, programId: string): Promise<Address>;
36
+ /** 32-byte Gateway PDA — the `gateway` field of `RequestAuth`. */
37
+ declare function deriveGatewayPda(gatewayAuthority: string, programId: string): Promise<Uint8Array>;
38
+ /** Validate an unwrapped `/v1/info` payload. */
39
+ declare function parseGatewayInfo(data: unknown): GatewayInfo;
40
+
41
+ declare const REQUEST_AUTH_DOMAIN: Uint8Array;
42
+ interface RequestAuthFields {
43
+ /** Program id, 32 bytes (see `addressToBytes` for base58). */
44
+ programId: Uint8Array;
45
+ /** Gateway PDA `["molpha_gateway", gatewayAuthority]`, 32 bytes (see `deriveGatewayPda`). */
46
+ gateway: Uint8Array;
47
+ /** 32-byte source id, hex or bytes. */
48
+ sourceId: Uint8Array | string;
49
+ /** u8 — the per-request quorum. */
9
50
  signaturesRequired: number;
51
+ /** u64 unix seconds. */
52
+ timestamp: number | bigint;
53
+ }
54
+ /** Borsh encoding of `RequestAuth` — the hash body, without the domain. */
55
+ declare function encodeRequestAuth(fields: RequestAuthFields): Uint8Array;
56
+ /** `keccak256(REQUEST_AUTH_DOMAIN || encodeRequestAuth(fields))` — the message the consumer signs. */
57
+ declare function hashRequestAuth(fields: RequestAuthFields): Uint8Array;
58
+
59
+ interface RequestSignedDataOptions {
60
+ /**
61
+ * The API definition to resolve. Its canonical form determines the round's
62
+ * `sourceId = keccak256(JSON.stringify(canonicalizeAPIConfig(apiConfig)))`, so pass the
63
+ * same config (including `{{secret.*}}` placeholders) every time.
64
+ */
10
65
  apiConfig: APIConfig;
66
+ /** Requested quorum (u8, ≥ the protocol `min_signers`). */
67
+ signaturesRequired: number;
11
68
  /**
12
69
  * Solana pubkey (base58) of the subscription owner.
13
70
  * Overrides the gateway's `defaultSubscriptionOwner` when set.
@@ -19,9 +76,10 @@ interface RequestSignedDataOptions {
19
76
  */
20
77
  consumerAuthority?: string;
21
78
  /**
22
- * Signs `authMessage(feedId, timestamp)`. Overrides the gateway's
23
- * `defaultSigner` when set. When both are omitted, sends all-zero authSig
24
- * (dev only).
79
+ * Signs `hashRequestAuth({ programId, gateway, sourceId, signaturesRequired, timestamp })`.
80
+ * The hash binds the gateway's on-chain account, so it is computed — and the signer
81
+ * invoked — once per endpoint actually tried. Overrides the gateway's `defaultSigner`
82
+ * when set. When both are omitted, sends an all-zero authSig (dev only).
25
83
  */
26
84
  signer?: Signer;
27
85
  encrypt?: {
@@ -40,8 +98,8 @@ interface RequestSignedDataOptions {
40
98
  * {@link MolphaGateway.prepareContext}.
41
99
  *
42
100
  * Caching is opt-in because these inputs can drift: a stale `registryVersion`,
43
- * `redundancyBuffer`, or `nodes` set produces a result the chain will reject.
44
- * Refresh the context when the on-chain registry version changes.
101
+ * `redundancyBuffer`, `nodeCount`, or `nodes` set produces a result the chain will
102
+ * reject. Refresh the context when the on-chain registry version changes.
45
103
  */
46
104
  context?: Partial<RoundContext>;
47
105
  /**
@@ -61,6 +119,11 @@ interface MolphaGatewayOptions {
61
119
  defaultSubscriptionOwner?: string;
62
120
  /** Solana pubkey (base58) of the consumer authority used when a request omits it. */
63
121
  defaultConsumerAuthority?: string;
122
+ /**
123
+ * Molpha program id the request authorization is bound to. Defaults to the vendored
124
+ * `MOLPHA_PROGRAM_ID`; must match the gateway's deployment.
125
+ */
126
+ programId?: string;
64
127
  /**
65
128
  * Authenticates selected gateway node encryption keys before private API
66
129
  * secrets are encrypted.
@@ -74,10 +137,10 @@ interface MolphaGatewayOptions {
74
137
  }
75
138
  /**
76
139
  * The slow-changing inputs a `requestSignedData` round binds to. Fetch once with
77
- * {@link MolphaGateway.prepareContext} and reuse across many rounds
140
+ * {@link MolphaGateway.prepareContext} and reuse across many rounds.
78
141
  */
79
142
  interface RoundContext extends RegistrySelectionConfig {
80
- /** Full node set used to derive the selection bitmap. */
143
+ /** Full node set used to encrypt private API secrets for the selected nodes. */
81
144
  nodes: Node[];
82
145
  }
83
146
  /** Default gateway base URL when `endpoints` is omitted. */
@@ -95,7 +158,12 @@ declare class MolphaGateway {
95
158
  private readonly defaultConsumerAuthority?;
96
159
  private readonly verifyNodeKeys?;
97
160
  private readonly allowUnverifiedNodeKeysForPrivateApi;
98
- constructor(endpoints?: string | string[], getRegistrySelectionConfig?: () => Promise<RegistrySelectionConfig>, defaultSigner?: Signer,
161
+ /** Program id the request authorization is bound to (base58). */
162
+ readonly programId: string;
163
+ private readonly programIdBytes;
164
+ /** Gateway PDA per endpoint URL; resolved once per client lifetime. */
165
+ private readonly gatewayPdas;
166
+ constructor(endpoints?: GatewayEndpointInput | GatewayEndpointInput[], getRegistrySelectionConfig?: () => Promise<RegistrySelectionConfig>, defaultSigner?: Signer,
99
167
  /**
100
168
  * Either a default subscription owner (base58) or gateway options. A string
101
169
  * keeps the previous positional form used by standalone callers/tests.
@@ -104,40 +172,90 @@ declare class MolphaGateway {
104
172
  /** Tries endpoints in order; returns the first node list it can fetch. */
105
173
  getNodes(): Promise<Node[]>;
106
174
  isHealthy(): Promise<boolean>;
175
+ /**
176
+ * `GET {url}/v1/info` — the gateway's on-chain identity. Throws when the gateway
177
+ * reports a `programId` different from this client's.
178
+ */
179
+ fetchGatewayInfo(endpoint: GatewayEndpointInput, timeoutMs?: number): Promise<GatewayInfo>;
107
180
  /**
108
181
  * Fetch the slow-changing round inputs (registry version, redundancy buffer,
109
- * node set) once so they can be reused across many {@link requestSignedData}
110
- * calls. Pass the result back via `requestSignedData({ ..., context })` to
111
- * skip the prelude and run a single-round "short" flow.
182
+ * node count, node set) once so they can be reused across many
183
+ * {@link requestSignedData} calls. Pass the result back via
184
+ * `requestSignedData({ ..., context })` to skip the prelude and run a
185
+ * single-round "short" flow.
112
186
  *
113
- * Both fetches run in parallel. Registry version and redundancy buffer come
114
- * from a single on-chain `RegistryState` read.
187
+ * Both fetches run in parallel. Registry version, redundancy buffer and node
188
+ * count come from the on-chain registry read.
115
189
  */
116
- prepareContext(_feedId: string): Promise<RoundContext>;
190
+ prepareContext(): Promise<RoundContext>;
117
191
  /**
118
192
  * Request a threshold-signed data update from the gateway, with retry +
119
193
  * failover. Per attempt a fresh timestamp yields a fresh selection bitmap; the
120
194
  * body is POSTed to each endpoint in order until one `completed`s.
121
195
  *
122
- * By default this fetches the registry selection config and node set up front
123
- * (in parallel). Supply `opts.context` (e.g. from {@link prepareContext}) to
124
- * reuse cached inputs and skip those fetches — a fully-populated context
125
- * collapses the call to a single POST round.
196
+ * The round's `sourceId` is derived from `apiConfig`. The request authorization
197
+ * binds the program id and each gateway's on-chain account, so the auth signature
198
+ * is recomputed for every endpoint tried.
199
+ *
200
+ * By default this fetches the registry selection config up front and the node
201
+ * set only when the round needs it (private API encryption, or when the registry
202
+ * read does not report `nodeCount`). Supply `opts.context` (e.g. from
203
+ * {@link prepareContext}) to reuse cached inputs and skip those fetches — a
204
+ * fully-populated context collapses the call to a single POST round.
126
205
  */
127
206
  requestSignedData(opts: RequestSignedDataOptions): Promise<DataUpdateResult>;
128
207
  /**
129
208
  * Resolve the round inputs, fetching only the fields absent from `cached`.
130
- * Registry version and redundancy buffer are treated as a unit (one account
131
- * read). Whatever fetching remains runs in parallel.
209
+ * Registry version, redundancy buffer and node count are treated as a unit (one
210
+ * snapshot read). The node list is fetched only when `needNodes` (private API
211
+ * encryption) or when nothing else can tell us the node count.
132
212
  */
133
213
  private resolveContext;
214
+ /** Gateway PDA bytes for an endpoint, cached per URL. A failed lookup is not cached. */
215
+ private resolveGatewayPda;
216
+ private lookupGatewayPda;
134
217
  private firstReachableData;
135
218
  private post;
219
+ private fetchWithTimeout;
220
+ }
221
+
222
+ /**
223
+ * Account views and remaining-accounts construction for `submit_attestation`.
224
+ */
225
+
226
+ /** On-chain `RegistryState` (Anchor camelCase): pointer to the current immutable snapshot. */
227
+ interface RegistryStateView {
228
+ currentVersion: number;
229
+ nextVersion: number;
136
230
  }
231
+ /**
232
+ * Immutable, version-addressed `Registry` snapshot. `nodes` holds only the populated
233
+ * `[..nodeCount]` entries; entry `i` is the `Node` account address for signer bit `i`.
234
+ */
235
+ interface RegistryView {
236
+ version: number;
237
+ nodeCount: number;
238
+ /** Selection padding: `min(signaturesRequired + redundancyBuffer, nodeCount)`. */
239
+ redundancyBuffer: number;
240
+ nodes: Address[];
241
+ /** Unix seconds until which this superseded snapshot still verifies; `0n` while current. */
242
+ graceActiveUntil: bigint;
243
+ }
244
+ /** Set-bit indices of a 32-byte big-endian bitmap (full 256-bit scan). */
245
+ declare function bitmapToIndices(signersBitmapHex: string): number[];
246
+ /**
247
+ * Signer `Node` accounts for `submit_attestation`, in ascending signers-bitmap bit order.
248
+ * Bit `i` resolves to `registry.nodes[i]` of the snapshot the round was signed against;
249
+ * a bit at or beyond `nodeCount` can never verify, so it is rejected client-side.
250
+ */
251
+ declare function resolveRemainingAccounts(signersBitmapHex: string, registry: RegistryView): SolanaAccountMeta[];
137
252
 
138
253
  /** On-chain subscription plan (`PlanType` in the Molpha program IDL). */
139
254
  declare enum PlanType {
140
- Basic = 0
255
+ Basic = 0,
256
+ Standard = 1,
257
+ Professional = 2,
258
+ Enterprise = 3
141
259
  }
142
260
  /** Numeric plan index used for PDA derivation and on-chain reads. */
143
261
  type PlanId = 0 | 1 | 2 | 3;
@@ -155,9 +273,9 @@ declare function planIdFromVariant(variant: Record<string, unknown>): PlanId;
155
273
 
156
274
  /**
157
275
  * `MolphaSolanaClient` — consumer on-chain surface only (subscribe, extend,
158
- * submitDataUpdate, readFeed/readPlan/readSubscription,
159
- * getRegistrySelectionConfig, verifyNodeKeysForPrivateApi). Built from an
160
- * Anchor `Program` over the vendored IDL.
276
+ * submitAttestation, readFeed/readPlan/readSubscription/readRegistry,
277
+ * getRegistrySelectionConfig, verifyNodeKeysForPrivateApi). Built from an Anchor
278
+ * `Program` over the vendored IDL.
161
279
  */
162
280
 
163
281
  type Commitment$1 = NonNullable<ConstructorParameters<typeof AnchorProvider>[2]>["commitment"];
@@ -172,6 +290,8 @@ interface PlanInfo {
172
290
  subscriptionPrice: bigint;
173
291
  maxSigners: number;
174
292
  maxDelegates: number;
293
+ /** Rounds a subscription on this plan may settle per period. */
294
+ maxRounds: bigint;
175
295
  privateApiEnabled: boolean;
176
296
  isActive: boolean;
177
297
  }
@@ -192,21 +312,36 @@ interface SubscriptionInfo {
192
312
  }
193
313
  interface SubmitResult {
194
314
  signature: string;
315
+ /** Feed PDA written by this submit (`["molpha_feed", sourceId, [signaturesRequired], submitter]`). */
316
+ feed: Address;
195
317
  }
196
318
  interface FeedAccount {
197
- feedId: number[];
198
- value: number[];
319
+ sourceId: number[];
320
+ /** Stored payload: raw value (`valueKind.value`) or keccak digest (`valueKind.hash`), ≤ 32 bytes. */
321
+ value: Uint8Array | number[];
199
322
  valueKind: {
200
323
  value: Record<string, never>;
201
324
  } | {
202
325
  hash: Record<string, never>;
203
326
  };
327
+ /** u64 unix seconds. */
204
328
  canonicalTimestamp: BN;
205
329
  signaturesRequired: number;
206
330
  signersBitmap: number[];
207
331
  registryVersion: number;
208
332
  bump: number;
209
333
  }
334
+ /** Anchor-encoded `SubmitAttestationArgs` (camelCase field names). */
335
+ interface SubmitAttestationArgs {
336
+ sourceId: number[];
337
+ registryVersion: number;
338
+ value: number[];
339
+ canonicalTimestamp: BN;
340
+ signaturesRequired: number;
341
+ aggSigS: number[];
342
+ commitment: number[];
343
+ signersBitmap: number[];
344
+ }
210
345
  interface CreateClientOpts {
211
346
  connection: SolanaConnection;
212
347
  wallet: Wallet;
@@ -225,12 +360,15 @@ declare class MolphaSolanaClient {
225
360
  private get methods();
226
361
  private get accounts();
227
362
  /**
228
- * Current registry version and selection `redundancy_buffer` from a single
229
- * `RegistryState` account read. Prefer this over {@link getRegistryVersion}
230
- * when deriving gateway selection bitmaps.
363
+ * Current registry version plus the selection inputs of that snapshot
364
+ * (`redundancy_buffer`, `node_count`). Two account reads: `RegistryState`, then the
365
+ * version-addressed `Registry`. Prefer this over {@link getRegistryVersion} when
366
+ * deriving gateway selection bitmaps.
231
367
  */
232
- getRegistrySelectionConfig(): Promise<RegistrySelectionConfig>;
368
+ getRegistrySelectionConfig(): Promise<Required<RegistrySelectionConfig>>;
233
369
  getRegistryVersion(): Promise<number>;
370
+ /** Read an immutable registry snapshot; defaults to the current version. */
371
+ readRegistry(version?: number): Promise<RegistryView>;
234
372
  /** Fetch a plan's on-chain terms, including the USDC `subscriptionPrice` charged on `subscribe`. */
235
373
  getPlan(plan: PlanType): Promise<PlanInfo>;
236
374
  /** Read a plan account, or `null` if it has not been initialized. */
@@ -267,30 +405,59 @@ declare class MolphaSolanaClient {
267
405
  * the caller agreed to pay. Returns the price (USDC base units) on success.
268
406
  */
269
407
  private confirmPlanPrice;
408
+ /**
409
+ * Submit a gateway attestation via `submit_attestation`. The feed account for
410
+ * `(sourceId, signaturesRequired, submitter)` is created on first use. Signer
411
+ * `Node` accounts are resolved from the registry snapshot the round was signed
412
+ * against and passed as remaining accounts.
413
+ */
414
+ submitAttestation(result: DataUpdateResult, opts?: {
415
+ computeUnitLimit?: number;
416
+ }): Promise<SubmitResult>;
417
+ /** @deprecated Renamed to {@link submitAttestation}. */
270
418
  submitDataUpdate(result: DataUpdateResult, opts?: {
271
419
  computeUnitLimit?: number;
272
420
  }): Promise<SubmitResult>;
273
- readFeed(feedId: string): Promise<FeedAccount | null>;
421
+ /**
422
+ * Read the feed written by `submitter` (default: this wallet) for
423
+ * `(sourceId, signaturesRequired)`, or `null` before its first submit.
424
+ */
425
+ readFeed(sourceId: string, signaturesRequired: number, submitter?: SolanaAddress): Promise<FeedAccount | null>;
274
426
  /**
275
427
  * Authenticate gateway-provided private API encryption keys against the
276
- * on-chain Node accounts for the round's registry version.
428
+ * on-chain Node accounts of the round's registry snapshot (`registry.nodes[index]`).
277
429
  */
278
430
  verifyNodeKeysForPrivateApi(args: NodeKeyVerifierArgs): Promise<void>;
279
- private buildSubmitArgs;
280
431
  private decodePlan;
432
+ private fetchRegistryState;
281
433
  private fetchRegistry;
282
434
  private fetchNodeAccount;
435
+ /** `usdc_mint` from `ProtocolConfig`; the treasury is its ATA owned by the config PDA. */
283
436
  private fetchProtocolTokens;
284
437
  }
438
+ /** Build the Anchor `SubmitAttestationArgs` for a gateway result. */
439
+ declare function buildSubmitAttestationArgs(result: DataUpdateResult): SubmitAttestationArgs;
285
440
 
286
441
  /** Gateway wire shape — defaults applied before hash / encryption. */
287
442
  declare function canonicalizeAPIConfig(apiConfig: APIConfig): APIConfig;
288
443
  /**
289
- * `apiConfigHash = keccak256(JSON.stringify(canonical apiConfig))`.
290
- * Pass the same config (including `{{secret.*}}` placeholders) you will send to
291
- * `MolphaGateway.requestSignedData` when deriving a feed id.
444
+ * `sourceId = keccak256(JSON.stringify(canonical apiConfig))` — the 32-byte identity of a
445
+ * data source. Hash the same config (including `{{secret.*}}` placeholders) you send to
446
+ * `MolphaGateway.requestSignedData`; the gateway and every verifier recompute it from
447
+ * `apiConfig`.
292
448
  */
293
- declare function deriveApiConfigHash(apiConfig: APIConfig): Uint8Array;
449
+ declare function deriveSourceId(apiConfig: APIConfig): Uint8Array;
450
+ /** Hex-encoded {@link deriveSourceId} (64 lowercase hex chars, no `0x`). */
451
+ declare function deriveSourceIdString(apiConfig: APIConfig): string;
452
+ /** @deprecated Renamed to {@link deriveSourceId}; identical bytes. */
453
+ declare const deriveApiConfigHash: typeof deriveSourceId;
454
+
455
+ /**
456
+ * Protocol-wide constants that must stay in sync with the vendored IDL. Kept as plain
457
+ * literals so gateway-only / browser bundles never pull in `idl/molpha.json`.
458
+ */
459
+ /** Molpha program id (`idl/molpha.json` → `address`). Asserted equal in `test/gateway-auth.test.ts`. */
460
+ declare const MOLPHA_PROGRAM_ID = "MoLFnEbuMS5gWnXNfUMLAYSqRM3eQZKWRzjeMQfqbT3";
294
461
 
295
462
  declare const utf8: (s: string) => Uint8Array;
296
463
  declare const concatBytes: (...arrays: Uint8Array[]) => Uint8Array;
@@ -317,15 +484,25 @@ declare function ensureLength(bytes: Uint8Array, len: number, label: string): Ui
317
484
  /** Coerce hex string or bytes to a fixed-length byte array. */
318
485
  declare function toFixedBytes(value: string | Uint8Array, len: number, label: string): Uint8Array;
319
486
 
320
- /**
321
- * `feedId = keccak256(FEED_ID_PREFIX || owner || apiConfigHash || [signaturesRequired])`.
322
- * @param owner 32-byte owner pubkey.
323
- * @param apiConfigHash 32-byte API config hash.
324
- * @param signaturesRequired Per-feed quorum threshold (u8 on-chain).
325
- */
326
- declare function deriveFeedId(owner: Uint8Array, apiConfigHash: Uint8Array, signaturesRequired: number): Uint8Array;
327
- /** Hex-encoded `deriveFeedId` (64 lowercase hex chars). */
328
- declare function deriveFeedIdString(owner: Uint8Array, apiConfigHash: Uint8Array, signaturesRequired: number): string;
487
+ /** `keccak256("MOLPHA_MESSAGE_V1")` domain separator. */
488
+ declare const MESSAGE_PREFIX: Uint8Array;
489
+ interface AttestationMessageFields {
490
+ /** 32-byte source id (hex or bytes). */
491
+ sourceId: string | Uint8Array;
492
+ registryVersion: number;
493
+ /** Encoded as `uint32` in the message even though the program stores a `u8`. */
494
+ signaturesRequired: number;
495
+ /** 32-byte big-endian signers bitmap (hex or bytes). */
496
+ signersBitmap: string | Uint8Array;
497
+ /** 32-byte packed value (hex or bytes). */
498
+ value: string | Uint8Array;
499
+ /** Unix seconds (u64). */
500
+ canonicalTimestamp: number | bigint;
501
+ }
502
+ /** Compute the attestation message hash (32 bytes). */
503
+ declare function attestationMessageHash(fields: AttestationMessageFields): Uint8Array;
504
+ /** Message hash of a completed gateway round (`valuePacked` is the signed value). */
505
+ declare function attestationMessageHashFromResult(result: DataUpdateResult): Uint8Array;
329
506
 
330
507
  /**
331
508
  * Parse a secp256k1 public key and return canonical compressed lower-case hex.
@@ -336,9 +513,9 @@ declare function normalizeSecp256k1PublicKeyHex(publicKeyHex: string, label?: st
336
513
  declare function secp256k1PublicKeyFromCoordinates(x: Uint8Array, y: Uint8Array, label?: string): string;
337
514
 
338
515
  /**
339
- * `seed = keccak256(keccak256("MOLPHA_SELECTION_V1") || feedId || be32(rv) || be64(ts))`.
516
+ * `seed = keccak256(keccak256("MOLPHA_SELECTION_V1") || sourceId || be32(rv) || be64(ts))`.
340
517
  */
341
- declare function deriveSelectionSeed(feedId: Uint8Array, registryVersion: number, canonicalTimestamp: number | bigint): Uint8Array;
518
+ declare function deriveSelectionSeed(sourceId: Uint8Array, registryVersion: number, canonicalTimestamp: number | bigint): Uint8Array;
342
519
  /** `min(signaturesRequired + redundancyBuffer, nodeCount)`. */
343
520
  declare function effectiveSelectionSize(signaturesRequired: number, redundancyBuffer: number, nodeCount: number): number;
344
521
  /** Is bit `bit` set in the 32-byte big-endian `bitmap`? */
@@ -355,11 +532,13 @@ declare function deriveGroupBitmap(seed: Uint8Array, nodeCount: number, groupSiz
355
532
  * Convenience orchestrator: derive the selection bitmap end-to-end.
356
533
  * `redundancy` defaults to 0; `ts` defaults to the current unix second.
357
534
  */
358
- declare function deriveSelectionBitmap(feedId: Uint8Array, registryVersion: number, nodeCount: number, signaturesRequired: number, redundancy?: number, ts?: number | bigint): Uint8Array;
535
+ declare function deriveSelectionBitmap(sourceId: Uint8Array, registryVersion: number, nodeCount: number, signaturesRequired: number, redundancy?: number, ts?: number | bigint): Uint8Array;
359
536
 
360
537
  /**
361
538
  * Minimal Molpha verifier ABI for `verify` and registry reads.
362
- * Matches `IValidator` in the Molpha EVM contracts repo.
539
+ * Matches the deployed `verify(DataUpdate, SchnorrSignature)` verifier. The first tuple
540
+ * component carries the 32-byte source id (the contract source names it `jobId`;
541
+ * component names do not affect ABI encoding).
363
542
  */
364
543
  declare const MOLPHA_VERIFIER_ABI: readonly [{
365
544
  readonly type: "function";
@@ -369,7 +548,7 @@ declare const MOLPHA_VERIFIER_ABI: readonly [{
369
548
  readonly name: "dataUpdate";
370
549
  readonly type: "tuple";
371
550
  readonly components: readonly [{
372
- readonly name: "jobId";
551
+ readonly name: "sourceId";
373
552
  readonly type: "bytes32";
374
553
  }, {
375
554
  readonly name: "registryVersion";
@@ -422,9 +601,9 @@ type MolphaEvmNetwork = "evm-sepolia" | "arbitrum-sepolia" | "avalanche-fuji" |
422
601
  /** CREATE2 Molpha verifier address — identical on all supported EVM chains. */
423
602
  declare const MOLPHA_VERIFIER_ADDRESS: "0xE1fd792b7E54e0C8F0Cd1c8055E446ff36d233eB";
424
603
 
425
- /** `(bytes32 feedId, uint32 registryVersion, uint32 signaturesRequired, bytes32 valuePacked, uint64 timestamp)` */
604
+ /** `(bytes32 sourceId, uint32 registryVersion, uint32 signaturesRequired, bytes32 valuePacked, uint64 timestamp)` */
426
605
  type EvmDataUpdateTuple = readonly [
427
- feedId: `0x${string}`,
606
+ sourceId: `0x${string}`,
428
607
  registryVersion: number,
429
608
  signaturesRequired: number,
430
609
  valuePacked: `0x${string}`,
@@ -466,7 +645,8 @@ declare function getMolphaStarknetVerifierAddress(network: MolphaStarknetNetwork
466
645
 
467
646
  /** Starknet calldata shape for `DataUpdate`. */
468
647
  interface StarknetDataUpdate {
469
- feed_id: bigint;
648
+ /** 32-byte source id as u256 (the Cairo struct still names this field `feed_id`). */
649
+ source_id: bigint;
470
650
  registry_version: number;
471
651
  signatures_required: number;
472
652
  value: bigint;
@@ -490,49 +670,31 @@ declare function signersBitmapToStarknetUint256(value: string): bigint;
490
670
  declare function buildStarknetVerifierArgs(result: DataUpdateResult): StarknetVerifierArgs;
491
671
 
492
672
  /**
493
- * Consumer PDA derivations (no node PDA). Seed byte strings are cross-checked
494
- * against the IDL const seeds.
673
+ * Consumer PDA derivations. Seed byte strings are cross-checked against the IDL const
674
+ * seeds in `test/solana.test.ts` / `test/idl.test.ts`.
495
675
  */
496
676
 
497
- /** Virtual registry index used for a removed slot during a version transition. */
498
- declare const VIRTUAL_INDEX = 4294967295;
499
677
  declare const protocolConfigPda: (programId: SolanaAddress) => Address;
678
+ /** Mutable pointer to the current registry snapshot: `["molpha_registry"]`. */
500
679
  declare const registryStatePda: (programId: SolanaAddress) => Address;
501
- /** Slot-keyed `Node` account PDA: `["molpha_node", index u32 LE]`. */
502
- declare const nodePda: (index: number, programId: SolanaAddress) => Address;
503
- /** Plan PDA is `[b"molpha_plan", [planType as u8]]` in `subscribe`. */
680
+ /** Immutable, version-addressed registry snapshot: `["molpha_registry", version u32 LE]`. */
681
+ declare const registryPda: (version: number, programId: SolanaAddress) => Address;
682
+ /**
683
+ * Owner-keyed `Node` account: `["molpha_node", owner]`. Registry snapshots store these
684
+ * addresses directly in `nodes[i]`, so consumers rarely need to derive them.
685
+ */
686
+ declare const nodePda: (owner: SolanaAddress, programId: SolanaAddress) => Address;
687
+ /** Bonded gateway account: `["molpha_gateway", gatewayAuthority]` — the `gateway` bound into `RequestAuth`. */
688
+ declare const gatewayPda: (authority: SolanaAddress, programId: SolanaAddress) => Address;
689
+ /** Plan PDA is `[b"molpha_plan", [planType as u8]]`. */
504
690
  declare const planPda: (planId: number, programId: SolanaAddress) => Address;
505
691
  declare const subscriptionPda: (owner: SolanaAddress, programId: SolanaAddress) => Address;
506
- declare const feedPda: (feedId: Uint8Array, programId: SolanaAddress) => Address;
507
-
508
- /** The subset of on-chain `RegistryState` the client needs (Anchor camelCase). */
509
- interface RegistryStateView {
510
- currentVersion: number;
511
- previousVersion: number;
512
- previousExpiresAt: bigint;
513
- /** On-chain selection padding: `signatures_required + redundancy_buffer`. */
514
- redundancyBuffer: number;
515
- lastTransitionType: {
516
- none: Record<string, never>;
517
- } | {
518
- add: Record<string, never>;
519
- } | {
520
- removeTail: Record<string, never>;
521
- } | {
522
- removeSwap: Record<string, never>;
523
- };
524
- removedOldIndex: number;
525
- movedOldIndex: number;
526
- }
527
- /** Set-bit indices of a 32-byte big-endian bitmap (full 256-bit scan). */
528
- declare function bitmapToIndices(signersBitmapHex: string): number[];
529
692
  /**
530
- * Build the registry-index remaining accounts for a submit. Valid only
531
- * against the current or previous registry version (else thrown client-side).
693
+ * Feed state, keyed per `(sourceId, signaturesRequired, submitter)`:
694
+ * `["molpha_feed", sourceId, [signaturesRequired], submitter]`. Created lazily by the
695
+ * first `submit_attestation` from that submitter.
532
696
  */
533
- declare function resolveRemainingAccounts(result: DataUpdateResult, registry: RegistryStateView, programId: SolanaAddress): SolanaAccountMeta[];
534
- /** Map a selected node index to its registry-index PDA index for a registry version. */
535
- declare function resolveRegistryIndexForVersion(index: number, registryVersion: number, registry: RegistryStateView): number;
697
+ declare function feedPda(sourceId: Uint8Array, signaturesRequired: number, submitter: SolanaAddress, programId: SolanaAddress): Address;
536
698
 
537
699
  /**
538
700
  * Vendored Molpha Anchor IDL (`target/idl/molpha.json` from the program repo).
@@ -556,12 +718,16 @@ declare const MOLPHA_PROGRAM_ADDRESS: string;
556
718
  type Commitment = NonNullable<ConstructorParameters<typeof AnchorProvider>[2]>["commitment"];
557
719
 
558
720
  interface MolphaSDKOptions {
559
- /** Defaults to `DEFAULT_GATEWAY_ENDPOINT`. Pass multiple URLs for failover. */
560
- endpoints?: string | string[];
721
+ /**
722
+ * Defaults to `DEFAULT_GATEWAY_ENDPOINT`. Pass multiple entries for failover. Each
723
+ * entry is a URL or `{ url, gatewayAuthority }`; when the authority is omitted it is
724
+ * discovered from the gateway's `GET /v1/info`.
725
+ */
726
+ endpoints?: GatewayEndpointInput | GatewayEndpointInput[];
561
727
  connection: SolanaConnection;
562
728
  /** On-chain txs + gateway auth (see `MolphaWallet`). */
563
729
  wallet: MolphaWallet;
564
- /** Defaults to the vendored IDL's program address. */
730
+ /** Defaults to the vendored IDL's program address. Bound into gateway request auth. */
565
731
  programId?: Address | string;
566
732
  /** Defaults to `MOLPHA_IDL`. Override when pinning a different deployment. */
567
733
  idl?: Idl;
@@ -573,12 +739,13 @@ declare class MolphaSDK {
573
739
  constructor(opts: MolphaSDKOptions);
574
740
  /**
575
741
  * Request a threshold-signed data update from the gateway (against the current
576
- * on-chain registry version) and submit it to the feed.
742
+ * on-chain registry version) and submit it via `submit_attestation`.
577
743
  */
578
- requestAndSubmit(feedId: string, opts: Omit<RequestSignedDataOptions, "feedId">): Promise<{
744
+ requestAndSubmit(opts: RequestSignedDataOptions): Promise<{
579
745
  result: DataUpdateResult;
580
746
  signature: string;
747
+ feed: Address;
581
748
  }>;
582
749
  }
583
750
 
584
- export { APIConfig, DEFAULT_GATEWAY_ENDPOINT, DataUpdateResult, type EvmDataUpdateTuple, type EvmSchnorrSignatureTuple, type EvmVerifierArgs, type FeedAccount, GatewayError, MOLPHA_IDL, MOLPHA_PROGRAM_ADDRESS, MOLPHA_VERIFIER_ABI, MOLPHA_VERIFIER_ADDRESS, MOLPHA_VERIFIER_STARKNET_ADDRESSES, MOLPHA_VERIFIER_STARKNET_SEPOLIA, type MolphaEvmNetwork, MolphaGateway, type MolphaGatewayOptions, MolphaSDK, type MolphaSDKOptions, MolphaSolanaClient, type MolphaStarknetNetwork, MolphaWallet, Node, NodeKeyVerifier, NodeKeyVerifierArgs, type PlanId, type PlanInfo, PlanType, RegistrySelectionConfig, type RegistryStateView, type RequestSignedDataOptions, type RoundContext, Signer, type StarknetDataUpdate, type StarknetSchnorrSignature, type StarknetVerifierArgs, type SubmitResult, type SubscribeResult, type SubscriptionInfo, VIRTUAL_INDEX, bigIntFromBytesBe, bitmapBitSet, bitmapToIndices, buildEvmVerifierArgs, buildStarknetVerifierArgs, bytesToHex, bytesToHex0x, canonicalizeAPIConfig, commitmentAddressToStarknetFelt, concatBytes, deriveApiConfigHash, deriveFeedId, deriveFeedIdString, deriveGroupBitmap, deriveSelectionBitmap, deriveSelectionSeed, effectiveSelectionSize, ensureLength, feedPda, getMolphaStarknetVerifierAddress, hexToBytes, nodePda, normalizeSecp256k1PublicKeyHex, planIdFromVariant, planPda, planVariant, protocolConfigPda, registryStatePda, resolveRegistryIndexForVersion, resolveRemainingAccounts, secp256k1PublicKeyFromCoordinates, selectedIndices, signersBitmapToDecimal, signersBitmapToStarknetUint256, signersBitmapToUint256, subscriptionPda, toFixedBytes, toFixedHex, u256beFromBigInt, u32be, u32le, u64be, u64le, utf8 };
751
+ export { APIConfig, type AttestationMessageFields, DEFAULT_GATEWAY_ENDPOINT, DataUpdateResult, type EvmDataUpdateTuple, type EvmSchnorrSignatureTuple, type EvmVerifierArgs, type FeedAccount, type GatewayEndpoint, type GatewayEndpointInput, GatewayError, type GatewayInfo, MESSAGE_PREFIX, MOLPHA_IDL, MOLPHA_PROGRAM_ADDRESS, MOLPHA_PROGRAM_ID, MOLPHA_VERIFIER_ABI, MOLPHA_VERIFIER_ADDRESS, MOLPHA_VERIFIER_STARKNET_ADDRESSES, MOLPHA_VERIFIER_STARKNET_SEPOLIA, type MolphaEvmNetwork, MolphaGateway, type MolphaGatewayOptions, MolphaSDK, type MolphaSDKOptions, MolphaSolanaClient, type MolphaStarknetNetwork, MolphaWallet, Node, NodeKeyVerifier, NodeKeyVerifierArgs, type PlanId, type PlanInfo, PlanType, REQUEST_AUTH_DOMAIN, RegistrySelectionConfig, type RegistryStateView, type RegistryView, type RequestAuthFields, type RequestSignedDataOptions, type RoundContext, Signer, type StarknetDataUpdate, type StarknetSchnorrSignature, type StarknetVerifierArgs, type SubmitAttestationArgs, type SubmitResult, type SubscribeResult, type SubscriptionInfo, addressToBytes, attestationMessageHash, attestationMessageHashFromResult, bigIntFromBytesBe, bitmapBitSet, bitmapToIndices, buildEvmVerifierArgs, buildStarknetVerifierArgs, buildSubmitAttestationArgs, bytesToHex, bytesToHex0x, canonicalizeAPIConfig, commitmentAddressToStarknetFelt, concatBytes, deriveApiConfigHash, deriveGatewayPda, deriveGatewayPdaAddress, deriveGroupBitmap, deriveSelectionBitmap, deriveSelectionSeed, deriveSourceId, deriveSourceIdString, effectiveSelectionSize, encodeRequestAuth, ensureLength, feedPda, gatewayPda, getMolphaStarknetVerifierAddress, hashRequestAuth, hexToBytes, nodePda, normalizeEndpoint, normalizeSecp256k1PublicKeyHex, parseGatewayInfo, planIdFromVariant, planPda, planVariant, protocolConfigPda, registryPda, registryStatePda, resolveRemainingAccounts, secp256k1PublicKeyFromCoordinates, selectedIndices, signersBitmapToDecimal, signersBitmapToStarknetUint256, signersBitmapToUint256, subscriptionPda, toFixedBytes, toFixedHex, u256beFromBigInt, u32be, u32le, u64be, u64le, utf8 };