@elgora/cli 9.0.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.
- package/README.md +5 -4
- package/dist/cli.js +301 -352
- 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
|
|
31
|
-
|
|
32
|
-
- `poster:publish-fund`
|
|
33
|
-
|
|
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
|
|
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
|
-
|
|
400
|
-
var
|
|
401
|
-
var
|
|
402
|
-
|
|
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
|
-
|
|
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:
|
|
398
|
+
created_at: z2.string().datetime({ offset: true })
|
|
468
399
|
}).strict();
|
|
469
|
-
var bountyPublicationResponseSchema =
|
|
400
|
+
var bountyPublicationResponseSchema = z2.object({
|
|
470
401
|
content_record: bountyChallengeContentRecordSchema,
|
|
471
|
-
create_bounty_transaction:
|
|
472
|
-
chain_id:
|
|
402
|
+
create_bounty_transaction: z2.object({
|
|
403
|
+
chain_id: z2.number().int().positive(),
|
|
473
404
|
to: addressSchema,
|
|
474
|
-
value:
|
|
405
|
+
value: z2.literal("0"),
|
|
475
406
|
data: hexBytesSchema,
|
|
476
|
-
function_name:
|
|
477
|
-
args:
|
|
478
|
-
spec_commitment:
|
|
479
|
-
escrow_amount:
|
|
480
|
-
submission_deadline:
|
|
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:
|
|
414
|
+
protocol_fee_policy: z2.object({
|
|
484
415
|
treasury_recipient: addressSchema,
|
|
485
|
-
treasury_fee_bps:
|
|
416
|
+
treasury_fee_bps: z2.number().int().min(0).max(1e4),
|
|
486
417
|
guardian_fee_recipient: addressSchema,
|
|
487
|
-
guardian_fee_bps:
|
|
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,28 +426,33 @@ var bountyPublicationResponseSchema = z3.object({
|
|
|
495
426
|
});
|
|
496
427
|
}
|
|
497
428
|
});
|
|
498
|
-
var priorIssueSchema =
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
prior_issues_resolved: z3.array(priorIssueSchema),
|
|
505
|
-
prior_issues_open: z3.array(priorIssueSchema)
|
|
506
|
-
}).strict()
|
|
507
|
-
}).strict().superRefine((response, context) => {
|
|
508
|
-
if (response.readiness.signoff.spec_commitment.toLowerCase() !== response.content_record.spec_commitment.toLowerCase()) {
|
|
509
|
-
context.addIssue({
|
|
510
|
-
code: "custom",
|
|
511
|
-
path: ["readiness", "signoff", "spec_commitment"],
|
|
512
|
-
message: "Must match content_record.spec_commitment"
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
var readinessSignerResponseSchema = z3.object({
|
|
517
|
-
signer_address: addressSchema,
|
|
518
|
-
audience: z3.string().min(1)
|
|
429
|
+
var priorIssueSchema = z2.object({
|
|
430
|
+
issue_index: z2.number().int().nonnegative(),
|
|
431
|
+
message: z2.string().trim().min(1).max(1500)
|
|
432
|
+
}).strict();
|
|
433
|
+
var priorIssueStatusSchema = priorIssueSchema.extend({
|
|
434
|
+
status: z2.enum(["resolved", "open"])
|
|
519
435
|
}).strict();
|
|
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()
|
|
442
|
+
});
|
|
443
|
+
var MAX_READINESS_FINDINGS = 20;
|
|
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 }),
|
|
450
|
+
// The dissenting pass's findings on a ready check; never blocking.
|
|
451
|
+
warnings: z2.array(readinessFindingSchema).max(MAX_READINESS_FINDINGS),
|
|
452
|
+
prior_issues_resolved: z2.array(priorIssueSchema),
|
|
453
|
+
prior_issues_open: z2.array(priorIssueSchema)
|
|
454
|
+
})
|
|
455
|
+
});
|
|
520
456
|
|
|
521
457
|
// ../../packages/core/src/chain-registry.ts
|
|
522
458
|
import { base, baseSepolia, foundry } from "viem/chains";
|
|
@@ -540,7 +476,7 @@ var FOUNDRY_CHAIN_ID = foundry.id;
|
|
|
540
476
|
import { Aes256Gcm, CipherSuite, HkdfSha256 } from "@hpke/core";
|
|
541
477
|
import { DhkemX25519HkdfSha256 } from "@hpke/dhkem-x25519";
|
|
542
478
|
import { concatBytes, keccak256 as keccak2562, toBytes as toBytes2 } from "viem";
|
|
543
|
-
import { z as
|
|
479
|
+
import { z as z3 } from "zod";
|
|
544
480
|
|
|
545
481
|
// ../../packages/core/src/base64.ts
|
|
546
482
|
var BASE64_ENCODE_CHUNK_BYTES = 3 * 16384;
|
|
@@ -626,42 +562,42 @@ var BASE64URL_RE = /^[A-Za-z0-9_-]+$/;
|
|
|
626
562
|
var SOLVER_SUBMISSION_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
627
563
|
var MEDIA_TYPE_RE = /^[a-z0-9][a-z0-9!#$&^_.+-]*\/[a-z0-9][a-z0-9!#$&^_.+-]*$/;
|
|
628
564
|
var KEY_ID_RE = /^[A-Za-z0-9][ -~]*$/;
|
|
629
|
-
var base64UrlSchema =
|
|
630
|
-
var lowerAddressSchema =
|
|
631
|
-
var
|
|
632
|
-
var sha256HexSchema =
|
|
633
|
-
var keyIdSchema =
|
|
634
|
-
var artifactNameSchema =
|
|
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(
|
|
635
571
|
MAX_SOLVER_SUBMISSION_NAME_CHARACTERS,
|
|
636
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.`
|
|
637
573
|
).regex(SOLVER_SUBMISSION_NAME_RE);
|
|
638
|
-
var mediaTypeSchema =
|
|
639
|
-
var bountyIdSchema =
|
|
640
|
-
var chainIdSchema =
|
|
641
|
-
var privateArtifactContextSchema =
|
|
642
|
-
type:
|
|
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"),
|
|
643
579
|
chain_id: chainIdSchema,
|
|
644
580
|
hub_address: lowerAddressSchema,
|
|
645
581
|
bounty_id: bountyIdSchema,
|
|
646
582
|
actor_address: lowerAddressSchema
|
|
647
583
|
});
|
|
648
|
-
var guardianRecipientSchema =
|
|
584
|
+
var guardianRecipientSchema = z3.strictObject({
|
|
649
585
|
key_id: keyIdSchema,
|
|
650
|
-
suite:
|
|
586
|
+
suite: z3.literal(PRIVATE_ARTIFACT_HPKE_SUITE),
|
|
651
587
|
public_key: base64UrlSchema.length(
|
|
652
588
|
43,
|
|
653
589
|
"public_key must encode a 32-byte X25519 public key"
|
|
654
590
|
)
|
|
655
591
|
});
|
|
656
|
-
var guardianRecipientPrivateKeySchema =
|
|
592
|
+
var guardianRecipientPrivateKeySchema = z3.strictObject({
|
|
657
593
|
key_id: keyIdSchema,
|
|
658
|
-
suite:
|
|
594
|
+
suite: z3.literal(PRIVATE_ARTIFACT_HPKE_SUITE),
|
|
659
595
|
private_key: base64UrlSchema.length(
|
|
660
596
|
43,
|
|
661
597
|
"private_key must encode a 32-byte X25519 private key"
|
|
662
598
|
)
|
|
663
599
|
});
|
|
664
|
-
var guardianRecipientsSchema =
|
|
600
|
+
var guardianRecipientsSchema = z3.array(guardianRecipientSchema).min(1).superRefine((recipients, ctx) => {
|
|
665
601
|
const seen = /* @__PURE__ */ new Set();
|
|
666
602
|
for (const recipient of recipients) {
|
|
667
603
|
if (seen.has(recipient.key_id)) {
|
|
@@ -674,24 +610,24 @@ var guardianRecipientsSchema = z4.array(guardianRecipientSchema).min(1).superRef
|
|
|
674
610
|
seen.add(recipient.key_id);
|
|
675
611
|
}
|
|
676
612
|
});
|
|
677
|
-
var guardianRecipientPrivateKeysSchema =
|
|
678
|
-
var artifactManifestEntrySchema =
|
|
613
|
+
var guardianRecipientPrivateKeysSchema = z3.array(guardianRecipientPrivateKeySchema).min(1);
|
|
614
|
+
var artifactManifestEntrySchema = z3.strictObject({
|
|
679
615
|
name: artifactNameSchema,
|
|
680
616
|
media_type: mediaTypeSchema,
|
|
681
|
-
size_bytes:
|
|
617
|
+
size_bytes: z3.number().int().nonnegative().lte(Number.MAX_SAFE_INTEGER),
|
|
682
618
|
sha256: sha256HexSchema
|
|
683
619
|
});
|
|
684
|
-
var privateArtifactPublicManifestSchema =
|
|
685
|
-
kind:
|
|
620
|
+
var privateArtifactPublicManifestSchema = z3.strictObject({
|
|
621
|
+
kind: z3.literal(PRIVATE_ARTIFACT_PUBLIC_MANIFEST_KIND),
|
|
686
622
|
context: privateArtifactContextSchema
|
|
687
623
|
});
|
|
688
624
|
var encryptedBundleArtifactSchema = artifactManifestEntrySchema.extend({
|
|
689
625
|
bytes: base64UrlSchema
|
|
690
626
|
});
|
|
691
|
-
var privateArtifactEncryptedBundleSchema =
|
|
692
|
-
kind:
|
|
627
|
+
var privateArtifactEncryptedBundleSchema = z3.strictObject({
|
|
628
|
+
kind: z3.literal(PRIVATE_ARTIFACT_ENCRYPTED_BUNDLE_KIND),
|
|
693
629
|
context: privateArtifactContextSchema,
|
|
694
|
-
artifacts:
|
|
630
|
+
artifacts: z3.array(encryptedBundleArtifactSchema).min(1).max(
|
|
695
631
|
MAX_SOLVER_SUBMISSION_FILES,
|
|
696
632
|
`Submission exceeds the maximum of ${MAX_SOLVER_SUBMISSION_FILES} files.`
|
|
697
633
|
).refine(
|
|
@@ -699,33 +635,33 @@ var privateArtifactEncryptedBundleSchema = z4.strictObject({
|
|
|
699
635
|
"artifact names must be unique case-insensitively"
|
|
700
636
|
)
|
|
701
637
|
});
|
|
702
|
-
var privateArtifactRevealPolicySchema =
|
|
703
|
-
kind:
|
|
704
|
-
network:
|
|
705
|
-
chain_hash:
|
|
706
|
-
round:
|
|
707
|
-
not_before:
|
|
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)
|
|
708
644
|
});
|
|
709
|
-
var wrappedRecipientKeySchema =
|
|
645
|
+
var wrappedRecipientKeySchema = z3.strictObject({
|
|
710
646
|
key_id: keyIdSchema,
|
|
711
|
-
suite:
|
|
647
|
+
suite: z3.literal(PRIVATE_ARTIFACT_HPKE_SUITE),
|
|
712
648
|
enc: base64UrlSchema,
|
|
713
649
|
ciphertext: base64UrlSchema
|
|
714
650
|
});
|
|
715
|
-
var wrappedKeyBagSchema =
|
|
716
|
-
kind:
|
|
717
|
-
keys:
|
|
651
|
+
var wrappedKeyBagSchema = z3.strictObject({
|
|
652
|
+
kind: z3.literal(PRIVATE_ARTIFACT_WRAPPED_KEY_BAG_KIND),
|
|
653
|
+
keys: z3.array(wrappedRecipientKeySchema).min(1)
|
|
718
654
|
});
|
|
719
|
-
var privateArtifactEnvelopeSchema =
|
|
720
|
-
kind:
|
|
721
|
-
alg:
|
|
655
|
+
var privateArtifactEnvelopeSchema = z3.strictObject({
|
|
656
|
+
kind: z3.literal(PRIVATE_ARTIFACT_ENVELOPE_KIND),
|
|
657
|
+
alg: z3.literal(SUBMISSION_ENCRYPTION_TYPE),
|
|
722
658
|
context: privateArtifactContextSchema,
|
|
723
659
|
public_manifest: privateArtifactPublicManifestSchema,
|
|
724
660
|
public_manifest_sha256: sha256HexSchema,
|
|
725
661
|
encrypted_bundle_sha256: sha256HexSchema,
|
|
726
662
|
ciphertext_sha256: sha256HexSchema,
|
|
727
663
|
guardian_recipients: guardianRecipientsSchema,
|
|
728
|
-
guardian_recipients_commitment:
|
|
664
|
+
guardian_recipients_commitment: bytes32Schema2,
|
|
729
665
|
reveal_policy: privateArtifactRevealPolicySchema,
|
|
730
666
|
envelope_nonce: base64UrlSchema.length(
|
|
731
667
|
22,
|
|
@@ -733,7 +669,7 @@ var privateArtifactEnvelopeSchema = z4.strictObject({
|
|
|
733
669
|
),
|
|
734
670
|
iv: base64UrlSchema.length(16, "iv must encode 12 bytes"),
|
|
735
671
|
wrapped_key_bag: base64UrlSchema,
|
|
736
|
-
ciphertext_locator:
|
|
672
|
+
ciphertext_locator: z3.string().min(1)
|
|
737
673
|
});
|
|
738
674
|
function parsePrivateArtifactEnvelope(input) {
|
|
739
675
|
return privateArtifactEnvelopeSchema.parse(input);
|
|
@@ -791,11 +727,11 @@ var x25519PrivateKeySchema = base64UrlSchema.length(
|
|
|
791
727
|
43,
|
|
792
728
|
"must encode a 32-byte X25519 private key"
|
|
793
729
|
);
|
|
794
|
-
var winningSolutionDeliveryContextSchema =
|
|
730
|
+
var winningSolutionDeliveryContextSchema = z3.strictObject({
|
|
795
731
|
chain_id: chainIdSchema,
|
|
796
732
|
hub_address: lowerAddressSchema,
|
|
797
733
|
bounty_id: bountyIdSchema,
|
|
798
|
-
submission_commitment:
|
|
734
|
+
submission_commitment: bytes32Schema2
|
|
799
735
|
});
|
|
800
736
|
async function generateX25519KeyPair(input) {
|
|
801
737
|
const suite = createHpkeSuite();
|
|
@@ -872,7 +808,7 @@ function buildWinningSolutionDeliveryInfo(contextCommitment) {
|
|
|
872
808
|
var GUARDIAN_ROSTER_KEY_PROOF_INFO = "elgora/guardian-roster-key-proof/hpke-fixture/v0";
|
|
873
809
|
var GUARDIAN_ROSTER_KEY_PROOF_MESSAGE_TYPE = "elgora_guardian_roster_key_proof_v0";
|
|
874
810
|
var GUARDIAN_ROSTER_KEY_PROOF_FIXTURE_BYTES = 32;
|
|
875
|
-
var guardianRosterKeyProofContextSchema =
|
|
811
|
+
var guardianRosterKeyProofContextSchema = z3.strictObject({
|
|
876
812
|
chain_id: chainIdSchema,
|
|
877
813
|
hub_address: lowerAddressSchema,
|
|
878
814
|
proposed_account: lowerAddressSchema,
|
|
@@ -1200,7 +1136,7 @@ async function wrapAesKeyForRecipients(input) {
|
|
|
1200
1136
|
}
|
|
1201
1137
|
async function openAesKeyForRecipient(input) {
|
|
1202
1138
|
const suite = createHpkeSuite();
|
|
1203
|
-
const wrappedKeys =
|
|
1139
|
+
const wrappedKeys = z3.array(wrappedRecipientKeySchema).parse(input.wrappedKeys);
|
|
1204
1140
|
const privateKeys = guardianRecipientPrivateKeysSchema.parse(
|
|
1205
1141
|
input.privateKeys
|
|
1206
1142
|
);
|
|
@@ -3911,7 +3847,7 @@ function settlementAmounts(escrowAmount, treasuryFeeBps, guardianFeeBps) {
|
|
|
3911
3847
|
import { zeroAddress } from "viem";
|
|
3912
3848
|
|
|
3913
3849
|
// ../../packages/core/src/api/bounty-preparation.ts
|
|
3914
|
-
import { ZodError, z as
|
|
3850
|
+
import { ZodError, z as z4 } from "zod";
|
|
3915
3851
|
|
|
3916
3852
|
// ../../packages/core/src/submission-timelock.ts
|
|
3917
3853
|
import {
|
|
@@ -4172,7 +4108,7 @@ import {
|
|
|
4172
4108
|
getAbiItem as getAbiItem2,
|
|
4173
4109
|
parseAbi,
|
|
4174
4110
|
parseSignature,
|
|
4175
|
-
recoverTypedDataAddress
|
|
4111
|
+
recoverTypedDataAddress
|
|
4176
4112
|
} from "viem";
|
|
4177
4113
|
var ELGORA_HUB_ERRORS = ELGORA_HUB_ABI.filter(
|
|
4178
4114
|
(item) => item.type === "error"
|
|
@@ -4329,7 +4265,7 @@ async function prepareAuthorizedCreateBountyTransaction(input) {
|
|
|
4329
4265
|
if (unsupported) return null;
|
|
4330
4266
|
throw error;
|
|
4331
4267
|
}
|
|
4332
|
-
if ((await
|
|
4268
|
+
if ((await recoverTypedDataAddress({ ...authorization, signature })).toLowerCase() !== poster.toLowerCase()) {
|
|
4333
4269
|
throw new Error("USDC authorization was not signed by the funding Poster.");
|
|
4334
4270
|
}
|
|
4335
4271
|
const { r, s, yParity } = parseSignature(signature);
|
|
@@ -4405,14 +4341,14 @@ var BoundaryValidationError = class extends Error {
|
|
|
4405
4341
|
this.issues = issues;
|
|
4406
4342
|
}
|
|
4407
4343
|
};
|
|
4408
|
-
var artifactUploadUrlRequestSchema =
|
|
4409
|
-
ciphertext_sha256:
|
|
4410
|
-
ciphertext_byte_length:
|
|
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)
|
|
4411
4347
|
}).strict();
|
|
4412
4348
|
|
|
4413
4349
|
// ../../packages/core/src/api/config.ts
|
|
4414
4350
|
import { createHash } from "crypto";
|
|
4415
|
-
import { z as
|
|
4351
|
+
import { z as z5 } from "zod";
|
|
4416
4352
|
function withDeploymentEnvDefaults(env) {
|
|
4417
4353
|
const merged = { ...env };
|
|
4418
4354
|
const setIfBlank = (key, value) => {
|
|
@@ -4433,11 +4369,11 @@ function withDeploymentEnvDefaults(env) {
|
|
|
4433
4369
|
setIfBlank("ELGORA_SUBGRAPH_ENDPOINT", deployment?.ELGORA_SUBGRAPH_ENDPOINT);
|
|
4434
4370
|
return merged;
|
|
4435
4371
|
}
|
|
4436
|
-
var chainIdField =
|
|
4372
|
+
var chainIdField = z5.coerce.number().int().positive().refine((chainId) => SUPPORTED_CHAINS[chainId] !== void 0, {
|
|
4437
4373
|
message: `ELGORA_CHAIN_ID must be a supported chain: ${Object.keys(SUPPORTED_CHAINS).join(", ")}`
|
|
4438
4374
|
});
|
|
4439
|
-
var hubAddressField =
|
|
4440
|
-
var publicDeploymentEnvSchema =
|
|
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({
|
|
4441
4377
|
ELGORA_CHAIN_ID: chainIdField,
|
|
4442
4378
|
ELGORA_HUB_ADDRESS: hubAddressField
|
|
4443
4379
|
});
|
|
@@ -4453,32 +4389,32 @@ function loadPublicDeploymentConfig(env = process.env) {
|
|
|
4453
4389
|
var envShape = {
|
|
4454
4390
|
ELGORA_CHAIN_ID: chainIdField,
|
|
4455
4391
|
ELGORA_HUB_ADDRESS: hubAddressField,
|
|
4456
|
-
ELGORA_ESCROW_TOKEN_ADDRESS:
|
|
4392
|
+
ELGORA_ESCROW_TOKEN_ADDRESS: z5.string().refine(
|
|
4457
4393
|
isHexAddress,
|
|
4458
4394
|
"ELGORA_ESCROW_TOKEN_ADDRESS must be a 20-byte EVM address"
|
|
4459
4395
|
).transform((value) => value.toLowerCase()),
|
|
4460
|
-
ELGORA_TIMELOCK_REVEAL_DELAY_SECONDS:
|
|
4461
|
-
ELGORA_RPC_URL:
|
|
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"),
|
|
4462
4398
|
/**
|
|
4463
4399
|
* Only consulted for a chain with no recorded deployment — a local anvil
|
|
4464
4400
|
* stack, whose addresses change on every deploy. A recorded deployment's
|
|
4465
4401
|
* scheme always wins, because settlement validation compares against it.
|
|
4466
4402
|
*/
|
|
4467
|
-
ELGORA_PAYOUT_SCHEME_ADDRESS:
|
|
4403
|
+
ELGORA_PAYOUT_SCHEME_ADDRESS: z5.string().refine(
|
|
4468
4404
|
isHexAddress,
|
|
4469
4405
|
"ELGORA_PAYOUT_SCHEME_ADDRESS must be a 20-byte EVM address"
|
|
4470
4406
|
).transform((value) => value.toLowerCase()).optional(),
|
|
4471
|
-
ELGORA_DATABASE_URL:
|
|
4472
|
-
ELGORA_SUBGRAPH_ENDPOINT:
|
|
4473
|
-
ELGORA_ARTIFACT_STORAGE_ENDPOINT:
|
|
4474
|
-
ELGORA_ARTIFACT_STORAGE_REGION:
|
|
4475
|
-
ELGORA_ARTIFACT_STORAGE_BUCKET:
|
|
4476
|
-
ELGORA_ARTIFACT_STORAGE_ACCESS_KEY_ID:
|
|
4477
|
-
ELGORA_ARTIFACT_STORAGE_SECRET_ACCESS_KEY:
|
|
4478
|
-
ELGORA_DELIVERY_PUBLIC_KEY:
|
|
4479
|
-
ELGORA_DELIVERY_PRIVATE_KEY:
|
|
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")
|
|
4480
4416
|
};
|
|
4481
|
-
var readinessAudienceSchema =
|
|
4417
|
+
var readinessAudienceSchema = z5.string().trim().toLowerCase().min(1).max(512).refine((host) => {
|
|
4482
4418
|
try {
|
|
4483
4419
|
const url = new URL(`https://${host}`);
|
|
4484
4420
|
return url.host === host && url.pathname === "/" && !url.username && !url.password && !url.search && !url.hash;
|
|
@@ -4492,11 +4428,11 @@ var publicationEnvShape = {
|
|
|
4492
4428
|
ELGORA_ESCROW_TOKEN_ADDRESS: envShape.ELGORA_ESCROW_TOKEN_ADDRESS,
|
|
4493
4429
|
ELGORA_DATABASE_URL: envShape.ELGORA_DATABASE_URL,
|
|
4494
4430
|
ELGORA_SUBGRAPH_ENDPOINT: envShape.ELGORA_SUBGRAPH_ENDPOINT,
|
|
4495
|
-
ELGORA_PUBLICATION_REVIEW_ENABLED:
|
|
4496
|
-
ELGORA_READINESS_TIMEOUT_MS:
|
|
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)
|
|
4497
4433
|
};
|
|
4498
|
-
var envSchema =
|
|
4499
|
-
var bountyPublicationEnvSchema =
|
|
4434
|
+
var envSchema = z5.object(envShape);
|
|
4435
|
+
var bountyPublicationEnvSchema = z5.object(publicationEnvShape);
|
|
4500
4436
|
|
|
4501
4437
|
// ../../packages/core/src/api/elgora-hub-error-catalog.ts
|
|
4502
4438
|
import { decodeErrorResult } from "viem";
|
|
@@ -4511,81 +4447,81 @@ var ELGORA_HUB_FEE_POLICY_ABI = [
|
|
|
4511
4447
|
];
|
|
4512
4448
|
|
|
4513
4449
|
// ../../packages/core/src/api/solver-submission-responses.ts
|
|
4514
|
-
import { isHex as
|
|
4515
|
-
import { z as
|
|
4516
|
-
var hexAddressSchema =
|
|
4517
|
-
var hexBytes32Schema =
|
|
4518
|
-
var hexDataSchema =
|
|
4519
|
-
var artifactUploadUrlResponseSchema =
|
|
4520
|
-
locator:
|
|
4521
|
-
upload_url:
|
|
4522
|
-
method:
|
|
4523
|
-
expires_at:
|
|
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)
|
|
4524
4460
|
});
|
|
4525
|
-
var solverSubmissionPrepareResponseSchema =
|
|
4526
|
-
content_record:
|
|
4527
|
-
content_kind:
|
|
4461
|
+
var solverSubmissionPrepareResponseSchema = z6.object({
|
|
4462
|
+
content_record: z6.object({
|
|
4463
|
+
content_kind: z6.literal(SOLVER_SUBMISSION_CONTENT_KIND),
|
|
4528
4464
|
submission_commitment: hexBytes32Schema,
|
|
4529
|
-
byte_length:
|
|
4530
|
-
created_at:
|
|
4465
|
+
byte_length: z6.number().int().nonnegative(),
|
|
4466
|
+
created_at: z6.string().min(1)
|
|
4531
4467
|
}),
|
|
4532
|
-
submit_transaction:
|
|
4533
|
-
chain_id:
|
|
4468
|
+
submit_transaction: z6.object({
|
|
4469
|
+
chain_id: z6.number().int().positive(),
|
|
4534
4470
|
to: hexAddressSchema,
|
|
4535
|
-
value:
|
|
4471
|
+
value: z6.literal("0"),
|
|
4536
4472
|
data: hexDataSchema,
|
|
4537
|
-
function_name:
|
|
4538
|
-
args:
|
|
4539
|
-
bounty_id:
|
|
4473
|
+
function_name: z6.literal("submit"),
|
|
4474
|
+
args: z6.object({
|
|
4475
|
+
bounty_id: z6.string().min(1),
|
|
4540
4476
|
submission_commitment: hexBytes32Schema,
|
|
4541
4477
|
guardian_roster_hash: hexBytes32Schema,
|
|
4542
|
-
extra_data:
|
|
4478
|
+
extra_data: z6.literal("0x")
|
|
4543
4479
|
})
|
|
4544
4480
|
})
|
|
4545
4481
|
});
|
|
4546
|
-
var solverSubmissionContentResponseSchema =
|
|
4547
|
-
content_record:
|
|
4548
|
-
bounty_id:
|
|
4549
|
-
canonical_json:
|
|
4482
|
+
var solverSubmissionContentResponseSchema = z6.object({
|
|
4483
|
+
content_record: z6.object({
|
|
4484
|
+
bounty_id: z6.string().min(1),
|
|
4485
|
+
canonical_json: z6.string().min(1)
|
|
4550
4486
|
}),
|
|
4551
|
-
ciphertext_download_url:
|
|
4552
|
-
expires_at:
|
|
4487
|
+
ciphertext_download_url: z6.string().min(1),
|
|
4488
|
+
expires_at: z6.string().min(1)
|
|
4553
4489
|
});
|
|
4554
|
-
var bountyGuardianRosterResponseSchema =
|
|
4555
|
-
bounty:
|
|
4490
|
+
var bountyGuardianRosterResponseSchema = z6.object({
|
|
4491
|
+
bounty: z6.object({
|
|
4556
4492
|
guardian_roster_hash: hexBytes32Schema,
|
|
4557
|
-
guardian_roster:
|
|
4558
|
-
|
|
4559
|
-
name:
|
|
4493
|
+
guardian_roster: z6.array(
|
|
4494
|
+
z6.object({
|
|
4495
|
+
name: z6.string(),
|
|
4560
4496
|
account: hexAddressSchema,
|
|
4561
|
-
encryption_public_key:
|
|
4497
|
+
encryption_public_key: z6.string().min(1)
|
|
4562
4498
|
})
|
|
4563
4499
|
).min(1)
|
|
4564
4500
|
})
|
|
4565
4501
|
});
|
|
4566
4502
|
|
|
4567
4503
|
// ../../packages/core/src/api/verification-records.ts
|
|
4568
|
-
import { z as
|
|
4569
|
-
var hexAddressSchema2 =
|
|
4570
|
-
var hexBytes32Schema2 =
|
|
4571
|
-
var integerStringSchema =
|
|
4572
|
-
var verdictEntrySchema =
|
|
4573
|
-
name:
|
|
4574
|
-
outcome:
|
|
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(),
|
|
4575
4511
|
winner: hexAddressSchema2.nullable(),
|
|
4576
4512
|
report_commitment: hexBytes32Schema2.nullable(),
|
|
4577
|
-
committed_at:
|
|
4578
|
-
supporting:
|
|
4513
|
+
committed_at: z7.string().datetime({ offset: true }).nullable(),
|
|
4514
|
+
supporting: z7.boolean()
|
|
4579
4515
|
}).strict();
|
|
4580
|
-
var formattedVerificationRecordSchema =
|
|
4581
|
-
chain_id:
|
|
4516
|
+
var formattedVerificationRecordSchema = z7.object({
|
|
4517
|
+
chain_id: z7.number().int().positive(),
|
|
4582
4518
|
hub_address: hexAddressSchema2,
|
|
4583
4519
|
bounty_id: integerStringSchema,
|
|
4584
|
-
status:
|
|
4520
|
+
status: z7.enum(["awarded", "no_valid_submission", "timed_out"]),
|
|
4585
4521
|
spec_commitment: hexBytes32Schema2,
|
|
4586
4522
|
winner: hexAddressSchema2.nullable(),
|
|
4587
|
-
verdicts:
|
|
4588
|
-
settlement:
|
|
4523
|
+
verdicts: z7.record(z7.string(), verdictEntrySchema),
|
|
4524
|
+
settlement: z7.object({
|
|
4589
4525
|
escrow_amount: integerStringSchema,
|
|
4590
4526
|
settlement_recipient: hexAddressSchema2,
|
|
4591
4527
|
settlement_amount: integerStringSchema,
|
|
@@ -4596,10 +4532,10 @@ var formattedVerificationRecordSchema = z8.object({
|
|
|
4596
4532
|
settled_tx_hash: hexBytes32Schema2,
|
|
4597
4533
|
settled_block_number: integerStringSchema
|
|
4598
4534
|
}).strict(),
|
|
4599
|
-
content_record:
|
|
4600
|
-
spec_content_byte_length:
|
|
4535
|
+
content_record: z7.object({
|
|
4536
|
+
spec_content_byte_length: z7.number().int().positive()
|
|
4601
4537
|
}).strict(),
|
|
4602
|
-
verified_at:
|
|
4538
|
+
verified_at: z7.string().datetime({ offset: true })
|
|
4603
4539
|
}).strict();
|
|
4604
4540
|
function parseBountyVerificationRecord(input, expected) {
|
|
4605
4541
|
const slice = input;
|
|
@@ -4621,79 +4557,79 @@ function parseBountyVerificationRecord(input, expected) {
|
|
|
4621
4557
|
}
|
|
4622
4558
|
|
|
4623
4559
|
// ../../packages/core/src/api/winning-solution-delivery.ts
|
|
4624
|
-
import { z as
|
|
4625
|
-
var hexBytes32Schema3 =
|
|
4626
|
-
var hexAddressSchema3 =
|
|
4627
|
-
var deliveryKeyIdSchema =
|
|
4628
|
-
var winningSolutionWrappedKeySchema =
|
|
4629
|
-
enc:
|
|
4630
|
-
ciphertext:
|
|
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)
|
|
4631
4567
|
});
|
|
4632
|
-
var deliveryWrapRequestSchema =
|
|
4568
|
+
var deliveryWrapRequestSchema = z8.strictObject({
|
|
4633
4569
|
solver_address: hexAddressSchema3,
|
|
4634
4570
|
submission_commitment: hexBytes32Schema3,
|
|
4635
4571
|
wrapped_key: winningSolutionWrappedKeySchema
|
|
4636
4572
|
});
|
|
4637
|
-
var deliveryWrapRecordSchema =
|
|
4638
|
-
bounty_id:
|
|
4573
|
+
var deliveryWrapRecordSchema = z8.strictObject({
|
|
4574
|
+
bounty_id: z8.string().min(1),
|
|
4639
4575
|
guardian_address: hexAddressSchema3,
|
|
4640
4576
|
solver_address: hexAddressSchema3,
|
|
4641
4577
|
submission_commitment: hexBytes32Schema3,
|
|
4642
4578
|
delivery_key_id: deliveryKeyIdSchema,
|
|
4643
|
-
created_at:
|
|
4579
|
+
created_at: z8.string().min(1)
|
|
4644
4580
|
});
|
|
4645
|
-
var deliveryWrapResponseSchema =
|
|
4646
|
-
status:
|
|
4581
|
+
var deliveryWrapResponseSchema = z8.strictObject({
|
|
4582
|
+
status: z8.literal("stored"),
|
|
4647
4583
|
wrap: deliveryWrapRecordSchema
|
|
4648
4584
|
});
|
|
4649
|
-
var deliveryRetrieveRequestSchema =
|
|
4585
|
+
var deliveryRetrieveRequestSchema = z8.strictObject({
|
|
4650
4586
|
poster_ephemeral_public_key: x25519PublicKeySchema
|
|
4651
4587
|
});
|
|
4652
|
-
var deliveryRetrieveResponseSchema =
|
|
4588
|
+
var deliveryRetrieveResponseSchema = z8.strictObject({
|
|
4653
4589
|
submission_commitment: hexBytes32Schema3,
|
|
4654
4590
|
wrapped_key: winningSolutionWrappedKeySchema
|
|
4655
4591
|
});
|
|
4656
|
-
var deliveryStatusResponseSchema =
|
|
4657
|
-
exists:
|
|
4592
|
+
var deliveryStatusResponseSchema = z8.strictObject({
|
|
4593
|
+
exists: z8.boolean()
|
|
4658
4594
|
});
|
|
4659
|
-
var deliveryKeyConfigResponseSchema =
|
|
4595
|
+
var deliveryKeyConfigResponseSchema = z8.strictObject({
|
|
4660
4596
|
delivery_key_id: deliveryKeyIdSchema,
|
|
4661
|
-
public_key:
|
|
4597
|
+
public_key: z8.string().min(1)
|
|
4662
4598
|
});
|
|
4663
4599
|
|
|
4664
4600
|
// ../../packages/core/src/api/written-verdicts.ts
|
|
4665
4601
|
import { keccak256 as keccak2564, toBytes as toBytes3, zeroAddress as zeroAddress2 } from "viem";
|
|
4666
|
-
import { z as
|
|
4602
|
+
import { z as z9 } from "zod";
|
|
4667
4603
|
var WRITTEN_VERDICT_FORMAT_VERSION = 0;
|
|
4668
4604
|
var FRONTMATTER_DELIMITER2 = "---";
|
|
4669
|
-
var decimalSchema =
|
|
4670
|
-
var bountyIdSchema2 =
|
|
4671
|
-
var addressSchema2 =
|
|
4672
|
-
var
|
|
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);
|
|
4673
4609
|
var commonFields = {
|
|
4674
|
-
format_version:
|
|
4610
|
+
format_version: z9.literal(WRITTEN_VERDICT_FORMAT_VERSION.toString()).transform(() => WRITTEN_VERDICT_FORMAT_VERSION),
|
|
4675
4611
|
chain_id: decimalSchema,
|
|
4676
4612
|
hub_address: addressSchema2,
|
|
4677
4613
|
bounty_id: bountyIdSchema2,
|
|
4678
|
-
verdict_body:
|
|
4614
|
+
verdict_body: z9.string().refine((value) => value.trim().length > 0, "Must not be empty")
|
|
4679
4615
|
};
|
|
4680
|
-
var writtenVerdictSchema =
|
|
4681
|
-
|
|
4616
|
+
var writtenVerdictSchema = z9.discriminatedUnion("outcome", [
|
|
4617
|
+
z9.object({
|
|
4682
4618
|
...commonFields,
|
|
4683
|
-
outcome:
|
|
4619
|
+
outcome: z9.literal("awarded"),
|
|
4684
4620
|
winner: addressSchema2.refine(
|
|
4685
4621
|
(value) => value !== zeroAddress2,
|
|
4686
4622
|
"Must not be the zero address"
|
|
4687
4623
|
),
|
|
4688
|
-
awarded_submission_commitment:
|
|
4624
|
+
awarded_submission_commitment: bytes32Schema3.refine(
|
|
4689
4625
|
(value) => value !== ZERO_BYTES32,
|
|
4690
4626
|
"Must not be zero bytes"
|
|
4691
4627
|
)
|
|
4692
4628
|
}).strict(),
|
|
4693
|
-
|
|
4629
|
+
z9.object({
|
|
4694
4630
|
...commonFields,
|
|
4695
|
-
outcome:
|
|
4696
|
-
winner:
|
|
4631
|
+
outcome: z9.literal("no_valid_submission"),
|
|
4632
|
+
winner: z9.literal(zeroAddress2)
|
|
4697
4633
|
}).strict()
|
|
4698
4634
|
]);
|
|
4699
4635
|
function buildWrittenVerdictMarkdown(input) {
|
|
@@ -5176,6 +5112,8 @@ function defaultApiBaseUrl(env) {
|
|
|
5176
5112
|
// ../../packages/core/src/api-client.ts
|
|
5177
5113
|
var ApiRequestError = class extends Error {
|
|
5178
5114
|
issues;
|
|
5115
|
+
priorIssuesResolved;
|
|
5116
|
+
priorIssuesOpen;
|
|
5179
5117
|
status;
|
|
5180
5118
|
code;
|
|
5181
5119
|
retryAfterMs;
|
|
@@ -5185,15 +5123,19 @@ var ApiRequestError = class extends Error {
|
|
|
5185
5123
|
);
|
|
5186
5124
|
this.name = "ApiRequestError";
|
|
5187
5125
|
this.issues = readApiErrorIssues(input.body);
|
|
5126
|
+
const error = input.body && typeof input.body === "object" && "error" in input.body ? input.body.error : void 0;
|
|
5127
|
+
const fields = error && typeof error === "object" ? error : {};
|
|
5128
|
+
this.priorIssuesResolved = priorIssueSchema.array().safeParse(fields.prior_issues_resolved).data ?? [];
|
|
5129
|
+
this.priorIssuesOpen = priorIssueSchema.array().safeParse(fields.prior_issues_open).data ?? [];
|
|
5188
5130
|
this.status = input.status;
|
|
5189
5131
|
this.code = readApiErrorCode(input.body);
|
|
5190
5132
|
this.retryAfterMs = input.retryAfterMs;
|
|
5191
5133
|
}
|
|
5192
5134
|
};
|
|
5193
|
-
async function postText(url, body, contentType, authorization
|
|
5135
|
+
async function postText(url, body, contentType, authorization) {
|
|
5194
5136
|
const response = await fetch(url, {
|
|
5195
5137
|
method: "POST",
|
|
5196
|
-
headers: {
|
|
5138
|
+
headers: { "content-type": contentType, authorization },
|
|
5197
5139
|
body
|
|
5198
5140
|
});
|
|
5199
5141
|
return parseJsonResponse(url, response);
|
|
@@ -5353,7 +5295,7 @@ function toArrayBuffer(bytes) {
|
|
|
5353
5295
|
import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
|
|
5354
5296
|
|
|
5355
5297
|
// ../../packages/core/src/auth/authorization-header.ts
|
|
5356
|
-
import { isAddress as isAddress3, isHex as
|
|
5298
|
+
import { isAddress as isAddress3, isHex as isHex4 } from "viem";
|
|
5357
5299
|
var ELGORA_APPROVAL_AUTH_SCHEME = "Elgora-Approval";
|
|
5358
5300
|
var FIELD_SEPARATOR = "~";
|
|
5359
5301
|
function encodeApiRequestApprovalHeader(fields) {
|
|
@@ -5366,27 +5308,59 @@ function encodeApiRequestApprovalHeader(fields) {
|
|
|
5366
5308
|
return `${ELGORA_APPROVAL_AUTH_SCHEME} ${btoa(payload)}`;
|
|
5367
5309
|
}
|
|
5368
5310
|
|
|
5369
|
-
// ../../packages/core/src/auth/
|
|
5370
|
-
var
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
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();
|
|
5376
5350
|
}
|
|
5377
5351
|
|
|
5378
5352
|
// ../../packages/core/src/auth/request-approval.ts
|
|
5379
5353
|
import {
|
|
5380
5354
|
hashTypedData,
|
|
5381
|
-
isAddressEqual as
|
|
5355
|
+
isAddressEqual as isAddressEqual2,
|
|
5382
5356
|
keccak256 as keccak2565,
|
|
5383
5357
|
toBytes as toBytes4
|
|
5384
5358
|
} from "viem";
|
|
5385
5359
|
|
|
5386
5360
|
// ../../packages/core/src/auth/signature.ts
|
|
5387
5361
|
import {
|
|
5388
|
-
isAddressEqual
|
|
5389
|
-
recoverTypedDataAddress as
|
|
5362
|
+
isAddressEqual,
|
|
5363
|
+
recoverTypedDataAddress as recoverTypedDataAddress2
|
|
5390
5364
|
} from "viem";
|
|
5391
5365
|
|
|
5392
5366
|
// ../../packages/core/src/auth/request-approval-header.ts
|
|
@@ -7148,7 +7122,7 @@ function resolveChainId(selector) {
|
|
|
7148
7122
|
}
|
|
7149
7123
|
|
|
7150
7124
|
// src/version.ts
|
|
7151
|
-
var CLI_VERSION = true ? "
|
|
7125
|
+
var CLI_VERSION = true ? "10.0.0" : "0.0.0-dev";
|
|
7152
7126
|
var CLI_NODE_ENGINES = true ? ">=24 <25" : ">=24 <25";
|
|
7153
7127
|
|
|
7154
7128
|
// src/node-engines.ts
|
|
@@ -7355,7 +7329,6 @@ function required3(env, name) {
|
|
|
7355
7329
|
}
|
|
7356
7330
|
|
|
7357
7331
|
// src/publish-fund.ts
|
|
7358
|
-
import { readFile as readFile5 } from "fs/promises";
|
|
7359
7332
|
import {
|
|
7360
7333
|
decodeFunctionData,
|
|
7361
7334
|
parseAbi as parseAbi2,
|
|
@@ -7383,15 +7356,6 @@ function loadPosterConfig(env, apiBaseUrlOverride) {
|
|
|
7383
7356
|
posterPrivateKey: privateKey
|
|
7384
7357
|
};
|
|
7385
7358
|
}
|
|
7386
|
-
function takeFlag(argv, flag, usage) {
|
|
7387
|
-
const uses = argv.filter(
|
|
7388
|
-
(arg) => arg === flag || arg.startsWith(`${flag}=`)
|
|
7389
|
-
).length;
|
|
7390
|
-
const extracted = extractFlagValue(argv, flag);
|
|
7391
|
-
if (uses > 1 || uses === 1 && (!extracted.value || extracted.value.startsWith("--")))
|
|
7392
|
-
throw new Error(usage);
|
|
7393
|
-
return extracted;
|
|
7394
|
-
}
|
|
7395
7359
|
async function readBountyChallengeMarkdown2(path5) {
|
|
7396
7360
|
return path5 === "-" ? readStdinText3(process.stdin) : readFile4(path5, "utf8");
|
|
7397
7361
|
}
|
|
@@ -7409,19 +7373,14 @@ async function signPosterRequest(input) {
|
|
|
7409
7373
|
}
|
|
7410
7374
|
|
|
7411
7375
|
// src/publish-fund.ts
|
|
7412
|
-
var PUBLISH_FUND_USAGE = "Usage: elgora-cli poster:publish-fund <bounty_challenge_md_path|->
|
|
7376
|
+
var PUBLISH_FUND_USAGE = "Usage: elgora-cli poster:publish-fund <bounty_challenge_md_path|->";
|
|
7413
7377
|
var usdcAbi = parseAbi2([
|
|
7414
7378
|
"function approve(address spender,uint256 value) returns (bool)",
|
|
7415
7379
|
"function balanceOf(address account) view returns (uint256)"
|
|
7416
7380
|
]);
|
|
7417
7381
|
async function main9(env = process.env, argv = process.argv.slice(2)) {
|
|
7418
|
-
const { apiBaseUrl: apiBaseUrlOverride, argv:
|
|
7419
|
-
|
|
7420
|
-
afterApiBaseUrl,
|
|
7421
|
-
"--signoff",
|
|
7422
|
-
PUBLISH_FUND_USAGE
|
|
7423
|
-
);
|
|
7424
|
-
if (!signoffPath || remainingArgv.length !== 1 || !remainingArgv[0])
|
|
7382
|
+
const { apiBaseUrl: apiBaseUrlOverride, argv: remainingArgv } = extractApiBaseUrlFlag(argv);
|
|
7383
|
+
if (remainingArgv.length !== 1 || !remainingArgv[0])
|
|
7425
7384
|
throw new Error(PUBLISH_FUND_USAGE);
|
|
7426
7385
|
const config = loadPosterConfig(env, apiBaseUrlOverride);
|
|
7427
7386
|
const escrowTokenAddress = withDeploymentDefaults(env).ELGORA_ESCROW_TOKEN_ADDRESS?.trim();
|
|
@@ -7437,17 +7396,6 @@ async function main9(env = process.env, argv = process.argv.slice(2)) {
|
|
|
7437
7396
|
const localSpecCommitment = deriveBountyChallengeContentCommitment(
|
|
7438
7397
|
bountyChallengeMarkdown
|
|
7439
7398
|
);
|
|
7440
|
-
const signoff = readinessSignoffSchema.parse(
|
|
7441
|
-
JSON.parse(await readFile5(signoffPath, "utf8"))
|
|
7442
|
-
);
|
|
7443
|
-
if (signoff.spec_commitment.toLowerCase() !== localSpecCommitment) {
|
|
7444
|
-
throw new Error(
|
|
7445
|
-
"Readiness sign-off does not match the exact bounty_challenge.md bytes. Run poster:review again."
|
|
7446
|
-
);
|
|
7447
|
-
}
|
|
7448
|
-
if (signoff.expires_at <= Math.floor(Date.now() / 1e3)) {
|
|
7449
|
-
throw new Error("Readiness sign-off has expired. Run poster:review again.");
|
|
7450
|
-
}
|
|
7451
7399
|
const account = privateKeyToAccount8(config.posterPrivateKey);
|
|
7452
7400
|
const publicClient = createChainPublicClient(config.chainId, config.rpcUrl);
|
|
7453
7401
|
const walletClient = createChainWalletClient(
|
|
@@ -7471,8 +7419,7 @@ async function main9(env = process.env, argv = process.argv.slice(2)) {
|
|
|
7471
7419
|
const prepared = await requestPreparePublication({
|
|
7472
7420
|
requestUrl: requestUrl.toString(),
|
|
7473
7421
|
markdown: bountyChallengeMarkdown,
|
|
7474
|
-
authorization
|
|
7475
|
-
signoff: encodeReadinessSignoffHeader(signoff)
|
|
7422
|
+
authorization
|
|
7476
7423
|
});
|
|
7477
7424
|
if (prepared.content_record.spec_commitment !== localSpecCommitment) {
|
|
7478
7425
|
throw new Error(
|
|
@@ -7612,8 +7559,7 @@ async function requestPreparePublication(input) {
|
|
|
7612
7559
|
new URL(input.requestUrl),
|
|
7613
7560
|
input.markdown,
|
|
7614
7561
|
"text/markdown",
|
|
7615
|
-
input.authorization
|
|
7616
|
-
{ [ELGORA_READINESS_SIGNOFF_HEADER]: input.signoff }
|
|
7562
|
+
input.authorization
|
|
7617
7563
|
);
|
|
7618
7564
|
return bountyPublicationResponseSchema.parse(body);
|
|
7619
7565
|
}
|
|
@@ -7624,28 +7570,28 @@ function missingRequiredEnv(required4, env) {
|
|
|
7624
7570
|
}
|
|
7625
7571
|
|
|
7626
7572
|
// src/review.ts
|
|
7627
|
-
import { writeFile as writeFile3 } from "fs/promises";
|
|
7628
|
-
import { resolve } from "path";
|
|
7629
7573
|
import { privateKeyToAccount as privateKeyToAccount9 } from "viem/accounts";
|
|
7630
|
-
var USAGE2 = "Usage: elgora-cli poster:review <path|-> [--previous <commitment>]
|
|
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
|
+
}
|
|
7631
7584
|
async function main10(env = process.env, argv = process.argv.slice(2)) {
|
|
7632
7585
|
const { apiBaseUrl, argv: args } = extractApiBaseUrlFlag(argv);
|
|
7633
|
-
const { value: previous, argv:
|
|
7586
|
+
const { value: previous, argv: paths } = takeFlag(
|
|
7634
7587
|
args,
|
|
7635
7588
|
"--previous",
|
|
7636
7589
|
"--previous must be one bytes32 page commitment"
|
|
7637
7590
|
);
|
|
7638
7591
|
if (previous && !isHexBytes32(previous))
|
|
7639
7592
|
throw new Error("--previous must be one bytes32 page commitment");
|
|
7640
|
-
const { value: signoffOut, argv: paths } = takeFlag(
|
|
7641
|
-
afterPrevious,
|
|
7642
|
-
"--signoff-out",
|
|
7643
|
-
USAGE2
|
|
7644
|
-
);
|
|
7645
7593
|
if (paths.length !== 1 || !paths[0] || paths[0].startsWith("--"))
|
|
7646
7594
|
throw new Error(USAGE2);
|
|
7647
|
-
if (signoffOut && paths[0] !== "-" && resolve(signoffOut) === resolve(paths[0]))
|
|
7648
|
-
throw new Error("--signoff-out must not overwrite the bounty draft");
|
|
7649
7595
|
const config = loadPosterConfig(env, apiBaseUrl);
|
|
7650
7596
|
const markdown = await readBountyChallengeMarkdown2(paths[0]);
|
|
7651
7597
|
const commitment = deriveBountyChallengeContentCommitment(markdown);
|
|
@@ -7658,7 +7604,10 @@ async function main10(env = process.env, argv = process.argv.slice(2)) {
|
|
|
7658
7604
|
);
|
|
7659
7605
|
requestUrl.searchParams.set("poster_address", account.address);
|
|
7660
7606
|
if (previous)
|
|
7661
|
-
requestUrl.searchParams.set(
|
|
7607
|
+
requestUrl.searchParams.set(
|
|
7608
|
+
"previous_spec_commitment",
|
|
7609
|
+
previous.toLowerCase()
|
|
7610
|
+
);
|
|
7662
7611
|
const authorization = await signPosterRequest({
|
|
7663
7612
|
requestUrl,
|
|
7664
7613
|
markdown,
|
|
@@ -7674,7 +7623,12 @@ async function main10(env = process.env, argv = process.argv.slice(2)) {
|
|
|
7674
7623
|
} catch (error) {
|
|
7675
7624
|
if (error instanceof ApiRequestError && error.code === "bounty_challenge_not_ready") {
|
|
7676
7625
|
console.log(
|
|
7677
|
-
JSON.stringify({
|
|
7626
|
+
JSON.stringify({
|
|
7627
|
+
event: "review.not_ready",
|
|
7628
|
+
issues: error.issues,
|
|
7629
|
+
prior_issues_resolved: error.priorIssuesResolved,
|
|
7630
|
+
prior_issues_open: error.priorIssuesOpen
|
|
7631
|
+
})
|
|
7678
7632
|
);
|
|
7679
7633
|
process.exitCode = 2;
|
|
7680
7634
|
return;
|
|
@@ -7686,17 +7640,12 @@ async function main10(env = process.env, argv = process.argv.slice(2)) {
|
|
|
7686
7640
|
"Elgora API returned a review for different bounty_challenge.md bytes"
|
|
7687
7641
|
);
|
|
7688
7642
|
}
|
|
7689
|
-
if (signoffOut)
|
|
7690
|
-
await writeFile3(
|
|
7691
|
-
signoffOut,
|
|
7692
|
-
`${JSON.stringify(response.readiness.signoff, null, 2)}
|
|
7693
|
-
`
|
|
7694
|
-
);
|
|
7695
7643
|
console.log(
|
|
7696
7644
|
JSON.stringify({
|
|
7697
7645
|
event: "review.ready",
|
|
7698
7646
|
spec_commitment: commitment,
|
|
7699
|
-
|
|
7647
|
+
approved_until: response.readiness.approved_until,
|
|
7648
|
+
warnings: response.readiness.warnings,
|
|
7700
7649
|
prior_issues_resolved: response.readiness.prior_issues_resolved,
|
|
7701
7650
|
prior_issues_open: response.readiness.prior_issues_open
|
|
7702
7651
|
})
|
|
@@ -7926,8 +7875,8 @@ function usageError3() {
|
|
|
7926
7875
|
}
|
|
7927
7876
|
|
|
7928
7877
|
// src/roster-verify-guardian-proof.ts
|
|
7929
|
-
import { readFile as
|
|
7930
|
-
import { isAddress as isAddress6, isHex as
|
|
7878
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
7879
|
+
import { isAddress as isAddress6, isHex as isHex5, recoverMessageAddress } from "viem";
|
|
7931
7880
|
async function main13(_env = process.env, argv = process.argv.slice(2)) {
|
|
7932
7881
|
const [preparedPath, responsePath] = argv;
|
|
7933
7882
|
if (!preparedPath || !responsePath) {
|
|
@@ -7935,8 +7884,8 @@ async function main13(_env = process.env, argv = process.argv.slice(2)) {
|
|
|
7935
7884
|
"Usage: elgora-cli roster:verify-guardian-proof <prepared_json_path> <response_json_path>"
|
|
7936
7885
|
);
|
|
7937
7886
|
}
|
|
7938
|
-
const prepared = parsePrepared(await
|
|
7939
|
-
const response = parseResponse(await
|
|
7887
|
+
const prepared = parsePrepared(await readFile5(preparedPath, "utf8"));
|
|
7888
|
+
const response = parseResponse(await readFile5(responsePath, "utf8"));
|
|
7940
7889
|
const fixture = base64UrlToBytes(prepared.fixture);
|
|
7941
7890
|
const signedPayload = buildGuardianRosterKeyProofSignedPayload(
|
|
7942
7891
|
prepared.message,
|
|
@@ -8000,7 +7949,7 @@ function parseResponse(text) {
|
|
|
8000
7949
|
}
|
|
8001
7950
|
const guardianAccount = get(parsed, "guardian_account");
|
|
8002
7951
|
const signature = get(parsed, "signature");
|
|
8003
|
-
if (typeof guardianAccount !== "string" || !isAddress6(guardianAccount) || typeof signature !== "string" || !
|
|
7952
|
+
if (typeof guardianAccount !== "string" || !isAddress6(guardianAccount) || typeof signature !== "string" || !isHex5(signature) || signature.length !== 132) {
|
|
8004
7953
|
throw new Error(
|
|
8005
7954
|
"Guardian response JSON must be the unmodified stdout of guardian:prove-roster-key"
|
|
8006
7955
|
);
|
|
@@ -8018,7 +7967,7 @@ function get(value, key) {
|
|
|
8018
7967
|
}
|
|
8019
7968
|
|
|
8020
7969
|
// src/spec-commitment.ts
|
|
8021
|
-
import { readFile as
|
|
7970
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
8022
7971
|
import { text as readStdinText4 } from "stream/consumers";
|
|
8023
7972
|
var SPEC_COMMITMENT_USAGE = "Usage: elgora-cli spec-commitment <bounty_challenge_md_path>\n or: elgora-cli spec-commitment -";
|
|
8024
7973
|
async function main14(_env = process.env, argv = process.argv.slice(2)) {
|
|
@@ -8040,23 +7989,23 @@ async function readBountyChallengeMarkdown3(argv) {
|
|
|
8040
7989
|
if (path5 === "-") {
|
|
8041
7990
|
return readStdinText4(process.stdin);
|
|
8042
7991
|
}
|
|
8043
|
-
return
|
|
7992
|
+
return readFile6(path5, "utf8");
|
|
8044
7993
|
}
|
|
8045
7994
|
|
|
8046
7995
|
// src/submit.ts
|
|
8047
|
-
import { readdir, readFile as
|
|
7996
|
+
import { readdir, readFile as readFile7, stat } from "fs/promises";
|
|
8048
7997
|
import path3 from "path";
|
|
8049
7998
|
import { createInterface } from "readline";
|
|
8050
7999
|
import { isAddress as isAddress7 } from "viem";
|
|
8051
8000
|
import { privateKeyToAccount as privateKeyToAccount11 } from "viem/accounts";
|
|
8052
8001
|
|
|
8053
8002
|
// src/external-api-approval-signer.ts
|
|
8054
|
-
import { isHex as
|
|
8003
|
+
import { isHex as isHex6 } from "viem";
|
|
8055
8004
|
function createExternalApiApprovalSigner(input) {
|
|
8056
8005
|
return async (typedData) => {
|
|
8057
8006
|
input.writePrompt(input.renderPrompt(typedData));
|
|
8058
8007
|
const signature = (await input.readSignature())?.trim();
|
|
8059
|
-
if (!signature || signature === "0x" || !
|
|
8008
|
+
if (!signature || signature === "0x" || !isHex6(signature)) {
|
|
8060
8009
|
throw new Error(
|
|
8061
8010
|
"External signer must return one non-empty 0x-prefixed hex signature line on stdin"
|
|
8062
8011
|
);
|
|
@@ -8496,7 +8445,7 @@ async function readArtifactDirectory(artifactDir) {
|
|
|
8496
8445
|
}
|
|
8497
8446
|
return Promise.all(
|
|
8498
8447
|
entries.map(async (entry) => {
|
|
8499
|
-
const bytes = await
|
|
8448
|
+
const bytes = await readFile7(path3.join(artifactDir, entry.name));
|
|
8500
8449
|
return {
|
|
8501
8450
|
name: entry.name,
|
|
8502
8451
|
media_type: guessMediaType(entry.name),
|
|
@@ -8565,7 +8514,7 @@ async function requestPrepareSubmission(input) {
|
|
|
8565
8514
|
})
|
|
8566
8515
|
);
|
|
8567
8516
|
}
|
|
8568
|
-
await new Promise((
|
|
8517
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
8569
8518
|
}
|
|
8570
8519
|
}
|
|
8571
8520
|
}
|
|
@@ -8773,9 +8722,9 @@ var COMMAND_HELP = {
|
|
|
8773
8722
|
apiBaseUrlFlag: true
|
|
8774
8723
|
},
|
|
8775
8724
|
"poster:review": {
|
|
8776
|
-
usage: "elgora-cli poster:review <path|-> [--previous <commitment>]
|
|
8777
|
-
title: "Review a bounty page
|
|
8778
|
-
description: "
|
|
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.",
|
|
8779
8728
|
required: ["ELGORA_POSTER_PRIVATE_KEY"],
|
|
8780
8729
|
defaulted: [
|
|
8781
8730
|
"ELGORA_CHAIN_ID",
|
|
@@ -8786,9 +8735,9 @@ var COMMAND_HELP = {
|
|
|
8786
8735
|
apiBaseUrlFlag: true
|
|
8787
8736
|
},
|
|
8788
8737
|
"poster:publish-fund": {
|
|
8789
|
-
usage: "elgora-cli poster:publish-fund <bounty_challenge_md_path|->
|
|
8738
|
+
usage: "elgora-cli poster:publish-fund <bounty_challenge_md_path|->",
|
|
8790
8739
|
title: "Publish an approved challenge and fund its bounty.",
|
|
8791
|
-
description: "Read the exact approved bounty_challenge.md bytes
|
|
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.",
|
|
8792
8741
|
required: ["ELGORA_POSTER_PRIVATE_KEY"],
|
|
8793
8742
|
defaulted: [
|
|
8794
8743
|
"ELGORA_CHAIN_ID",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elgora/cli",
|
|
3
|
-
"version": "
|
|
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",
|