@molpha/sdk 0.2.0-dev-20261010103545 → 0.2.0-dev-20261011124853
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 +29 -1
- package/dist/index.d.ts +84 -3
- package/dist/index.js +172 -20
- package/dist/index.js.map +1 -1
- package/idl/profiles/stable/molpha.json +4531 -2268
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,7 +84,7 @@ Defaults are baked at publish time from `config/deployments.json` (`MOLPHA_SDK_P
|
|
|
84
84
|
|
|
85
85
|
| npm dist-tag | Profile | Default gateway | Solana program | EVM / Starknet |
|
|
86
86
|
|---|---|---|---|---|
|
|
87
|
-
| `latest` | `stable` | `https://gateway.molpha.io/` | `
|
|
87
|
+
| `latest` | `stable` | `https://gateway.molpha.io/` | `MoLF3pgVA9MENSuEujxNNSMaTo71aLyewaH5nrWfUZs` | Documented CREATE2 / Sepolia addresses |
|
|
88
88
|
| `dev` | `dev` | `https://dev-gateway.molpha.io/` | `chivcFQgxzwkpLvW41PV431HQ4dYpaW3povQH3AdpQt` | Provisional until redeploy (`MOLPHA_DEV_VERIFIERS_PROVISIONAL`); falls back to stable addresses |
|
|
89
89
|
|
|
90
90
|
Inspect the active profile via `MOLPHA_SDK_PROFILE` and `MOLPHA_DEV_VERIFIERS_PROVISIONAL`. Local builds: `MOLPHA_SDK_PROFILE=stable pnpm build` or `MOLPHA_SDK_PROFILE=dev pnpm build` (default `dev`).
|
|
@@ -419,6 +419,34 @@ for (const r of results) {
|
|
|
419
419
|
|
|
420
420
|
It reads the registry inputs once for the whole batch; bounds concurrency, starting from half the gateway's advertised `maxInflightRounds` (at most 64, else 32) and adapting (halving on a busy answer, growing back while requests succeed); runs Solana submits on their own smaller limiter (`submitConcurrency`, default 8); never discards the signed attestation of a round whose submit failed; and returns one result per feed in input order, so a failing feed does not stop the others. Pass `submit: false` to collect attestations only. Throughput is limited by the submit path (one transaction per attestation) long before it is limited by the gateway.
|
|
421
421
|
|
|
422
|
+
### Batching attestations of one feed
|
|
423
|
+
|
|
424
|
+
At a high update rate, submit several attestations of the same feed in one transaction:
|
|
425
|
+
|
|
426
|
+
```ts
|
|
427
|
+
const { signature, count } = await sdk.solana.submitAttestations([older, newer, newest]);
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Each becomes its own `submit_attestation` instruction, sorted by timestamp, and instructions run in
|
|
431
|
+
the order they are listed, so every attestation is applied, oldest first. Separate transactions give
|
|
432
|
+
no such order. Sent a few hundred milliseconds apart they reach a leader in a different order often
|
|
433
|
+
enough (about a third at 250 ms spacing in a devnet run) that the older one is refused with
|
|
434
|
+
`FeedNotNewer`; a batch makes the spacing between transactions several times longer, and one
|
|
435
|
+
transaction costs one fee.
|
|
436
|
+
|
|
437
|
+
- All attestations must be for one feed (the same `sourceId` and `signaturesRequired`), with distinct
|
|
438
|
+
timestamps. They may differ in registry version and signer set.
|
|
439
|
+
- The transaction is atomic. If a newer attestation of the feed has already landed, every
|
|
440
|
+
instruction is stale and none applies, so batch what is due together and send batches of one feed
|
|
441
|
+
in order.
|
|
442
|
+
- A transaction holds 1232 bytes, which is about three attestations with three signers, two with
|
|
443
|
+
four or five. `maxAttestationsPerTransaction(signerCount, { distinctSigners })` estimates it, and a
|
|
444
|
+
batch that does not fit throws `BatchTooLargeError` before sending, with `fits` saying how many
|
|
445
|
+
go: submit those and the rest apart. A priority-fee instruction costs bytes too.
|
|
446
|
+
- `rawValue` is not supported in a batch; use `submitAttestation` for values longer than 32 bytes.
|
|
447
|
+
- An attestation waits for the others in its batch, so a batch of `n` made at an interval of `t`
|
|
448
|
+
delays the oldest by `(n - 1) * t`.
|
|
449
|
+
|
|
422
450
|
### Fast requests with a cached context
|
|
423
451
|
|
|
424
452
|
By default every `requestSignedData` call reads the on-chain registry up front
|
package/dist/index.d.ts
CHANGED
|
@@ -12,8 +12,8 @@ import BN from 'bn.js';
|
|
|
12
12
|
declare const MOLPHA_SDK_PROFILE: "dev";
|
|
13
13
|
declare const DEFAULT_GATEWAY_ENDPOINT = "https://dev-gateway.molpha.io/";
|
|
14
14
|
declare const MOLPHA_PROGRAM_ID = "chivcFQgxzwkpLvW41PV431HQ4dYpaW3povQH3AdpQt";
|
|
15
|
-
declare const MOLPHA_VERIFIER_ADDRESS: "
|
|
16
|
-
declare const MOLPHA_VERIFIER_STARKNET_SEPOLIA: "
|
|
15
|
+
declare const MOLPHA_VERIFIER_ADDRESS: "0xA6e49A3A1caf3E110cC04765B934C8FF118C2568";
|
|
16
|
+
declare const MOLPHA_VERIFIER_STARKNET_SEPOLIA: "0x032b9f47f12189668b94a5d62fb7d60f968ed0dbaf22090649d1d7a91d79cc38";
|
|
17
17
|
/** True when the active profile has unset EVM/Starknet addresses (dev falls back to stable). */
|
|
18
18
|
declare const MOLPHA_DEV_VERIFIERS_PROVISIONAL: true;
|
|
19
19
|
|
|
@@ -470,6 +470,33 @@ declare function planIdFromVariant(variant: Record<string, unknown>): PlanId;
|
|
|
470
470
|
* benchmark's, and a limit that is hit fails the transaction for good.
|
|
471
471
|
*/
|
|
472
472
|
declare function estimateSubmitComputeUnits(signerCount: number): number;
|
|
473
|
+
/**
|
|
474
|
+
* Compute-unit limit for one transaction that carries a `submit_attestation` per entry of
|
|
475
|
+
* `signerCounts`: the same margin as {@link estimateSubmitComputeUnits} on the sum, with the fixed
|
|
476
|
+
* 10k once for the transaction.
|
|
477
|
+
*/
|
|
478
|
+
declare function estimateSubmitBatchComputeUnits(signerCounts: number[]): number;
|
|
479
|
+
/**
|
|
480
|
+
* Bytes of `submit_attestation` instruction data with no raw value: the 8 byte discriminator, the
|
|
481
|
+
* payload (32 + 32 + 4 + 1 + 8), the signature (32 + 20 + 32), the empty `Option` and the coalition
|
|
482
|
+
* key (32 + 32).
|
|
483
|
+
*/
|
|
484
|
+
declare const SUBMIT_INSTRUCTION_DATA_BYTES = 234;
|
|
485
|
+
/**
|
|
486
|
+
* Serialized size of a transaction with `count` attestations of `signerCount` signers each, to plan
|
|
487
|
+
* a batch before there is one. The signer `Node` accounts are shared between attestations, so the
|
|
488
|
+
* size depends on how many distinct ones there are: `distinctSigners` (default `signerCount`, the
|
|
489
|
+
* best case; the registry's node count is the worst).
|
|
490
|
+
*/
|
|
491
|
+
declare function estimateSubmitTransactionSize(count: number, signerCount: number, opts?: {
|
|
492
|
+
distinctSigners?: number;
|
|
493
|
+
priorityFee?: boolean;
|
|
494
|
+
}): number;
|
|
495
|
+
/** The most attestations of `signerCount` signers that fit in one transaction; see {@link estimateSubmitTransactionSize}. */
|
|
496
|
+
declare function maxAttestationsPerTransaction(signerCount: number, opts?: {
|
|
497
|
+
distinctSigners?: number;
|
|
498
|
+
priorityFee?: boolean;
|
|
499
|
+
}): number;
|
|
473
500
|
type Commitment$1 = NonNullable<ConstructorParameters<typeof AnchorProvider>[2]>["commitment"];
|
|
474
501
|
interface SubscribeResult {
|
|
475
502
|
signature: string;
|
|
@@ -507,6 +534,31 @@ interface SubmitResult {
|
|
|
507
534
|
/** Feed PDA written by this submit (`["molpha_feed", sourceId, [signaturesRequired], submitter]`). */
|
|
508
535
|
feed: Address;
|
|
509
536
|
}
|
|
537
|
+
/** What {@link MolphaSolanaClient.submitAttestations} returns. */
|
|
538
|
+
interface SubmitAttestationsResult extends SubmitResult {
|
|
539
|
+
/** Attestations in the transaction. They were applied in timestamp order. */
|
|
540
|
+
count: number;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Thrown by {@link MolphaSolanaClient.submitAttestations} when the attestations do not fit in one
|
|
544
|
+
* transaction. Nothing was sent: submit the first `fits` of them (oldest first) and the rest apart.
|
|
545
|
+
*/
|
|
546
|
+
declare class BatchTooLargeError extends RangeError {
|
|
547
|
+
/** How many of the attestations, oldest first, do fit. */
|
|
548
|
+
readonly fits: number;
|
|
549
|
+
/** The serialized size of the whole batch, in bytes. */
|
|
550
|
+
readonly size: number;
|
|
551
|
+
/** The largest transaction the network accepts, in bytes. */
|
|
552
|
+
readonly limit: number;
|
|
553
|
+
readonly count: number;
|
|
554
|
+
constructor(
|
|
555
|
+
/** How many of the attestations, oldest first, do fit. */
|
|
556
|
+
fits: number,
|
|
557
|
+
/** The serialized size of the whole batch, in bytes. */
|
|
558
|
+
size: number,
|
|
559
|
+
/** The largest transaction the network accepts, in bytes. */
|
|
560
|
+
limit: number, count: number);
|
|
561
|
+
}
|
|
510
562
|
/**
|
|
511
563
|
* On-chain `Feed` (Anchor-decoded). `value` is always the signed
|
|
512
564
|
* `AttestationPayload.value` (32 bytes): the oracle value itself when `valueKind` is
|
|
@@ -577,6 +629,8 @@ interface SubmitAttestationOptions {
|
|
|
577
629
|
*/
|
|
578
630
|
rawValue?: Uint8Array;
|
|
579
631
|
}
|
|
632
|
+
/** Options for {@link MolphaSolanaClient.submitAttestations}. */
|
|
633
|
+
type SubmitAttestationsOptions = Pick<SubmitAttestationOptions, "computeUnitLimit" | "priorityFeeMicroLamports">;
|
|
580
634
|
interface CreateClientOpts {
|
|
581
635
|
connection: SolanaConnection;
|
|
582
636
|
wallet: Wallet;
|
|
@@ -659,6 +713,33 @@ declare class MolphaSolanaClient {
|
|
|
659
713
|
* `keccak256(rawValue)`; {@link buildSubmitAttestationArgs} validates that before send.
|
|
660
714
|
*/
|
|
661
715
|
submitAttestation(attestation: Attestation, opts?: SubmitAttestationOptions): Promise<SubmitResult>;
|
|
716
|
+
/**
|
|
717
|
+
* Submit several attestations of one feed in one transaction.
|
|
718
|
+
*
|
|
719
|
+
* Each becomes its own `submit_attestation` instruction, in timestamp order, and instructions run
|
|
720
|
+
* in the order they are listed: all of them are applied, oldest first, whatever order other
|
|
721
|
+
* transactions reach the leader in. That is what separate submits cannot promise. Transactions sent
|
|
722
|
+
* milliseconds apart for one feed are overtaken by a newer one often enough (about a third at 250 ms
|
|
723
|
+
* spacing in a devnet run) that the older one fails with `FeedNotNewer`; a batch makes the spacing
|
|
724
|
+
* between transactions several times longer and spends one fee and one signature for them all.
|
|
725
|
+
*
|
|
726
|
+
* The transaction is atomic: if one instruction fails (typically because a newer attestation
|
|
727
|
+
* of the feed landed first, so every instruction is stale) none of them applies. Batch only what
|
|
728
|
+
* is due together, and keep batches of one feed in the order they were made.
|
|
729
|
+
*
|
|
730
|
+
* All attestations must be for one feed (the same `sourceId` and `signaturesRequired`) with
|
|
731
|
+
* distinct timestamps. They need not share a registry version or a signer set. Values longer than
|
|
732
|
+
* 32 bytes (`rawValue`) are not supported here: submit those with {@link submitAttestation}.
|
|
733
|
+
*
|
|
734
|
+
* @throws {BatchTooLargeError} when they do not fit in one transaction (about three do with
|
|
735
|
+
* three signers; see {@link maxAttestationsPerTransaction}). Nothing is sent.
|
|
736
|
+
*/
|
|
737
|
+
submitAttestations(attestations: Attestation[], opts?: SubmitAttestationsOptions): Promise<SubmitAttestationsResult>;
|
|
738
|
+
/**
|
|
739
|
+
* Everything one `submit_attestation` instruction needs: the arguments, the named accounts, the
|
|
740
|
+
* signer `Node` accounts (ascending bit order) and the feed address.
|
|
741
|
+
*/
|
|
742
|
+
private prepareSubmit;
|
|
662
743
|
/** The registry for `version`, reused for {@link REGISTRY_CACHE_MS}. */
|
|
663
744
|
private fetchRegistryCached;
|
|
664
745
|
private resolvePriorityFee;
|
|
@@ -1592,4 +1673,4 @@ declare class MolphaSDK {
|
|
|
1592
1673
|
}>;
|
|
1593
1674
|
}
|
|
1594
1675
|
|
|
1595
|
-
export { APIConfig, AdaptiveLimiter, AggregationConfig, AggregationConfigError, AssetDomain, Attestation, type AttestationMessageFields, type BuildEvmVerifierArgsOptions, type BuildStarknetVerifierArgsOptions, type BulkFeed, type BulkOptions, type BulkResult, type CoalitionKey, DEFAULT_GATEWAY_ENDPOINT, DEFAULT_MAX_RETRIES, DEFAULT_ROUND_TIMEOUT_MS, EIP712_DOMAIN_TYPEHASH, type Eip712Domain, type EvmAttestation, type EvmAttestationPayload, type EvmSchnorrSignature, EvmSigner, type EvmVerifierArgs, type EvmVerifyResult, type FeedAccount, type GatewayEndpoint, type GatewayEndpointInput, GatewayError, type GatewayInfo, INT256_MAX, INT256_MIN, MESSAGE_PREFIX, MIN_TOLERANCE_SIGNATURES, MOLPHA_DEV_VERIFIERS_PROVISIONAL, MOLPHA_IDL, MOLPHA_PROGRAM_ADDRESS, MOLPHA_PROGRAM_ID, MOLPHA_SDK_PROFILE, 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, ROUND_TICK_MS, RegistrySelectionConfig, type RegistryStateView, type RegistryView, type RequestAuthFields, type RequestSignedDataOptions, type RetryCause, type RoundContext, SELECTION_WINDOW_MS, type Secp256k1KeyInput, Signer, SourcePaymentOptions, type StarknetAttestation, type StarknetAttestationPayload, type StarknetFeltLike, type StarknetSchnorrSignature, type StarknetVerifierArgs, type StarknetVerifyResult, type SubmitAttestationArgs, type SubmitAttestationOptions, SubmitFailedError, type SubmitResult, type SubscribeResult, type SubscriptionInfo, TRANSFER_WITH_AUTHORIZATION_TYPEHASH, type TransferAuthorization, UpstreamPaymentRequiredError, UpstreamQuote, UpstreamTerms, VERIFY_CODES, type VerifyCode, type VerifyCodeName, addressToBytes, assertAggregationQuorum, attestationMessageHash, attestationMessageHashFromAttestation, base64ToBytes, bigIntFromBytesBe, bitmapBitSet, bitmapToIndices, buildEvmVerifierArgs, buildStarknetVerifierArgs, buildSubmitAttestationArgs, bytesToBase64, bytesToHex, bytesToHex0x, canonicalizeAPIConfig, canonicalizeAggregation, commitmentAddressToStarknetFelt, computeCoalitionKey, concatBytes, createEvmSignerFromPrivateKey, decodeInt256, deriveGatewayPda, deriveGatewayPdaAddress, deriveGroupBitmap, deriveSelectionBitmap, deriveSelectionSeed, deriveSourceId, deriveSourceIdString, domainSeparator, effectiveSelectionSize, eligibleSetSize, encodeEvmVerifyCalldata, encodeInt256, encodeInt256Decimal, encodeRequestAuth, encodeStarknetVerifyCalldata, ensureLength, estimateSubmitComputeUnits, evmAddressFromPrivateKey, feedPda, formatInt256Decimal, gatewayPda, getMolphaStarknetVerifierAddress, hashRequestAuth, hexToBytes, nodePda, normalizeEndpoint, normalizeSecp256k1PublicKeyHex, parseEvmVerifyResult, parseGatewayInfo, parseStarknetVerifyResult, parseUpstreamQuote, planIdFromVariant, planPda, planVariant, probeSource, protocolConfigPda, registryPda, registryStatePda, requestMany, resolveRemainingAccounts, retryDelayMs, secp256k1PublicKeyFromCoordinates, selectedIndices, signSourcePayments, signersBitmapToDecimal, signersBitmapToStarknetUint256, signersBitmapToUint256, spreadOffsetMs, subscriptionPda, timestampAgeSeconds, timestampSeconds, toChecksumAddress, toFixedBytes, toFixedHex, transferWithAuthorizationDigest, transferWithAuthorizationHash, u256beFromBigInt, u32be, u32le, u64be, u64le, u8, utf8, validateSuppliedTerms, verifyCodeName };
|
|
1676
|
+
export { APIConfig, AdaptiveLimiter, AggregationConfig, AggregationConfigError, AssetDomain, Attestation, type AttestationMessageFields, BatchTooLargeError, type BuildEvmVerifierArgsOptions, type BuildStarknetVerifierArgsOptions, type BulkFeed, type BulkOptions, type BulkResult, type CoalitionKey, DEFAULT_GATEWAY_ENDPOINT, DEFAULT_MAX_RETRIES, DEFAULT_ROUND_TIMEOUT_MS, EIP712_DOMAIN_TYPEHASH, type Eip712Domain, type EvmAttestation, type EvmAttestationPayload, type EvmSchnorrSignature, EvmSigner, type EvmVerifierArgs, type EvmVerifyResult, type FeedAccount, type GatewayEndpoint, type GatewayEndpointInput, GatewayError, type GatewayInfo, INT256_MAX, INT256_MIN, MESSAGE_PREFIX, MIN_TOLERANCE_SIGNATURES, MOLPHA_DEV_VERIFIERS_PROVISIONAL, MOLPHA_IDL, MOLPHA_PROGRAM_ADDRESS, MOLPHA_PROGRAM_ID, MOLPHA_SDK_PROFILE, 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, ROUND_TICK_MS, RegistrySelectionConfig, type RegistryStateView, type RegistryView, type RequestAuthFields, type RequestSignedDataOptions, type RetryCause, type RoundContext, SELECTION_WINDOW_MS, SUBMIT_INSTRUCTION_DATA_BYTES, type Secp256k1KeyInput, Signer, SourcePaymentOptions, type StarknetAttestation, type StarknetAttestationPayload, type StarknetFeltLike, type StarknetSchnorrSignature, type StarknetVerifierArgs, type StarknetVerifyResult, type SubmitAttestationArgs, type SubmitAttestationOptions, type SubmitAttestationsOptions, type SubmitAttestationsResult, SubmitFailedError, type SubmitResult, type SubscribeResult, type SubscriptionInfo, TRANSFER_WITH_AUTHORIZATION_TYPEHASH, type TransferAuthorization, UpstreamPaymentRequiredError, UpstreamQuote, UpstreamTerms, VERIFY_CODES, type VerifyCode, type VerifyCodeName, addressToBytes, assertAggregationQuorum, attestationMessageHash, attestationMessageHashFromAttestation, base64ToBytes, bigIntFromBytesBe, bitmapBitSet, bitmapToIndices, buildEvmVerifierArgs, buildStarknetVerifierArgs, buildSubmitAttestationArgs, bytesToBase64, bytesToHex, bytesToHex0x, canonicalizeAPIConfig, canonicalizeAggregation, commitmentAddressToStarknetFelt, computeCoalitionKey, concatBytes, createEvmSignerFromPrivateKey, decodeInt256, deriveGatewayPda, deriveGatewayPdaAddress, deriveGroupBitmap, deriveSelectionBitmap, deriveSelectionSeed, deriveSourceId, deriveSourceIdString, domainSeparator, effectiveSelectionSize, eligibleSetSize, encodeEvmVerifyCalldata, encodeInt256, encodeInt256Decimal, encodeRequestAuth, encodeStarknetVerifyCalldata, ensureLength, estimateSubmitBatchComputeUnits, estimateSubmitComputeUnits, estimateSubmitTransactionSize, evmAddressFromPrivateKey, feedPda, formatInt256Decimal, gatewayPda, getMolphaStarknetVerifierAddress, hashRequestAuth, hexToBytes, maxAttestationsPerTransaction, nodePda, normalizeEndpoint, normalizeSecp256k1PublicKeyHex, parseEvmVerifyResult, parseGatewayInfo, parseStarknetVerifyResult, parseUpstreamQuote, planIdFromVariant, planPda, planVariant, probeSource, protocolConfigPda, registryPda, registryStatePda, requestMany, resolveRemainingAccounts, retryDelayMs, secp256k1PublicKeyFromCoordinates, selectedIndices, signSourcePayments, signersBitmapToDecimal, signersBitmapToStarknetUint256, signersBitmapToUint256, spreadOffsetMs, subscriptionPda, timestampAgeSeconds, timestampSeconds, toChecksumAddress, toFixedBytes, toFixedHex, transferWithAuthorizationDigest, transferWithAuthorizationHash, u256beFromBigInt, u32be, u32le, u64be, u64le, u8, utf8, validateSuppliedTerms, verifyCodeName };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { toPublicKey, addressBytes,
|
|
1
|
+
import { toPublicKey, addressBytes, setComputeUnitLimit, setComputeUnitPrice, SYSTEM_PROGRAM_ADDRESS, toSolanaAddress, getAssociatedTokenAddressSync, TOKEN_PROGRAM_ADDRESS, addressFromBytes, findProgramAddressSync } from './chunk-H77BBZOL.js';
|
|
2
2
|
import { getAddressEncoder, address, getProgramDerivedAddress } from '@solana/kit';
|
|
3
3
|
import { keccak_256 } from '@noble/hashes/sha3.js';
|
|
4
4
|
import { utf8ToBytes, hexToBytes as hexToBytes$1, concatBytes as concatBytes$1, bytesToHex as bytesToHex$1, randomBytes } from '@noble/hashes/utils.js';
|
|
5
5
|
import { secp256k1 } from '@noble/curves/secp256k1.js';
|
|
6
6
|
import { gcm } from '@noble/ciphers/aes.js';
|
|
7
|
-
import { AnchorProvider, Program
|
|
7
|
+
import { web3, AnchorProvider, Program } from '@anchor-lang/core';
|
|
8
8
|
import BN from 'bn.js';
|
|
9
9
|
import { ed25519 } from '@noble/curves/ed25519.js';
|
|
10
10
|
|
|
@@ -205,8 +205,8 @@ function deriveSourceIdString(apiConfig) {
|
|
|
205
205
|
var MOLPHA_SDK_PROFILE = "dev";
|
|
206
206
|
var DEFAULT_GATEWAY_ENDPOINT = "https://dev-gateway.molpha.io/";
|
|
207
207
|
var MOLPHA_PROGRAM_ID = "chivcFQgxzwkpLvW41PV431HQ4dYpaW3povQH3AdpQt";
|
|
208
|
-
var MOLPHA_VERIFIER_ADDRESS = "
|
|
209
|
-
var MOLPHA_VERIFIER_STARKNET_SEPOLIA = "
|
|
208
|
+
var MOLPHA_VERIFIER_ADDRESS = "0xA6e49A3A1caf3E110cC04765B934C8FF118C2568";
|
|
209
|
+
var MOLPHA_VERIFIER_STARKNET_SEPOLIA = "0x032b9f47f12189668b94a5d62fb7d60f968ed0dbaf22090649d1d7a91d79cc38";
|
|
210
210
|
var MOLPHA_DEV_VERIFIERS_PROVISIONAL = true;
|
|
211
211
|
|
|
212
212
|
// src/core/int256.ts
|
|
@@ -9470,11 +9470,85 @@ function estimateSubmitComputeUnits(signerCount) {
|
|
|
9470
9470
|
const measured = 43e3 + 9200 * signerCount;
|
|
9471
9471
|
return Math.min(Math.round(measured * 1.15) + 1e4, MAX_COMPUTE_UNIT_LIMIT);
|
|
9472
9472
|
}
|
|
9473
|
+
function estimateSubmitBatchComputeUnits(signerCounts) {
|
|
9474
|
+
if (signerCounts.length === 0 || signerCounts.some((n) => !Number.isInteger(n) || n < 1)) {
|
|
9475
|
+
return MAX_COMPUTE_UNIT_LIMIT;
|
|
9476
|
+
}
|
|
9477
|
+
const measured = signerCounts.reduce((sum, n) => sum + 43e3 + 9200 * n, 0);
|
|
9478
|
+
return Math.min(Math.round(measured * 1.15) + 1e4, MAX_COMPUTE_UNIT_LIMIT);
|
|
9479
|
+
}
|
|
9480
|
+
var SUBMIT_INSTRUCTION_DATA_BYTES = 234;
|
|
9481
|
+
var PLACEHOLDER_BLOCKHASH = "11111111111111111111111111111111";
|
|
9482
|
+
var shortVecBytes = (n) => n < 128 ? 1 : n < 16384 ? 2 : 3;
|
|
9483
|
+
function transactionSize(payer, instructions) {
|
|
9484
|
+
const tx = new web3.Transaction();
|
|
9485
|
+
tx.feePayer = payer;
|
|
9486
|
+
tx.recentBlockhash = PLACEHOLDER_BLOCKHASH;
|
|
9487
|
+
tx.add(...instructions);
|
|
9488
|
+
const message = tx.compileMessage();
|
|
9489
|
+
const keys = message.accountKeys.length;
|
|
9490
|
+
let size = 1 + 64 + 3 + shortVecBytes(keys) + 32 * keys + 32 + shortVecBytes(message.instructions.length);
|
|
9491
|
+
message.instructions.forEach((compiled, i) => {
|
|
9492
|
+
const dataBytes = instructions[i].data.length;
|
|
9493
|
+
size += 1 + shortVecBytes(compiled.accounts.length) + compiled.accounts.length + shortVecBytes(dataBytes) + dataBytes;
|
|
9494
|
+
});
|
|
9495
|
+
return size;
|
|
9496
|
+
}
|
|
9497
|
+
function estimateSubmitTransactionSize(count, signerCount, opts = {}) {
|
|
9498
|
+
const key = () => web3.Keypair.generate().publicKey;
|
|
9499
|
+
const [payer, registry, feed, protocolConfig, program] = [key(), key(), key(), key(), key()];
|
|
9500
|
+
const distinct = Math.max(signerCount, opts.distinctSigners ?? signerCount);
|
|
9501
|
+
const nodes = Array.from({ length: distinct }, key);
|
|
9502
|
+
const instructions = [setComputeUnitLimit(1)];
|
|
9503
|
+
if (opts.priorityFee) instructions.push(setComputeUnitPrice(1));
|
|
9504
|
+
for (let i = 0; i < count; i++) {
|
|
9505
|
+
instructions.push(
|
|
9506
|
+
new web3.TransactionInstruction({
|
|
9507
|
+
programId: program,
|
|
9508
|
+
keys: [
|
|
9509
|
+
{ pubkey: payer, isSigner: true, isWritable: true },
|
|
9510
|
+
{ pubkey: registry, isSigner: false, isWritable: false },
|
|
9511
|
+
{ pubkey: feed, isSigner: false, isWritable: true },
|
|
9512
|
+
{ pubkey: protocolConfig, isSigner: false, isWritable: false },
|
|
9513
|
+
{ pubkey: new web3.PublicKey(SYSTEM_PROGRAM_ADDRESS), isSigner: false, isWritable: false },
|
|
9514
|
+
...Array.from({ length: signerCount }, (_, j) => ({
|
|
9515
|
+
pubkey: nodes[(i * signerCount + j) % distinct],
|
|
9516
|
+
isSigner: false,
|
|
9517
|
+
isWritable: false
|
|
9518
|
+
}))
|
|
9519
|
+
],
|
|
9520
|
+
data: Buffer.alloc(SUBMIT_INSTRUCTION_DATA_BYTES)
|
|
9521
|
+
})
|
|
9522
|
+
);
|
|
9523
|
+
}
|
|
9524
|
+
return transactionSize(payer, instructions);
|
|
9525
|
+
}
|
|
9526
|
+
function maxAttestationsPerTransaction(signerCount, opts = {}) {
|
|
9527
|
+
let count = 0;
|
|
9528
|
+
while (estimateSubmitTransactionSize(count + 1, signerCount, opts) <= web3.PACKET_DATA_SIZE) count++;
|
|
9529
|
+
return count;
|
|
9530
|
+
}
|
|
9473
9531
|
var REGISTRY_CACHE_MS = 3e4;
|
|
9474
9532
|
var KEY_CACHE_LIMIT = 8192;
|
|
9475
9533
|
var PRIORITY_FEE_CACHE_MS = 5e3;
|
|
9476
9534
|
var AUTO_FEE_PERCENTILE = 0.75;
|
|
9477
9535
|
var AUTO_FEE_CAP_MICRO_LAMPORTS = 1e6;
|
|
9536
|
+
var BatchTooLargeError = class extends RangeError {
|
|
9537
|
+
constructor(fits, size, limit, count) {
|
|
9538
|
+
super(
|
|
9539
|
+
`${count} attestations need a ${size} byte transaction, over the ${limit} byte limit; ${fits} fit`
|
|
9540
|
+
);
|
|
9541
|
+
this.fits = fits;
|
|
9542
|
+
this.size = size;
|
|
9543
|
+
this.limit = limit;
|
|
9544
|
+
this.count = count;
|
|
9545
|
+
this.name = "BatchTooLargeError";
|
|
9546
|
+
}
|
|
9547
|
+
fits;
|
|
9548
|
+
size;
|
|
9549
|
+
limit;
|
|
9550
|
+
count;
|
|
9551
|
+
};
|
|
9478
9552
|
var MolphaSolanaClient = class _MolphaSolanaClient {
|
|
9479
9553
|
constructor(program, provider, programId) {
|
|
9480
9554
|
this.program = program;
|
|
@@ -9646,6 +9720,87 @@ var MolphaSolanaClient = class _MolphaSolanaClient {
|
|
|
9646
9720
|
* `keccak256(rawValue)`; {@link buildSubmitAttestationArgs} validates that before send.
|
|
9647
9721
|
*/
|
|
9648
9722
|
async submitAttestation(attestation, opts) {
|
|
9723
|
+
const { args, accounts, remaining, feed } = await this.prepareSubmit(attestation, opts);
|
|
9724
|
+
const preInstructions = [
|
|
9725
|
+
setComputeUnitLimit(opts?.computeUnitLimit ?? estimateSubmitComputeUnits(remaining.length))
|
|
9726
|
+
];
|
|
9727
|
+
const price = await this.resolvePriorityFee(opts?.priorityFeeMicroLamports, feed);
|
|
9728
|
+
if (price > 0) preInstructions.push(setComputeUnitPrice(price));
|
|
9729
|
+
const signature = await this.methods.submitAttestation(args).accountsPartial(accounts).remainingAccounts(remaining).preInstructions(preInstructions).rpc();
|
|
9730
|
+
return { signature, feed };
|
|
9731
|
+
}
|
|
9732
|
+
/**
|
|
9733
|
+
* Submit several attestations of one feed in one transaction.
|
|
9734
|
+
*
|
|
9735
|
+
* Each becomes its own `submit_attestation` instruction, in timestamp order, and instructions run
|
|
9736
|
+
* in the order they are listed: all of them are applied, oldest first, whatever order other
|
|
9737
|
+
* transactions reach the leader in. That is what separate submits cannot promise. Transactions sent
|
|
9738
|
+
* milliseconds apart for one feed are overtaken by a newer one often enough (about a third at 250 ms
|
|
9739
|
+
* spacing in a devnet run) that the older one fails with `FeedNotNewer`; a batch makes the spacing
|
|
9740
|
+
* between transactions several times longer and spends one fee and one signature for them all.
|
|
9741
|
+
*
|
|
9742
|
+
* The transaction is atomic: if one instruction fails (typically because a newer attestation
|
|
9743
|
+
* of the feed landed first, so every instruction is stale) none of them applies. Batch only what
|
|
9744
|
+
* is due together, and keep batches of one feed in the order they were made.
|
|
9745
|
+
*
|
|
9746
|
+
* All attestations must be for one feed (the same `sourceId` and `signaturesRequired`) with
|
|
9747
|
+
* distinct timestamps. They need not share a registry version or a signer set. Values longer than
|
|
9748
|
+
* 32 bytes (`rawValue`) are not supported here: submit those with {@link submitAttestation}.
|
|
9749
|
+
*
|
|
9750
|
+
* @throws {BatchTooLargeError} when they do not fit in one transaction (about three do with
|
|
9751
|
+
* three signers; see {@link maxAttestationsPerTransaction}). Nothing is sent.
|
|
9752
|
+
*/
|
|
9753
|
+
async submitAttestations(attestations, opts) {
|
|
9754
|
+
if (attestations.length === 0) {
|
|
9755
|
+
throw new RangeError("submitAttestations needs at least one attestation");
|
|
9756
|
+
}
|
|
9757
|
+
const sorted = [...attestations].sort((a, b) => a.payload.timestamp - b.payload.timestamp);
|
|
9758
|
+
const feedKey = (a) => `${bytesToHex(toFixedBytes(a.payload.sourceId, 32, "sourceId"))}:${a.payload.signaturesRequired}`;
|
|
9759
|
+
const first = feedKey(sorted[0]);
|
|
9760
|
+
sorted.forEach((a, i) => {
|
|
9761
|
+
if (feedKey(a) !== first) {
|
|
9762
|
+
throw new RangeError(
|
|
9763
|
+
"submitAttestations: every attestation must be for the same feed (sourceId and signaturesRequired)"
|
|
9764
|
+
);
|
|
9765
|
+
}
|
|
9766
|
+
if (i > 0 && a.payload.timestamp === sorted[i - 1].payload.timestamp) {
|
|
9767
|
+
throw new RangeError(
|
|
9768
|
+
`submitAttestations: two attestations have timestamp ${a.payload.timestamp}; the second would be refused as not newer`
|
|
9769
|
+
);
|
|
9770
|
+
}
|
|
9771
|
+
});
|
|
9772
|
+
if (sorted.length === 1) return { ...await this.submitAttestation(sorted[0], opts), count: 1 };
|
|
9773
|
+
const prepared = await Promise.all(sorted.map((a) => this.prepareSubmit(a)));
|
|
9774
|
+
const instructions = await Promise.all(
|
|
9775
|
+
prepared.map(
|
|
9776
|
+
(p) => this.methods.submitAttestation(p.args).accountsPartial(p.accounts).remainingAccounts(p.remaining).instruction()
|
|
9777
|
+
)
|
|
9778
|
+
);
|
|
9779
|
+
const feed = prepared[0].feed;
|
|
9780
|
+
const budget = [
|
|
9781
|
+
setComputeUnitLimit(
|
|
9782
|
+
opts?.computeUnitLimit ?? estimateSubmitBatchComputeUnits(prepared.map((p) => p.remaining.length))
|
|
9783
|
+
)
|
|
9784
|
+
];
|
|
9785
|
+
const price = await this.resolvePriorityFee(opts?.priorityFeeMicroLamports, feed);
|
|
9786
|
+
if (price > 0) budget.push(setComputeUnitPrice(price));
|
|
9787
|
+
const payer = this.provider.wallet.publicKey;
|
|
9788
|
+
const size = transactionSize(payer, [...budget, ...instructions]);
|
|
9789
|
+
if (size > web3.PACKET_DATA_SIZE) {
|
|
9790
|
+
let fits = 0;
|
|
9791
|
+
while (fits < instructions.length && transactionSize(payer, [...budget, ...instructions.slice(0, fits + 1)]) <= web3.PACKET_DATA_SIZE) {
|
|
9792
|
+
fits++;
|
|
9793
|
+
}
|
|
9794
|
+
throw new BatchTooLargeError(fits, size, web3.PACKET_DATA_SIZE, instructions.length);
|
|
9795
|
+
}
|
|
9796
|
+
const signature = await this.provider.sendAndConfirm(new web3.Transaction().add(...budget, ...instructions));
|
|
9797
|
+
return { signature, feed, count: instructions.length };
|
|
9798
|
+
}
|
|
9799
|
+
/**
|
|
9800
|
+
* Everything one `submit_attestation` instruction needs: the arguments, the named accounts, the
|
|
9801
|
+
* signer `Node` accounts (ascending bit order) and the feed address.
|
|
9802
|
+
*/
|
|
9803
|
+
async prepareSubmit(attestation, opts) {
|
|
9649
9804
|
const { payload, signature: schnorr } = attestation;
|
|
9650
9805
|
const sourceId = toFixedBytes(payload.sourceId, 32, "sourceId");
|
|
9651
9806
|
const submitter = this.wallet;
|
|
@@ -9654,21 +9809,18 @@ var MolphaSolanaClient = class _MolphaSolanaClient {
|
|
|
9654
9809
|
assertSignerCount(remaining.length, payload.signaturesRequired, registry);
|
|
9655
9810
|
const coalitionKey = opts?.coalitionKey ?? await this.computeSignerCoalitionKey(remaining, registry, schnorr.signersBitmap);
|
|
9656
9811
|
const feed = feedPda(sourceId, payload.signaturesRequired, submitter, this.programId);
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
9665
|
-
|
|
9666
|
-
|
|
9667
|
-
feed
|
|
9668
|
-
|
|
9669
|
-
systemProgram: SYSTEM_PROGRAM_ADDRESS
|
|
9670
|
-
}).remainingAccounts(remaining).preInstructions(preInstructions).rpc();
|
|
9671
|
-
return { signature, feed };
|
|
9812
|
+
return {
|
|
9813
|
+
args: buildSubmitAttestationArgs(attestation, coalitionKey, opts?.rawValue),
|
|
9814
|
+
accounts: {
|
|
9815
|
+
submitter,
|
|
9816
|
+
registry: registryPda(payload.registryVersion, this.programId),
|
|
9817
|
+
feed,
|
|
9818
|
+
protocolConfig: protocolConfigPda(this.programId),
|
|
9819
|
+
systemProgram: SYSTEM_PROGRAM_ADDRESS
|
|
9820
|
+
},
|
|
9821
|
+
remaining,
|
|
9822
|
+
feed
|
|
9823
|
+
};
|
|
9672
9824
|
}
|
|
9673
9825
|
/** The registry for `version`, reused for {@link REGISTRY_CACHE_MS}. */
|
|
9674
9826
|
fetchRegistryCached(version) {
|
|
@@ -10591,6 +10743,6 @@ var MolphaSDK = class {
|
|
|
10591
10743
|
}
|
|
10592
10744
|
};
|
|
10593
10745
|
|
|
10594
|
-
export { AdaptiveLimiter, AggregationConfigError, DEFAULT_GATEWAY_ENDPOINT, DEFAULT_MAX_RETRIES, DEFAULT_ROUND_TIMEOUT_MS, EIP712_DOMAIN_TYPEHASH, GatewayError, INT256_MAX, INT256_MIN, MESSAGE_PREFIX, MIN_TOLERANCE_SIGNATURES, MOLPHA_DEV_VERIFIERS_PROVISIONAL, MOLPHA_IDL, MOLPHA_PROGRAM_ADDRESS, MOLPHA_PROGRAM_ID, MOLPHA_SDK_PROFILE, MOLPHA_VERIFIER_ABI, MOLPHA_VERIFIER_ADDRESS, MOLPHA_VERIFIER_STARKNET_ADDRESSES, MOLPHA_VERIFIER_STARKNET_SEPOLIA, MolphaGateway, MolphaSDK, MolphaSolanaClient, PlanType, REQUEST_AUTH_DOMAIN, ROUND_TICK_MS, SELECTION_WINDOW_MS, SubmitFailedError, TRANSFER_WITH_AUTHORIZATION_TYPEHASH, UpstreamPaymentRequiredError, VERIFY_CODES, addressToBytes, assertAggregationQuorum, attestationMessageHash, attestationMessageHashFromAttestation, base64ToBytes, bigIntFromBytesBe, bitmapBitSet, bitmapToIndices, buildEvmVerifierArgs, buildStarknetVerifierArgs, buildSubmitAttestationArgs, bytesToBase64, bytesToHex, bytesToHex0x, canonicalizeAPIConfig, canonicalizeAggregation, commitmentAddressToStarknetFelt, computeCoalitionKey, concatBytes, createEvmSignerFromPrivateKey, decodeInt256, deriveGatewayPda, deriveGatewayPdaAddress, deriveGroupBitmap, deriveSelectionBitmap, deriveSelectionSeed, deriveSourceId, deriveSourceIdString, domainSeparator, effectiveSelectionSize, eligibleSetSize, encodeEvmVerifyCalldata, encodeInt256, encodeInt256Decimal, encodeRequestAuth, encodeStarknetVerifyCalldata, ensureLength, estimateSubmitComputeUnits, evmAddressFromPrivateKey, feedPda, formatInt256Decimal, gatewayPda, gatewaySignerFromWallet, getMolphaStarknetVerifierAddress, hashRequestAuth, hexToBytes, nodePda, normalizeEndpoint, normalizeSecp256k1PublicKeyHex, parseEvmVerifyResult, parseGatewayInfo, parseStarknetVerifyResult, parseUpstreamQuote, planIdFromVariant, planPda, planVariant, probeSource, protocolConfigPda, registryPda, registryStatePda, requestMany, resolveRemainingAccounts, retryDelayMs, secp256k1PublicKeyFromCoordinates, selectedIndices, signSourcePayments, signerFromKeypair, signersBitmapToDecimal, signersBitmapToStarknetUint256, signersBitmapToUint256, spreadOffsetMs, subscriptionPda, timestampAgeSeconds, timestampSeconds, toChecksumAddress, toFixedBytes, toFixedHex, transferWithAuthorizationDigest, transferWithAuthorizationHash, u256beFromBigInt, u32be, u32le, u64be, u64le, u8, utf8, validateSuppliedTerms, verifyCodeName };
|
|
10746
|
+
export { AdaptiveLimiter, AggregationConfigError, BatchTooLargeError, DEFAULT_GATEWAY_ENDPOINT, DEFAULT_MAX_RETRIES, DEFAULT_ROUND_TIMEOUT_MS, EIP712_DOMAIN_TYPEHASH, GatewayError, INT256_MAX, INT256_MIN, MESSAGE_PREFIX, MIN_TOLERANCE_SIGNATURES, MOLPHA_DEV_VERIFIERS_PROVISIONAL, MOLPHA_IDL, MOLPHA_PROGRAM_ADDRESS, MOLPHA_PROGRAM_ID, MOLPHA_SDK_PROFILE, MOLPHA_VERIFIER_ABI, MOLPHA_VERIFIER_ADDRESS, MOLPHA_VERIFIER_STARKNET_ADDRESSES, MOLPHA_VERIFIER_STARKNET_SEPOLIA, MolphaGateway, MolphaSDK, MolphaSolanaClient, PlanType, REQUEST_AUTH_DOMAIN, ROUND_TICK_MS, SELECTION_WINDOW_MS, SUBMIT_INSTRUCTION_DATA_BYTES, SubmitFailedError, TRANSFER_WITH_AUTHORIZATION_TYPEHASH, UpstreamPaymentRequiredError, VERIFY_CODES, addressToBytes, assertAggregationQuorum, attestationMessageHash, attestationMessageHashFromAttestation, base64ToBytes, bigIntFromBytesBe, bitmapBitSet, bitmapToIndices, buildEvmVerifierArgs, buildStarknetVerifierArgs, buildSubmitAttestationArgs, bytesToBase64, bytesToHex, bytesToHex0x, canonicalizeAPIConfig, canonicalizeAggregation, commitmentAddressToStarknetFelt, computeCoalitionKey, concatBytes, createEvmSignerFromPrivateKey, decodeInt256, deriveGatewayPda, deriveGatewayPdaAddress, deriveGroupBitmap, deriveSelectionBitmap, deriveSelectionSeed, deriveSourceId, deriveSourceIdString, domainSeparator, effectiveSelectionSize, eligibleSetSize, encodeEvmVerifyCalldata, encodeInt256, encodeInt256Decimal, encodeRequestAuth, encodeStarknetVerifyCalldata, ensureLength, estimateSubmitBatchComputeUnits, estimateSubmitComputeUnits, estimateSubmitTransactionSize, evmAddressFromPrivateKey, feedPda, formatInt256Decimal, gatewayPda, gatewaySignerFromWallet, getMolphaStarknetVerifierAddress, hashRequestAuth, hexToBytes, maxAttestationsPerTransaction, nodePda, normalizeEndpoint, normalizeSecp256k1PublicKeyHex, parseEvmVerifyResult, parseGatewayInfo, parseStarknetVerifyResult, parseUpstreamQuote, planIdFromVariant, planPda, planVariant, probeSource, protocolConfigPda, registryPda, registryStatePda, requestMany, resolveRemainingAccounts, retryDelayMs, secp256k1PublicKeyFromCoordinates, selectedIndices, signSourcePayments, signerFromKeypair, signersBitmapToDecimal, signersBitmapToStarknetUint256, signersBitmapToUint256, spreadOffsetMs, subscriptionPda, timestampAgeSeconds, timestampSeconds, toChecksumAddress, toFixedBytes, toFixedHex, transferWithAuthorizationDigest, transferWithAuthorizationHash, u256beFromBigInt, u32be, u32le, u64be, u64le, u8, utf8, validateSuppliedTerms, verifyCodeName };
|
|
10595
10747
|
//# sourceMappingURL=index.js.map
|
|
10596
10748
|
//# sourceMappingURL=index.js.map
|