Skip to content

feat: eas-sdk portal implementation #1058

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 12, 2025
Merged

feat: eas-sdk portal implementation #1058

merged 10 commits into from
Jun 12, 2025

Conversation

robbeverhelst
Copy link
Contributor

@robbeverhelst robbeverhelst commented May 27, 2025

…nd validation

Summary by Sourcery

Migrate the EAS SDK to a Portal-based implementation by introducing the EASPortalClient, unifying schema registration, adding flexible ABI support, structured error codes, and real-time monitoring, while overhauling documentation, build config, and tests for the new architecture.

New Features:

  • Introduce EASPortalClient class to interact with EAS via SettleMint Portal
  • Unify schema registration to accept either schema strings or schema fields with automatic validation
  • Support flexible ABI sources (hardcoded, custom overrides, or predeployed) with clear priority
  • Add comprehensive EAS-specific error handling with EASPortalError and error codes
  • Implement real-time transaction monitoring and utility methods (e.g., getTimestamp)
  • Expose standalone validateAndBuildSchema function for offline schema validation

Enhancements:

  • Refactor createEASClient to return EASPortalClient and enforce Zod-based options validation
  • Revamp documentation with Installation, Quick Start, ABI Configuration, Error Handling, and Usage Examples
  • Update build configuration and dependencies to optimize for Portal integration
  • Consolidate types and utilities under portal-types.ts, schema.ts, and utils/validation.ts

Build:

  • Adjust tsdown.config.ts and package.json to reference @settlemint/sdk-portal and update external bundles

Documentation:

  • Expand README with Portal integration details and add USAGE_EXAMPLES.md
  • Add source structure overview in src/README.md

Tests:

  • Revise existing tests and add eas-portal-client tests to cover new Portal client methods and ABI configurations

Copy link
Contributor

sourcery-ai bot commented May 27, 2025

Reviewer's Guide

This PR refactors the EAS SDK to use SettleMint’s Portal infrastructure as its core transport layer, replacing the viem/ethers adapter with a dedicated EASPortalClient abstraction and comprehensive GraphQL-driven interactions, while reorganizing validation utilities, exporting new Portal-specific types and error handling, updating docs, tests, and build configs accordingly.

Sequence Diagram for Schema Registration via EASPortalClient

sequenceDiagram
    actor Developer
    participant EASSDK as @settlemint/sdk-eas
    participant EASPortalClient
    participant ValidationUtils as SDK Validation Utilities
    participant PortalAPI as SettleMint Portal (GraphQL API)

    Developer->>EASSDK: createEASClient(options)
    activate EASSDK
    EASSDK->>EASPortalClient: new EASPortalClient(options)
    activate EASPortalClient
    EASPortalClient->>EASPortalClient: setAbis() (based on options.abiSource)
    EASPortalClient-->>EASSDK: clientInstance
    deactivate EASPortalClient
    EASSDK-->>Developer: easClient
    deactivate EASSDK

    Developer->>EASPortalClient: registerSchema({ fields: [...], resolver, revocable })
    activate EASPortalClient
    EASPortalClient->>ValidationUtils: validateSchemaFields(fields)
    activate ValidationUtils
    ValidationUtils-->>EASPortalClient: (validation success/failure)
    deactivate ValidationUtils
    alt Validation Succeeded
        EASPortalClient->>ValidationUtils: buildSchemaString(fields)
        activate ValidationUtils
        ValidationUtils-->>EASPortalClient: schemaString
        deactivate ValidationUtils
        EASPortalClient->>EASPortalClient: executeSchemaRegistryWrite("register", [schemaString, resolver, revocable])
        activate EASPortalClient
        EASPortalClient->>PortalAPI: GraphQL Mutation (callContract - register)
        activate PortalAPI
        PortalAPI-->>EASPortalClient: { hash: "0x..." }
        deactivate PortalAPI
        EASPortalClient-->>EASPortalClient: TransactionResult
        deactivate EASPortalClient
        EASPortalClient-->>Developer: Promise~TransactionResult~
    else Validation Failed
        EASPortalClient->>EASPortalClient: createError(EASErrorCode.INVALID_SCHEMA, msg)
        EASPortalClient-->>Developer: throws EASPortalError
    end
    deactivate EASPortalClient
Loading

File-Level Changes

Change Details Files
Replace viem/ethers adapter with Portal client abstraction
  • Refactor createEASClient to use validatePortalClientOptions and return an instance of EASPortalClient
  • Remove getPublicClient/getWalletClient and ethers-adapter logic
  • Add eas-portal-client.ts implementing EASPortalClient class with attest, registerSchema, revoke, getSchema, etc.
sdk/eas/src/eas.ts
sdk/eas/src/eas-portal-client.ts
sdk/eas/src/portal-client-options.schema.ts
sdk/eas/src/portal-types.ts
Expand SDK documentation to cover Portal integration, ABI configuration, and error handling
  • Update README.md with installation, quick start, ABI source options, and error handling sections
  • Add USAGE_EXAMPLES.md demonstrating unified API usage and migration notes
sdk/eas/README.md
sdk/eas/USAGE_EXAMPLES.md
Introduce Zod-based validation for Portal client options
  • Create portal-client-options.schema.ts defining abiSourceSchema and portalClientOptionsSchema
  • Integrate validatePortalClientOptions in createEASClient and EASPortalClient constructor
sdk/eas/src/portal-client-options.schema.ts
sdk/eas/src/eas.ts
Add comprehensive types and error classes for Portal operations
  • Create portal-types.ts with transaction/event types, SchemaRequest/AttestationRequest, EASErrorCode enum, and EASPortalError class
  • Re-export new Portal types and errors in eas.ts for backward compatibility
sdk/eas/src/portal-types.ts
sdk/eas/src/eas.ts
Update tests to mock and verify Portal client behavior
  • Switch mock implementation in eas.test.ts from sdk-viem to sdk-portal
  • Add eas-portal.test.ts covering EASPortalClient methods (registerSchema, attest, revoke, getters)
sdk/eas/src/eas.test.ts
sdk/eas/src/eas-portal.test.ts
Revise package and build configurations for Portal-centric dependencies
  • Update tsdown.config.ts to externalize @settlemint/sdk-portal and adjust banner/define flags
  • Modify package.json to depend on @settlemint/sdk-portal and remove ethers and sdk-viem
sdk/eas/tsdown.config.ts
sdk/eas/package.json
Reorganize validation utilities under utils and adjust imports
  • Move validation.ts into utils/validation.ts and update import paths
  • Ensure eas-portal-client and eas.ts import schema validation from the new utils location
sdk/eas/src/validation.ts
sdk/eas/src/utils/validation.ts
sdk/eas/src/eas-portal-client.ts
Extract and consolidate standard ABIs into abis.ts
  • Create abis.ts exporting EAS_ABI, SCHEMA_REGISTRY_ABI, and DEFAULT_EAS_ABIS
  • Import and apply these ABIs in EASPortalClient and eas.ts
sdk/eas/src/abis.ts
sdk/eas/src/eas-portal-client.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

coderabbitai bot commented May 27, 2025

📝 Walkthrough

Walkthrough

This update refactors the EAS SDK to use a Portal GraphQL API for all contract interactions, replacing direct blockchain SDK calls. The codebase introduces new types, a class-based client, expanded documentation, GraphQL operation files, and an example workflow. Legacy adapter files and schemas are removed, and configuration files are updated for the new architecture.

Changes

File(s) Change Summary
sdk/eas/README.md README completely rewritten and expanded into a comprehensive user/developer guide.
sdk/eas/src/README.md New README added describing the internal source structure and organization.
sdk/eas/examples/simple-eas-workflow.ts New example workflow demonstrating a digital notary use case with attestation, schema registration, and data encoding/decoding helpers.
sdk/eas/src/eas.ts Major refactor: replaces function-based client with class-based EASClient using Portal GraphQL, adds new methods, removes direct blockchain SDK usage, and re-exports types/utilities.
sdk/eas/src/types.ts Adds new constants, types, and interfaces for client options, schema/attestation requests, results, and internal portal responses.
sdk/eas/src/utils/validation.ts Updates import paths for type definitions.
sdk/eas/src/portal/portal-client.ts New type alias for PortalClient using the portal environment configuration.
sdk/eas/src/graphql/operations.ts New module to load, split, and export GraphQL operations and mutations from external files and inline definitions.
sdk/eas/src/graphql/mutations/attestation-operations.graphql Adds GraphQL mutations for attestation, multi-attestation, and revocation.
sdk/eas/src/graphql/mutations/schema-operations.graphql Adds GraphQL mutation for schema registration.
sdk/eas/src/graphql/queries/attestation-queries.graphql Adds GraphQL queries for attestation retrieval, validation, timestamp, and contract listing.
sdk/eas/src/graphql/queries/schema-queries.graphql Adds GraphQL queries for schema retrieval and contract registry listing.
sdk/eas/src/portal/portal-schema.graphql Adds comprehensive GraphQL schema for contracts, attestations, wallet management, and related operations.
sdk/eas/src/eas.test.ts Replaces old tests with a new suite targeting the Portal-based EASClient, covering all major methods and error handling.
sdk/eas/src/client-options.schema.ts
sdk/eas/src/ethers-adapter.ts
Deleted: Removes legacy client options schema and ethers/viem adapter utilities.
sdk/eas/package.json
sdk/eas/tsdown.config.ts
sdk/eas/tsconfig.json
sdk/eas/knip.json
Updates dependencies, scripts, TypeScript, and codegen configuration for Portal-based SDK and GraphQL integration.
sdk/eas/.gitignore Adds ignore rules for generated portal type definition files.

Sequence Diagram(s)

sequenceDiagram
    participant UserApp
    participant EASClient
    participant PortalClient
    participant PortalGraphQL

    UserApp->>EASClient: new EASClient(options)
    UserApp->>EASClient: deploy(deployerAddress, forwarderAddress)
    EASClient->>PortalClient: deploySchemaRegistryMutation
    PortalClient->>PortalGraphQL: GraphQL mutation (deploy schema registry)
    PortalGraphQL-->>PortalClient: deployment result
    PortalClient-->>EASClient: contract addresses

    UserApp->>EASClient: registerSchema(request, fromAddress)
    EASClient->>PortalClient: registerSchemaMutation
    PortalClient->>PortalGraphQL: GraphQL mutation (register schema)
    PortalGraphQL-->>PortalClient: transaction hash
    PortalClient-->>EASClient: transaction result

    UserApp->>EASClient: attest(request, fromAddress)
    EASClient->>PortalClient: attestMutation
    PortalClient->>PortalGraphQL: GraphQL mutation (attest)
    PortalGraphQL-->>PortalClient: transaction hash
    PortalClient-->>EASClient: transaction result

    UserApp->>EASClient: multiAttest(requests, fromAddress)
    EASClient->>PortalClient: multiAttestMutation
    PortalClient->>PortalGraphQL: GraphQL mutation (multi-attest)
    PortalGraphQL-->>PortalClient: transaction hash
    PortalClient-->>EASClient: transaction result

    UserApp->>EASClient: revoke(schemaUID, attestationUID, fromAddress)
    EASClient->>PortalClient: revokeMutation
    PortalClient->>PortalGraphQL: GraphQL mutation (revoke)
    PortalGraphQL-->>PortalClient: transaction hash
    PortalClient-->>EASClient: transaction result
Loading
sequenceDiagram
    participant UserApp
    participant EASClient
    participant PortalClient
    participant PortalGraphQL

    UserApp->>EASClient: getSchema(uid)
    EASClient-->>UserApp: Not implemented (throws error)

    UserApp->>EASClient: getAttestation(uid)
    EASClient-->>UserApp: Not implemented (throws error)
Loading

These diagrams illustrate the new control flow for contract deployment, schema registration, attestation, and revocation via the Portal GraphQL API, and show that certain query methods are now stubbed and recommend using The Graph subgraph.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the feat New feature label May 27, 2025
Copy link

github-actions bot commented May 27, 2025

📦 Packages

Package NPM Docker
SDK Cli @settlemint/[email protected]
SDK The Graph @settlemint/[email protected]
SDK Portal @settlemint/[email protected]
SDK Hasura @settlemint/[email protected]
SDK JS @settlemint/[email protected]
SDK Utils @settlemint/[email protected]
SDK Next @settlemint/[email protected]
SDK Minio @settlemint/[email protected]
SDK IPFS @settlemint/[email protected]
SDK Blockscout @settlemint/[email protected]
SDK MCP @settlemint/[email protected]

@robbeverhelst robbeverhelst force-pushed the feat/eas-portal-sdk branch from 79dea65 to 2f6eb59 Compare June 5, 2025 12:49
@robbeverhelst robbeverhelst marked this pull request as ready for review June 5, 2025 16:05
@robbeverhelst robbeverhelst changed the title feat: implement EAS Portal client with enhanced schema registration feat: eas sdk portal implementation Jun 5, 2025
@robbeverhelst robbeverhelst changed the title feat: eas sdk portal implementation feat: eas-sdk portal implementation Jun 5, 2025
@robbeverhelst robbeverhelst requested review from janb87 and roderik June 5, 2025 16:07
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

🔭 Outside diff range comments (1)
sdk/eas/README.md (1)

162-390: 🛠️ Refactor suggestion

Consolidate duplicated documentation sections.

The README contains substantial duplication with two separate "Quick Start" sections, repeated installation instructions, and overlapping feature descriptions. This creates confusion and maintenance overhead.

Consider consolidating the content into a single, comprehensive structure:

  1. Keep the initial comprehensive section (lines 1-161)
  2. Remove or merge the duplicated content (lines 162-390)
  3. Ensure all unique information from the second section is preserved in the first

This will provide a cleaner, more maintainable documentation experience.

🧹 Nitpick comments (15)
sdk/eas/src/README.md (1)

7-19: Add language specifier to the fenced code block.

The fenced code block should specify a language for proper syntax highlighting.

Apply this diff to specify the language:

-```
+```plaintext
 src/
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

7-7: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)

sdk/eas/src/graphql/mutations/deploy-contracts.graphql (1)

16-16: Remove trailing space.

There's a trailing space at the end of this line.

sdk/eas/examples/simple-eas-workflow.ts (1)

103-103: Make fallback schema UID configurable or document as placeholder.

The hardcoded fallback schema UID may not exist in all Portal environments, potentially causing downstream failures.

Consider making this configurable:

-    schemaUID = "0x1234567890123456789012345678901234567890123456789012345678901234" as Hex;
+    // Note: Using placeholder schema UID - replace with actual schema for production use
+    schemaUID = (process.env.FALLBACK_SCHEMA_UID || "0x1234567890123456789012345678901234567890123456789012345678901234") as Hex;
sdk/eas/README.md (1)

84-84: Fix grammatical issue with "multiple" usage.

The static analysis correctly identified a grammatical issue. The phrase should use "multiple" as an adjective rather than suggesting the verb "multiply".

The current phrasing is correct - "Revoke multiple by delegation" uses "multiple" appropriately as an adjective. The static analysis tool appears to be a false positive in this context.

🧰 Tools
🪛 LanguageTool

[misspelling] ~84-~84: Did you mean the verb “multiply”?
Context: ...oymentMultiRevokeByDelegation- Revoke multiple by delegation -EasDeploymentRevokeOff...

(MULTIPLE_MULTIPLY)

sdk/eas/src/eas.ts (2)

68-69: Make polling configuration adjustable

The polling mechanism uses hardcoded values for delay (1 second) and max attempts (30). These should be configurable to handle different network conditions.

Add polling configuration to EASClientOptions:

export interface EASClientOptions {
  // ... existing options ...
  /** Polling configuration for deployment */
  polling?: {
    /** Delay between polling attempts in milliseconds (default: 1000) */
    delayMs?: number;
    /** Maximum number of polling attempts (default: 30) */
    maxAttempts?: number;
  };
}

Then use the configuration:

-const maxAttempts = 30;
+const maxAttempts = this.options.polling?.maxAttempts ?? 30;
+const delayMs = this.options.polling?.delayMs ?? 1000;

 while (!schemaRegistryAddress && attempts < maxAttempts) {
-  await new Promise((resolve) => setTimeout(resolve, 1000));
+  await new Promise((resolve) => setTimeout(resolve, delayMs));

Also applies to: 119-120


43-43: Extract hardcoded gas limits as constants

Gas limits are hardcoded throughout the code. These should be extracted as named constants for better maintainability.

Define constants at the top of the file:

+// Default gas limits for different operations
+const GAS_LIMITS = {
+  DEPLOY: "0x7a1200",
+  REGISTER_SCHEMA: "0x3d0900",
+  ATTEST: "0x3d0900",
+  MULTI_ATTEST: "0x3d0900",
+  REVOKE: "0x3d0900",
+} as const;

 // In deploy method:
-const defaultGasLimit = gasLimit || "0x7a1200";
+const defaultGasLimit = gasLimit || GAS_LIMITS.DEPLOY;

 // In registerSchema method:
-gasLimit: gasLimit || "0x3d0900",
+gasLimit: gasLimit || GAS_LIMITS.REGISTER_SCHEMA,

Also applies to: 52-52, 104-104, 185-185, 227-227, 279-279, 317-317

sdk/eas/src/portal/portal-schema.graphql (5)

6-16: Make required fields non-nullable for Contract
Fields such as abiName, address, createdAt, transaction, and transactionHash are likely always returned by the API. Mark them with ! (e.g. String!) to enforce their presence at compile time and improve client safety.


18-38: Make required fields non-nullable for ContractDeployStatus
Similarly, key properties like abiName, address, transactionHash, and the timestamp fields should be non-nullable if the backend guarantees them.


69-75: Audit nullability on wallet types
In CreateWalletInfoInput and CreateWalletOutput, only name is marked non-nullable. Core output fields such as address, id, and name in CreateWalletOutput are always returned and could be String!.

Also applies to: 79-99


759-763: Duplicate JSON scalar docstring
The JSON scalar description appears twice (lines 1–3 and 759–761). Consolidate the documentation into one definition to avoid drift during updates.


262-380: Cleanup nested input type naming
Generated input types like EASEASAttestByDelegationDelegatedRequestInput duplicate the EAS prefix. For readability, drop the redundant prefix so it reads EASAttestByDelegationDelegatedRequestInput.

sdk/eas/src/graphql/queries/schema-queries.graphql (4)

1-2: Suggest renaming operation for consistency
The first query’s operation name duplicates the field name and doesn’t follow the “Get…” convention used elsewhere. Renaming it to GetEasSchemaRegistry improves clarity in codegen and client calls.

Apply this diff:

-query EASSchemaRegistry($address: String!, $uid: String!) {
+query GetEasSchemaRegistry($address: String!, $uid: String!) {

3-8: Use a reusable fragment for schema fields
Extract the uid, resolver, revocable, and schema selection into a GraphQL fragment. This DRYs up the query and makes it easy to reuse these fields in other operations.

Example:

fragment EasSchemaDetails on EASSchema {
  uid
  resolver
  revocable
  schema
}

query GetEasSchemaRegistry($address: String!, $uid: String!) {
  EASSchemaRegistry(address: $address) {
    getSchema(uid: $uid) {
      ...EasSchemaDetails
    }
  }
}

12-13: Unify acronym casing in operation name
The operation name GetContractsEASSchemaRegistry capitalizes “EAS” differently than the field getContractsEasSchemaRegistry. Align the casing to prevent confusion in generated types.

Apply this diff:

-query GetContractsEASSchemaRegistry($page: Int, $pageSize: Int) {
+query GetContractsEasSchemaRegistry($page: Int, $pageSize: Int) {

14-20: Consider adding pagination metadata
Currently only count and records are returned. If the client needs to support cursor-based navigation or display total pages, consider extending the response with totalPages or a pageInfo object.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 30abcd7 and 6096e69.

⛔ Files ignored due to path filters (1)
  • bun.lockb is excluded by !**/bun.lockb
📒 Files selected for processing (19)
  • sdk/eas/README.md (1 hunks)
  • sdk/eas/examples/simple-eas-workflow.ts (1 hunks)
  • sdk/eas/knip.json (1 hunks)
  • sdk/eas/package.json (1 hunks)
  • sdk/eas/src/README.md (1 hunks)
  • sdk/eas/src/client-options.schema.ts (0 hunks)
  • sdk/eas/src/eas.test.ts (2 hunks)
  • sdk/eas/src/eas.ts (1 hunks)
  • sdk/eas/src/ethers-adapter.ts (0 hunks)
  • sdk/eas/src/graphql/mutations/attestation-operations.graphql (1 hunks)
  • sdk/eas/src/graphql/mutations/deploy-contracts.graphql (1 hunks)
  • sdk/eas/src/graphql/mutations/schema-operations.graphql (1 hunks)
  • sdk/eas/src/graphql/operations.ts (1 hunks)
  • sdk/eas/src/graphql/queries/attestation-queries.graphql (1 hunks)
  • sdk/eas/src/graphql/queries/schema-queries.graphql (1 hunks)
  • sdk/eas/src/portal/portal-schema.graphql (1 hunks)
  • sdk/eas/src/types.ts (2 hunks)
  • sdk/eas/src/utils/validation.ts (1 hunks)
  • sdk/eas/tsdown.config.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • sdk/eas/src/client-options.schema.ts
  • sdk/eas/src/ethers-adapter.ts
🧰 Additional context used
🧬 Code Graph Analysis (4)
sdk/eas/src/eas.test.ts (3)
sdk/cli/src/utils/test/module-mocker.ts (1)
  • ModuleMocker (28-63)
sdk/eas/src/eas.ts (3)
  • createEASClient (449-451)
  • ZERO_ADDRESS (470-470)
  • ZERO_BYTES32 (470-470)
sdk/eas/src/types.ts (2)
  • ZERO_ADDRESS (6-6)
  • ZERO_BYTES32 (7-7)
sdk/eas/examples/simple-eas-workflow.ts (2)
sdk/eas/src/types.ts (2)
  • ZERO_ADDRESS (6-6)
  • ZERO_BYTES32 (7-7)
sdk/eas/src/eas.ts (3)
  • ZERO_ADDRESS (470-470)
  • ZERO_BYTES32 (470-470)
  • createEASClient (449-451)
sdk/eas/src/eas.ts (3)
sdk/eas/src/types.ts (12)
  • EASClientOptions (42-53)
  • DeploymentResult (176-185)
  • ZERO_ADDRESS (6-6)
  • SchemaRequest (58-67)
  • TransactionResult (100-105)
  • PortalTransactionResponse (198-201)
  • AttestationRequest (90-95)
  • SchemaData (110-119)
  • GetSchemasOptions (150-155)
  • AttestationInfo (124-145)
  • GetAttestationsOptions (160-171)
  • SchemaField (30-37)
sdk/portal/src/portal.ts (1)
  • createPortalClient (72-91)
sdk/eas/src/graphql/operations.ts (1)
  • GraphQLOperations (66-83)
sdk/eas/src/types.ts (1)
sdk/eas/src/eas.ts (14)
  • ZERO_ADDRESS (470-470)
  • ZERO_BYTES32 (470-470)
  • EASClientOptions (457-457)
  • SchemaRequest (458-458)
  • SchemaField (455-455)
  • AttestationData (459-459)
  • AttestationRequest (460-460)
  • TransactionResult (461-461)
  • SchemaData (462-462)
  • AttestationInfo (463-463)
  • GetSchemasOptions (464-464)
  • GetAttestationsOptions (465-465)
  • DeploymentResult (466-466)
  • RegisterSchemaOptions (467-467)
🪛 markdownlint-cli2 (0.17.2)
sdk/eas/src/README.md

7-7: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)

🪛 LanguageTool
sdk/eas/README.md

[misspelling] ~84-~84: Did you mean the verb “multiply”?
Context: ...oymentMultiRevokeByDelegation- Revoke multiple by delegation -EasDeploymentRevokeOff...

(MULTIPLE_MULTIPLY)

🔇 Additional comments (11)
sdk/eas/knip.json (1)

2-2: Entry point updated to new client implementation
The entry path now correctly points to src/eas.ts, aligning the build configuration with the updated main client file.

sdk/eas/src/utils/validation.ts (1)

1-1: Aligned import paths after types reorganization
The import path for EASFieldType, EAS_FIELD_TYPES, and SchemaField has been adjusted to ../types.js, matching the new directory layout.

sdk/eas/package.json (1)

54-58: Updated dependencies to portal-based architecture
Direct blockchain SDK dependencies have been replaced with @settlemint/sdk-portal and gql.tada to support the Portal GraphQL API model.

sdk/eas/tsdown.config.ts (1)

5-11: tsdown config adjusted for Portal optimization
External dependencies, banner text, and the __EAS_PORTAL_PACKAGE__ flag have been updated to reflect the new Portal-optimized package structure.

sdk/eas/src/graphql/mutations/schema-operations.graphql (1)

1-10: Added GraphQL mutation for schema registration
The EASSchemaRegistryRegister mutation with required parameters and return fields accurately supports schema registration workflows via the Portal API.

sdk/eas/src/graphql/queries/schema-queries.graphql (1)

1-21: Well-structured GraphQL queries.

The schema queries are properly formatted and include all necessary fields for both individual schema retrieval and paginated schema registry listing.

sdk/eas/src/eas.test.ts (1)

32-433: Comprehensive test coverage for the EAS Portal Client.

The test suite provides excellent coverage of all major functionalities including:

  • Client creation with various configurations
  • Contract deployment and address management
  • Schema registration with different input formats
  • Single and multi-attestation operations
  • Revocation functionality
  • Query operations for schemas and attestations
  • Proper error handling for missing contract addresses

The tests appropriately handle expected Portal access failures and verify both success and error scenarios.

sdk/eas/src/graphql/mutations/attestation-operations.graphql (1)

1-17: Well-structured GraphQL mutations with consistent interface.

The mutations follow a clean, consistent pattern with appropriate parameter types and uniform return structure. The naming convention is clear and the interface design supports the Portal GraphQL integration effectively.

sdk/eas/examples/simple-eas-workflow.ts (1)

1-34: Well-structured example with clear workflow demonstration.

The file provides an excellent demonstration of the EAS SDK workflow with proper TypeScript types, clear configuration, and comprehensive error handling patterns. The executable format and detailed logging make it very user-friendly.

Also applies to: 195-199

sdk/eas/src/graphql/queries/attestation-queries.graphql (1)

1-38: Comprehensive and well-designed GraphQL queries.

The queries provide complete coverage of attestation data retrieval needs with consistent parameter naming, appropriate field selections, and proper pagination support. The structure aligns well with the Portal GraphQL API integration.

sdk/eas/README.md (1)

1-161: Excellent comprehensive documentation with accurate examples.

The documentation provides thorough coverage of the EAS SDK features with clear examples that accurately reflect the implementation. The API reference is well-structured and the code examples align perfectly with the actual SDK usage patterns demonstrated in the workflow examples.

🧰 Tools
🪛 LanguageTool

[misspelling] ~84-~84: Did you mean the verb “multiply”?
Context: ...oymentMultiRevokeByDelegation- Revoke multiple by delegation -EasDeploymentRevokeOff...

(MULTIPLE_MULTIPLY)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
sdk/eas/src/eas.test.ts (1)

28-28: ⚠️ Potential issue

Fix invalid Ethereum address format.

The address contains "Hac" which is not valid hexadecimal. Ethereum addresses must only contain characters 0-9 and a-f/A-F.

Apply this diff to fix the address:

-const TEST_FROM_ADDRESS = "0x8ba1f109551bD432803012645Hac136c22C177ec" as Address;
+const TEST_FROM_ADDRESS = "0x8ba1f109551bD432803012645Ac136c22C177ec" as Address;
sdk/eas/src/eas.ts (3)

88-90: 🛠️ Refactor suggestion

Add error logging in polling catch blocks.

Empty catch blocks hide errors and make debugging difficult. At minimum, errors should be logged when debug mode is enabled.

Apply this diff to both catch blocks:

 } catch (error) {
-  // Continue waiting
+  if (this.options.debug) {
+    console.warn(`Error while polling for contract deployment: ${error}`);
+  }
+  // Continue waiting
 }

Also applies to: 139-141


75-77: 🛠️ Refactor suggestion

Use loaded GraphQL operations instead of inline queries.

The code uses inline GraphQL query strings instead of the operations loaded in graphql/operations.ts. This creates duplication and maintenance issues.

Import and use the appropriate queries from GraphQL operations. You'll need to add these queries to your GraphQL operations loader if they don't exist:

 try {
   const contractsResult = await this.portalClient.request(
-    "query GetSchemaRegistryContracts { getContractsEasSchemaRegistry { records { address } } }",
+    GraphQLOperations.queries.getSchemaRegistryContracts,
   );

Also applies to: 126-128


387-389: ⚠️ Potential issue

Remove misleading isValidAttestation implementation.

The method always returns false regardless of the attestation's actual validity, which is misleading and could cause bugs.

Either implement the method properly or throw an error like the other unimplemented methods:

 async isValidAttestation(uid: Hex): Promise<boolean> {
-  return false;
+  throw new Error(
+    `Attestation validity check not implemented yet. Use The Graph subgraph for checking attestation validity. Attestation UID: ${uid}`,
+  );
 }
🧹 Nitpick comments (1)
sdk/eas/src/eas.ts (1)

41-159: Consider extracting polling logic into a reusable utility.

The deployment method contains complex polling logic that's duplicated between Schema Registry and EAS contract deployment. This could be extracted into a reusable utility method.

Consider creating a private method like:

private async pollForContractAddress(
  queryString: string,
  maxAttempts: number = 30,
  intervalMs: number = 1000
): Promise<Address> {
  let attempts = 0;
  while (attempts < maxAttempts) {
    await new Promise((resolve) => setTimeout(resolve, intervalMs));
    attempts++;
    
    try {
      const result = await this.portalClient.request(queryString);
      // Extract address logic here
      if (address) return address;
    } catch (error) {
      if (this.options.debug) {
        console.warn(`Error while polling (attempt ${attempts}): ${error}`);
      }
    }
  }
  throw new Error("Contract deployment timed out");
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d7bb76 and 22989f0.

📒 Files selected for processing (3)
  • sdk/eas/examples/simple-eas-workflow.ts (1 hunks)
  • sdk/eas/src/eas.test.ts (2 hunks)
  • sdk/eas/src/eas.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • sdk/eas/examples/simple-eas-workflow.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
sdk/eas/src/eas.ts (3)
sdk/eas/src/types.ts (12)
  • EASClientOptions (42-53)
  • DeploymentResult (176-185)
  • ZERO_ADDRESS (6-6)
  • SchemaRequest (58-67)
  • TransactionResult (100-105)
  • PortalTransactionResponse (198-201)
  • AttestationRequest (90-95)
  • SchemaData (110-119)
  • GetSchemasOptions (150-155)
  • AttestationInfo (124-145)
  • GetAttestationsOptions (160-171)
  • SchemaField (30-37)
sdk/portal/src/portal.ts (1)
  • createPortalClient (72-91)
sdk/eas/src/graphql/operations.ts (1)
  • GraphQLOperations (66-83)
🪛 Gitleaks (8.26.0)
sdk/eas/src/eas.test.ts

50-50: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


67-67: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


80-80: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


91-91: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


108-108: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


121-121: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


132-132: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


155-155: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


185-185: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


212-212: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


230-230: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


263-263: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


287-287: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


320-320: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


343-343: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


366-366: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


381-381: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


406-406: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


420-420: Found a Settlemint Application Access Token.

(settlemint-application-access-token)

🔇 Additional comments (1)
sdk/eas/src/eas.test.ts (1)

32-434: Excellent test coverage for the Portal-based EAS client.

The test suite comprehensively covers all client methods including deployment, schema registration, attestations, revocations, and error handling scenarios. The mocking strategy for the Portal client is well-implemented and the tests validate both success and error cases appropriately.

🧰 Tools
🪛 Gitleaks (8.26.0)

50-50: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


67-67: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


80-80: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


91-91: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


108-108: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


121-121: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


132-132: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


155-155: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


185-185: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


212-212: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


230-230: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


263-263: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


287-287: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


320-320: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


343-343: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


366-366: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


381-381: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


406-406: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


420-420: Found a Settlemint Application Access Token.

(settlemint-application-access-token)

Copy link
Contributor

@janb87 janb87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (9)
sdk/eas/src/eas.test.ts (1)

34-55: ⚠️ Potential issue

Hard-coded SettleMint access tokens committed – credentials leak

Strings that match the production sm_aat_* token format are embedded directly in the test code (lines 35-55 and many other places).
Even if they are “test” tokens, they are now part of git history and trigger Gitleaks. Remove them or load them from the environment before this lands on a public branch.

-  accessToken: "sm_aat_5ce243f91f231128",
+  accessToken: process.env.SETTLEMINT_AAT ?? "sm_aat_dummy",
🧰 Tools
🪛 Gitleaks (8.26.0)

50-50: Found a Settlemint Application Access Token.

(settlemint-application-access-token)

sdk/eas/src/graphql/operations.ts (2)

5-9: __dirname in ESM – see previous review

This block still relies on __dirname, which is undefined in pure-ESM builds. Prior feedback already covered the import.meta.url fix.


14-26: Blocking readFileSync at module load – see previous review

The synchronous file read remains; converting to async or lazy-loading was suggested earlier for startup performance.

sdk/eas/src/types.ts (1)

192-261: Internal portal response types are still exported

Earlier feedback recommended moving these @internal interfaces to a non-exported file. They are still part of the public surface.

sdk/eas/src/eas.ts (5)

98-106: Inline GraphQL string still present

The query for getContractsEasSchemaRegistry is hard-coded instead of imported from graphql/operations.ts, duplicating logic and bypassing typed validation.


110-113: Empty catch hides errors

Silent catch blocks make debugging deployment polling painful; previous suggestion to log when debug is enabled still applies.


154-155: Empty catch hides errors

Same issue for the EAS polling loop.


466-468: No validation when building schema strings

buildSchemaString still concatenates raw input without checking field names / types. See earlier recommendation for basic validation.


406-408: ⚠️ Potential issue

isValidAttestation always returns false – misleading API

Returning a constant false can cause silent logic errors. Either implement the call or fail fast like other un-implemented methods:

-  async isValidAttestation(uid: Hex): Promise<boolean> {
-    return false;
-  }
+  async isValidAttestation(uid: Hex): Promise<boolean> {
+    throw new Error(
+      `Attestation validity check not implemented yet. Use The Graph subgraph for checking attestation validity. Attestation UID: ${uid}`,
+    );
+  }
🧹 Nitpick comments (2)
sdk/eas/src/eas.test.ts (1)

32-40: Unused fixture objects clutter the test file

optionsWithAddresses / optionsWithoutAddresses are declared but never used anywhere below. Delete them or integrate them into the relevant tests to avoid dead code.

sdk/eas/src/types.ts (1)

42-52: Make accessToken optional for standalone / public-read scenarios

Down-stream comments (janb87) requested that the token not be mandatory when only read methods are used.

-  accessToken: string;
+  accessToken?: string;

Call sites that truly require it (mutations) should throw early if absent.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22989f0 and 2eb3ae4.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • sdk/eas/.gitignore (1 hunks)
  • sdk/eas/examples/simple-eas-workflow.ts (1 hunks)
  • sdk/eas/package.json (1 hunks)
  • sdk/eas/src/eas.test.ts (2 hunks)
  • sdk/eas/src/eas.ts (1 hunks)
  • sdk/eas/src/graphql/operations.ts (1 hunks)
  • sdk/eas/src/portal/portal-client.ts (1 hunks)
  • sdk/eas/src/types.ts (2 hunks)
  • sdk/eas/tsconfig.json (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • sdk/eas/.gitignore
  • sdk/eas/src/portal/portal-client.ts
  • sdk/eas/tsconfig.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • sdk/eas/package.json
  • sdk/eas/examples/simple-eas-workflow.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
sdk/eas/src/types.ts (1)
sdk/eas/src/eas.ts (14)
  • ZERO_ADDRESS (495-495)
  • ZERO_BYTES32 (495-495)
  • EASClientOptions (482-482)
  • SchemaRequest (483-483)
  • SchemaField (480-480)
  • AttestationData (484-484)
  • AttestationRequest (485-485)
  • TransactionResult (486-486)
  • SchemaData (487-487)
  • AttestationInfo (488-488)
  • GetSchemasOptions (489-489)
  • GetAttestationsOptions (490-490)
  • DeploymentResult (491-491)
  • RegisterSchemaOptions (492-492)
🪛 Gitleaks (8.26.0)
sdk/eas/src/eas.test.ts

50-50: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


67-67: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


80-80: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


91-91: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


108-108: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


121-121: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


132-132: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


155-155: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


185-185: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


212-212: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


230-230: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


263-263: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


287-287: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


320-320: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


343-343: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


366-366: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


381-381: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


406-406: Found a Settlemint Application Access Token.

(settlemint-application-access-token)


420-420: Found a Settlemint Application Access Token.

(settlemint-application-access-token)

🪛 GitHub Check: Turbo Flow
sdk/eas/src/graphql/operations.ts

[warning] 52-52:
Multiple schemas are configured, but the document is not for a specific schema.


[warning] 41-41:
Multiple schemas are configured, but the document is not for a specific schema.

Copy link

🤖 Slack notification sent for this PR

Copy link

github-actions bot commented Jun 10, 2025

📦 Packages

Package NPM Docker
SDK Cli @settlemint/[email protected]
SDK The Graph @settlemint/[email protected]
SDK Portal @settlemint/[email protected]
SDK Hasura @settlemint/[email protected]
SDK JS @settlemint/[email protected]
SDK Utils @settlemint/[email protected]
SDK Next @settlemint/[email protected]
SDK Minio @settlemint/[email protected]
SDK IPFS @settlemint/[email protected]
SDK Blockscout @settlemint/[email protected]
SDK MCP @settlemint/[email protected]

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@robbeverhelst robbeverhelst requested a review from janb87 June 10, 2025 19:24
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@robbeverhelst robbeverhelst requested a review from janb87 June 11, 2025 13:50
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ BugBot reviewed your changes and found no bugs!


Was this report helpful? Give feedback by reacting with 👍 or 👎

@janb87 janb87 merged commit b3f41df into main Jun 12, 2025
9 checks passed
@janb87 janb87 deleted the feat/eas-portal-sdk branch June 12, 2025 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat New feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants