Skip to content

feat: add edit portfolio endpoint#49

Open
CedrikNikita wants to merge 1 commit intomainfrom
feature/support-contract-profile
Open

feat: add edit portfolio endpoint#49
CedrikNikita wants to merge 1 commit intomainfrom
feature/support-contract-profile

Conversation

@CedrikNikita
Copy link
Contributor

@CedrikNikita CedrikNikita commented Feb 13, 2026

Note

High Risk
Adds new auth-adjacent X OAuth code exchange and backend signing of attestations using a private key, plus a new scheduled indexer that writes to database cache; misconfiguration or logic errors could impact security posture or load/consistency.

Overview
Adds a new Profile Identity backend slice that integrates with an on-chain ProfileRegistry_v1 contract: a scheduled indexer tracks relevant contract calls via middleware and maintains a profile_cache, while new /api/profile endpoints serve single, batch, feed, and direct on-chain (dry-run) reads.

Introduces POST /api/profile/x/attestation to mint contract-verifiable signatures for an X username using either an access token or OAuth2 PKCE code exchange; expands OAuthService with X code exchange + improved X token verification and returns provider username for GitHub/Google/X.

Wires the new module into AppModule and enriches GET /accounts/:address responses with merged profile, public_name, and names; updates env/examples and tooling (new profile env vars, gitignore entries, prod start path) and adds docs/tests plus a reference userProfile.ts demo client.

Written by Cursor Bugbot for commit 2db868e. This will update automatically on new commits. Configure here.

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.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

const profile = this.mergeProfile(cache, onChainProfile, account);

const publicName =
cache?.public_name || this.resolvePublicName(profile, address);
Copy link

Choose a reason for hiding this comment

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

On-chain reads still return cached public name

Medium Severity

getProfile and batch getProfileFromAggregates prioritize cache.public_name even when includeOnChain is true. This can return stale public_name that disagrees with fresh on-chain profile fields, so /api/profile and /api/profile?includeOnChain=true may expose inconsistent identity data.

Additional Locations (1)

Fix in Cursor Fix in Web

"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"start:prod": "node dist/src/main",
Copy link

Choose a reason for hiding this comment

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

Production startup points to wrong build entry

High Severity

start:prod now runs node dist/src/main, but this Nest setup builds to dist/main with nest build. This makes production startup look for a non-existent entrypoint, so npm run start:prod fails at runtime.

Fix in Cursor Fix in Web

const profile = await this.profileContractService.getProfile(address);
if (!profile) {
return;
}
Copy link

Choose a reason for hiding this comment

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

Indexer can silently drop profile updates

Medium Severity

refreshAddress returns early when getProfile yields null, but syncProfileChanges still advances last_indexed_micro_time. If contract reads fail transiently and getProfile returns null, those addresses are skipped and their changes are never retried, leaving profile_cache stale.

Additional Locations (1)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant