@molpha/sdk 0.1.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.
@@ -0,0 +1,51 @@
1
+ import { web3 } from '@anchor-lang/core';
2
+ import { address, getAddressEncoder } from '@solana/kit';
3
+ import { ed25519 } from '@noble/curves/ed25519.js';
4
+
5
+ // src/solana/kit.ts
6
+ var TOKEN_PROGRAM_ADDRESS = address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
7
+ var ASSOCIATED_TOKEN_PROGRAM_ADDRESS = address(
8
+ "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
9
+ );
10
+ var SYSTEM_PROGRAM_ADDRESS = address("11111111111111111111111111111111");
11
+ var addressEncoder = getAddressEncoder();
12
+ function toSolanaAddress(value) {
13
+ return address(typeof value === "string" ? value : value.toBase58());
14
+ }
15
+ function toPublicKey(value) {
16
+ return value instanceof web3.PublicKey ? value : new web3.PublicKey(value);
17
+ }
18
+ function addressBytes(value) {
19
+ return Uint8Array.from(addressEncoder.encode(toSolanaAddress(value)));
20
+ }
21
+ function findProgramAddressSync(seeds, programAddress) {
22
+ const [pda] = web3.PublicKey.findProgramAddressSync(seeds, toPublicKey(programAddress));
23
+ return toSolanaAddress(pda);
24
+ }
25
+ function getAssociatedTokenAddressSync(mint, owner, tokenProgram = TOKEN_PROGRAM_ADDRESS) {
26
+ return findProgramAddressSync(
27
+ [addressBytes(owner), addressBytes(tokenProgram), addressBytes(mint)],
28
+ ASSOCIATED_TOKEN_PROGRAM_ADDRESS
29
+ );
30
+ }
31
+ function setComputeUnitLimit(units) {
32
+ return web3.ComputeBudgetProgram.setComputeUnitLimit({ units });
33
+ }
34
+ function keypairFromSecretKey(secretKey) {
35
+ return web3.Keypair.fromSecretKey(secretKey);
36
+ }
37
+ var isKeypair = (value) => typeof value === "object" && value !== null && "secretKey" in value && value.secretKey instanceof Uint8Array;
38
+ function signerFromKeypair(keypair) {
39
+ const seed = keypair.secretKey.slice(0, 32);
40
+ return async (message) => ed25519.sign(message, seed);
41
+ }
42
+ function gatewaySignerFromWallet(wallet) {
43
+ const molpha = wallet;
44
+ if (molpha.signAuthMessage) return molpha.signAuthMessage;
45
+ if ("payer" in wallet && isKeypair(wallet.payer)) return signerFromKeypair(wallet.payer);
46
+ return void 0;
47
+ }
48
+
49
+ export { SYSTEM_PROGRAM_ADDRESS, TOKEN_PROGRAM_ADDRESS, addressBytes, findProgramAddressSync, gatewaySignerFromWallet, getAssociatedTokenAddressSync, keypairFromSecretKey, setComputeUnitLimit, signerFromKeypair, toPublicKey, toSolanaAddress };
50
+ //# sourceMappingURL=chunk-MFELBWSL.js.map
51
+ //# sourceMappingURL=chunk-MFELBWSL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/solana/kit.ts","../src/wallet.ts"],"names":[],"mappings":";;;;;AAaO,IAAM,qBAAA,GAAwB,QAAQ,6CAA6C;AACnF,IAAM,gCAAA,GAAmC,OAAA;AAAA,EAC9C;AACF,CAAA;AACO,IAAM,sBAAA,GAAyB,QAAQ,kCAAkC;AAEhF,IAAM,iBAAiB,iBAAA,EAAkB;AAElC,SAAS,gBAAgB,KAAA,EAA+B;AAC7D,EAAA,OAAO,QAAQ,OAAO,KAAA,KAAU,WAAW,KAAA,GAAQ,KAAA,CAAM,UAAU,CAAA;AACrE;AAEO,SAAS,YAAY,KAAA,EAA2D;AACrF,EAAA,OAAO,iBAAiB,IAAA,CAAK,SAAA,GAAY,QAAQ,IAAI,IAAA,CAAK,UAAU,KAAK,CAAA;AAC3E;AAEO,SAAS,aAAa,KAAA,EAAkC;AAC7D,EAAA,OAAO,WAAW,IAAA,CAAK,cAAA,CAAe,OAAO,eAAA,CAAgB,KAAK,CAAC,CAAC,CAAA;AACtE;AAEO,SAAS,sBAAA,CACd,OACA,cAAA,EACS;AACT,EAAA,MAAM,CAAC,GAAG,CAAA,GAAI,IAAA,CAAK,UAAU,sBAAA,CAAuB,KAAA,EAAO,WAAA,CAAY,cAAc,CAAC,CAAA;AACtF,EAAA,OAAO,gBAAgB,GAAG,CAAA;AAC5B;AAUO,SAAS,6BAAA,CACd,IAAA,EACA,KAAA,EACA,YAAA,GAA8B,qBAAA,EACrB;AACT,EAAA,OAAO,sBAAA;AAAA,IACL,CAAC,aAAa,KAAK,CAAA,EAAG,aAAa,YAAY,CAAA,EAAG,YAAA,CAAa,IAAI,CAAC,CAAA;AAAA,IACpE;AAAA,GACF;AACF;AAEO,SAAS,oBAAoB,KAAA,EAAkC;AACpE,EAAA,OAAO,IAAA,CAAK,oBAAA,CAAqB,mBAAA,CAAoB,EAAE,OAAO,CAAA;AAChE;AAEO,SAAS,qBAAqB,SAAA,EAAsC;AACzE,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,SAAS,CAAA;AAC7C;ACjDA,IAAM,SAAA,GAAY,CAAC,KAAA,KACjB,OAAO,KAAA,KAAU,QAAA,IACjB,KAAA,KAAU,IAAA,IACV,WAAA,IAAe,KAAA,IACf,KAAA,CAAM,SAAA,YAAqB,UAAA;AAGtB,SAAS,kBAAkB,OAAA,EAAgC;AAChE,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,SAAA,CAAU,KAAA,CAAM,GAAG,EAAE,CAAA;AAC1C,EAAA,OAAO,OAAO,OAAA,KAA6C,OAAA,CAAQ,IAAA,CAAK,SAAS,IAAI,CAAA;AACvF;AAGO,SAAS,wBAAwB,MAAA,EAAoC;AAC1E,EAAA,MAAM,MAAA,GAAS,MAAA;AACf,EAAA,IAAI,MAAA,CAAO,eAAA,EAAiB,OAAO,MAAA,CAAO,eAAA;AAC1C,EAAA,IAAI,OAAA,IAAW,UAAU,SAAA,CAAU,MAAA,CAAO,KAAK,CAAA,EAAG,OAAO,iBAAA,CAAkB,MAAA,CAAO,KAAK,CAAA;AACvF,EAAA,OAAO,MAAA;AACT","file":"chunk-MFELBWSL.js","sourcesContent":["import { web3 } from \"@anchor-lang/core\";\nimport { address, getAddressEncoder, type Address } from \"@solana/kit\";\n\nexport type SolanaAddress = Address | string | InstanceType<typeof web3.PublicKey>;\nexport type SolanaConnection = InstanceType<typeof web3.Connection>;\nexport type SolanaKeypair = InstanceType<typeof web3.Keypair>;\nexport type SolanaInstruction = InstanceType<typeof web3.TransactionInstruction>;\nexport type SolanaAccountMeta = {\n pubkey: InstanceType<typeof web3.PublicKey>;\n isSigner: boolean;\n isWritable: boolean;\n};\n\nexport const TOKEN_PROGRAM_ADDRESS = address(\"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\");\nexport const ASSOCIATED_TOKEN_PROGRAM_ADDRESS = address(\n \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\",\n);\nexport const SYSTEM_PROGRAM_ADDRESS = address(\"11111111111111111111111111111111\");\n\nconst addressEncoder = getAddressEncoder();\n\nexport function toSolanaAddress(value: SolanaAddress): Address {\n return address(typeof value === \"string\" ? value : value.toBase58());\n}\n\nexport function toPublicKey(value: SolanaAddress): InstanceType<typeof web3.PublicKey> {\n return value instanceof web3.PublicKey ? value : new web3.PublicKey(value);\n}\n\nexport function addressBytes(value: SolanaAddress): Uint8Array {\n return Uint8Array.from(addressEncoder.encode(toSolanaAddress(value)));\n}\n\nexport function findProgramAddressSync(\n seeds: Uint8Array[],\n programAddress: SolanaAddress,\n): Address {\n const [pda] = web3.PublicKey.findProgramAddressSync(seeds, toPublicKey(programAddress));\n return toSolanaAddress(pda);\n}\n\nexport function findProgramPublicKeySync(\n seeds: Uint8Array[],\n programAddress: SolanaAddress,\n): InstanceType<typeof web3.PublicKey> {\n const [pda] = web3.PublicKey.findProgramAddressSync(seeds, toPublicKey(programAddress));\n return pda;\n}\n\nexport function getAssociatedTokenAddressSync(\n mint: SolanaAddress,\n owner: SolanaAddress,\n tokenProgram: SolanaAddress = TOKEN_PROGRAM_ADDRESS,\n): Address {\n return findProgramAddressSync(\n [addressBytes(owner), addressBytes(tokenProgram), addressBytes(mint)],\n ASSOCIATED_TOKEN_PROGRAM_ADDRESS,\n );\n}\n\nexport function setComputeUnitLimit(units: number): SolanaInstruction {\n return web3.ComputeBudgetProgram.setComputeUnitLimit({ units });\n}\n\nexport function keypairFromSecretKey(secretKey: Uint8Array): SolanaKeypair {\n return web3.Keypair.fromSecretKey(secretKey);\n}\n\nexport function generateKeypair(): SolanaKeypair {\n return web3.Keypair.generate();\n}\n","/**\n * Unified wallet surface: Anchor txs + optional gateway authSig signing.\n */\nimport type { Wallet } from \"@anchor-lang/core\";\nimport { ed25519 } from \"@noble/curves/ed25519.js\";\nimport type { Signer } from \"./core/types.js\";\nimport type { SolanaKeypair } from \"./solana/kit.js\";\n\n/** Anchor `Wallet` plus optional gateway auth override. */\nexport type MolphaWallet = Wallet & {\n /**\n * Signs gateway `authMessage` payloads. When omitted, derived from Anchor\n * `Wallet.payer` when the keypair secret is available (Node `Wallet`, etc.).\n */\n signAuthMessage?: Signer;\n};\n\nconst isKeypair = (value: unknown): value is SolanaKeypair =>\n typeof value === \"object\" &&\n value !== null &&\n \"secretKey\" in value &&\n value.secretKey instanceof Uint8Array;\n\n/** ed25519 gateway signer from a Solana keypair's 32-byte seed. */\nexport function signerFromKeypair(keypair: SolanaKeypair): Signer {\n const seed = keypair.secretKey.slice(0, 32);\n return async (message: Uint8Array): Promise<Uint8Array> => ed25519.sign(message, seed);\n}\n\n/** Resolve the gateway auth signer for a Molpha wallet, if available. */\nexport function gatewaySignerFromWallet(wallet: Wallet): Signer | undefined {\n const molpha = wallet as MolphaWallet;\n if (molpha.signAuthMessage) return molpha.signAuthMessage;\n if (\"payer\" in wallet && isKeypair(wallet.payer)) return signerFromKeypair(wallet.payer);\n return undefined;\n}\n"]}
@@ -0,0 +1,584 @@
1
+ import { Address } from '@solana/kit';
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';
5
+ import BN from 'bn.js';
6
+
7
+ interface RequestSignedDataOptions {
8
+ feedId: string;
9
+ signaturesRequired: number;
10
+ apiConfig: APIConfig;
11
+ /**
12
+ * Solana pubkey (base58) of the subscription owner.
13
+ * Overrides the gateway's `defaultSubscriptionOwner` when set.
14
+ */
15
+ subscriptionOwner?: string;
16
+ /**
17
+ * Solana pubkey (base58) of the consumer authority that signs gateway auth.
18
+ * Overrides the gateway's `defaultConsumerAuthority` when set.
19
+ */
20
+ consumerAuthority?: string;
21
+ /**
22
+ * Signs `authMessage(feedId, timestamp)`. Overrides the gateway's
23
+ * `defaultSigner` when set. When both are omitted, sends all-zero authSig
24
+ * (dev only).
25
+ */
26
+ signer?: Signer;
27
+ encrypt?: {
28
+ secrets: Record<string, string>;
29
+ };
30
+ /** Max accepted value age in seconds. Default 60. */
31
+ maxAge?: number;
32
+ /** Each retry re-rolls the timestamp. Default 15. */
33
+ maxRetries?: number;
34
+ /** Per-request timeout in ms. Default 5000. */
35
+ timeoutMs?: number;
36
+ /**
37
+ * Pre-fetched round inputs. Any field present here skips its network/on-chain
38
+ * fetch, so a fully-populated context turns `requestSignedData` into a single
39
+ * POST round (the "short" flow). Build a reusable one with
40
+ * {@link MolphaGateway.prepareContext}.
41
+ *
42
+ * 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.
45
+ */
46
+ context?: Partial<RoundContext>;
47
+ /**
48
+ * Authenticates selected gateway node encryption keys before private API
49
+ * secrets are encrypted. Overrides the gateway-level verifier when set.
50
+ */
51
+ verifyNodeKeys?: NodeKeyVerifier;
52
+ /**
53
+ * Unsafe development escape hatch for standalone gateway usage. When true,
54
+ * encrypted private API requests may use gateway-provided node keys without
55
+ * authentication. Defaults to false.
56
+ */
57
+ allowUnverifiedNodeKeysForPrivateApi?: boolean;
58
+ }
59
+ interface MolphaGatewayOptions {
60
+ /** Solana pubkey (base58) of the subscription owner used when a request omits it. */
61
+ defaultSubscriptionOwner?: string;
62
+ /** Solana pubkey (base58) of the consumer authority used when a request omits it. */
63
+ defaultConsumerAuthority?: string;
64
+ /**
65
+ * Authenticates selected gateway node encryption keys before private API
66
+ * secrets are encrypted.
67
+ */
68
+ verifyNodeKeys?: NodeKeyVerifier;
69
+ /**
70
+ * Unsafe development escape hatch. When true, encrypted private API requests
71
+ * may use gateway-provided node keys without authentication. Defaults to false.
72
+ */
73
+ allowUnverifiedNodeKeysForPrivateApi?: boolean;
74
+ }
75
+ /**
76
+ * The slow-changing inputs a `requestSignedData` round binds to. Fetch once with
77
+ * {@link MolphaGateway.prepareContext} and reuse across many rounds
78
+ */
79
+ interface RoundContext extends RegistrySelectionConfig {
80
+ /** Full node set used to derive the selection bitmap. */
81
+ nodes: Node[];
82
+ }
83
+ /** Default gateway base URL when `endpoints` is omitted. */
84
+ declare const DEFAULT_GATEWAY_ENDPOINT = "https://dev-gateway.molpha.io/";
85
+ /** Thrown for terminal gateway errors (400/401) — never retried. */
86
+ declare class GatewayError extends Error {
87
+ readonly status?: number | undefined;
88
+ constructor(message: string, status?: number | undefined);
89
+ }
90
+ declare class MolphaGateway {
91
+ private readonly endpoints;
92
+ private readonly getRegistrySelectionConfig;
93
+ private readonly defaultSigner?;
94
+ private readonly defaultSubscriptionOwner?;
95
+ private readonly defaultConsumerAuthority?;
96
+ private readonly verifyNodeKeys?;
97
+ private readonly allowUnverifiedNodeKeysForPrivateApi;
98
+ constructor(endpoints?: string | string[], getRegistrySelectionConfig?: () => Promise<RegistrySelectionConfig>, defaultSigner?: Signer,
99
+ /**
100
+ * Either a default subscription owner (base58) or gateway options. A string
101
+ * keeps the previous positional form used by standalone callers/tests.
102
+ */
103
+ defaultSubscriptionOwnerOrOptions?: string | MolphaGatewayOptions, defaultConsumerAuthority?: string);
104
+ /** Tries endpoints in order; returns the first node list it can fetch. */
105
+ getNodes(): Promise<Node[]>;
106
+ isHealthy(): Promise<boolean>;
107
+ /**
108
+ * 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.
112
+ *
113
+ * Both fetches run in parallel. Registry version and redundancy buffer come
114
+ * from a single on-chain `RegistryState` read.
115
+ */
116
+ prepareContext(_feedId: string): Promise<RoundContext>;
117
+ /**
118
+ * Request a threshold-signed data update from the gateway, with retry +
119
+ * failover. Per attempt a fresh timestamp yields a fresh selection bitmap; the
120
+ * body is POSTed to each endpoint in order until one `completed`s.
121
+ *
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.
126
+ */
127
+ requestSignedData(opts: RequestSignedDataOptions): Promise<DataUpdateResult>;
128
+ /**
129
+ * 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.
132
+ */
133
+ private resolveContext;
134
+ private firstReachableData;
135
+ private post;
136
+ }
137
+
138
+ /** On-chain subscription plan (`PlanType` in the Molpha program IDL). */
139
+ declare enum PlanType {
140
+ Basic = 0
141
+ }
142
+ /** Numeric plan index used for PDA derivation and on-chain reads. */
143
+ type PlanId = 0 | 1 | 2 | 3;
144
+ declare const PLAN_VARIANTS: readonly [{
145
+ readonly basic: {};
146
+ }, {
147
+ readonly standard: {};
148
+ }, {
149
+ readonly professional: {};
150
+ }, {
151
+ readonly enterprise: {};
152
+ }];
153
+ declare function planVariant(planId: PlanId): (typeof PLAN_VARIANTS)[number];
154
+ declare function planIdFromVariant(variant: Record<string, unknown>): PlanId;
155
+
156
+ /**
157
+ * `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.
161
+ */
162
+
163
+ type Commitment$1 = NonNullable<ConstructorParameters<typeof AnchorProvider>[2]>["commitment"];
164
+ interface SubscribeResult {
165
+ signature: string;
166
+ /** USDC base units actually debited from the owner for this subscription. */
167
+ pricePaid: bigint;
168
+ }
169
+ interface PlanInfo {
170
+ planType: PlanType;
171
+ /** Subscription price in USDC base units (raw u64, e.g. 1_000_000 = 1 USDC at 6 decimals). */
172
+ subscriptionPrice: bigint;
173
+ maxSigners: number;
174
+ maxDelegates: number;
175
+ privateApiEnabled: boolean;
176
+ isActive: boolean;
177
+ }
178
+ interface SubscriptionInfo {
179
+ owner: Address;
180
+ planType: PlanType;
181
+ /** USDC base units prepaid on the subscription vault. */
182
+ prepaidUsdc: bigint;
183
+ /** Locked subscription price in USDC base units for the current period. */
184
+ price: bigint;
185
+ /** Unix timestamp (seconds) until which the subscription is valid. */
186
+ validUntil: bigint;
187
+ usedRounds: bigint;
188
+ maxRounds: bigint;
189
+ delegateCount: number;
190
+ maxDelegates: number;
191
+ maxSigners: number;
192
+ }
193
+ interface SubmitResult {
194
+ signature: string;
195
+ }
196
+ interface FeedAccount {
197
+ feedId: number[];
198
+ value: number[];
199
+ valueKind: {
200
+ value: Record<string, never>;
201
+ } | {
202
+ hash: Record<string, never>;
203
+ };
204
+ canonicalTimestamp: BN;
205
+ signaturesRequired: number;
206
+ signersBitmap: number[];
207
+ registryVersion: number;
208
+ bump: number;
209
+ }
210
+ interface CreateClientOpts {
211
+ connection: SolanaConnection;
212
+ wallet: Wallet;
213
+ programId?: SolanaAddress;
214
+ idl?: Idl;
215
+ commitment?: Commitment$1;
216
+ }
217
+ declare class MolphaSolanaClient {
218
+ private readonly program;
219
+ private readonly provider;
220
+ readonly programId: Address;
221
+ private constructor();
222
+ static create(opts: CreateClientOpts): MolphaSolanaClient;
223
+ private get wallet();
224
+ /** Anchor's method/account namespaces are untyped without an IDL type param. */
225
+ private get methods();
226
+ private get accounts();
227
+ /**
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.
231
+ */
232
+ getRegistrySelectionConfig(): Promise<RegistrySelectionConfig>;
233
+ getRegistryVersion(): Promise<number>;
234
+ /** Fetch a plan's on-chain terms, including the USDC `subscriptionPrice` charged on `subscribe`. */
235
+ getPlan(plan: PlanType): Promise<PlanInfo>;
236
+ /** Read a plan account, or `null` if it has not been initialized. */
237
+ readPlan(plan: PlanType): Promise<PlanInfo | null>;
238
+ /** Read an owner's subscription, or `null` if they have not subscribed. */
239
+ readSubscription(owner?: SolanaAddress): Promise<SubscriptionInfo | null>;
240
+ /**
241
+ * Subscribe to a plan. This **debits USDC** from the owner: the plan's
242
+ * `subscriptionPrice` is transferred to the protocol treasury on-chain.
243
+ *
244
+ * Payment is explicit and must be confirmed: pass `maxPriceUsdc` (USDC base
245
+ * units) as the most you agree to pay. The SDK reads the live on-chain price
246
+ * and aborts before sending the transaction if it exceeds that amount, so a
247
+ * price change between display and confirmation can never silently overcharge.
248
+ * The amount actually paid is returned as `pricePaid`.
249
+ *
250
+ * Use {@link getPlan} to display the current price to the user beforehand.
251
+ */
252
+ subscribe(plan: PlanType, opts: {
253
+ maxPriceUsdc: bigint | number | BN;
254
+ ownerUsdc?: SolanaAddress;
255
+ }): Promise<SubscribeResult>;
256
+ /**
257
+ * Extend the current subscription for another period. Like {@link subscribe}
258
+ * this **debits USDC** (the plan's `subscriptionPrice`) and requires explicit
259
+ * payment confirmation via `maxPriceUsdc`.
260
+ */
261
+ extendSubscription(opts: {
262
+ maxPriceUsdc: bigint | number | BN;
263
+ ownerUsdc?: SolanaAddress;
264
+ }): Promise<SubscribeResult>;
265
+ /**
266
+ * Read the live on-chain plan price and verify it does not exceed the amount
267
+ * the caller agreed to pay. Returns the price (USDC base units) on success.
268
+ */
269
+ private confirmPlanPrice;
270
+ submitDataUpdate(result: DataUpdateResult, opts?: {
271
+ computeUnitLimit?: number;
272
+ }): Promise<SubmitResult>;
273
+ readFeed(feedId: string): Promise<FeedAccount | null>;
274
+ /**
275
+ * Authenticate gateway-provided private API encryption keys against the
276
+ * on-chain Node accounts for the round's registry version.
277
+ */
278
+ verifyNodeKeysForPrivateApi(args: NodeKeyVerifierArgs): Promise<void>;
279
+ private buildSubmitArgs;
280
+ private decodePlan;
281
+ private fetchRegistry;
282
+ private fetchNodeAccount;
283
+ private fetchProtocolTokens;
284
+ }
285
+
286
+ /** Gateway wire shape — defaults applied before hash / encryption. */
287
+ declare function canonicalizeAPIConfig(apiConfig: APIConfig): APIConfig;
288
+ /**
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.
292
+ */
293
+ declare function deriveApiConfigHash(apiConfig: APIConfig): Uint8Array;
294
+
295
+ declare const utf8: (s: string) => Uint8Array;
296
+ declare const concatBytes: (...arrays: Uint8Array[]) => Uint8Array;
297
+ /** Lower-case hex, no `0x` prefix. */
298
+ declare const bytesToHex: (bytes: Uint8Array) => string;
299
+ /** Accepts an optional leading `0x`; case-insensitive. */
300
+ declare function hexToBytes(hex: string): Uint8Array;
301
+ /** Hex with a leading `0x`. */
302
+ declare const bytesToHex0x: (bytes: Uint8Array) => string;
303
+ /** Big-endian u32 → 4 bytes. */
304
+ declare function u32be(value: number): Uint8Array;
305
+ /** Little-endian u32 → 4 bytes (used for PDA seeds like the registry index). */
306
+ declare function u32le(value: number): Uint8Array;
307
+ /** Big-endian u64 → 8 bytes. Accepts `number` or `bigint`. */
308
+ declare function u64be(value: number | bigint): Uint8Array;
309
+ /** Little-endian u64 → 8 bytes. Accepts `number` or `bigint`. */
310
+ declare function u64le(value: number | bigint): Uint8Array;
311
+ /** Big-endian 32-byte word ← bigint (0 ≤ v < 2^256). */
312
+ declare function u256beFromBigInt(value: bigint): Uint8Array;
313
+ /** bigint ← big-endian byte word (any length). */
314
+ declare function bigIntFromBytesBe(bytes: Uint8Array): bigint;
315
+ /** Throw unless `bytes.length === len`. Returns the input for chaining. */
316
+ declare function ensureLength(bytes: Uint8Array, len: number, label: string): Uint8Array;
317
+ /** Coerce hex string or bytes to a fixed-length byte array. */
318
+ declare function toFixedBytes(value: string | Uint8Array, len: number, label: string): Uint8Array;
319
+
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;
329
+
330
+ /**
331
+ * Parse a secp256k1 public key and return canonical compressed lower-case hex.
332
+ * Accepts compressed or uncompressed SEC1 public keys with an optional `0x`.
333
+ */
334
+ declare function normalizeSecp256k1PublicKeyHex(publicKeyHex: string, label?: string): string;
335
+ /** Reconstruct a compressed secp256k1 public key from 32-byte affine X/Y coordinates. */
336
+ declare function secp256k1PublicKeyFromCoordinates(x: Uint8Array, y: Uint8Array, label?: string): string;
337
+
338
+ /**
339
+ * `seed = keccak256(keccak256("MOLPHA_SELECTION_V1") || feedId || be32(rv) || be64(ts))`.
340
+ */
341
+ declare function deriveSelectionSeed(feedId: Uint8Array, registryVersion: number, canonicalTimestamp: number | bigint): Uint8Array;
342
+ /** `min(signaturesRequired + redundancyBuffer, nodeCount)`. */
343
+ declare function effectiveSelectionSize(signaturesRequired: number, redundancyBuffer: number, nodeCount: number): number;
344
+ /** Is bit `bit` set in the 32-byte big-endian `bitmap`? */
345
+ declare function bitmapBitSet(bitmap: Uint8Array, bit: number): boolean;
346
+ /** Indices of set bits in `[0, nodeCount)`, ascending. */
347
+ declare function selectedIndices(bitmap: Uint8Array, nodeCount: number): number[];
348
+ /**
349
+ * Rejection-sample `groupSize` distinct indices out of `nodeCount` from `seed`,
350
+ * returning a 32-byte big-endian bitmap. Uses the complement optimization when
351
+ * `groupSize > nodeCount / 2` (sample the smaller set, then invert).
352
+ */
353
+ declare function deriveGroupBitmap(seed: Uint8Array, nodeCount: number, groupSize: number): Uint8Array;
354
+ /**
355
+ * Convenience orchestrator: derive the selection bitmap end-to-end.
356
+ * `redundancy` defaults to 0; `ts` defaults to the current unix second.
357
+ */
358
+ declare function deriveSelectionBitmap(feedId: Uint8Array, registryVersion: number, nodeCount: number, signaturesRequired: number, redundancy?: number, ts?: number | bigint): Uint8Array;
359
+
360
+ /**
361
+ * Minimal Molpha verifier ABI for `verify` and registry reads.
362
+ * Matches `IValidator` in the Molpha EVM contracts repo.
363
+ */
364
+ declare const MOLPHA_VERIFIER_ABI: readonly [{
365
+ readonly type: "function";
366
+ readonly name: "verify";
367
+ readonly stateMutability: "view";
368
+ readonly inputs: readonly [{
369
+ readonly name: "dataUpdate";
370
+ readonly type: "tuple";
371
+ readonly components: readonly [{
372
+ readonly name: "jobId";
373
+ readonly type: "bytes32";
374
+ }, {
375
+ readonly name: "registryVersion";
376
+ readonly type: "uint32";
377
+ }, {
378
+ readonly name: "signaturesRequired";
379
+ readonly type: "uint32";
380
+ }, {
381
+ readonly name: "value";
382
+ readonly type: "bytes32";
383
+ }, {
384
+ readonly name: "canonicalTimestamp";
385
+ readonly type: "uint64";
386
+ }];
387
+ }, {
388
+ readonly name: "schnorrData";
389
+ readonly type: "tuple";
390
+ readonly components: readonly [{
391
+ readonly name: "signature";
392
+ readonly type: "bytes32";
393
+ }, {
394
+ readonly name: "commitment";
395
+ readonly type: "address";
396
+ }, {
397
+ readonly name: "signersBitmap";
398
+ readonly type: "uint256";
399
+ }];
400
+ }];
401
+ readonly outputs: readonly [{
402
+ readonly name: "";
403
+ readonly type: "bool";
404
+ }];
405
+ }, {
406
+ readonly type: "function";
407
+ readonly name: "getRegistryVersion";
408
+ readonly stateMutability: "view";
409
+ readonly inputs: readonly [];
410
+ readonly outputs: readonly [{
411
+ readonly name: "registryVersion";
412
+ readonly type: "uint256";
413
+ }];
414
+ }];
415
+
416
+ /**
417
+ * Deployed Molpha verifier contract address on EVM chains.
418
+ * Deployed via CREATE2 for the same address on every supported chain.
419
+ */
420
+ /** Supported EVM testnet identifiers (chain selection only). */
421
+ type MolphaEvmNetwork = "evm-sepolia" | "arbitrum-sepolia" | "avalanche-fuji" | "bsc-testnet";
422
+ /** CREATE2 Molpha verifier address — identical on all supported EVM chains. */
423
+ declare const MOLPHA_VERIFIER_ADDRESS: "0xE1fd792b7E54e0C8F0Cd1c8055E446ff36d233eB";
424
+
425
+ /** `(bytes32 feedId, uint32 registryVersion, uint32 signaturesRequired, bytes32 valuePacked, uint64 timestamp)` */
426
+ type EvmDataUpdateTuple = readonly [
427
+ feedId: `0x${string}`,
428
+ registryVersion: number,
429
+ signaturesRequired: number,
430
+ valuePacked: `0x${string}`,
431
+ timestamp: number
432
+ ];
433
+ /** `(bytes32 s, address commitment, uint256 signersBitmap)` */
434
+ type EvmSchnorrSignatureTuple = readonly [
435
+ s: `0x${string}`,
436
+ commitment: `0x${string}`,
437
+ signersBitmap: bigint
438
+ ];
439
+ interface EvmVerifierArgs {
440
+ dataUpdate: EvmDataUpdateTuple;
441
+ signature: EvmSchnorrSignatureTuple;
442
+ }
443
+ /**
444
+ * Normalize hex to a fixed-size `0x`-prefixed value.
445
+ * Accepts optional `0x` prefix and surrounding quotes.
446
+ */
447
+ declare function toFixedHex(value: string, bytes: number, label: string): `0x${string}`;
448
+ /** Convert a 32-byte hex bitmap to a `uint256` bigint (big-endian). */
449
+ declare function signersBitmapToUint256(value: string): bigint;
450
+ /** Build verifier `DataUpdate` and `SchnorrSignature` tuples from a gateway result. */
451
+ declare function buildEvmVerifierArgs(result: DataUpdateResult): EvmVerifierArgs;
452
+ /** Decimal string form of the signers bitmap — useful for JSON logging or legacy tooling. */
453
+ declare function signersBitmapToDecimal(value: string): string;
454
+
455
+ /**
456
+ * Deployed Molpha verifier contract addresses on Starknet testnets.
457
+ */
458
+ /** Supported Starknet testnet identifiers. */
459
+ type MolphaStarknetNetwork = "starknet-sepolia";
460
+ /** Deployed verifier address on Starknet Sepolia. */
461
+ declare const MOLPHA_VERIFIER_STARKNET_SEPOLIA: "0x0378df4dbecf8f0c7daa801282932f7011c7a5e5773bab9eaf68f5fa5e7530ef";
462
+ /** Network id -> deployed verifier address. */
463
+ declare const MOLPHA_VERIFIER_STARKNET_ADDRESSES: Record<MolphaStarknetNetwork, `0x${string}`>;
464
+ /** Resolve the deployed verifier address for a supported Starknet network. */
465
+ declare function getMolphaStarknetVerifierAddress(network: MolphaStarknetNetwork): `0x${string}`;
466
+
467
+ /** Starknet calldata shape for `DataUpdate`. */
468
+ interface StarknetDataUpdate {
469
+ feed_id: bigint;
470
+ registry_version: number;
471
+ signatures_required: number;
472
+ value: bigint;
473
+ canonical_timestamp: number;
474
+ }
475
+ /** Starknet calldata shape for `SchnorrSignature`. */
476
+ interface StarknetSchnorrSignature {
477
+ signature: bigint;
478
+ commitment: bigint;
479
+ signers_bitmap: bigint;
480
+ }
481
+ interface StarknetVerifierArgs {
482
+ dataUpdate: StarknetDataUpdate;
483
+ signature: StarknetSchnorrSignature;
484
+ }
485
+ /** Convert a 20-byte EVM-style address hex to a Starknet felt-compatible bigint. */
486
+ declare function commitmentAddressToStarknetFelt(value: string): bigint;
487
+ /** Convert a 32-byte bitmap hex to a Starknet/Cairo `u256` bigint. */
488
+ declare function signersBitmapToStarknetUint256(value: string): bigint;
489
+ /** Build verifier `DataUpdate` and `SchnorrSignature` structs from a gateway result. */
490
+ declare function buildStarknetVerifierArgs(result: DataUpdateResult): StarknetVerifierArgs;
491
+
492
+ /**
493
+ * Consumer PDA derivations (no node PDA). Seed byte strings are cross-checked
494
+ * against the IDL const seeds.
495
+ */
496
+
497
+ /** Virtual registry index used for a removed slot during a version transition. */
498
+ declare const VIRTUAL_INDEX = 4294967295;
499
+ declare const protocolConfigPda: (programId: SolanaAddress) => Address;
500
+ 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`. */
504
+ declare const planPda: (planId: number, programId: SolanaAddress) => Address;
505
+ 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
+ /**
530
+ * Build the registry-index remaining accounts for a submit. Valid only
531
+ * against the current or previous registry version (else thrown client-side).
532
+ */
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;
536
+
537
+ /**
538
+ * Vendored Molpha Anchor IDL (`target/idl/molpha.json` from the program repo).
539
+ *
540
+ * Re-exported as `MOLPHA_IDL` and used as the default in `MolphaSDK` /
541
+ * `MolphaSolanaClient.create`. Pass `idl` / `programId` only when pinning a
542
+ * different deployment. Keep this copy aligned with the on-chain program you target.
543
+ */
544
+ declare const MOLPHA_IDL: Idl;
545
+ /** Program address baked into the vendored IDL. */
546
+ declare const MOLPHA_PROGRAM_ADDRESS: string;
547
+
548
+ /**
549
+ * `@molpha/sdk` — Consumer SDK public surface.
550
+ *
551
+ * The `MolphaSDK` facade wires the gateway and Solana clients together; consumers
552
+ * who only read or only run gateway rounds can use `sdk.gateway` / `sdk.solana`
553
+ * directly (or import `MolphaGateway` / `MolphaSolanaClient` standalone).
554
+ */
555
+
556
+ type Commitment = NonNullable<ConstructorParameters<typeof AnchorProvider>[2]>["commitment"];
557
+
558
+ interface MolphaSDKOptions {
559
+ /** Defaults to `DEFAULT_GATEWAY_ENDPOINT`. Pass multiple URLs for failover. */
560
+ endpoints?: string | string[];
561
+ connection: SolanaConnection;
562
+ /** On-chain txs + gateway auth (see `MolphaWallet`). */
563
+ wallet: MolphaWallet;
564
+ /** Defaults to the vendored IDL's program address. */
565
+ programId?: Address | string;
566
+ /** Defaults to `MOLPHA_IDL`. Override when pinning a different deployment. */
567
+ idl?: Idl;
568
+ commitment?: Commitment;
569
+ }
570
+ declare class MolphaSDK {
571
+ readonly gateway: MolphaGateway;
572
+ readonly solana: MolphaSolanaClient;
573
+ constructor(opts: MolphaSDKOptions);
574
+ /**
575
+ * Request a threshold-signed data update from the gateway (against the current
576
+ * on-chain registry version) and submit it to the feed.
577
+ */
578
+ requestAndSubmit(feedId: string, opts: Omit<RequestSignedDataOptions, "feedId">): Promise<{
579
+ result: DataUpdateResult;
580
+ signature: string;
581
+ }>;
582
+ }
583
+
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 };