Skip to content

Add AsterPay KYA Trust Score demo for ACK-ID integration#75

Open
petteri74dev wants to merge 15 commits intoagentcommercekit:mainfrom
petteri74dev:feat/asterpay-kya-demo
Open

Add AsterPay KYA Trust Score demo for ACK-ID integration#75
petteri74dev wants to merge 15 commits intoagentcommercekit:mainfrom
petteri74dev:feat/asterpay-kya-demo

Conversation

@petteri74dev
Copy link
Copy Markdown

@petteri74dev petteri74dev commented Apr 4, 2026

Summary

  • Adds a complete AsterPay KYA Trust Score demo that integrates with ACK-ID's identity infrastructure
  • Demonstrates the 5-layer trust verification framework: VERIFY -> SCREEN -> SCORE -> ATTEST -> COMPLY
  • Shows JWT-based KYA token creation, verification, and conversion to W3C Verifiable Credentials
  • Includes ERC-8183 IACPHook simulation with real gate enforcement

What's included

File Description
\demos/asterpay-kya/src/kya-token.ts\ KYA Trust Score JWT token creation with 7 on-chain signal components
\demos/asterpay-kya/src/asterpay-kya-ack-id.ts\ JWT to ACK-ID Verifiable Credential conversion + verification
\demos/asterpay-kya/src/index.ts\ Full demo: token lifecycle, VC conversion, IACPHook gate
\demos/asterpay-kya/README.md\ Documentation with architecture, API reference, trust tiers

Key features

  • KYA Trust Score 0-100 from 7 data sources (ERC-8004, Chainalysis, Coinbase KYC, Gitcoin Passport, token balance, transaction history, InsumerAPI attestation)
  • 4-tier access control: Open (0-24), Verified (25-49), Trusted (50-74), Enterprise (75-100)
  • JWT -> VC bridge: Converts KYA tokens to W3C Verifiable Credentials compatible with ACK-ID
  • Trust-critical claim validation: Rejects tokens missing trustScore or sanctioned fields
  • IACPHook gate enforcement: Actually blocks low-score or sanctioned agents

Test plan

  • Demo compiles without type errors
  • \pnpm demo:asterpay-kya\ runs successfully
  • CodeRabbit review findings addressed

Context

This is a resubmission of #63 from a new account. The previous account experienced GitHub flagging issues unrelated to this contribution.


AI Disclosure: This PR was developed with assistance from Claude (Anthropic).

Summary by CodeRabbit

  • New Features

    • Added a new AsterPay KYA Trust Score demo that showcases end-to-end trust verification, JWT↔Verifiable Credential conversion, and trust-score–gated commerce flows with interactive CLI steps.
  • Documentation

    • Added comprehensive demo docs covering flow, verification checks, attestation details, expected outputs, and production considerations.
  • Chores

    • Exposed a top-level demo script to run the new AsterPay KYA demo.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 4, 2026

Warning

Rate limit exceeded

@petteri74dev has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 11 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 6 minutes and 11 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 283dc9db-a5c8-4fc5-826b-5d121ebee743

📥 Commits

Reviewing files that changed from the base of the PR and between af69b3a and 7d232cc.

📒 Files selected for processing (3)
  • demos/asterpay-kya/src/asterpay-kya-ack-id.ts
  • demos/asterpay-kya/src/index.ts
  • demos/asterpay-kya/src/kya-token.ts

Walkthrough

A new demo package for AsterPay KYA Trust Score integration is added, featuring JWT-to-W3C Verifiable Credential conversion, ACK-ID verification, and ERC-8183 IACPHook-style gating. The demo includes cryptographic operations, trust-score validation, and an end-to-end CLI workflow with configurable security thresholds.

Changes

Cohort / File(s) Summary
Documentation
demos/README.md, demos/asterpay-kya/README.md
Added demo entry in demos README and a comprehensive demo README describing ACK-ID/AsterPay KYA concepts, JWT↔VC flow, verification checks, expected VC shape, demo steps, and runnable instructions.
Configuration & Setup
demos/asterpay-kya/package.json, demos/asterpay-kya/tsconfig.json, demos/asterpay-kya/vitest.config.ts, package.json
Added demo package manifest (workspace deps, scripts), TS config with path alias, Vitest config, and monorepo script demo:asterpay-kya.
Core Verification & Models
demos/asterpay-kya/src/asterpay-kya-ack-id.ts, demos/asterpay-kya/src/kya-token.ts
New modules: Zod schemas for AsterPay KYA JWT, creation of mock KYA JWTs, JWT verification via JWKS/JOSE, conversion to/from synthetic W3C VC (proof.jwt preserved), VC field extractors, and multi-check verifier gating by issuer, expiry, sanctions, and trust-score.
Keys & Demo Orchestration
demos/asterpay-kya/src/jwk-keys.ts, demos/asterpay-kya/src/index.ts
Added JWKS/keypair generation helper and an interactive CLI demo that generates keys/tokens, converts JWT↔VC, reconstructs token equality, runs verifier scenarios (trusted/untrusted, threshold gating), and simulates ERC-8183 IACPHook gating with reputation events.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • pitluga
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Add AsterPay KYA Trust Score demo for ACK-ID integration' accurately summarizes the main change: adding a new demo implementation that integrates AsterPay KYA Trust Score with ACK-ID identity infrastructure.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@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: 5

🧹 Nitpick comments (4)
demos/asterpay-kya/vitest.config.ts (1)

4-6: Avoid a green test run with zero assertions.

passWithNoTests: true lets this package report success even if none of the new JWT/VC round-trip or gate-rejection paths are exercised. I'd add at least one colocated smoke test for create → convert → verify plus a blocked case, then drop this flag so regressions surface in CI. Based on learnings, test files must be co-located with source code as *.test.ts files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demos/asterpay-kya/vitest.config.ts` around lines 4 - 6, Update the Vitest
config to stop allowing empty test runs by removing or setting
test.passWithNoTests to false, and add at least one colocated smoke test file (a
*.test.ts next to the related source) that exercises the create → convert →
verify happy path and one gate-rejection/blocked case so CI fails on
regressions; locate the test configuration under the test object in
vitest.config.ts (property name passWithNoTests) and add tests co-located with
the source implementing the round-trip and rejection scenarios.
demos/asterpay-kya/src/index.ts (1)

235-235: Make COMPLY a real policy check, or rename it.

The job advertises a 50 USDC budget, but tierAuthorized = allPassed means this stage never inspects vc.credentialSubject.tier or the budget. Right now the fifth shield is just a re-label of earlier gates, not a distinct tier-based authorization step.

Also applies to: 296-300

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demos/asterpay-kya/src/index.ts` at line 235, COMPLY is currently a no-op
because tierAuthorized is set to allPassed; either implement a real tier/budget
check or rename the shield to reflect it's just repeating prior checks. Replace
the allPassed assignment for tierAuthorized with a function that inspects
vc.credentialSubject.tier and the job budget (e.g., verify
vc.credentialSubject.tier >= requiredTier and that the credential holder is
allowed the advertised 50 USDC budget), or if you don't want tier logic now,
rename the COMPLY symbol to something like ALL_PASSED/REDUNDANT_COMPLIANCE and
keep tierAuthorized = allPassed; update references to COMPLY and tierAuthorized
accordingly so the intent is clear.
demos/asterpay-kya/src/asterpay-kya-ack-id.ts (2)

195-219: Tight coupling between VC creation and JWT reconstruction.

This function relies on the specific jws format (header..signature) and non-standard originalPayload field created by convertAsterPayKyaToVerifiableCredential. Consider adding a comment to document this coupling and that this reconstruction only works with VCs created by this module.

📝 Suggested documentation
+/**
+ * Reconstructs the original KYA JWT from a synthetic VC.
+ *
+ * Note: This only works with VCs created by `convertAsterPayKyaToVerifiableCredential`
+ * as it relies on the non-standard `originalPayload` field in the proof.
+ */
 export function convertVerifiableCredentialToAsterPayKya(
   vc: Verifiable<W3CCredential<AsterPayKyaCredentialSubject>>,
 ): JwtString {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demos/asterpay-kya/src/asterpay-kya-ack-id.ts` around lines 195 - 219,
Document the tight coupling and limitations of
convertVerifiableCredentialToAsterPayKya: add a clear comment near the function
explaining it expects vc.proof.jws in the specific "header..signature" form and
relies on a non-standard proof.originalPayload produced by
convertAsterPayKyaToVerifiableCredential, and explicitly state this
reconstruction is only guaranteed for VCs created by that module; also mention
the thrown errors (missing jws, invalid format, missing originalPayload) so
callers know the preconditions.

172-180: Consider making Coinbase KYC check configurable.

The coinbaseKyc.met check is a hard requirement. For flexibility, consider making this configurable via a parameter, similar to minTrustScore, allowing callers to decide which attestations are required.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demos/asterpay-kya/src/asterpay-kya-ack-id.ts` around lines 172 - 180, The
Coinbase KYC attestation is currently enforced unconditionally; update the
verifier (the function in asterpay-kya-ack-id.ts that reads vc.credentialSubject
and uses att = vc.credentialSubject.insumerAttestation) to accept a new optional
parameter (e.g., requireCoinbaseKyc or requiredAttestations) with a sensible
default (true to retain current behavior) and use that flag instead of
hard-coding the check of att.coinbaseKyc.met; modify the conditional around
att.coinbaseKyc.met to only return the failure object when the flag is set, and
propagate this parameter through any callers (and tests) and document the new
option similar to minTrustScore.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@demos/asterpay-kya/src/asterpay-kya-ack-id.ts`:
- Around line 144-148: The current issuer check only looks for the literal
string "did:web:api.asterpay.io" in trustedIssuers without validating the
credential's actual issuer; after calling
convertAsterPayKyaToVerifiableCredential and obtaining vc, replace the existing
check with logic that validates vc.issuer.id against the trustedIssuers list
(e.g., ensure vc?.issuer?.id exists and trustedIssuers.includes(vc.issuer.id))
and return invalid if it does not match; reference
convertAsterPayKyaToVerifiableCredential, vc, vc.issuer.id, and trustedIssuers
when making this change.
- Around line 89-96: The proof object currently uses type "JsonWebSignature2020"
with fields jws and originalPayload which is incompatible with the ACK verifier;
update the proof to use type "JwtProof2020" and replace the jws/originalPayload
fields with a single jwt field containing the full compact JWT
(header.payload.signature) so verifyProof
(packages/vc/src/verification/verify-proof.ts) can recognize it; keep created,
verificationMethod and proofPurpose unchanged and remove jws and originalPayload
from the proof object.

In `@demos/asterpay-kya/src/index.ts`:
- Around line 111-115: The catch blocks inside runDemo (the one that logs
errorMessage("Conversion failed") and the other similar catches at the spots
mentioned and around line 315) currently log and return, causing runDemo() to
resolve successfully on fatal errors; change them to rethrow the caught error
(e.g., throw error) after logging (or call process.exit(1) if you prefer an
immediate non-zero exit) so the top-level .catch(console.error) can observe the
failure; update the catch blocks in runDemo(), and the similar handlers
referenced (the conversion error catch and the other two catches) to either
rethrow the original error or call process.exit(1) instead of returning.
- Around line 289-293: The attestation gate is missing the country check: update
the attestPass boolean (used to decide COMPLY) to include
att.coinbaseCountry.met along with att.coinbaseKyc.met, att.gitcoinPassport.met,
and att.tokenBalance.met so a failed country check blocks approval; locate the
attestPass definition in index.ts (variable att from
vc.credentialSubject.insumerAttestation) and adjust it to require
att.coinbaseCountry.met, and ensure the log line that prints
KYC/Country/Passport/USDC reflects the enforced check.

In `@demos/asterpay-kya/src/kya-token.ts`:
- Around line 67-68: The mock entry with properties trustScore and tier is
inconsistent: trustScore is 82 but tier is "trusted"; update the mock in
kya-token.ts so the values align with the 4-tier mapping — either set tier to
"enterprise" to match trustScore: 82, or lower trustScore into the 50–74 range
if "trusted" is intended; edit the object that defines trustScore and tier to
make them consistent.

---

Nitpick comments:
In `@demos/asterpay-kya/src/asterpay-kya-ack-id.ts`:
- Around line 195-219: Document the tight coupling and limitations of
convertVerifiableCredentialToAsterPayKya: add a clear comment near the function
explaining it expects vc.proof.jws in the specific "header..signature" form and
relies on a non-standard proof.originalPayload produced by
convertAsterPayKyaToVerifiableCredential, and explicitly state this
reconstruction is only guaranteed for VCs created by that module; also mention
the thrown errors (missing jws, invalid format, missing originalPayload) so
callers know the preconditions.
- Around line 172-180: The Coinbase KYC attestation is currently enforced
unconditionally; update the verifier (the function in asterpay-kya-ack-id.ts
that reads vc.credentialSubject and uses att =
vc.credentialSubject.insumerAttestation) to accept a new optional parameter
(e.g., requireCoinbaseKyc or requiredAttestations) with a sensible default (true
to retain current behavior) and use that flag instead of hard-coding the check
of att.coinbaseKyc.met; modify the conditional around att.coinbaseKyc.met to
only return the failure object when the flag is set, and propagate this
parameter through any callers (and tests) and document the new option similar to
minTrustScore.

In `@demos/asterpay-kya/src/index.ts`:
- Line 235: COMPLY is currently a no-op because tierAuthorized is set to
allPassed; either implement a real tier/budget check or rename the shield to
reflect it's just repeating prior checks. Replace the allPassed assignment for
tierAuthorized with a function that inspects vc.credentialSubject.tier and the
job budget (e.g., verify vc.credentialSubject.tier >= requiredTier and that the
credential holder is allowed the advertised 50 USDC budget), or if you don't
want tier logic now, rename the COMPLY symbol to something like
ALL_PASSED/REDUNDANT_COMPLIANCE and keep tierAuthorized = allPassed; update
references to COMPLY and tierAuthorized accordingly so the intent is clear.

In `@demos/asterpay-kya/vitest.config.ts`:
- Around line 4-6: Update the Vitest config to stop allowing empty test runs by
removing or setting test.passWithNoTests to false, and add at least one
colocated smoke test file (a *.test.ts next to the related source) that
exercises the create → convert → verify happy path and one
gate-rejection/blocked case so CI fails on regressions; locate the test
configuration under the test object in vitest.config.ts (property name
passWithNoTests) and add tests co-located with the source implementing the
round-trip and rejection scenarios.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 56a11b75-20db-4bf9-8f26-b3b75db16a43

📥 Commits

Reviewing files that changed from the base of the PR and between 6f65936 and b75959f.

📒 Files selected for processing (10)
  • demos/README.md
  • demos/asterpay-kya/README.md
  • demos/asterpay-kya/package.json
  • demos/asterpay-kya/src/asterpay-kya-ack-id.ts
  • demos/asterpay-kya/src/index.ts
  • demos/asterpay-kya/src/jwk-keys.ts
  • demos/asterpay-kya/src/kya-token.ts
  • demos/asterpay-kya/tsconfig.json
  • demos/asterpay-kya/vitest.config.ts
  • package.json

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (2)
demos/asterpay-kya/src/asterpay-kya-ack-id.ts (1)

38-42: Unused variable jwtSignature.

The jwtSignature is extracted but never used. This appears to be leftover code from the previous JsonWebSignature2020 proof format that included a jws field.

🧹 Proposed cleanup
   const jwtParts = kyaToken.split(".")
   if (jwtParts.length !== 3) {
     throw new Error("Invalid JWT format")
   }
-  const jwtSignature = jwtParts[2]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demos/asterpay-kya/src/asterpay-kya-ack-id.ts` around lines 38 - 42, Remove
the unused jwtSignature extraction: delete the jwtParts[2] assignment and, if
you don't need the signature, also remove the jwtSignature variable and any
related dead code; keep or adjust the existing JWT format validation around
kyaToken/jwtParts as needed. Specifically, update the logic around the kyaToken
variable and the jwtParts split (used in the current function) so there are no
unused variables (jwtSignature) left in the scope and no references to the old
JsonWebSignature2020 `jws` behavior.
demos/asterpay-kya/src/index.ts (1)

257-257: Consider returning the VC from verification to avoid redundant conversion.

The token is converted twice: once in verifyAsterPayKyaAsAckId (line 242-247) and again here (line 257). For demo purposes this is acceptable, but if this pattern were used in production, consider having verifyAsterPayKyaAsAckId return the converted VC when valid to avoid the duplicate JWT verification overhead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@demos/asterpay-kya/src/index.ts` at line 257, The verifyAsterPayKyaAsAckId
flow currently verifies the JWT and then you re-run conversion with
convertAsterPayKyaToVerifiableCredential, causing duplicate work; change
verifyAsterPayKyaAsAckId to return the already-converted Verifiable Credential
(or an object containing both verification result and vc) instead of only a
boolean, update the call site here to accept that returned vc (use it instead of
calling convertAsterPayKyaToVerifiableCredential again), and adjust any other
callers of verifyAsterPayKyaAsAckId to handle the new return shape (preserve
existing error/validation behavior).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@demos/asterpay-kya/src/asterpay-kya-ack-id.ts`:
- Around line 38-42: Remove the unused jwtSignature extraction: delete the
jwtParts[2] assignment and, if you don't need the signature, also remove the
jwtSignature variable and any related dead code; keep or adjust the existing JWT
format validation around kyaToken/jwtParts as needed. Specifically, update the
logic around the kyaToken variable and the jwtParts split (used in the current
function) so there are no unused variables (jwtSignature) left in the scope and
no references to the old JsonWebSignature2020 `jws` behavior.

In `@demos/asterpay-kya/src/index.ts`:
- Line 257: The verifyAsterPayKyaAsAckId flow currently verifies the JWT and
then you re-run conversion with convertAsterPayKyaToVerifiableCredential,
causing duplicate work; change verifyAsterPayKyaAsAckId to return the
already-converted Verifiable Credential (or an object containing both
verification result and vc) instead of only a boolean, update the call site here
to accept that returned vc (use it instead of calling
convertAsterPayKyaToVerifiableCredential again), and adjust any other callers of
verifyAsterPayKyaAsAckId to handle the new return shape (preserve existing
error/validation behavior).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ab378682-3133-45c4-8293-2a1f4196b914

📥 Commits

Reviewing files that changed from the base of the PR and between b75959f and af69b3a.

📒 Files selected for processing (2)
  • demos/asterpay-kya/src/asterpay-kya-ack-id.ts
  • demos/asterpay-kya/src/index.ts

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