@molpha/sdk 0.2.0-dev-20260912150104 → 0.2.0-dev-20260913100330

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -578,40 +578,100 @@ const sepoliaDirect = MOLPHA_VERIFIER_STARKNET_SEPOLIA;
578
578
 
579
579
  ### Build verifier arguments
580
580
 
581
+ The verifier's entrypoint is `verify(attestation: Attestation, max_age: u64) -> (bool, u8)`.
582
+
581
583
  ```ts
582
584
  import { buildStarknetVerifierArgs } from "@molpha/sdk";
583
585
 
584
586
  const result = await sdk.gateway.requestSignedData({ apiConfig, signaturesRequired });
585
587
 
586
- const { dataUpdate, signature } = buildStarknetVerifierArgs(result);
588
+ const { attestation, maxAge } = buildStarknetVerifierArgs(result, { maxAge: 300 });
587
589
  ```
588
590
 
589
- The generated objects match the Molpha Starknet verifier interface (the Cairo struct still names the first field `feed_id`; positional calldata is unchanged):
591
+ `maxAge` is required. It is the freshness window in seconds: the verifier reports an older
592
+ attestation as `STALE`. `0` disables the check entirely — pass it only when your contract
593
+ enforces freshness or ordering itself, because a stateless verifier otherwise accepts a
594
+ correctly signed attestation forever.
595
+
596
+ The generated object matches the Cairo `Attestation` struct. Member order is Cairo `Serde`
597
+ order (and the signed message's order), so it differs from `DataUpdateResult`:
590
598
 
591
599
  ```ts
592
- // dataUpdate:
593
- // {
594
- // source_id: u256,
595
- // registry_version: u32,
596
- // signatures_required: u32,
597
- // value: u256,
598
- // canonical_timestamp: u64,
599
- // }
600
+ attestation:
601
+ {
602
+ payload: {
603
+ value: u256,
604
+ source_id: u256,
605
+ registry_version: u32,
606
+ signatures_required: u8,
607
+ canonical_timestamp: u64,
608
+ },
609
+ signature: {
610
+ signature: u256,
611
+ commitment: felt252, // 20-byte address as felt
612
+ signers_bitmap: u256,
613
+ },
614
+ }
615
+ ```
600
616
 
601
- // signature:
602
- // {
603
- // signature: u256,
604
- // commitment: felt252, // EVM-style 20-byte address as felt
605
- // signers_bitmap: u256,
606
- // }
617
+ The builder range-checks every integer against its Cairo type. Out-of-range calldata never
618
+ reaches `verify`: Cairo `Serde` fails while decoding the arguments and the call reverts
619
+ instead of returning a result code.
620
+
621
+ ### Call `verify` and read the result
622
+
623
+ `encodeStarknetVerifyCalldata` flattens the arguments into the 13 felts a raw `starknet_call`
624
+ takes, and `parseStarknetVerifyResult` decodes the `(bool, u8)` it returns. Any Starknet
625
+ client works; with `starknet.js`:
626
+
627
+ ```ts
628
+ import { RpcProvider } from "starknet";
629
+ import {
630
+ buildStarknetVerifierArgs,
631
+ encodeStarknetVerifyCalldata,
632
+ parseStarknetVerifyResult,
633
+ } from "@molpha/sdk";
634
+
635
+ const provider = new RpcProvider({ nodeUrl: STARKNET_RPC_URL });
636
+ const args = buildStarknetVerifierArgs(result, { maxAge: 300 });
637
+
638
+ const response = await provider.callContract({
639
+ contractAddress: verifierAddress,
640
+ entrypoint: "verify",
641
+ calldata: encodeStarknetVerifyCalldata(args),
642
+ });
643
+
644
+ const { success, code, reason } = parseStarknetVerifyResult(response);
645
+ // { success: true, code: 0, reason: "OK" }
646
+ // { success: false, code: 10, reason: "STALE" }
607
647
  ```
608
648
 
649
+ `verify` never reverts on well-formed calldata; a rejection is a result code. The codes are
650
+ shared with the EVM verifier contract and exported as `VERIFY_CODES`:
651
+
652
+ | Code | Name | Meaning |
653
+ |---|---|---|
654
+ | 0 | `OK` | Verified |
655
+ | 2 | `BAD_REGISTRY_VERSION` | `registryVersion` does not exist on this verifier |
656
+ | 3 | `MALFORMED` | Structurally invalid input, or dated in the future when `maxAge != 0` |
657
+ | 4 | `NOT_YET_ACTIVE` | `canonicalTimestamp` predates the registry version's activation |
658
+ | 5 | `VERSION_EXPIRED` | Registry version superseded more than the grace window earlier |
659
+ | 7 | `BAD_QUORUM` | Signers are not within the round's derived selection group |
660
+ | 8 | `BAD_AGGREGATE` | The signers' aggregate key is the point at infinity |
661
+ | 9 | `BAD_SIGNATURE` | The aggregate Schnorr signature does not verify |
662
+ | 10 | `STALE` | Older than `maxAge` |
663
+
664
+ Codes 1 and 6 are reserved and never returned. Codes are append-only, so
665
+ `parseStarknetVerifyResult` reports a code newer than your SDK as `reason: "UNKNOWN"` rather
666
+ than throwing.
667
+
609
668
  Lower-level helpers are also exported:
610
669
 
611
670
  ```ts
612
671
  import {
613
672
  commitmentAddressToStarknetFelt,
614
673
  signersBitmapToStarknetUint256,
674
+ verifyCodeName,
615
675
  } from "@molpha/sdk";
616
676
  ```
617
677
 
@@ -686,7 +746,7 @@ Current scope:
686
746
  - Solana attestation submission and feed/registry reads;
687
747
  - private API encryption helpers (pre-production);
688
748
  - caller-funded x402 payments for paywalled API sources (Base USDC, pre-production);
689
- - EVM and Starknet verifier argument building;
749
+ - EVM and Starknet verifier argument building, Starknet `verify` calldata encoding and result decoding;
690
750
  - deployed testnet verifier address helpers.
691
751
 
692
752
  Known limitations:
@@ -716,6 +776,9 @@ Solana paths such as selection bitmap and `submit_attestation` remaining-account
716
776
  | `result.feedId` / `NodeKeyVerifierArgs.feedId` | `.sourceId` |
717
777
  | EVM tuple `feedId`, ABI `jobId` | `sourceId` |
718
778
  | Starknet `feed_id` | `source_id` |
779
+ | `buildStarknetVerifierArgs(result)` → `{ dataUpdate, signature }` | `buildStarknetVerifierArgs(result, { maxAge })` → `{ attestation, maxAge }` for `verify(attestation, max_age)` |
780
+ | `StarknetDataUpdate` (`signatures_required: u32`) | `StarknetAttestationPayload` (`signatures_required: u8`, `value` first), nested in `StarknetAttestation` |
781
+ | Starknet `verify` returns `bool` | returns `(bool, u8)` — decode with `parseStarknetVerifyResult` |
719
782
  | `resolveRegistryIndexForVersion`, `VIRTUAL_INDEX`, `nodePda(index)` | removed — signer accounts are `registry.nodes[bit]`; `nodePda(owner)` |
720
783
 
721
784
  ## Develop
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Address } from '@solana/kit';
2
2
  import { Wallet, Idl, AnchorProvider } from '@anchor-lang/core';
3
- import { U as UpstreamQuote, A as APIConfig, a as AssetDomain, b as UpstreamTerms, E as EvmSigner, R as RegistrySelectionConfig, S as Signer, N as NodeKeyVerifier, c as Node, d as NodesInfo, e as SourcePaymentOptions, D as DataUpdateResult, f as SolanaAccountMeta, g as SolanaConnection, h as SolanaAddress, i as NodeKeyVerifierArgs, M as MolphaWallet } from './wallet-B3mYmC2b.js';
4
- export { j as EncKeyBundle, k as RegistryInfo, l as SchnorrSignature, m as gatewaySignerFromWallet, s as signerFromKeypair } from './wallet-B3mYmC2b.js';
3
+ import { U as UpstreamQuote, A as APIConfig, a as AssetDomain, b as UpstreamTerms, E as EvmSigner, R as RegistrySelectionConfig, S as Signer, N as NodeKeyVerifier, c as Node, d as NodesInfo, e as SourcePaymentOptions, D as DataUpdateResult, f as SolanaAccountMeta, g as SolanaConnection, h as SolanaAddress, i as NodeKeyVerifierArgs, M as MolphaWallet } from './wallet-DwdBZgl1.js';
4
+ export { j as EncKeyBundle, k as RegistryInfo, l as SchnorrSignature, m as gatewaySignerFromWallet, s as signerFromKeypair } from './wallet-DwdBZgl1.js';
5
5
  import BN from 'bn.js';
6
6
 
7
7
  /**
@@ -608,6 +608,45 @@ declare function deriveGroupBitmap(seed: Uint8Array, nodeCount: number, groupSiz
608
608
  */
609
609
  declare function deriveSelectionBitmap(sourceId: Uint8Array, registryVersion: number, nodeCount: number, signaturesRequired: number, redundancy?: number, ts?: number | bigint): Uint8Array;
610
610
 
611
+ /**
612
+ * Result codes returned by Molpha's stateless verifier contracts (`verify` on EVM and
613
+ * Starknet). Shared across VMs: the same attestation yields the same code on every chain.
614
+ *
615
+ * Append-only — never renumber. Mirrors `VerifyCodes.sol` in `molpha-core-contracts` and
616
+ * `verify_codes.cairo` in `molpha-starknet`. Two codes belong to mechanisms the verifiers
617
+ * do not implement; they are kept so the numbering can never shift under them.
618
+ */
619
+ declare const VERIFY_CODES: {
620
+ readonly OK: 0;
621
+ /** Reserved. Never returned. */
622
+ readonly FEED_WITNESS: 1;
623
+ /** The payload's `registryVersion` does not exist on this verifier. */
624
+ readonly BAD_REGISTRY_VERSION: 2;
625
+ /** Structurally invalid input, or a `canonicalTimestamp` in the future when `maxAge != 0`. */
626
+ readonly MALFORMED: 3;
627
+ /** `canonicalTimestamp` predates the registry version's activation. */
628
+ readonly NOT_YET_ACTIVE: 4;
629
+ /** The registry version was superseded more than the grace window before `canonicalTimestamp`. */
630
+ readonly VERSION_EXPIRED: 5;
631
+ /** Reserved. Never returned. */
632
+ readonly COMPROMISED_QUORUM: 6;
633
+ /** The signer set is not within the round's derived selection group. */
634
+ readonly BAD_QUORUM: 7;
635
+ /** The signers' aggregate public key is the point at infinity. */
636
+ readonly BAD_AGGREGATE: 8;
637
+ /** The aggregate Schnorr signature does not verify. */
638
+ readonly BAD_SIGNATURE: 9;
639
+ /** Older than the caller's `maxAge`. */
640
+ readonly STALE: 10;
641
+ };
642
+ type VerifyCodeName = keyof typeof VERIFY_CODES;
643
+ type VerifyCode = (typeof VERIFY_CODES)[VerifyCodeName];
644
+ /**
645
+ * Name of a verifier result code, or `undefined` for a code this SDK version does not know.
646
+ * Codes are append-only, so an unknown code is a newer verifier, not a malformed response.
647
+ */
648
+ declare function verifyCodeName(code: number): VerifyCodeName | undefined;
649
+
611
650
  /**
612
651
  * Minimal Molpha verifier ABI for `verify` and registry reads.
613
652
  * Matches the deployed `verify(DataUpdate, SchnorrSignature)` verifier. The first tuple
@@ -751,31 +790,100 @@ declare const MOLPHA_VERIFIER_STARKNET_ADDRESSES: Record<MolphaStarknetNetwork,
751
790
  /** Resolve the deployed verifier address for a supported Starknet network. */
752
791
  declare function getMolphaStarknetVerifierAddress(network: MolphaStarknetNetwork): `0x${string}`;
753
792
 
754
- /** Starknet calldata shape for `DataUpdate`. */
755
- interface StarknetDataUpdate {
756
- /** 32-byte source id as u256 (the Cairo struct still names this field `feed_id`). */
793
+ /**
794
+ * Starknet calldata shape for `AttestationPayload`.
795
+ *
796
+ * Member order is the order of the signed message preimage and of Cairo `Serde`, so it is
797
+ * load bearing — it is not the order of `DataUpdateResult`.
798
+ */
799
+ interface StarknetAttestationPayload {
800
+ /** 32-byte packed value as `u256`. */
801
+ value: bigint;
802
+ /** 32-byte source id as `u256`. */
757
803
  source_id: bigint;
804
+ /** `u32`. */
758
805
  registry_version: number;
806
+ /** `u8`. */
759
807
  signatures_required: number;
760
- value: bigint;
808
+ /** `u64`, unix seconds. */
761
809
  canonical_timestamp: number;
762
810
  }
763
811
  /** Starknet calldata shape for `SchnorrSignature`. */
764
812
  interface StarknetSchnorrSignature {
813
+ /** Schnorr scalar `s` as `u256`. */
765
814
  signature: bigint;
815
+ /** Ethereum-style 20-byte address of the nonce point `R`, as a `felt252`. */
766
816
  commitment: bigint;
817
+ /** Big-endian signers bitmap as `u256`; bit `i` is node `i` of the registry version. */
767
818
  signers_bitmap: bigint;
768
819
  }
769
- interface StarknetVerifierArgs {
770
- dataUpdate: StarknetDataUpdate;
820
+ /** Starknet calldata shape for `Attestation`. */
821
+ interface StarknetAttestation {
822
+ payload: StarknetAttestationPayload;
771
823
  signature: StarknetSchnorrSignature;
772
824
  }
773
- /** Convert a 20-byte EVM-style address hex to a Starknet felt-compatible bigint. */
825
+ /** Positional arguments for `verify(attestation, max_age)`. */
826
+ interface StarknetVerifierArgs {
827
+ attestation: StarknetAttestation;
828
+ /** Freshness window in seconds (`u64`). `0` disables the check. */
829
+ maxAge: number;
830
+ }
831
+ interface BuildStarknetVerifierArgsOptions {
832
+ /**
833
+ * Freshness window in seconds. The verifier rejects the attestation with `STALE` when it
834
+ * is older than this, and as `MALFORMED` when it is dated in the future.
835
+ *
836
+ * Required on purpose. `0` disables the check entirely, and that is not a neutral
837
+ * default: the verifier is stateless, so without a window it accepts a correctly signed
838
+ * attestation forever. Pass `0` only when the consuming contract enforces freshness or
839
+ * ordering itself.
840
+ */
841
+ maxAge: number;
842
+ }
843
+ /** Decoded `verify` return value. */
844
+ interface StarknetVerifyResult {
845
+ success: boolean;
846
+ /** Raw result code — see `VERIFY_CODES`. */
847
+ code: number;
848
+ /** Name of `code`, or `"UNKNOWN"` for a code newer than this SDK. */
849
+ reason: VerifyCodeName | "UNKNOWN";
850
+ }
851
+ /** A felt as returned by `starknet_call` (hex or decimal string) or by an ABI-aware client. */
852
+ type StarknetFeltLike = string | number | bigint | boolean;
853
+ /** Convert a 20-byte commitment address hex to a Starknet felt-compatible bigint. */
774
854
  declare function commitmentAddressToStarknetFelt(value: string): bigint;
775
855
  /** Convert a 32-byte bitmap hex to a Starknet/Cairo `u256` bigint. */
776
856
  declare function signersBitmapToStarknetUint256(value: string): bigint;
777
- /** Build verifier `DataUpdate` and `SchnorrSignature` structs from a gateway result. */
778
- declare function buildStarknetVerifierArgs(result: DataUpdateResult): StarknetVerifierArgs;
857
+ /**
858
+ * Build the `verify(attestation, max_age)` arguments from a gateway result.
859
+ *
860
+ * ```ts
861
+ * const { attestation, maxAge } = buildStarknetVerifierArgs(result, { maxAge: 300 });
862
+ * ```
863
+ */
864
+ declare function buildStarknetVerifierArgs(result: DataUpdateResult, options: BuildStarknetVerifierArgsOptions): StarknetVerifierArgs;
865
+ /**
866
+ * Flat felt calldata for `verify(attestation, max_age)`, in Cairo `Serde` order — 13 felts:
867
+ *
868
+ * `value.low, value.high, source_id.low, source_id.high, registry_version,
869
+ * signatures_required, canonical_timestamp, signature.low, signature.high, commitment,
870
+ * signers_bitmap.low, signers_bitmap.high, max_age`
871
+ *
872
+ * For a raw `starknet_call` with `entry_point_selector = selector("verify")`.
873
+ */
874
+ declare function encodeStarknetVerifyCalldata(args: StarknetVerifierArgs): `0x${string}`[];
875
+ /**
876
+ * Decode the `(bool, u8)` returned by `verify`.
877
+ *
878
+ * Accepts the raw two-felt array from `starknet_call` (e.g. `["0x1", "0x0"]`) or the tuple
879
+ * an ABI-aware client decodes (e.g. `{ 0: true, 1: 0n }`). Throws when the two halves
880
+ * disagree (`success` with a non-zero code, or failure with `OK`), which means the call did
881
+ * not reach a Molpha verifier of this interface.
882
+ */
883
+ declare function parseStarknetVerifyResult(result: readonly StarknetFeltLike[] | {
884
+ readonly 0: StarknetFeltLike;
885
+ readonly 1: StarknetFeltLike;
886
+ }): StarknetVerifyResult;
779
887
 
780
888
  /**
781
889
  * Consumer PDA derivations. Seed byte strings are cross-checked against the IDL const
@@ -856,4 +964,4 @@ declare class MolphaSDK {
856
964
  }>;
857
965
  }
858
966
 
859
- export { APIConfig, AssetDomain, type AttestationMessageFields, DEFAULT_GATEWAY_ENDPOINT, DataUpdateResult, EIP712_DOMAIN_TYPEHASH, type Eip712Domain, type EvmDataUpdateTuple, type EvmSchnorrSignatureTuple, EvmSigner, 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, NodesInfo, type PlanId, type PlanInfo, PlanType, REQUEST_AUTH_DOMAIN, RegistrySelectionConfig, type RegistryStateView, type RegistryView, type RequestAuthFields, type RequestSignedDataOptions, type RoundContext, Signer, SourcePaymentOptions, type StarknetDataUpdate, type StarknetSchnorrSignature, type StarknetVerifierArgs, type SubmitAttestationArgs, type SubmitResult, type SubscribeResult, type SubscriptionInfo, TRANSFER_WITH_AUTHORIZATION_TYPEHASH, type TransferAuthorization, UpstreamPaymentRequiredError, UpstreamQuote, UpstreamTerms, addressToBytes, attestationMessageHash, attestationMessageHashFromResult, base64ToBytes, bigIntFromBytesBe, bitmapBitSet, bitmapToIndices, buildEvmVerifierArgs, buildStarknetVerifierArgs, buildSubmitAttestationArgs, bytesToBase64, bytesToHex, bytesToHex0x, canonicalizeAPIConfig, commitmentAddressToStarknetFelt, concatBytes, createEvmSignerFromPrivateKey, deriveApiConfigHash, deriveGatewayPda, deriveGatewayPdaAddress, deriveGroupBitmap, deriveSelectionBitmap, deriveSelectionSeed, deriveSourceId, deriveSourceIdString, domainSeparator, effectiveSelectionSize, eligibleSetSize, encodeRequestAuth, ensureLength, evmAddressFromPrivateKey, feedPda, gatewayPda, getMolphaStarknetVerifierAddress, hashRequestAuth, hexToBytes, nodePda, normalizeEndpoint, normalizeSecp256k1PublicKeyHex, parseGatewayInfo, parseUpstreamQuote, planIdFromVariant, planPda, planVariant, probeSource, protocolConfigPda, registryPda, registryStatePda, resolveRemainingAccounts, secp256k1PublicKeyFromCoordinates, selectedIndices, signSourcePayments, signersBitmapToDecimal, signersBitmapToStarknetUint256, signersBitmapToUint256, subscriptionPda, toChecksumAddress, toFixedBytes, toFixedHex, transferWithAuthorizationDigest, transferWithAuthorizationHash, u256beFromBigInt, u32be, u32le, u64be, u64le, utf8, validateSuppliedTerms };
967
+ export { APIConfig, AssetDomain, type AttestationMessageFields, type BuildStarknetVerifierArgsOptions, DEFAULT_GATEWAY_ENDPOINT, DataUpdateResult, EIP712_DOMAIN_TYPEHASH, type Eip712Domain, type EvmDataUpdateTuple, type EvmSchnorrSignatureTuple, EvmSigner, 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, NodesInfo, type PlanId, type PlanInfo, PlanType, REQUEST_AUTH_DOMAIN, RegistrySelectionConfig, type RegistryStateView, type RegistryView, type RequestAuthFields, type RequestSignedDataOptions, type RoundContext, Signer, SourcePaymentOptions, type StarknetAttestation, type StarknetAttestationPayload, type StarknetFeltLike, type StarknetSchnorrSignature, type StarknetVerifierArgs, type StarknetVerifyResult, type SubmitAttestationArgs, type SubmitResult, type SubscribeResult, type SubscriptionInfo, TRANSFER_WITH_AUTHORIZATION_TYPEHASH, type TransferAuthorization, UpstreamPaymentRequiredError, UpstreamQuote, UpstreamTerms, VERIFY_CODES, type VerifyCode, type VerifyCodeName, addressToBytes, attestationMessageHash, attestationMessageHashFromResult, base64ToBytes, bigIntFromBytesBe, bitmapBitSet, bitmapToIndices, buildEvmVerifierArgs, buildStarknetVerifierArgs, buildSubmitAttestationArgs, bytesToBase64, bytesToHex, bytesToHex0x, canonicalizeAPIConfig, commitmentAddressToStarknetFelt, concatBytes, createEvmSignerFromPrivateKey, deriveApiConfigHash, deriveGatewayPda, deriveGatewayPdaAddress, deriveGroupBitmap, deriveSelectionBitmap, deriveSelectionSeed, deriveSourceId, deriveSourceIdString, domainSeparator, effectiveSelectionSize, eligibleSetSize, encodeRequestAuth, encodeStarknetVerifyCalldata, ensureLength, evmAddressFromPrivateKey, feedPda, gatewayPda, getMolphaStarknetVerifierAddress, hashRequestAuth, hexToBytes, nodePda, normalizeEndpoint, normalizeSecp256k1PublicKeyHex, parseGatewayInfo, parseStarknetVerifyResult, parseUpstreamQuote, planIdFromVariant, planPda, planVariant, probeSource, protocolConfigPda, registryPda, registryStatePda, resolveRemainingAccounts, secp256k1PublicKeyFromCoordinates, selectedIndices, signSourcePayments, signersBitmapToDecimal, signersBitmapToStarknetUint256, signersBitmapToUint256, subscriptionPda, toChecksumAddress, toFixedBytes, toFixedHex, transferWithAuthorizationDigest, transferWithAuthorizationHash, u256beFromBigInt, u32be, u32le, u64be, u64le, utf8, validateSuppliedTerms, verifyCodeName };
package/dist/index.js CHANGED
@@ -11559,6 +11559,40 @@ function attestationMessageHashFromResult(result) {
11559
11559
  });
11560
11560
  }
11561
11561
 
11562
+ // src/core/verifyCodes.ts
11563
+ var VERIFY_CODES = {
11564
+ OK: 0,
11565
+ /** Reserved. Never returned. */
11566
+ FEED_WITNESS: 1,
11567
+ /** The payload's `registryVersion` does not exist on this verifier. */
11568
+ BAD_REGISTRY_VERSION: 2,
11569
+ /** Structurally invalid input, or a `canonicalTimestamp` in the future when `maxAge != 0`. */
11570
+ MALFORMED: 3,
11571
+ /** `canonicalTimestamp` predates the registry version's activation. */
11572
+ NOT_YET_ACTIVE: 4,
11573
+ /** The registry version was superseded more than the grace window before `canonicalTimestamp`. */
11574
+ VERSION_EXPIRED: 5,
11575
+ /** Reserved. Never returned. */
11576
+ COMPROMISED_QUORUM: 6,
11577
+ /** The signer set is not within the round's derived selection group. */
11578
+ BAD_QUORUM: 7,
11579
+ /** The signers' aggregate public key is the point at infinity. */
11580
+ BAD_AGGREGATE: 8,
11581
+ /** The aggregate Schnorr signature does not verify. */
11582
+ BAD_SIGNATURE: 9,
11583
+ /** Older than the caller's `maxAge`. */
11584
+ STALE: 10
11585
+ };
11586
+ var NAMES_BY_CODE = new Map(
11587
+ Object.entries(VERIFY_CODES).map(([name, code]) => [
11588
+ code,
11589
+ name
11590
+ ])
11591
+ );
11592
+ function verifyCodeName(code) {
11593
+ return NAMES_BY_CODE.get(code);
11594
+ }
11595
+
11562
11596
  // src/evm/abi.ts
11563
11597
  var MOLPHA_VERIFIER_ABI = [
11564
11598
  {
@@ -11654,6 +11688,12 @@ function getMolphaStarknetVerifierAddress(network) {
11654
11688
  }
11655
11689
 
11656
11690
  // src/starknet/helpers.ts
11691
+ var U8_MAX = 0xffn;
11692
+ var U32_MAX2 = 0xffffffffn;
11693
+ var U64_MAX = 0xffffffffffffffffn;
11694
+ var U128_MASK = (1n << 128n) - 1n;
11695
+ var U256_MAX = (1n << 256n) - 1n;
11696
+ var ADDRESS_MAX = (1n << 160n) - 1n;
11657
11697
  function strip0x2(value) {
11658
11698
  return value.startsWith("0x") || value.startsWith("0X") ? value.slice(2) : value;
11659
11699
  }
@@ -11678,26 +11718,99 @@ function fixedHexToBigInt(value, bytes, label) {
11678
11718
  const raw = toFixedBytes(hex, bytes, label);
11679
11719
  return bigIntFromBytesBe(raw);
11680
11720
  }
11721
+ function assertUint2(value, max, label) {
11722
+ if (!Number.isSafeInteger(value) || value < 0 || BigInt(value) > max) {
11723
+ throw new RangeError(`${label}: expected an integer in 0..${max}, got ${value}`);
11724
+ }
11725
+ return value;
11726
+ }
11727
+ function assertBigUint(value, max, label) {
11728
+ if (value < 0n || value > max) {
11729
+ throw new RangeError(`${label}: expected an integer in 0..${max}, got ${value}`);
11730
+ }
11731
+ return value;
11732
+ }
11733
+ function toFelt(value) {
11734
+ return `0x${BigInt(value).toString(16)}`;
11735
+ }
11736
+ function u256Felts(value, label) {
11737
+ assertBigUint(value, U256_MAX, label);
11738
+ return [toFelt(value & U128_MASK), toFelt(value >> 128n)];
11739
+ }
11740
+ function feltToBigInt(value, label) {
11741
+ if (typeof value === "boolean") return value ? 1n : 0n;
11742
+ if (typeof value === "bigint") return value;
11743
+ if (typeof value === "number") {
11744
+ if (!Number.isSafeInteger(value)) throw new RangeError(`${label}: not an integer: ${value}`);
11745
+ return BigInt(value);
11746
+ }
11747
+ const text = value.trim();
11748
+ if (!/^(0x[0-9a-fA-F]+|[0-9]+)$/.test(text)) {
11749
+ throw new RangeError(`${label}: not a felt: ${JSON.stringify(value)}`);
11750
+ }
11751
+ return BigInt(text);
11752
+ }
11681
11753
  function commitmentAddressToStarknetFelt(value) {
11682
11754
  return fixedHexToBigInt(value, 20, "commitment");
11683
11755
  }
11684
11756
  function signersBitmapToStarknetUint256(value) {
11685
11757
  return fixedHexToBigInt(value, 32, "signersBitmap");
11686
11758
  }
11687
- function buildStarknetVerifierArgs(result) {
11688
- const dataUpdate = {
11689
- source_id: fixedHexToBigInt(result.sourceId, 32, "sourceId"),
11690
- registry_version: result.registryVersion,
11691
- signatures_required: result.signaturesRequired,
11759
+ function buildStarknetVerifierArgs(result, options) {
11760
+ const payload = {
11692
11761
  value: fixedHexToBigInt(result.valuePacked, 32, "valuePacked"),
11693
- canonical_timestamp: result.timestamp
11762
+ source_id: fixedHexToBigInt(result.sourceId, 32, "sourceId"),
11763
+ registry_version: assertUint2(result.registryVersion, U32_MAX2, "registryVersion"),
11764
+ signatures_required: assertUint2(result.signaturesRequired, U8_MAX, "signaturesRequired"),
11765
+ canonical_timestamp: assertUint2(result.timestamp, U64_MAX, "timestamp")
11694
11766
  };
11695
11767
  const signature = {
11696
11768
  signature: fixedHexToBigInt(result.s, 32, "signature"),
11697
11769
  commitment: commitmentAddressToStarknetFelt(result.commitmentAddr),
11698
11770
  signers_bitmap: signersBitmapToStarknetUint256(result.signersBitmap)
11699
11771
  };
11700
- return { dataUpdate, signature };
11772
+ return {
11773
+ attestation: { payload, signature },
11774
+ maxAge: assertUint2(options.maxAge, U64_MAX, "maxAge")
11775
+ };
11776
+ }
11777
+ function encodeStarknetVerifyCalldata(args) {
11778
+ const { payload, signature } = args.attestation;
11779
+ return [
11780
+ ...u256Felts(payload.value, "value"),
11781
+ ...u256Felts(payload.source_id, "source_id"),
11782
+ toFelt(assertUint2(payload.registry_version, U32_MAX2, "registry_version")),
11783
+ toFelt(assertUint2(payload.signatures_required, U8_MAX, "signatures_required")),
11784
+ toFelt(assertUint2(payload.canonical_timestamp, U64_MAX, "canonical_timestamp")),
11785
+ ...u256Felts(signature.signature, "signature"),
11786
+ // An Ethereum-style address, so it must fit 160 bits (the verifier reports a wider one
11787
+ // as `MALFORMED`; one past the field prime would not even deserialize).
11788
+ toFelt(assertBigUint(signature.commitment, ADDRESS_MAX, "commitment")),
11789
+ ...u256Felts(signature.signers_bitmap, "signers_bitmap"),
11790
+ toFelt(assertUint2(args.maxAge, U64_MAX, "maxAge"))
11791
+ ];
11792
+ }
11793
+ function parseStarknetVerifyResult(result) {
11794
+ if (Array.isArray(result) && result.length !== 2) {
11795
+ throw new RangeError(`verify result: expected 2 felts, got ${result.length}`);
11796
+ }
11797
+ const tuple = result;
11798
+ const successFelt = feltToBigInt(tuple[0], "verify result success");
11799
+ if (successFelt !== 0n && successFelt !== 1n) {
11800
+ throw new RangeError(`verify result: success must be 0 or 1, got ${successFelt}`);
11801
+ }
11802
+ const codeFelt = feltToBigInt(tuple[1], "verify result code");
11803
+ if (codeFelt < 0n || codeFelt > U8_MAX) {
11804
+ throw new RangeError(`verify result: code must fit u8, got ${codeFelt}`);
11805
+ }
11806
+ const success = successFelt === 1n;
11807
+ const code = Number(codeFelt);
11808
+ if (success !== (code === VERIFY_CODES.OK)) {
11809
+ throw new Error(
11810
+ `verify result is inconsistent: success=${success} with code ${code}; the call did not reach a Molpha verifier with this interface`
11811
+ );
11812
+ }
11813
+ return { success, code, reason: verifyCodeName(code) ?? "UNKNOWN" };
11701
11814
  }
11702
11815
 
11703
11816
  // src/index.ts
@@ -11735,6 +11848,6 @@ var MolphaSDK = class {
11735
11848
  }
11736
11849
  };
11737
11850
 
11738
- export { DEFAULT_GATEWAY_ENDPOINT, EIP712_DOMAIN_TYPEHASH, GatewayError, MESSAGE_PREFIX, MOLPHA_IDL, MOLPHA_PROGRAM_ADDRESS, MOLPHA_PROGRAM_ID, MOLPHA_VERIFIER_ABI, MOLPHA_VERIFIER_ADDRESS, MOLPHA_VERIFIER_STARKNET_ADDRESSES, MOLPHA_VERIFIER_STARKNET_SEPOLIA, MolphaGateway, MolphaSDK, MolphaSolanaClient, PlanType, REQUEST_AUTH_DOMAIN, TRANSFER_WITH_AUTHORIZATION_TYPEHASH, UpstreamPaymentRequiredError, addressToBytes, attestationMessageHash, attestationMessageHashFromResult, base64ToBytes, bigIntFromBytesBe, bitmapBitSet, bitmapToIndices, buildEvmVerifierArgs, buildStarknetVerifierArgs, buildSubmitAttestationArgs, bytesToBase64, bytesToHex, bytesToHex0x, canonicalizeAPIConfig, commitmentAddressToStarknetFelt, concatBytes, createEvmSignerFromPrivateKey, deriveApiConfigHash, deriveGatewayPda, deriveGatewayPdaAddress, deriveGroupBitmap, deriveSelectionBitmap, deriveSelectionSeed, deriveSourceId, deriveSourceIdString, domainSeparator, effectiveSelectionSize, eligibleSetSize, encodeRequestAuth, ensureLength, evmAddressFromPrivateKey, feedPda, gatewayPda, getMolphaStarknetVerifierAddress, hashRequestAuth, hexToBytes, nodePda, normalizeEndpoint, normalizeSecp256k1PublicKeyHex, parseGatewayInfo, parseUpstreamQuote, planIdFromVariant, planPda, planVariant, probeSource, protocolConfigPda, registryPda, registryStatePda, resolveRemainingAccounts, secp256k1PublicKeyFromCoordinates, selectedIndices, signSourcePayments, signersBitmapToDecimal, signersBitmapToStarknetUint256, signersBitmapToUint256, subscriptionPda, toChecksumAddress, toFixedBytes, toFixedHex, transferWithAuthorizationDigest, transferWithAuthorizationHash, u256beFromBigInt, u32be, u32le, u64be, u64le, utf8, validateSuppliedTerms };
11851
+ export { DEFAULT_GATEWAY_ENDPOINT, EIP712_DOMAIN_TYPEHASH, GatewayError, MESSAGE_PREFIX, MOLPHA_IDL, MOLPHA_PROGRAM_ADDRESS, MOLPHA_PROGRAM_ID, MOLPHA_VERIFIER_ABI, MOLPHA_VERIFIER_ADDRESS, MOLPHA_VERIFIER_STARKNET_ADDRESSES, MOLPHA_VERIFIER_STARKNET_SEPOLIA, MolphaGateway, MolphaSDK, MolphaSolanaClient, PlanType, REQUEST_AUTH_DOMAIN, TRANSFER_WITH_AUTHORIZATION_TYPEHASH, UpstreamPaymentRequiredError, VERIFY_CODES, addressToBytes, attestationMessageHash, attestationMessageHashFromResult, base64ToBytes, bigIntFromBytesBe, bitmapBitSet, bitmapToIndices, buildEvmVerifierArgs, buildStarknetVerifierArgs, buildSubmitAttestationArgs, bytesToBase64, bytesToHex, bytesToHex0x, canonicalizeAPIConfig, commitmentAddressToStarknetFelt, concatBytes, createEvmSignerFromPrivateKey, deriveApiConfigHash, deriveGatewayPda, deriveGatewayPdaAddress, deriveGroupBitmap, deriveSelectionBitmap, deriveSelectionSeed, deriveSourceId, deriveSourceIdString, domainSeparator, effectiveSelectionSize, eligibleSetSize, encodeRequestAuth, encodeStarknetVerifyCalldata, ensureLength, evmAddressFromPrivateKey, feedPda, gatewayPda, getMolphaStarknetVerifierAddress, hashRequestAuth, hexToBytes, nodePda, normalizeEndpoint, normalizeSecp256k1PublicKeyHex, parseGatewayInfo, parseStarknetVerifyResult, parseUpstreamQuote, planIdFromVariant, planPda, planVariant, probeSource, protocolConfigPda, registryPda, registryStatePda, resolveRemainingAccounts, secp256k1PublicKeyFromCoordinates, selectedIndices, signSourcePayments, signersBitmapToDecimal, signersBitmapToStarknetUint256, signersBitmapToUint256, subscriptionPda, toChecksumAddress, toFixedBytes, toFixedHex, transferWithAuthorizationDigest, transferWithAuthorizationHash, u256beFromBigInt, u32be, u32le, u64be, u64le, utf8, validateSuppliedTerms, verifyCodeName };
11739
11852
  //# sourceMappingURL=index.js.map
11740
11853
  //# sourceMappingURL=index.js.map