Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# ─── Wallets ──────────────────────────────────────────────────────────────────
# Deployer wallet — pays gas for contract deployments and delegation txs
PRIVATE_KEY=0xyour_deployer_private_key

# Secondary wallet (optional — used for testing with a second account)
PRIVATE_KEY2=0xyour_second_private_key

# Platform owner / whitelisted user — signs UserOps (needs no ETH for gasless ops)
OWNER_PRIVATE_KEY=0xyour_owner_private_key

# ─── RPC Endpoints ────────────────────────────────────────────────────────────
# Get free endpoints at https://infura.io or https://alchemy.com
SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/your_infura_project_id
AMOY_RPC_URL=https://polygon-amoy.infura.io/v3/your_infura_project_id

# ─── Bundler ──────────────────────────────────────────────────────────────────
# Get a free Pimlico API key at https://dashboard.pimlico.io
PIMLICO_API_KEY=pim_your_pimlico_api_key

# ─── EntryPoint ───────────────────────────────────────────────────────────────
# Canonical EntryPoint v0.8 — same address on all supported chains
ENTRY_POINT=0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108

# ─── Document / Token Config ──────────────────────────────────────────────────
# Used by mintDocumentGasless.ts
TOKEN_ID=0xyour_document_hash_as_uint256
TOKEN_NAME=MyRegistry
TOKEN_SYMBOL=MYR
REMARK=optional remark text
BENEFICIARY_ADDRESS=0xbeneficiary_wallet_address
HOLDER_ADDRESS=0xholder_wallet_address
NOMINEE_ADDR=0xnominee_wallet_address
NEW_HOLDER_ADDR=0xnew_holder_wallet_address

# ─── Sepolia Deployments ──────────────────────────────────────────────────────
# Filled in automatically by deploy scripts — run in order:
# 1. npx hardhat run scripts/deployEIP7702.ts --network sepolia
# 2. npx hardhat run scripts/deployImplementation.ts --network sepolia
# 3. npx hardhat run scripts/deployFactory.ts --network sepolia
# 4. npx hardhat run scripts/deployPlatformPaymaster.ts --network sepolia
# 5. npx hardhat run scripts/stakePlatformPaymaster.ts --network sepolia

EIP7702_IMPL_ADDRESS_SEPOLIA=0x_filled_by_deployEIP7702
PAYMASTER_IMPLEMENTATION_SEPOLIA=0x_filled_by_deployImplementation
FACTORY_ADDRESS_SEPOLIA=0x_filled_by_deployFactory
PAYMASTER_ADDRESS_SEPOLIA=0x_filled_by_deployPlatformPaymaster

# TrustVC infrastructure on Sepolia (pre-deployed — do not change)
TDOC_DEPLOYER_ADDRESS_SEPOLIA=0x64bc665056DC8bE4092e569ED13a7F273Be28cD2
TDOC_IMPLEMENTATION_SEPOLIA=0x45c382574bb1B9C432a2e100Ab2086A4EAcB73Fd

# Filled in after running deployRegistryGasless.ts / mintDocumentGasless.ts
REGISTRY_ADDRESS_SEPOLIA=0x_filled_after_deployRegistry
TITLE_ESCROW_ADDRESS_SEPOLIA=0x_filled_after_mintDocument

# ─── Polygon Amoy Deployments ─────────────────────────────────────────────────
# Same deploy order as above but with --network amoy and NETWORK=amoy

Comment on lines +52 to +58

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 4 '\bNETWORK\b|process\.env\.NETWORK|NETWORK=' scripts hardhat.config.ts

Repository: TrustVC/7702SmartAccount

Length of output: 8682


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- target .env.example sections ---'
sed -n '40,78p' .env.example

printf '%s\n' '--- network resolution and usage ---'
rg -n -C 8 'function getNetworkConfig|const getNetworkConfig|export .*getNetworkConfig|networkName|NETWORK' scripts/trFunctions scripts/deployRegistryGasless.ts scripts/mintDocumentGasless.ts scripts -g '*.ts' | head -n 220

printf '%s\n' '--- documentation commands ---'
rg -n -C 5 'deployRegistryGasless|mintDocumentGasless|NETWORK=|NETWORK ' README.md docs .github 2>/dev/null || true

Repository: TrustVC/7702SmartAccount

Length of output: 19400


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- network helper ---'
sed -n '1,180p' scripts/lib/network.ts

printf '%s\n' '--- deployment call using TDOC_IMPLEMENTATION ---'
rg -n -C 12 'tdocImpl|deployRegistry|encodeFunctionData' scripts/deployRegistryGasless.ts

printf '%s\n' '--- Amoy placeholder references ---'
rg -n -C 3 'TDOC_IMPLEMENTATION_AMOY|0x_tdoc_implementation_on_amoy' .

Repository: TrustVC/7702SmartAccount

Length of output: 7040


Provide a valid Amoy TDoc implementation address.

TDOC_IMPLEMENTATION_AMOY=0x_tdoc_implementation_on_amoy is not a valid address. scripts/deployRegistryGasless.ts passes it to encodeFunctionData as the implementation argument, so Amoy registry deployment fails.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.env.example around lines 52 - 58, Update TDOC_IMPLEMENTATION_AMOY in
.env.example to a valid deployed Amoy TDoc implementation address, preserving
the variable name so scripts/deployRegistryGasless.ts can pass it to
encodeFunctionData successfully.

EIP7702_IMPL_ADDRESS_AMOY=0x_filled_by_deployEIP7702
PAYMASTER_IMPLEMENTATION_AMOY=0x_filled_by_deployImplementation
FACTORY_ADDRESS_AMOY=0x_filled_by_deployFactory
PAYMASTER_ADDRESS_AMOY=0x_filled_by_deployPlatformPaymaster

# TrustVC infrastructure on Amoy (pre-deployed — do not change)
TDOC_DEPLOYER_ADDRESS_AMOY=0xfcafea839e576967b96ad1FBFB52b5CA26cd1D25
TDOC_IMPLEMENTATION_AMOY=0x_tdoc_implementation_on_amoy
Comment on lines +64 to +66

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Provide a valid Amoy TDOC implementation address.

TDOC_IMPLEMENTATION_AMOY=0x_tdoc_implementation_on_amoy is not a valid EVM address, but the surrounding comment marks this infrastructure as pre-deployed. Any Amoy script that consumes this value will fail address validation or use invalid configuration.

Replace it with the deployed address, or document it as a required value that users must populate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.env.example around lines 64 - 66, Replace the placeholder value in
TDOC_IMPLEMENTATION_AMOY with the valid deployed Amoy TDOC implementation
address; if that address cannot be committed, clearly mark the variable as a
required user-provided value instead of leaving an invalid EVM address.


# Filled in after running gasless scripts with NETWORK=amoy
REGISTRY_ADDRESS_AMOY=0x_filled_after_deployRegistry
TITLE_ESCROW_ADDRESS_AMOY=0x_filled_after_mintDocument
6 changes: 6 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dist
artifacts
cache
src/abis
node_modules
7702Frontend
43 changes: 43 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json",
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"env": {
"node": true,
"mocha": true
},
"rules": {
"no-console": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"import/no-extraneous-dependencies": "off"
},
"overrides": [
{
"files": ["test/**/*.ts"],
"env": { "mocha": true },
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-unused-expressions": "off",
"no-unused-expressions": "off"
}
},
{
"files": ["scripts/**/*.ts"],
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
}
],
"ignorePatterns": ["dist", "artifacts", "cache", "src/abis", "7702Frontend", "node_modules"]
}
28 changes: 28 additions & 0 deletions .github/workflows/linters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
on:
workflow_call:

env:
NODE_ENV: ci

name: "Linters"

jobs:
lint:
name: Code Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24.x
- run: npm ci --ignore-scripts
- run: npm run lint

commit-lint:
name: Commit Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Commit Lint Dependencies
run: npm install @commitlint/config-conventional
- uses: JulienKode/pull-request-name-linter-action@v0.5.0
30 changes: 30 additions & 0 deletions .github/workflows/pull_requests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
on:
pull_request:
types: [opened, reopened, synchronize]
Comment on lines +1 to +3

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="$(gh repo view --json nameWithOwner --jq .nameWithOwner)"
gh api "repos/${repo}/actions/permissions/workflow" | jq .

Repository: TrustVC/7702SmartAccount

Length of output: 418


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- workflow files ---'
git ls-files '.github/workflows/*'

printf '%s\n' '--- pull_requests.yml ---'
cat -n .github/workflows/pull_requests.yml

printf '%s\n' '--- release.yml ---'
cat -n .github/workflows/release.yml

printf '%s\n' '--- permission declarations and workflow/job references ---'
rg -n -C 3 '(^|[[:space:]])permissions:|uses:|^[[:space:]]{2,}jobs:|^[[:space:]]{2,}[A-Za-z0-9_-]+:' .github/workflows

Repository: TrustVC/7702SmartAccount

Length of output: 10400


🌐 Web query:

GitHub Actions permissions workflow-level job-level precedence reusable workflow caller permissions contents read documentation

💡 Result:

In GitHub Actions, GITHUB_TOKEN permissions are determined by a hierarchical precedence and, in the context of reusable workflows, are strictly capped by the caller's configuration [1][2][3]. Permission Precedence The permissions for a GITHUB_TOKEN are calculated by applying configurations in the following order of precedence, where each subsequent level can further restrict the token's access [1][4][5]: 1. Default Settings: Permissions are initially set by the enterprise, organization, or repository default settings [1][5]. 2. Workflow-Level: If a permissions key is defined at the top level of a workflow file, it overrides the default settings for all jobs in that workflow [1][4]. 3. Job-Level: If a permissions key is defined within a specific job, it overrides the workflow-level and default settings for that job only [1][6]. Reusable Workflow Caller Permissions When using reusable workflows, the caller's permissions act as a security boundary or "envelope" for the called workflow [7][2]. The following rules apply: - Capping: A reusable workflow cannot request or be granted permissions that exceed those explicitly granted by the caller (either at the workflow or job level) [2][3]. - Effective Permissions: The effective permissions for a reusable workflow are the intersection of the permissions it requests and the permissions the caller allows [2][3]. - Error Behavior: If a reusable workflow requests a permission (e.g., contents: write) that the caller has not granted (e.g., the caller only provides contents: read or the default), the workflow will fail with an error similar to: The workflow is requesting X, but is only allowed Y [2][3]. - Best Practices: To ensure successful execution and security, it is recommended to explicitly declare the minimum required permissions in both the caller (for the specific job calling the workflow) and the reusable workflow itself [2]. For example, if a reusable workflow requires contents: read, the calling job should explicitly grant that scope [8][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

files = [
    Path(".github/workflows/pull_requests.yml"),
    Path(".github/workflows/release.yml"),
]

for path in files:
    lines = path.read_text().splitlines()
    top_permissions = [
        line.strip()
        for line in lines
        if line and not line.startswith((" ", "\t")) and line.strip().startswith("permissions:")
    ]

    jobs = {}
    in_jobs = False
    current_job = None
    for line in lines:
        if line == "jobs:":
            in_jobs = True
            continue
        if not in_jobs:
            continue
        if line.startswith("  ") and not line.startswith("    ") and line.rstrip().endswith(":"):
            current_job = line.strip()[:-1]
            jobs[current_job] = {"uses": None, "permissions": []}
        elif current_job and line.startswith("    uses:"):
            jobs[current_job]["uses"] = line.split(":", 1)[1].strip()
        elif current_job and line.startswith("      ") and line.strip().startswith(("contents:", "pull-requests:", "packages:", "id-token:")):
            jobs[current_job]["permissions"].append(line.strip())

    print(path)
    print("  top-level permissions:", top_permissions or "absent")
    for job, data in jobs.items():
        if data["uses"] or data["permissions"]:
            print(f"  {job}: uses={data['uses'] or 'none'} permissions={data['permissions'] or 'absent'}")
PY

Repository: TrustVC/7702SmartAccount

Length of output: 725


Set restrictive workflow permission defaults.

Both workflows omit top-level permissions, so reusable tests and linters jobs inherit repository or organization defaults. Add permissions: { contents: read } to both workflows. Existing job-level permissions for eslint-review and release remain in effect.

🧰 Tools
🪛 zizmor (1.29.0)

[warning] 1-31: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)

📍 Affects 2 files
  • .github/workflows/pull_requests.yml#L1-L3 (this comment)
  • .github/workflows/release.yml#L3-L7
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pull_requests.yml around lines 1 - 3, Add top-level
restrictive permissions to both .github/workflows/pull_requests.yml (lines 1-3)
and .github/workflows/release.yml (lines 3-7), setting contents to read.
Preserve the existing job-level permissions for eslint-review and release.

Source: Linters/SAST tools


env:
NODE_ENV: ci

name: "Pull Requests"

jobs:
tests:
name: Tests
uses: ./.github/workflows/tests.yml

linters:
name: Linters
uses: ./.github/workflows/linters.yml

eslint-review:
name: ESLint Review
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: reviewdog/action-eslint@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
eslint_flags: "src scripts test --ext .ts"
Comment on lines +22 to +30

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 3 'reviewdog/action-eslint|npm (ci|install)' \
  .github/workflows/pull_requests.yml .github/workflows/linters.yml

curl -fsSL https://raw.githubusercontent.com/reviewdog/action-eslint/v1/script.sh \
  | sed -n '6,20p'

Repository: TrustVC/7702SmartAccount

Length of output: 2054


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- workflow files ---'
cat -n .github/workflows/pull_requests.yml
cat -n .github/workflows/linters.yml

printf '%s\n' '--- package manifests and lockfiles ---'
git ls-files | grep -E '(^|/)(package\.json|package-lock\.json|npm-shrinkwrap\.json|yarn\.lock|pnpm-lock\.yaml)$' | sort
for f in package.json package-lock.json npm-shrinkwrap.json yarn.lock pnpm-lock.yaml; do
  if [ -f "$f" ]; then
    printf '\n--- %s ---\n' "$f"
    case "$f" in
      package.json) node -e 'const p=require("./package.json"); console.log(JSON.stringify({scripts:p.scripts,dependencies:p.dependencies,devDependencies:p.devDependencies},null,2))' ;;
      *) sed -n '1,24p' "$f" ;;
    esac
  fi
done

printf '%s\n' '--- action script ---'
curl -fsSL https://raw.githubusercontent.com/reviewdog/action-eslint/v1/script.sh | cat -n | sed -n '1,80p'

Repository: TrustVC/7702SmartAccount

Length of output: 6008


Block lifecycle scripts in pull-request dependency installs.

reviewdog/action-eslint@v1 runs npm install when ESLint is unavailable. This executes lifecycle scripts from pull-request-controlled package metadata while GITHUB_TOKEN has pull-requests: write.

Add actions/setup-node@v4 and npm ci --ignore-scripts before reviewdog/action-eslint@v1. Replace the npm install @commitlint/config-conventional`` step in .github/workflows/linters.yml with the same lockfile-based flow.

🧰 Tools
🪛 zizmor (1.29.0)

[warning] 26-26: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

📍 Affects 2 files
  • .github/workflows/pull_requests.yml#L22-L30 (this comment)
  • .github/workflows/linters.yml#L26-L28
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pull_requests.yml around lines 22 - 30, Before
reviewdog/action-eslint@v1 in .github/workflows/pull_requests.yml at lines
22-30, add actions/setup-node@v4 and run npm ci --ignore-scripts so ESLint
dependencies are installed from the lockfile without lifecycle scripts. In
.github/workflows/linters.yml at lines 26-28, replace the npm install
`@commitlint/config-conventional` step with the same setup-node and lockfile-based
npm ci --ignore-scripts flow.

Source: Linters/SAST tools

53 changes: 53 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Release

on:
push:
branches:
- main
- dev

env:
NODE_ENV: ci

jobs:
tests:
name: Tests
uses: ./.github/workflows/tests.yml

linters:
name: Linters
uses: ./.github/workflows/linters.yml

release:
name: Publish Release
runs-on: ubuntu-latest
needs: [tests, linters]
permissions:
contents: write
packages: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Cache node modules
uses: actions/cache@v4
with:
path: ~/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org/

- run: npm ci
- run: npm run build
- run: npm run semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
31 changes: 31 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
on:
workflow_call:

env:
NODE_ENV: ci

name: "Tests"

jobs:
run-tests:
name: Run Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24.x
- run: npm ci --ignore-scripts
- run: npm run build:sol
- run: npm test

test-build:
name: Test Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24.x
- run: npm ci --ignore-scripts
- run: npm run build
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
node_modules
.env
/dist

# Hardhat files
/cache
/artifacts
/7702Frontend

# TypeChain files
/typechain
Expand Down
11 changes: 0 additions & 11 deletions 7702Frontend/.env.example

This file was deleted.

12 changes: 0 additions & 12 deletions 7702Frontend/index.html

This file was deleted.

Loading
Loading