@elgora/cli 9.1.0 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +5 -4
  2. package/dist/cli.js +278 -363
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -27,10 +27,11 @@ answer.
27
27
 
28
28
  ## Commands
29
29
 
30
- - `poster:review` checks a bounty page and saves its readiness certificate
31
- with `--signoff-out <file>`. Rejected pages print the full issue list and exit 2.
32
- - `poster:publish-fund` requires `--signoff <file>`, publishes those exact
33
- approved `bounty_challenge.md` bytes, and funds the new bounty without another AI review.
30
+ - `poster:review` checks a bounty page; Elgora keeps the approval for those
31
+ exact bytes. Rejected pages print the full issue list and exit 2.
32
+ - `poster:publish-fund` publishes the exact `bounty_challenge.md` bytes and
33
+ funds the new bounty. It reuses the saved approval for those bytes without
34
+ another AI review, or reviews them first.
34
35
  - `poster:open-winning-submission` retrieves the finalized winning Submission
35
36
  for the funding Poster and decrypts it locally.
36
37
  - `check-page <bounty_challenge_md_path|->` checks structural conformance offline,
package/dist/cli.js CHANGED
@@ -71,6 +71,7 @@ var BOUNTY_CHALLENGE_PROFILE = "elgora_markdown_bounty_challenge_v0";
71
71
  var WINNER_TAKE_ALL_PAYOUT_POLICY = "winner_take_all";
72
72
  var SUBMISSION_ENCRYPTION_TYPE = "guardian_timelock_hpke_aes_256_gcm_v0";
73
73
  var ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000";
74
+ var READINESS_APPROVAL_VALIDITY_SECONDS = 7 * 24 * 60 * 60;
74
75
 
75
76
  // ../../packages/core/src/bounty-challenge-markdown.ts
76
77
  var FRONTMATTER_DELIMITER = "---";
@@ -384,107 +385,37 @@ function isBountyChallengeFrontmatterKey(value) {
384
385
  }
385
386
 
386
387
  // ../../packages/core/src/bounty-publication-response.ts
387
- import { isHex as isHex3 } from "viem";
388
- import { z as z3 } from "zod";
389
-
390
- // ../../packages/core/src/auth/readiness-signoff.ts
391
- import {
392
- isAddressEqual,
393
- isHex as isHex2,
394
- recoverTypedDataAddress,
395
- size as size2
396
- } from "viem";
388
+ import { isHex as isHex2 } from "viem";
397
389
  import { z as z2 } from "zod";
398
-
399
- // ../../packages/core/src/auth/eip712.ts
400
- var API_REQUEST_APPROVAL_PRIMARY_TYPE = "ApiRequestApproval";
401
- var API_REQUEST_APPROVAL_TYPES = {
402
- ApiRequestApproval: [
403
- { name: "endpointId", type: "string" },
404
- { name: "audience", type: "string" },
405
- { name: "bodyHash", type: "bytes32" },
406
- { name: "query", type: "string" },
407
- { name: "blockNumber", type: "uint256" },
408
- { name: "blockHash", type: "bytes32" }
409
- ]
410
- };
411
- function buildElgoraEip712Domain(params) {
412
- return {
413
- name: "Elgora",
414
- version: "1",
415
- chainId: params.chainId,
416
- verifyingContract: params.hubAddress
417
- };
418
- }
419
- function buildApiRequestApprovalTypedData(params) {
420
- return {
421
- domain: buildElgoraEip712Domain({
422
- chainId: params.chainId,
423
- hubAddress: params.hubAddress
424
- }),
425
- types: API_REQUEST_APPROVAL_TYPES,
426
- primaryType: API_REQUEST_APPROVAL_PRIMARY_TYPE,
427
- message: params.message
428
- };
429
- }
430
- function endpointIdFor(input) {
431
- return `${input.method.toUpperCase()} ${input.path}`;
432
- }
433
- function audienceFor(host) {
434
- return host.toLowerCase();
435
- }
436
- function queryFor(query) {
437
- return new URLSearchParams(query).toString();
438
- }
439
-
440
- // ../../packages/core/src/auth/readiness-signoff.ts
441
- var READINESS_APPROVAL_VALIDITY_SECONDS = 7 * 24 * 60 * 60;
442
- var bytes32Schema = z2.string().refine(isHexBytes32).transform((value) => value);
443
- var timestampSchema = z2.number().int().nonnegative().max(9999999999);
444
- var readinessSignoffMessageSchema = z2.object({
445
- audience: z2.string().min(1).max(512),
390
+ var addressSchema = z2.string().refine(isHexAddress, "Must be a 20-byte EVM address").transform((value) => value);
391
+ var bytes32Schema = z2.string().refine(isHexBytes32, "Must be a bytes32 hex string").transform((value) => value);
392
+ var hexBytesSchema = z2.string().refine(isHex2, "Must be hex-encoded calldata").transform((value) => value);
393
+ var bountyChallengeContentRecordSchema = z2.object({
394
+ content_kind: z2.literal("bounty_challenge_spec"),
446
395
  spec_commitment: bytes32Schema,
447
- reviewer_hash: bytes32Schema,
448
- model: z2.string().min(1).max(256),
449
- issued_at: timestampSchema,
450
- expires_at: timestampSchema
451
- }).strict();
452
- var signatureSchema = z2.string().refine((value) => isHex2(value) && size2(value) === 65).transform((value) => value);
453
- var readinessSignoffSchema = readinessSignoffMessageSchema.extend({ signature: signatureSchema }).refine((signoff) => signoff.expires_at > signoff.issued_at, {
454
- path: ["expires_at"],
455
- message: "Must expire after issuance"
456
- });
457
-
458
- // ../../packages/core/src/bounty-publication-response.ts
459
- var addressSchema = z3.string().refine(isHexAddress, "Must be a 20-byte EVM address").transform((value) => value);
460
- var bytes32Schema2 = z3.string().refine(isHexBytes32, "Must be a bytes32 hex string").transform((value) => value);
461
- var hexBytesSchema = z3.string().refine(isHex3, "Must be hex-encoded calldata").transform((value) => value);
462
- var bountyChallengeContentRecordSchema = z3.object({
463
- content_kind: z3.literal("bounty_challenge_spec"),
464
- spec_commitment: bytes32Schema2,
465
- byte_length: z3.number().int().positive(),
396
+ byte_length: z2.number().int().positive(),
466
397
  token_address: addressSchema,
467
- created_at: z3.string().datetime({ offset: true })
398
+ created_at: z2.string().datetime({ offset: true })
468
399
  }).strict();
469
- var bountyPublicationResponseSchema = z3.object({
400
+ var bountyPublicationResponseSchema = z2.object({
470
401
  content_record: bountyChallengeContentRecordSchema,
471
- create_bounty_transaction: z3.object({
472
- chain_id: z3.number().int().positive(),
402
+ create_bounty_transaction: z2.object({
403
+ chain_id: z2.number().int().positive(),
473
404
  to: addressSchema,
474
- value: z3.literal("0"),
405
+ value: z2.literal("0"),
475
406
  data: hexBytesSchema,
476
- function_name: z3.literal("create_bounty"),
477
- args: z3.object({
478
- spec_commitment: bytes32Schema2,
479
- escrow_amount: z3.string().refine(isPositiveInteger),
480
- submission_deadline: z3.number().int().positive()
407
+ function_name: z2.literal("create_bounty"),
408
+ args: z2.object({
409
+ spec_commitment: bytes32Schema,
410
+ escrow_amount: z2.string().refine(isPositiveInteger),
411
+ submission_deadline: z2.number().int().positive()
481
412
  }).strict()
482
413
  }).strict(),
483
- protocol_fee_policy: z3.object({
414
+ protocol_fee_policy: z2.object({
484
415
  treasury_recipient: addressSchema,
485
- treasury_fee_bps: z3.number().int().min(0).max(1e4),
416
+ treasury_fee_bps: z2.number().int().min(0).max(1e4),
486
417
  guardian_fee_recipient: addressSchema,
487
- guardian_fee_bps: z3.number().int().min(0).max(1e4)
418
+ guardian_fee_bps: z2.number().int().min(0).max(1e4)
488
419
  }).strict()
489
420
  }).strict().superRefine((response, context) => {
490
421
  if (response.content_record.spec_commitment !== response.create_bounty_transaction.args.spec_commitment) {
@@ -495,47 +426,33 @@ var bountyPublicationResponseSchema = z3.object({
495
426
  });
496
427
  }
497
428
  });
498
- var priorIssueSchema = z3.object({
499
- issue_index: z3.number().int().nonnegative(),
500
- message: z3.string().trim().min(1).max(1500)
429
+ var priorIssueSchema = z2.object({
430
+ issue_index: z2.number().int().nonnegative(),
431
+ message: z2.string().trim().min(1).max(1500)
501
432
  }).strict();
502
433
  var priorIssueStatusSchema = priorIssueSchema.extend({
503
- status: z3.enum(["resolved", "open"])
434
+ status: z2.enum(["resolved", "open"])
504
435
  }).strict();
505
- var readinessFindingSchema = z3.object({
506
- path: z3.string().trim().min(1).max(120),
507
- message: z3.string().trim().min(1).max(1500),
508
- code: z3.string().min(1).optional(),
509
- anchor: z3.string().trim().min(1).max(120).optional(),
510
- hazard: z3.boolean().optional()
436
+ var readinessFindingSchema = z2.object({
437
+ path: z2.string().trim().min(1).max(120),
438
+ message: z2.string().trim().min(1).max(1500),
439
+ code: z2.string().min(1).optional(),
440
+ anchor: z2.string().trim().min(1).max(120).optional(),
441
+ hazard: z2.boolean().optional()
511
442
  });
512
443
  var MAX_READINESS_FINDINGS = 20;
513
- var bountyReviewResponseSchema = z3.object({
514
- content_record: bountyChallengeContentRecordSchema,
515
- readiness: z3.object({
516
- decision: z3.literal("ready"),
517
- signoff: readinessSignoffSchema,
444
+ var bountyReviewResponseSchema = z2.object({
445
+ content_record: bountyChallengeContentRecordSchema.omit({ created_at: true }),
446
+ readiness: z2.object({
447
+ decision: z2.literal("ready"),
448
+ // Publication reuses the approval of these exact bytes until then.
449
+ approved_until: z2.string().datetime({ offset: true }),
518
450
  // The dissenting pass's findings on a ready check; never blocking.
519
- // Optional because servers before three-pass review do not send it.
520
- warnings: z3.array(readinessFindingSchema).max(MAX_READINESS_FINDINGS).optional(),
521
- prior_issues_resolved: z3.array(priorIssueSchema),
522
- prior_issues_open: z3.array(priorIssueSchema)
451
+ warnings: z2.array(readinessFindingSchema).max(MAX_READINESS_FINDINGS),
452
+ prior_issues_resolved: z2.array(priorIssueSchema),
453
+ prior_issues_open: z2.array(priorIssueSchema)
523
454
  })
524
- }).superRefine((response, context) => {
525
- if (response.readiness.signoff.spec_commitment.toLowerCase() !== response.content_record.spec_commitment.toLowerCase()) {
526
- context.addIssue({
527
- code: "custom",
528
- path: ["readiness", "signoff", "spec_commitment"],
529
- message: "Must match content_record.spec_commitment"
530
- });
531
- }
532
455
  });
533
- var readinessSignerResponseSchema = z3.object({
534
- signer_address: addressSchema,
535
- reviewer_hash: bytes32Schema2,
536
- configured_model: z3.string().min(1),
537
- audience: z3.string().min(1)
538
- }).strict();
539
456
 
540
457
  // ../../packages/core/src/chain-registry.ts
541
458
  import { base, baseSepolia, foundry } from "viem/chains";
@@ -559,7 +476,7 @@ var FOUNDRY_CHAIN_ID = foundry.id;
559
476
  import { Aes256Gcm, CipherSuite, HkdfSha256 } from "@hpke/core";
560
477
  import { DhkemX25519HkdfSha256 } from "@hpke/dhkem-x25519";
561
478
  import { concatBytes, keccak256 as keccak2562, toBytes as toBytes2 } from "viem";
562
- import { z as z4 } from "zod";
479
+ import { z as z3 } from "zod";
563
480
 
564
481
  // ../../packages/core/src/base64.ts
565
482
  var BASE64_ENCODE_CHUNK_BYTES = 3 * 16384;
@@ -645,42 +562,42 @@ var BASE64URL_RE = /^[A-Za-z0-9_-]+$/;
645
562
  var SOLVER_SUBMISSION_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
646
563
  var MEDIA_TYPE_RE = /^[a-z0-9][a-z0-9!#$&^_.+-]*\/[a-z0-9][a-z0-9!#$&^_.+-]*$/;
647
564
  var KEY_ID_RE = /^[A-Za-z0-9][ -~]*$/;
648
- var base64UrlSchema = z4.string().regex(BASE64URL_RE);
649
- var lowerAddressSchema = z4.string().refine(isLowercaseHexAddress);
650
- var bytes32Schema3 = z4.string().refine(isLowercaseBytes32);
651
- var sha256HexSchema = z4.string().refine(isSha256Hex);
652
- var keyIdSchema = z4.string().min(1).max(128).regex(KEY_ID_RE);
653
- var artifactNameSchema = z4.string().max(
565
+ var base64UrlSchema = z3.string().regex(BASE64URL_RE);
566
+ var lowerAddressSchema = z3.string().refine(isLowercaseHexAddress);
567
+ var bytes32Schema2 = z3.string().refine(isLowercaseBytes32);
568
+ var sha256HexSchema = z3.string().refine(isSha256Hex);
569
+ var keyIdSchema = z3.string().min(1).max(128).regex(KEY_ID_RE);
570
+ var artifactNameSchema = z3.string().max(
654
571
  MAX_SOLVER_SUBMISSION_NAME_CHARACTERS,
655
572
  `Artifact filename exceeds ${MAX_SOLVER_SUBMISSION_NAME_CHARACTERS} ASCII characters (including extension). Solvers may shorten it only if the published challenge permits, before the deadline.`
656
573
  ).regex(SOLVER_SUBMISSION_NAME_RE);
657
- var mediaTypeSchema = z4.string().regex(MEDIA_TYPE_RE);
658
- var bountyIdSchema = z4.string().refine(isBountyId);
659
- var chainIdSchema = z4.number().int().positive().lte(Number.MAX_SAFE_INTEGER);
660
- var privateArtifactContextSchema = z4.strictObject({
661
- type: z4.literal("solver_submission"),
574
+ var mediaTypeSchema = z3.string().regex(MEDIA_TYPE_RE);
575
+ var bountyIdSchema = z3.string().refine(isBountyId);
576
+ var chainIdSchema = z3.number().int().positive().lte(Number.MAX_SAFE_INTEGER);
577
+ var privateArtifactContextSchema = z3.strictObject({
578
+ type: z3.literal("solver_submission"),
662
579
  chain_id: chainIdSchema,
663
580
  hub_address: lowerAddressSchema,
664
581
  bounty_id: bountyIdSchema,
665
582
  actor_address: lowerAddressSchema
666
583
  });
667
- var guardianRecipientSchema = z4.strictObject({
584
+ var guardianRecipientSchema = z3.strictObject({
668
585
  key_id: keyIdSchema,
669
- suite: z4.literal(PRIVATE_ARTIFACT_HPKE_SUITE),
586
+ suite: z3.literal(PRIVATE_ARTIFACT_HPKE_SUITE),
670
587
  public_key: base64UrlSchema.length(
671
588
  43,
672
589
  "public_key must encode a 32-byte X25519 public key"
673
590
  )
674
591
  });
675
- var guardianRecipientPrivateKeySchema = z4.strictObject({
592
+ var guardianRecipientPrivateKeySchema = z3.strictObject({
676
593
  key_id: keyIdSchema,
677
- suite: z4.literal(PRIVATE_ARTIFACT_HPKE_SUITE),
594
+ suite: z3.literal(PRIVATE_ARTIFACT_HPKE_SUITE),
678
595
  private_key: base64UrlSchema.length(
679
596
  43,
680
597
  "private_key must encode a 32-byte X25519 private key"
681
598
  )
682
599
  });
683
- var guardianRecipientsSchema = z4.array(guardianRecipientSchema).min(1).superRefine((recipients, ctx) => {
600
+ var guardianRecipientsSchema = z3.array(guardianRecipientSchema).min(1).superRefine((recipients, ctx) => {
684
601
  const seen = /* @__PURE__ */ new Set();
685
602
  for (const recipient of recipients) {
686
603
  if (seen.has(recipient.key_id)) {
@@ -693,24 +610,24 @@ var guardianRecipientsSchema = z4.array(guardianRecipientSchema).min(1).superRef
693
610
  seen.add(recipient.key_id);
694
611
  }
695
612
  });
696
- var guardianRecipientPrivateKeysSchema = z4.array(guardianRecipientPrivateKeySchema).min(1);
697
- var artifactManifestEntrySchema = z4.strictObject({
613
+ var guardianRecipientPrivateKeysSchema = z3.array(guardianRecipientPrivateKeySchema).min(1);
614
+ var artifactManifestEntrySchema = z3.strictObject({
698
615
  name: artifactNameSchema,
699
616
  media_type: mediaTypeSchema,
700
- size_bytes: z4.number().int().nonnegative().lte(Number.MAX_SAFE_INTEGER),
617
+ size_bytes: z3.number().int().nonnegative().lte(Number.MAX_SAFE_INTEGER),
701
618
  sha256: sha256HexSchema
702
619
  });
703
- var privateArtifactPublicManifestSchema = z4.strictObject({
704
- kind: z4.literal(PRIVATE_ARTIFACT_PUBLIC_MANIFEST_KIND),
620
+ var privateArtifactPublicManifestSchema = z3.strictObject({
621
+ kind: z3.literal(PRIVATE_ARTIFACT_PUBLIC_MANIFEST_KIND),
705
622
  context: privateArtifactContextSchema
706
623
  });
707
624
  var encryptedBundleArtifactSchema = artifactManifestEntrySchema.extend({
708
625
  bytes: base64UrlSchema
709
626
  });
710
- var privateArtifactEncryptedBundleSchema = z4.strictObject({
711
- kind: z4.literal(PRIVATE_ARTIFACT_ENCRYPTED_BUNDLE_KIND),
627
+ var privateArtifactEncryptedBundleSchema = z3.strictObject({
628
+ kind: z3.literal(PRIVATE_ARTIFACT_ENCRYPTED_BUNDLE_KIND),
712
629
  context: privateArtifactContextSchema,
713
- artifacts: z4.array(encryptedBundleArtifactSchema).min(1).max(
630
+ artifacts: z3.array(encryptedBundleArtifactSchema).min(1).max(
714
631
  MAX_SOLVER_SUBMISSION_FILES,
715
632
  `Submission exceeds the maximum of ${MAX_SOLVER_SUBMISSION_FILES} files.`
716
633
  ).refine(
@@ -718,33 +635,33 @@ var privateArtifactEncryptedBundleSchema = z4.strictObject({
718
635
  "artifact names must be unique case-insensitively"
719
636
  )
720
637
  });
721
- var privateArtifactRevealPolicySchema = z4.strictObject({
722
- kind: z4.literal(PRIVATE_ARTIFACT_REVEAL_POLICY_KIND),
723
- network: z4.string().min(1),
724
- chain_hash: z4.string().min(1),
725
- round: z4.string().refine(isPositiveInteger),
726
- not_before: z4.number().int().nonnegative().lte(Number.MAX_SAFE_INTEGER)
638
+ var privateArtifactRevealPolicySchema = z3.strictObject({
639
+ kind: z3.literal(PRIVATE_ARTIFACT_REVEAL_POLICY_KIND),
640
+ network: z3.string().min(1),
641
+ chain_hash: z3.string().min(1),
642
+ round: z3.string().refine(isPositiveInteger),
643
+ not_before: z3.number().int().nonnegative().lte(Number.MAX_SAFE_INTEGER)
727
644
  });
728
- var wrappedRecipientKeySchema = z4.strictObject({
645
+ var wrappedRecipientKeySchema = z3.strictObject({
729
646
  key_id: keyIdSchema,
730
- suite: z4.literal(PRIVATE_ARTIFACT_HPKE_SUITE),
647
+ suite: z3.literal(PRIVATE_ARTIFACT_HPKE_SUITE),
731
648
  enc: base64UrlSchema,
732
649
  ciphertext: base64UrlSchema
733
650
  });
734
- var wrappedKeyBagSchema = z4.strictObject({
735
- kind: z4.literal(PRIVATE_ARTIFACT_WRAPPED_KEY_BAG_KIND),
736
- keys: z4.array(wrappedRecipientKeySchema).min(1)
651
+ var wrappedKeyBagSchema = z3.strictObject({
652
+ kind: z3.literal(PRIVATE_ARTIFACT_WRAPPED_KEY_BAG_KIND),
653
+ keys: z3.array(wrappedRecipientKeySchema).min(1)
737
654
  });
738
- var privateArtifactEnvelopeSchema = z4.strictObject({
739
- kind: z4.literal(PRIVATE_ARTIFACT_ENVELOPE_KIND),
740
- alg: z4.literal(SUBMISSION_ENCRYPTION_TYPE),
655
+ var privateArtifactEnvelopeSchema = z3.strictObject({
656
+ kind: z3.literal(PRIVATE_ARTIFACT_ENVELOPE_KIND),
657
+ alg: z3.literal(SUBMISSION_ENCRYPTION_TYPE),
741
658
  context: privateArtifactContextSchema,
742
659
  public_manifest: privateArtifactPublicManifestSchema,
743
660
  public_manifest_sha256: sha256HexSchema,
744
661
  encrypted_bundle_sha256: sha256HexSchema,
745
662
  ciphertext_sha256: sha256HexSchema,
746
663
  guardian_recipients: guardianRecipientsSchema,
747
- guardian_recipients_commitment: bytes32Schema3,
664
+ guardian_recipients_commitment: bytes32Schema2,
748
665
  reveal_policy: privateArtifactRevealPolicySchema,
749
666
  envelope_nonce: base64UrlSchema.length(
750
667
  22,
@@ -752,7 +669,7 @@ var privateArtifactEnvelopeSchema = z4.strictObject({
752
669
  ),
753
670
  iv: base64UrlSchema.length(16, "iv must encode 12 bytes"),
754
671
  wrapped_key_bag: base64UrlSchema,
755
- ciphertext_locator: z4.string().min(1)
672
+ ciphertext_locator: z3.string().min(1)
756
673
  });
757
674
  function parsePrivateArtifactEnvelope(input) {
758
675
  return privateArtifactEnvelopeSchema.parse(input);
@@ -810,11 +727,11 @@ var x25519PrivateKeySchema = base64UrlSchema.length(
810
727
  43,
811
728
  "must encode a 32-byte X25519 private key"
812
729
  );
813
- var winningSolutionDeliveryContextSchema = z4.strictObject({
730
+ var winningSolutionDeliveryContextSchema = z3.strictObject({
814
731
  chain_id: chainIdSchema,
815
732
  hub_address: lowerAddressSchema,
816
733
  bounty_id: bountyIdSchema,
817
- submission_commitment: bytes32Schema3
734
+ submission_commitment: bytes32Schema2
818
735
  });
819
736
  async function generateX25519KeyPair(input) {
820
737
  const suite = createHpkeSuite();
@@ -891,7 +808,7 @@ function buildWinningSolutionDeliveryInfo(contextCommitment) {
891
808
  var GUARDIAN_ROSTER_KEY_PROOF_INFO = "elgora/guardian-roster-key-proof/hpke-fixture/v0";
892
809
  var GUARDIAN_ROSTER_KEY_PROOF_MESSAGE_TYPE = "elgora_guardian_roster_key_proof_v0";
893
810
  var GUARDIAN_ROSTER_KEY_PROOF_FIXTURE_BYTES = 32;
894
- var guardianRosterKeyProofContextSchema = z4.strictObject({
811
+ var guardianRosterKeyProofContextSchema = z3.strictObject({
895
812
  chain_id: chainIdSchema,
896
813
  hub_address: lowerAddressSchema,
897
814
  proposed_account: lowerAddressSchema,
@@ -1219,7 +1136,7 @@ async function wrapAesKeyForRecipients(input) {
1219
1136
  }
1220
1137
  async function openAesKeyForRecipient(input) {
1221
1138
  const suite = createHpkeSuite();
1222
- const wrappedKeys = z4.array(wrappedRecipientKeySchema).parse(input.wrappedKeys);
1139
+ const wrappedKeys = z3.array(wrappedRecipientKeySchema).parse(input.wrappedKeys);
1223
1140
  const privateKeys = guardianRecipientPrivateKeysSchema.parse(
1224
1141
  input.privateKeys
1225
1142
  );
@@ -3930,7 +3847,7 @@ function settlementAmounts(escrowAmount, treasuryFeeBps, guardianFeeBps) {
3930
3847
  import { zeroAddress } from "viem";
3931
3848
 
3932
3849
  // ../../packages/core/src/api/bounty-preparation.ts
3933
- import { ZodError, z as z5 } from "zod";
3850
+ import { ZodError, z as z4 } from "zod";
3934
3851
 
3935
3852
  // ../../packages/core/src/submission-timelock.ts
3936
3853
  import {
@@ -4191,7 +4108,7 @@ import {
4191
4108
  getAbiItem as getAbiItem2,
4192
4109
  parseAbi,
4193
4110
  parseSignature,
4194
- recoverTypedDataAddress as recoverTypedDataAddress2
4111
+ recoverTypedDataAddress
4195
4112
  } from "viem";
4196
4113
  var ELGORA_HUB_ERRORS = ELGORA_HUB_ABI.filter(
4197
4114
  (item) => item.type === "error"
@@ -4348,7 +4265,7 @@ async function prepareAuthorizedCreateBountyTransaction(input) {
4348
4265
  if (unsupported) return null;
4349
4266
  throw error;
4350
4267
  }
4351
- if ((await recoverTypedDataAddress2({ ...authorization, signature })).toLowerCase() !== poster.toLowerCase()) {
4268
+ if ((await recoverTypedDataAddress({ ...authorization, signature })).toLowerCase() !== poster.toLowerCase()) {
4352
4269
  throw new Error("USDC authorization was not signed by the funding Poster.");
4353
4270
  }
4354
4271
  const { r, s, yParity } = parseSignature(signature);
@@ -4424,14 +4341,14 @@ var BoundaryValidationError = class extends Error {
4424
4341
  this.issues = issues;
4425
4342
  }
4426
4343
  };
4427
- var artifactUploadUrlRequestSchema = z5.object({
4428
- ciphertext_sha256: z5.string().refine(isSha256Hex),
4429
- ciphertext_byte_length: z5.number().int().positive().max(MAX_SOLVER_SUBMISSION_CIPHERTEXT_BYTES)
4344
+ var artifactUploadUrlRequestSchema = z4.object({
4345
+ ciphertext_sha256: z4.string().refine(isSha256Hex),
4346
+ ciphertext_byte_length: z4.number().int().positive().max(MAX_SOLVER_SUBMISSION_CIPHERTEXT_BYTES)
4430
4347
  }).strict();
4431
4348
 
4432
4349
  // ../../packages/core/src/api/config.ts
4433
4350
  import { createHash } from "crypto";
4434
- import { z as z6 } from "zod";
4351
+ import { z as z5 } from "zod";
4435
4352
  function withDeploymentEnvDefaults(env) {
4436
4353
  const merged = { ...env };
4437
4354
  const setIfBlank = (key, value) => {
@@ -4452,11 +4369,11 @@ function withDeploymentEnvDefaults(env) {
4452
4369
  setIfBlank("ELGORA_SUBGRAPH_ENDPOINT", deployment?.ELGORA_SUBGRAPH_ENDPOINT);
4453
4370
  return merged;
4454
4371
  }
4455
- var chainIdField = z6.coerce.number().int().positive().refine((chainId) => SUPPORTED_CHAINS[chainId] !== void 0, {
4372
+ var chainIdField = z5.coerce.number().int().positive().refine((chainId) => SUPPORTED_CHAINS[chainId] !== void 0, {
4456
4373
  message: `ELGORA_CHAIN_ID must be a supported chain: ${Object.keys(SUPPORTED_CHAINS).join(", ")}`
4457
4374
  });
4458
- var hubAddressField = z6.string().refine(isHexAddress, "ELGORA_HUB_ADDRESS must be a 20-byte EVM address").transform((value) => value.toLowerCase());
4459
- var publicDeploymentEnvSchema = z6.object({
4375
+ var hubAddressField = z5.string().refine(isHexAddress, "ELGORA_HUB_ADDRESS must be a 20-byte EVM address").transform((value) => value.toLowerCase());
4376
+ var publicDeploymentEnvSchema = z5.object({
4460
4377
  ELGORA_CHAIN_ID: chainIdField,
4461
4378
  ELGORA_HUB_ADDRESS: hubAddressField
4462
4379
  });
@@ -4472,32 +4389,32 @@ function loadPublicDeploymentConfig(env = process.env) {
4472
4389
  var envShape = {
4473
4390
  ELGORA_CHAIN_ID: chainIdField,
4474
4391
  ELGORA_HUB_ADDRESS: hubAddressField,
4475
- ELGORA_ESCROW_TOKEN_ADDRESS: z6.string().refine(
4392
+ ELGORA_ESCROW_TOKEN_ADDRESS: z5.string().refine(
4476
4393
  isHexAddress,
4477
4394
  "ELGORA_ESCROW_TOKEN_ADDRESS must be a 20-byte EVM address"
4478
4395
  ).transform((value) => value.toLowerCase()),
4479
- ELGORA_TIMELOCK_REVEAL_DELAY_SECONDS: z6.coerce.number().int().nonnegative().default(DEFAULT_TIMELOCK_REVEAL_DELAY_SECONDS),
4480
- ELGORA_RPC_URL: z6.string().min(1, "ELGORA_RPC_URL is required"),
4396
+ ELGORA_TIMELOCK_REVEAL_DELAY_SECONDS: z5.coerce.number().int().nonnegative().default(DEFAULT_TIMELOCK_REVEAL_DELAY_SECONDS),
4397
+ ELGORA_RPC_URL: z5.string().min(1, "ELGORA_RPC_URL is required"),
4481
4398
  /**
4482
4399
  * Only consulted for a chain with no recorded deployment — a local anvil
4483
4400
  * stack, whose addresses change on every deploy. A recorded deployment's
4484
4401
  * scheme always wins, because settlement validation compares against it.
4485
4402
  */
4486
- ELGORA_PAYOUT_SCHEME_ADDRESS: z6.string().refine(
4403
+ ELGORA_PAYOUT_SCHEME_ADDRESS: z5.string().refine(
4487
4404
  isHexAddress,
4488
4405
  "ELGORA_PAYOUT_SCHEME_ADDRESS must be a 20-byte EVM address"
4489
4406
  ).transform((value) => value.toLowerCase()).optional(),
4490
- ELGORA_DATABASE_URL: z6.string().min(1, "ELGORA_DATABASE_URL is required"),
4491
- ELGORA_SUBGRAPH_ENDPOINT: z6.string().min(1, "ELGORA_SUBGRAPH_ENDPOINT is required"),
4492
- ELGORA_ARTIFACT_STORAGE_ENDPOINT: z6.string().min(1, "ELGORA_ARTIFACT_STORAGE_ENDPOINT is required"),
4493
- ELGORA_ARTIFACT_STORAGE_REGION: z6.string().min(1, "ELGORA_ARTIFACT_STORAGE_REGION is required"),
4494
- ELGORA_ARTIFACT_STORAGE_BUCKET: z6.string().min(1, "ELGORA_ARTIFACT_STORAGE_BUCKET is required"),
4495
- ELGORA_ARTIFACT_STORAGE_ACCESS_KEY_ID: z6.string().min(1, "ELGORA_ARTIFACT_STORAGE_ACCESS_KEY_ID is required"),
4496
- ELGORA_ARTIFACT_STORAGE_SECRET_ACCESS_KEY: z6.string().min(1, "ELGORA_ARTIFACT_STORAGE_SECRET_ACCESS_KEY is required"),
4497
- ELGORA_DELIVERY_PUBLIC_KEY: z6.string().min(1, "ELGORA_DELIVERY_PUBLIC_KEY is required"),
4498
- ELGORA_DELIVERY_PRIVATE_KEY: z6.string().min(1, "ELGORA_DELIVERY_PRIVATE_KEY is required")
4407
+ ELGORA_DATABASE_URL: z5.string().min(1, "ELGORA_DATABASE_URL is required"),
4408
+ ELGORA_SUBGRAPH_ENDPOINT: z5.string().min(1, "ELGORA_SUBGRAPH_ENDPOINT is required"),
4409
+ ELGORA_ARTIFACT_STORAGE_ENDPOINT: z5.string().min(1, "ELGORA_ARTIFACT_STORAGE_ENDPOINT is required"),
4410
+ ELGORA_ARTIFACT_STORAGE_REGION: z5.string().min(1, "ELGORA_ARTIFACT_STORAGE_REGION is required"),
4411
+ ELGORA_ARTIFACT_STORAGE_BUCKET: z5.string().min(1, "ELGORA_ARTIFACT_STORAGE_BUCKET is required"),
4412
+ ELGORA_ARTIFACT_STORAGE_ACCESS_KEY_ID: z5.string().min(1, "ELGORA_ARTIFACT_STORAGE_ACCESS_KEY_ID is required"),
4413
+ ELGORA_ARTIFACT_STORAGE_SECRET_ACCESS_KEY: z5.string().min(1, "ELGORA_ARTIFACT_STORAGE_SECRET_ACCESS_KEY is required"),
4414
+ ELGORA_DELIVERY_PUBLIC_KEY: z5.string().min(1, "ELGORA_DELIVERY_PUBLIC_KEY is required"),
4415
+ ELGORA_DELIVERY_PRIVATE_KEY: z5.string().min(1, "ELGORA_DELIVERY_PRIVATE_KEY is required")
4499
4416
  };
4500
- var readinessAudienceSchema = z6.string().trim().toLowerCase().min(1).max(512).refine((host) => {
4417
+ var readinessAudienceSchema = z5.string().trim().toLowerCase().min(1).max(512).refine((host) => {
4501
4418
  try {
4502
4419
  const url = new URL(`https://${host}`);
4503
4420
  return url.host === host && url.pathname === "/" && !url.username && !url.password && !url.search && !url.hash;
@@ -4511,11 +4428,11 @@ var publicationEnvShape = {
4511
4428
  ELGORA_ESCROW_TOKEN_ADDRESS: envShape.ELGORA_ESCROW_TOKEN_ADDRESS,
4512
4429
  ELGORA_DATABASE_URL: envShape.ELGORA_DATABASE_URL,
4513
4430
  ELGORA_SUBGRAPH_ENDPOINT: envShape.ELGORA_SUBGRAPH_ENDPOINT,
4514
- ELGORA_PUBLICATION_REVIEW_ENABLED: z6.string().trim().toLowerCase().pipe(z6.enum(["true", "false"])).default("true").transform((value) => value === "true"),
4515
- ELGORA_READINESS_TIMEOUT_MS: z6.coerce.number().int().min(1).max(12e4).default(12e4)
4431
+ ELGORA_PUBLICATION_REVIEW_ENABLED: z5.string().trim().toLowerCase().pipe(z5.enum(["true", "false"])).default("true").transform((value) => value === "true"),
4432
+ ELGORA_READINESS_TIMEOUT_MS: z5.coerce.number().int().min(1).max(12e4).default(12e4)
4516
4433
  };
4517
- var envSchema = z6.object(envShape);
4518
- var bountyPublicationEnvSchema = z6.object(publicationEnvShape);
4434
+ var envSchema = z5.object(envShape);
4435
+ var bountyPublicationEnvSchema = z5.object(publicationEnvShape);
4519
4436
 
4520
4437
  // ../../packages/core/src/api/elgora-hub-error-catalog.ts
4521
4438
  import { decodeErrorResult } from "viem";
@@ -4530,81 +4447,81 @@ var ELGORA_HUB_FEE_POLICY_ABI = [
4530
4447
  ];
4531
4448
 
4532
4449
  // ../../packages/core/src/api/solver-submission-responses.ts
4533
- import { isHex as isHex4 } from "viem";
4534
- import { z as z7 } from "zod";
4535
- var hexAddressSchema = z7.string().refine(isHexAddress, "Must be a hex-encoded address");
4536
- var hexBytes32Schema = z7.string().refine(isHexBytes32, "Must be 32-byte hex");
4537
- var hexDataSchema = z7.string().refine((value) => isHex4(value), "Must be hex-encoded calldata");
4538
- var artifactUploadUrlResponseSchema = z7.object({
4539
- locator: z7.string().min(1),
4540
- upload_url: z7.string().min(1),
4541
- method: z7.literal("PUT"),
4542
- expires_at: z7.string().min(1)
4450
+ import { isHex as isHex3 } from "viem";
4451
+ import { z as z6 } from "zod";
4452
+ var hexAddressSchema = z6.string().refine(isHexAddress, "Must be a hex-encoded address");
4453
+ var hexBytes32Schema = z6.string().refine(isHexBytes32, "Must be 32-byte hex");
4454
+ var hexDataSchema = z6.string().refine((value) => isHex3(value), "Must be hex-encoded calldata");
4455
+ var artifactUploadUrlResponseSchema = z6.object({
4456
+ locator: z6.string().min(1),
4457
+ upload_url: z6.string().min(1),
4458
+ method: z6.literal("PUT"),
4459
+ expires_at: z6.string().min(1)
4543
4460
  });
4544
- var solverSubmissionPrepareResponseSchema = z7.object({
4545
- content_record: z7.object({
4546
- content_kind: z7.literal(SOLVER_SUBMISSION_CONTENT_KIND),
4461
+ var solverSubmissionPrepareResponseSchema = z6.object({
4462
+ content_record: z6.object({
4463
+ content_kind: z6.literal(SOLVER_SUBMISSION_CONTENT_KIND),
4547
4464
  submission_commitment: hexBytes32Schema,
4548
- byte_length: z7.number().int().nonnegative(),
4549
- created_at: z7.string().min(1)
4465
+ byte_length: z6.number().int().nonnegative(),
4466
+ created_at: z6.string().min(1)
4550
4467
  }),
4551
- submit_transaction: z7.object({
4552
- chain_id: z7.number().int().positive(),
4468
+ submit_transaction: z6.object({
4469
+ chain_id: z6.number().int().positive(),
4553
4470
  to: hexAddressSchema,
4554
- value: z7.literal("0"),
4471
+ value: z6.literal("0"),
4555
4472
  data: hexDataSchema,
4556
- function_name: z7.literal("submit"),
4557
- args: z7.object({
4558
- bounty_id: z7.string().min(1),
4473
+ function_name: z6.literal("submit"),
4474
+ args: z6.object({
4475
+ bounty_id: z6.string().min(1),
4559
4476
  submission_commitment: hexBytes32Schema,
4560
4477
  guardian_roster_hash: hexBytes32Schema,
4561
- extra_data: z7.literal("0x")
4478
+ extra_data: z6.literal("0x")
4562
4479
  })
4563
4480
  })
4564
4481
  });
4565
- var solverSubmissionContentResponseSchema = z7.object({
4566
- content_record: z7.object({
4567
- bounty_id: z7.string().min(1),
4568
- canonical_json: z7.string().min(1)
4482
+ var solverSubmissionContentResponseSchema = z6.object({
4483
+ content_record: z6.object({
4484
+ bounty_id: z6.string().min(1),
4485
+ canonical_json: z6.string().min(1)
4569
4486
  }),
4570
- ciphertext_download_url: z7.string().min(1),
4571
- expires_at: z7.string().min(1)
4487
+ ciphertext_download_url: z6.string().min(1),
4488
+ expires_at: z6.string().min(1)
4572
4489
  });
4573
- var bountyGuardianRosterResponseSchema = z7.object({
4574
- bounty: z7.object({
4490
+ var bountyGuardianRosterResponseSchema = z6.object({
4491
+ bounty: z6.object({
4575
4492
  guardian_roster_hash: hexBytes32Schema,
4576
- guardian_roster: z7.array(
4577
- z7.object({
4578
- name: z7.string(),
4493
+ guardian_roster: z6.array(
4494
+ z6.object({
4495
+ name: z6.string(),
4579
4496
  account: hexAddressSchema,
4580
- encryption_public_key: z7.string().min(1)
4497
+ encryption_public_key: z6.string().min(1)
4581
4498
  })
4582
4499
  ).min(1)
4583
4500
  })
4584
4501
  });
4585
4502
 
4586
4503
  // ../../packages/core/src/api/verification-records.ts
4587
- import { z as z8 } from "zod";
4588
- var hexAddressSchema2 = z8.string().refine(isHexAddress, "Must be a hex-encoded address").transform((value) => value.toLowerCase());
4589
- var hexBytes32Schema2 = z8.string().refine(isHexBytes32, "Must be 32-byte hex").transform((value) => value.toLowerCase());
4590
- var integerStringSchema = z8.string().regex(/^(0|[1-9][0-9]*)$/);
4591
- var verdictEntrySchema = z8.object({
4592
- name: z8.string().min(1),
4593
- outcome: z8.enum(["awarded", "no_valid_submission"]).nullable(),
4504
+ import { z as z7 } from "zod";
4505
+ var hexAddressSchema2 = z7.string().refine(isHexAddress, "Must be a hex-encoded address").transform((value) => value.toLowerCase());
4506
+ var hexBytes32Schema2 = z7.string().refine(isHexBytes32, "Must be 32-byte hex").transform((value) => value.toLowerCase());
4507
+ var integerStringSchema = z7.string().regex(/^(0|[1-9][0-9]*)$/);
4508
+ var verdictEntrySchema = z7.object({
4509
+ name: z7.string().min(1),
4510
+ outcome: z7.enum(["awarded", "no_valid_submission"]).nullable(),
4594
4511
  winner: hexAddressSchema2.nullable(),
4595
4512
  report_commitment: hexBytes32Schema2.nullable(),
4596
- committed_at: z8.string().datetime({ offset: true }).nullable(),
4597
- supporting: z8.boolean()
4513
+ committed_at: z7.string().datetime({ offset: true }).nullable(),
4514
+ supporting: z7.boolean()
4598
4515
  }).strict();
4599
- var formattedVerificationRecordSchema = z8.object({
4600
- chain_id: z8.number().int().positive(),
4516
+ var formattedVerificationRecordSchema = z7.object({
4517
+ chain_id: z7.number().int().positive(),
4601
4518
  hub_address: hexAddressSchema2,
4602
4519
  bounty_id: integerStringSchema,
4603
- status: z8.enum(["awarded", "no_valid_submission", "timed_out"]),
4520
+ status: z7.enum(["awarded", "no_valid_submission", "timed_out"]),
4604
4521
  spec_commitment: hexBytes32Schema2,
4605
4522
  winner: hexAddressSchema2.nullable(),
4606
- verdicts: z8.record(z8.string(), verdictEntrySchema),
4607
- settlement: z8.object({
4523
+ verdicts: z7.record(z7.string(), verdictEntrySchema),
4524
+ settlement: z7.object({
4608
4525
  escrow_amount: integerStringSchema,
4609
4526
  settlement_recipient: hexAddressSchema2,
4610
4527
  settlement_amount: integerStringSchema,
@@ -4615,10 +4532,10 @@ var formattedVerificationRecordSchema = z8.object({
4615
4532
  settled_tx_hash: hexBytes32Schema2,
4616
4533
  settled_block_number: integerStringSchema
4617
4534
  }).strict(),
4618
- content_record: z8.object({
4619
- spec_content_byte_length: z8.number().int().positive()
4535
+ content_record: z7.object({
4536
+ spec_content_byte_length: z7.number().int().positive()
4620
4537
  }).strict(),
4621
- verified_at: z8.string().datetime({ offset: true })
4538
+ verified_at: z7.string().datetime({ offset: true })
4622
4539
  }).strict();
4623
4540
  function parseBountyVerificationRecord(input, expected) {
4624
4541
  const slice = input;
@@ -4640,79 +4557,79 @@ function parseBountyVerificationRecord(input, expected) {
4640
4557
  }
4641
4558
 
4642
4559
  // ../../packages/core/src/api/winning-solution-delivery.ts
4643
- import { z as z9 } from "zod";
4644
- var hexBytes32Schema3 = z9.string().refine(isHexBytes32, "Must be 32-byte hex").refine((value) => value !== ZERO_BYTES32, "Must not be zero").transform((value) => value.toLowerCase());
4645
- var hexAddressSchema3 = z9.string().refine((value) => /^0x[0-9a-fA-F]{40}$/.test(value), "Must be an address").transform((value) => value.toLowerCase());
4646
- var deliveryKeyIdSchema = z9.string().min(1).max(128);
4647
- var winningSolutionWrappedKeySchema = z9.strictObject({
4648
- enc: z9.string().min(1),
4649
- ciphertext: z9.string().min(1)
4560
+ import { z as z8 } from "zod";
4561
+ var hexBytes32Schema3 = z8.string().refine(isHexBytes32, "Must be 32-byte hex").refine((value) => value !== ZERO_BYTES32, "Must not be zero").transform((value) => value.toLowerCase());
4562
+ var hexAddressSchema3 = z8.string().refine((value) => /^0x[0-9a-fA-F]{40}$/.test(value), "Must be an address").transform((value) => value.toLowerCase());
4563
+ var deliveryKeyIdSchema = z8.string().min(1).max(128);
4564
+ var winningSolutionWrappedKeySchema = z8.strictObject({
4565
+ enc: z8.string().min(1),
4566
+ ciphertext: z8.string().min(1)
4650
4567
  });
4651
- var deliveryWrapRequestSchema = z9.strictObject({
4568
+ var deliveryWrapRequestSchema = z8.strictObject({
4652
4569
  solver_address: hexAddressSchema3,
4653
4570
  submission_commitment: hexBytes32Schema3,
4654
4571
  wrapped_key: winningSolutionWrappedKeySchema
4655
4572
  });
4656
- var deliveryWrapRecordSchema = z9.strictObject({
4657
- bounty_id: z9.string().min(1),
4573
+ var deliveryWrapRecordSchema = z8.strictObject({
4574
+ bounty_id: z8.string().min(1),
4658
4575
  guardian_address: hexAddressSchema3,
4659
4576
  solver_address: hexAddressSchema3,
4660
4577
  submission_commitment: hexBytes32Schema3,
4661
4578
  delivery_key_id: deliveryKeyIdSchema,
4662
- created_at: z9.string().min(1)
4579
+ created_at: z8.string().min(1)
4663
4580
  });
4664
- var deliveryWrapResponseSchema = z9.strictObject({
4665
- status: z9.literal("stored"),
4581
+ var deliveryWrapResponseSchema = z8.strictObject({
4582
+ status: z8.literal("stored"),
4666
4583
  wrap: deliveryWrapRecordSchema
4667
4584
  });
4668
- var deliveryRetrieveRequestSchema = z9.strictObject({
4585
+ var deliveryRetrieveRequestSchema = z8.strictObject({
4669
4586
  poster_ephemeral_public_key: x25519PublicKeySchema
4670
4587
  });
4671
- var deliveryRetrieveResponseSchema = z9.strictObject({
4588
+ var deliveryRetrieveResponseSchema = z8.strictObject({
4672
4589
  submission_commitment: hexBytes32Schema3,
4673
4590
  wrapped_key: winningSolutionWrappedKeySchema
4674
4591
  });
4675
- var deliveryStatusResponseSchema = z9.strictObject({
4676
- exists: z9.boolean()
4592
+ var deliveryStatusResponseSchema = z8.strictObject({
4593
+ exists: z8.boolean()
4677
4594
  });
4678
- var deliveryKeyConfigResponseSchema = z9.strictObject({
4595
+ var deliveryKeyConfigResponseSchema = z8.strictObject({
4679
4596
  delivery_key_id: deliveryKeyIdSchema,
4680
- public_key: z9.string().min(1)
4597
+ public_key: z8.string().min(1)
4681
4598
  });
4682
4599
 
4683
4600
  // ../../packages/core/src/api/written-verdicts.ts
4684
4601
  import { keccak256 as keccak2564, toBytes as toBytes3, zeroAddress as zeroAddress2 } from "viem";
4685
- import { z as z10 } from "zod";
4602
+ import { z as z9 } from "zod";
4686
4603
  var WRITTEN_VERDICT_FORMAT_VERSION = 0;
4687
4604
  var FRONTMATTER_DELIMITER2 = "---";
4688
- var decimalSchema = z10.string().regex(/^[1-9][0-9]*$/, "Must be a positive integer").transform(Number).refine(Number.isSafeInteger, "Must be a safe integer");
4689
- var bountyIdSchema2 = z10.string().regex(/^(0|[1-9][0-9]*)$/, "Must be a non-negative integer");
4690
- var addressSchema2 = z10.string().refine(isHexAddress, "Must be a hex-encoded address").refine((value) => value === value.toLowerCase(), "Must use lowercase hex").transform((value) => value);
4691
- var bytes32Schema4 = z10.string().refine(isHexBytes32, "Must be 32-byte hex").refine((value) => value === value.toLowerCase(), "Must use lowercase hex").transform((value) => value);
4605
+ var decimalSchema = z9.string().regex(/^[1-9][0-9]*$/, "Must be a positive integer").transform(Number).refine(Number.isSafeInteger, "Must be a safe integer");
4606
+ var bountyIdSchema2 = z9.string().regex(/^(0|[1-9][0-9]*)$/, "Must be a non-negative integer");
4607
+ var addressSchema2 = z9.string().refine(isHexAddress, "Must be a hex-encoded address").refine((value) => value === value.toLowerCase(), "Must use lowercase hex").transform((value) => value);
4608
+ var bytes32Schema3 = z9.string().refine(isHexBytes32, "Must be 32-byte hex").refine((value) => value === value.toLowerCase(), "Must use lowercase hex").transform((value) => value);
4692
4609
  var commonFields = {
4693
- format_version: z10.literal(WRITTEN_VERDICT_FORMAT_VERSION.toString()).transform(() => WRITTEN_VERDICT_FORMAT_VERSION),
4610
+ format_version: z9.literal(WRITTEN_VERDICT_FORMAT_VERSION.toString()).transform(() => WRITTEN_VERDICT_FORMAT_VERSION),
4694
4611
  chain_id: decimalSchema,
4695
4612
  hub_address: addressSchema2,
4696
4613
  bounty_id: bountyIdSchema2,
4697
- verdict_body: z10.string().refine((value) => value.trim().length > 0, "Must not be empty")
4614
+ verdict_body: z9.string().refine((value) => value.trim().length > 0, "Must not be empty")
4698
4615
  };
4699
- var writtenVerdictSchema = z10.discriminatedUnion("outcome", [
4700
- z10.object({
4616
+ var writtenVerdictSchema = z9.discriminatedUnion("outcome", [
4617
+ z9.object({
4701
4618
  ...commonFields,
4702
- outcome: z10.literal("awarded"),
4619
+ outcome: z9.literal("awarded"),
4703
4620
  winner: addressSchema2.refine(
4704
4621
  (value) => value !== zeroAddress2,
4705
4622
  "Must not be the zero address"
4706
4623
  ),
4707
- awarded_submission_commitment: bytes32Schema4.refine(
4624
+ awarded_submission_commitment: bytes32Schema3.refine(
4708
4625
  (value) => value !== ZERO_BYTES32,
4709
4626
  "Must not be zero bytes"
4710
4627
  )
4711
4628
  }).strict(),
4712
- z10.object({
4629
+ z9.object({
4713
4630
  ...commonFields,
4714
- outcome: z10.literal("no_valid_submission"),
4715
- winner: z10.literal(zeroAddress2)
4631
+ outcome: z9.literal("no_valid_submission"),
4632
+ winner: z9.literal(zeroAddress2)
4716
4633
  }).strict()
4717
4634
  ]);
4718
4635
  function buildWrittenVerdictMarkdown(input) {
@@ -5215,10 +5132,10 @@ var ApiRequestError = class extends Error {
5215
5132
  this.retryAfterMs = input.retryAfterMs;
5216
5133
  }
5217
5134
  };
5218
- async function postText(url, body, contentType, authorization, headers = {}) {
5135
+ async function postText(url, body, contentType, authorization) {
5219
5136
  const response = await fetch(url, {
5220
5137
  method: "POST",
5221
- headers: { ...headers, "content-type": contentType, authorization },
5138
+ headers: { "content-type": contentType, authorization },
5222
5139
  body
5223
5140
  });
5224
5141
  return parseJsonResponse(url, response);
@@ -5378,7 +5295,7 @@ function toArrayBuffer(bytes) {
5378
5295
  import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
5379
5296
 
5380
5297
  // ../../packages/core/src/auth/authorization-header.ts
5381
- import { isAddress as isAddress3, isHex as isHex5 } from "viem";
5298
+ import { isAddress as isAddress3, isHex as isHex4 } from "viem";
5382
5299
  var ELGORA_APPROVAL_AUTH_SCHEME = "Elgora-Approval";
5383
5300
  var FIELD_SEPARATOR = "~";
5384
5301
  function encodeApiRequestApprovalHeader(fields) {
@@ -5391,27 +5308,59 @@ function encodeApiRequestApprovalHeader(fields) {
5391
5308
  return `${ELGORA_APPROVAL_AUTH_SCHEME} ${btoa(payload)}`;
5392
5309
  }
5393
5310
 
5394
- // ../../packages/core/src/auth/readiness-signoff-header.ts
5395
- var ELGORA_READINESS_SIGNOFF_HEADER = "Elgora-Readiness-Signoff";
5396
- function encodeReadinessSignoffHeader(signoff) {
5397
- const bytes = new TextEncoder().encode(
5398
- JSON.stringify(readinessSignoffSchema.parse(signoff))
5399
- );
5400
- return btoa(String.fromCharCode(...bytes));
5311
+ // ../../packages/core/src/auth/eip712.ts
5312
+ var API_REQUEST_APPROVAL_PRIMARY_TYPE = "ApiRequestApproval";
5313
+ var API_REQUEST_APPROVAL_TYPES = {
5314
+ ApiRequestApproval: [
5315
+ { name: "endpointId", type: "string" },
5316
+ { name: "audience", type: "string" },
5317
+ { name: "bodyHash", type: "bytes32" },
5318
+ { name: "query", type: "string" },
5319
+ { name: "blockNumber", type: "uint256" },
5320
+ { name: "blockHash", type: "bytes32" }
5321
+ ]
5322
+ };
5323
+ function buildElgoraEip712Domain(params) {
5324
+ return {
5325
+ name: "Elgora",
5326
+ version: "1",
5327
+ chainId: params.chainId,
5328
+ verifyingContract: params.hubAddress
5329
+ };
5330
+ }
5331
+ function buildApiRequestApprovalTypedData(params) {
5332
+ return {
5333
+ domain: buildElgoraEip712Domain({
5334
+ chainId: params.chainId,
5335
+ hubAddress: params.hubAddress
5336
+ }),
5337
+ types: API_REQUEST_APPROVAL_TYPES,
5338
+ primaryType: API_REQUEST_APPROVAL_PRIMARY_TYPE,
5339
+ message: params.message
5340
+ };
5341
+ }
5342
+ function endpointIdFor(input) {
5343
+ return `${input.method.toUpperCase()} ${input.path}`;
5344
+ }
5345
+ function audienceFor(host) {
5346
+ return host.toLowerCase();
5347
+ }
5348
+ function queryFor(query) {
5349
+ return new URLSearchParams(query).toString();
5401
5350
  }
5402
5351
 
5403
5352
  // ../../packages/core/src/auth/request-approval.ts
5404
5353
  import {
5405
5354
  hashTypedData,
5406
- isAddressEqual as isAddressEqual3,
5355
+ isAddressEqual as isAddressEqual2,
5407
5356
  keccak256 as keccak2565,
5408
5357
  toBytes as toBytes4
5409
5358
  } from "viem";
5410
5359
 
5411
5360
  // ../../packages/core/src/auth/signature.ts
5412
5361
  import {
5413
- isAddressEqual as isAddressEqual2,
5414
- recoverTypedDataAddress as recoverTypedDataAddress3
5362
+ isAddressEqual,
5363
+ recoverTypedDataAddress as recoverTypedDataAddress2
5415
5364
  } from "viem";
5416
5365
 
5417
5366
  // ../../packages/core/src/auth/request-approval-header.ts
@@ -7173,7 +7122,7 @@ function resolveChainId(selector) {
7173
7122
  }
7174
7123
 
7175
7124
  // src/version.ts
7176
- var CLI_VERSION = true ? "9.1.0" : "0.0.0-dev";
7125
+ var CLI_VERSION = true ? "10.0.0" : "0.0.0-dev";
7177
7126
  var CLI_NODE_ENGINES = true ? ">=24 <25" : ">=24 <25";
7178
7127
 
7179
7128
  // src/node-engines.ts
@@ -7380,7 +7329,6 @@ function required3(env, name) {
7380
7329
  }
7381
7330
 
7382
7331
  // src/publish-fund.ts
7383
- import { readFile as readFile5 } from "fs/promises";
7384
7332
  import {
7385
7333
  decodeFunctionData,
7386
7334
  parseAbi as parseAbi2,
@@ -7408,15 +7356,6 @@ function loadPosterConfig(env, apiBaseUrlOverride) {
7408
7356
  posterPrivateKey: privateKey
7409
7357
  };
7410
7358
  }
7411
- function takeFlag(argv, flag, usage) {
7412
- const uses = argv.filter(
7413
- (arg) => arg === flag || arg.startsWith(`${flag}=`)
7414
- ).length;
7415
- const extracted = extractFlagValue(argv, flag);
7416
- if (uses > 1 || uses === 1 && (!extracted.value || extracted.value.startsWith("--")))
7417
- throw new Error(usage);
7418
- return extracted;
7419
- }
7420
7359
  async function readBountyChallengeMarkdown2(path5) {
7421
7360
  return path5 === "-" ? readStdinText3(process.stdin) : readFile4(path5, "utf8");
7422
7361
  }
@@ -7434,19 +7373,14 @@ async function signPosterRequest(input) {
7434
7373
  }
7435
7374
 
7436
7375
  // src/publish-fund.ts
7437
- var PUBLISH_FUND_USAGE = "Usage: elgora-cli poster:publish-fund <bounty_challenge_md_path|-> --signoff <file>";
7376
+ var PUBLISH_FUND_USAGE = "Usage: elgora-cli poster:publish-fund <bounty_challenge_md_path|->";
7438
7377
  var usdcAbi = parseAbi2([
7439
7378
  "function approve(address spender,uint256 value) returns (bool)",
7440
7379
  "function balanceOf(address account) view returns (uint256)"
7441
7380
  ]);
7442
7381
  async function main9(env = process.env, argv = process.argv.slice(2)) {
7443
- const { apiBaseUrl: apiBaseUrlOverride, argv: afterApiBaseUrl } = extractApiBaseUrlFlag(argv);
7444
- const { value: signoffPath, argv: remainingArgv } = takeFlag(
7445
- afterApiBaseUrl,
7446
- "--signoff",
7447
- PUBLISH_FUND_USAGE
7448
- );
7449
- if (!signoffPath || remainingArgv.length !== 1 || !remainingArgv[0])
7382
+ const { apiBaseUrl: apiBaseUrlOverride, argv: remainingArgv } = extractApiBaseUrlFlag(argv);
7383
+ if (remainingArgv.length !== 1 || !remainingArgv[0])
7450
7384
  throw new Error(PUBLISH_FUND_USAGE);
7451
7385
  const config = loadPosterConfig(env, apiBaseUrlOverride);
7452
7386
  const escrowTokenAddress = withDeploymentDefaults(env).ELGORA_ESCROW_TOKEN_ADDRESS?.trim();
@@ -7462,17 +7396,6 @@ async function main9(env = process.env, argv = process.argv.slice(2)) {
7462
7396
  const localSpecCommitment = deriveBountyChallengeContentCommitment(
7463
7397
  bountyChallengeMarkdown
7464
7398
  );
7465
- const signoff = readinessSignoffSchema.parse(
7466
- JSON.parse(await readFile5(signoffPath, "utf8"))
7467
- );
7468
- if (signoff.spec_commitment.toLowerCase() !== localSpecCommitment) {
7469
- throw new Error(
7470
- "Readiness sign-off does not match the exact bounty_challenge.md bytes. Run poster:review again."
7471
- );
7472
- }
7473
- if (signoff.expires_at <= Math.floor(Date.now() / 1e3)) {
7474
- throw new Error("Readiness sign-off has expired. Run poster:review again.");
7475
- }
7476
7399
  const account = privateKeyToAccount8(config.posterPrivateKey);
7477
7400
  const publicClient = createChainPublicClient(config.chainId, config.rpcUrl);
7478
7401
  const walletClient = createChainWalletClient(
@@ -7496,8 +7419,7 @@ async function main9(env = process.env, argv = process.argv.slice(2)) {
7496
7419
  const prepared = await requestPreparePublication({
7497
7420
  requestUrl: requestUrl.toString(),
7498
7421
  markdown: bountyChallengeMarkdown,
7499
- authorization,
7500
- signoff: encodeReadinessSignoffHeader(signoff)
7422
+ authorization
7501
7423
  });
7502
7424
  if (prepared.content_record.spec_commitment !== localSpecCommitment) {
7503
7425
  throw new Error(
@@ -7637,8 +7559,7 @@ async function requestPreparePublication(input) {
7637
7559
  new URL(input.requestUrl),
7638
7560
  input.markdown,
7639
7561
  "text/markdown",
7640
- input.authorization,
7641
- { [ELGORA_READINESS_SIGNOFF_HEADER]: input.signoff }
7562
+ input.authorization
7642
7563
  );
7643
7564
  return bountyPublicationResponseSchema.parse(body);
7644
7565
  }
@@ -7649,28 +7570,28 @@ function missingRequiredEnv(required4, env) {
7649
7570
  }
7650
7571
 
7651
7572
  // src/review.ts
7652
- import { writeFile as writeFile3 } from "fs/promises";
7653
- import { resolve } from "path";
7654
7573
  import { privateKeyToAccount as privateKeyToAccount9 } from "viem/accounts";
7655
- var USAGE2 = "Usage: elgora-cli poster:review <path|-> [--previous <commitment>] [--signoff-out <file>]";
7574
+ var USAGE2 = "Usage: elgora-cli poster:review <path|-> [--previous <commitment>]";
7575
+ function takeFlag(argv, flag, usage) {
7576
+ const uses = argv.filter(
7577
+ (arg) => arg === flag || arg.startsWith(`${flag}=`)
7578
+ ).length;
7579
+ const extracted = extractFlagValue(argv, flag);
7580
+ if (uses > 1 || uses === 1 && (!extracted.value || extracted.value.startsWith("--")))
7581
+ throw new Error(usage);
7582
+ return extracted;
7583
+ }
7656
7584
  async function main10(env = process.env, argv = process.argv.slice(2)) {
7657
7585
  const { apiBaseUrl, argv: args } = extractApiBaseUrlFlag(argv);
7658
- const { value: previous, argv: afterPrevious } = takeFlag(
7586
+ const { value: previous, argv: paths } = takeFlag(
7659
7587
  args,
7660
7588
  "--previous",
7661
7589
  "--previous must be one bytes32 page commitment"
7662
7590
  );
7663
7591
  if (previous && !isHexBytes32(previous))
7664
7592
  throw new Error("--previous must be one bytes32 page commitment");
7665
- const { value: signoffOut, argv: paths } = takeFlag(
7666
- afterPrevious,
7667
- "--signoff-out",
7668
- USAGE2
7669
- );
7670
7593
  if (paths.length !== 1 || !paths[0] || paths[0].startsWith("--"))
7671
7594
  throw new Error(USAGE2);
7672
- if (signoffOut && paths[0] !== "-" && resolve(signoffOut) === resolve(paths[0]))
7673
- throw new Error("--signoff-out must not overwrite the bounty draft");
7674
7595
  const config = loadPosterConfig(env, apiBaseUrl);
7675
7596
  const markdown = await readBountyChallengeMarkdown2(paths[0]);
7676
7597
  const commitment = deriveBountyChallengeContentCommitment(markdown);
@@ -7719,18 +7640,12 @@ async function main10(env = process.env, argv = process.argv.slice(2)) {
7719
7640
  "Elgora API returned a review for different bounty_challenge.md bytes"
7720
7641
  );
7721
7642
  }
7722
- if (signoffOut)
7723
- await writeFile3(
7724
- signoffOut,
7725
- `${JSON.stringify(response.readiness.signoff, null, 2)}
7726
- `
7727
- );
7728
7643
  console.log(
7729
7644
  JSON.stringify({
7730
7645
  event: "review.ready",
7731
7646
  spec_commitment: commitment,
7732
- signoff: response.readiness.signoff,
7733
- warnings: response.readiness.warnings ?? [],
7647
+ approved_until: response.readiness.approved_until,
7648
+ warnings: response.readiness.warnings,
7734
7649
  prior_issues_resolved: response.readiness.prior_issues_resolved,
7735
7650
  prior_issues_open: response.readiness.prior_issues_open
7736
7651
  })
@@ -7960,8 +7875,8 @@ function usageError3() {
7960
7875
  }
7961
7876
 
7962
7877
  // src/roster-verify-guardian-proof.ts
7963
- import { readFile as readFile6 } from "fs/promises";
7964
- import { isAddress as isAddress6, isHex as isHex6, recoverMessageAddress } from "viem";
7878
+ import { readFile as readFile5 } from "fs/promises";
7879
+ import { isAddress as isAddress6, isHex as isHex5, recoverMessageAddress } from "viem";
7965
7880
  async function main13(_env = process.env, argv = process.argv.slice(2)) {
7966
7881
  const [preparedPath, responsePath] = argv;
7967
7882
  if (!preparedPath || !responsePath) {
@@ -7969,8 +7884,8 @@ async function main13(_env = process.env, argv = process.argv.slice(2)) {
7969
7884
  "Usage: elgora-cli roster:verify-guardian-proof <prepared_json_path> <response_json_path>"
7970
7885
  );
7971
7886
  }
7972
- const prepared = parsePrepared(await readFile6(preparedPath, "utf8"));
7973
- const response = parseResponse(await readFile6(responsePath, "utf8"));
7887
+ const prepared = parsePrepared(await readFile5(preparedPath, "utf8"));
7888
+ const response = parseResponse(await readFile5(responsePath, "utf8"));
7974
7889
  const fixture = base64UrlToBytes(prepared.fixture);
7975
7890
  const signedPayload = buildGuardianRosterKeyProofSignedPayload(
7976
7891
  prepared.message,
@@ -8034,7 +7949,7 @@ function parseResponse(text) {
8034
7949
  }
8035
7950
  const guardianAccount = get(parsed, "guardian_account");
8036
7951
  const signature = get(parsed, "signature");
8037
- if (typeof guardianAccount !== "string" || !isAddress6(guardianAccount) || typeof signature !== "string" || !isHex6(signature) || signature.length !== 132) {
7952
+ if (typeof guardianAccount !== "string" || !isAddress6(guardianAccount) || typeof signature !== "string" || !isHex5(signature) || signature.length !== 132) {
8038
7953
  throw new Error(
8039
7954
  "Guardian response JSON must be the unmodified stdout of guardian:prove-roster-key"
8040
7955
  );
@@ -8052,7 +7967,7 @@ function get(value, key) {
8052
7967
  }
8053
7968
 
8054
7969
  // src/spec-commitment.ts
8055
- import { readFile as readFile7 } from "fs/promises";
7970
+ import { readFile as readFile6 } from "fs/promises";
8056
7971
  import { text as readStdinText4 } from "stream/consumers";
8057
7972
  var SPEC_COMMITMENT_USAGE = "Usage: elgora-cli spec-commitment <bounty_challenge_md_path>\n or: elgora-cli spec-commitment -";
8058
7973
  async function main14(_env = process.env, argv = process.argv.slice(2)) {
@@ -8074,23 +7989,23 @@ async function readBountyChallengeMarkdown3(argv) {
8074
7989
  if (path5 === "-") {
8075
7990
  return readStdinText4(process.stdin);
8076
7991
  }
8077
- return readFile7(path5, "utf8");
7992
+ return readFile6(path5, "utf8");
8078
7993
  }
8079
7994
 
8080
7995
  // src/submit.ts
8081
- import { readdir, readFile as readFile8, stat } from "fs/promises";
7996
+ import { readdir, readFile as readFile7, stat } from "fs/promises";
8082
7997
  import path3 from "path";
8083
7998
  import { createInterface } from "readline";
8084
7999
  import { isAddress as isAddress7 } from "viem";
8085
8000
  import { privateKeyToAccount as privateKeyToAccount11 } from "viem/accounts";
8086
8001
 
8087
8002
  // src/external-api-approval-signer.ts
8088
- import { isHex as isHex7 } from "viem";
8003
+ import { isHex as isHex6 } from "viem";
8089
8004
  function createExternalApiApprovalSigner(input) {
8090
8005
  return async (typedData) => {
8091
8006
  input.writePrompt(input.renderPrompt(typedData));
8092
8007
  const signature = (await input.readSignature())?.trim();
8093
- if (!signature || signature === "0x" || !isHex7(signature)) {
8008
+ if (!signature || signature === "0x" || !isHex6(signature)) {
8094
8009
  throw new Error(
8095
8010
  "External signer must return one non-empty 0x-prefixed hex signature line on stdin"
8096
8011
  );
@@ -8530,7 +8445,7 @@ async function readArtifactDirectory(artifactDir) {
8530
8445
  }
8531
8446
  return Promise.all(
8532
8447
  entries.map(async (entry) => {
8533
- const bytes = await readFile8(path3.join(artifactDir, entry.name));
8448
+ const bytes = await readFile7(path3.join(artifactDir, entry.name));
8534
8449
  return {
8535
8450
  name: entry.name,
8536
8451
  media_type: guessMediaType(entry.name),
@@ -8599,7 +8514,7 @@ async function requestPrepareSubmission(input) {
8599
8514
  })
8600
8515
  );
8601
8516
  }
8602
- await new Promise((resolve2) => setTimeout(resolve2, retryDelay));
8517
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
8603
8518
  }
8604
8519
  }
8605
8520
  }
@@ -8807,9 +8722,9 @@ var COMMAND_HELP = {
8807
8722
  apiBaseUrlFlag: true
8808
8723
  },
8809
8724
  "poster:review": {
8810
- usage: "elgora-cli poster:review <path|-> [--previous <commitment>] [--signoff-out <file>]",
8811
- title: "Review a bounty page and save its readiness certificate.",
8812
- description: "Send the exact Markdown for a signed readiness review. Ready prints\n review.ready; --signoff-out saves the certificate for publication.\n Not-ready prints all issues and exits 2; other failures exit 1.\n --previous sends the previous page commitment with the signed request.",
8725
+ usage: "elgora-cli poster:review <path|-> [--previous <commitment>]",
8726
+ title: "Review a bounty page before publishing it.",
8727
+ description: "Sign and send the exact Markdown for a readiness review. Ready prints\n review.ready; Elgora keeps the approval for these exact bytes.\n Not-ready prints all issues and exits 2; other failures exit 1.\n --previous sends the previous page commitment with the signed request.",
8813
8728
  required: ["ELGORA_POSTER_PRIVATE_KEY"],
8814
8729
  defaulted: [
8815
8730
  "ELGORA_CHAIN_ID",
@@ -8820,9 +8735,9 @@ var COMMAND_HELP = {
8820
8735
  apiBaseUrlFlag: true
8821
8736
  },
8822
8737
  "poster:publish-fund": {
8823
- usage: "elgora-cli poster:publish-fund <bounty_challenge_md_path|-> --signoff <file>",
8738
+ usage: "elgora-cli poster:publish-fund <bounty_challenge_md_path|->",
8824
8739
  title: "Publish an approved challenge and fund its bounty.",
8825
- description: "Read the exact approved bounty_challenge.md bytes and its saved certificate.\n Publishing checks the certificate and never runs another AI review.\n Eligible wallets sign a USDC authorization, then send\n one funding transaction and pay gas. No new allowance is required;\n this authorization path does not revoke existing allowances.\n Unsupported accounts use approval then creation. Pass '-' to read stdin.",
8740
+ description: "Read the exact approved bounty_challenge.md bytes. Publishing reuses\n their saved approval without another AI review, or reviews them first.\n Eligible wallets sign a USDC authorization, then send\n one funding transaction and pay gas. No new allowance is required;\n this authorization path does not revoke existing allowances.\n Unsupported accounts use approval then creation. Pass '-' to read stdin.",
8826
8741
  required: ["ELGORA_POSTER_PRIVATE_KEY"],
8827
8742
  defaulted: [
8828
8743
  "ELGORA_CHAIN_ID",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elgora/cli",
3
- "version": "9.1.0",
3
+ "version": "10.0.0",
4
4
  "description": "Command-line client for Elgora, a decentralized bounty marketplace for science. Lets Posters, Solvers, and Guardians interact with Elgora's public API and on-chain contracts.",
5
5
  "type": "module",
6
6
  "license": "MIT",