Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
4b0727d
fix(deps): patch HIGH CVE dependencies (TASK-002)
carlosfebres Feb 20, 2026
3de4b17
feat(node): add Node.js version constraints and startup guard (TASK-003)
carlosfebres Feb 20, 2026
45f6bfe
chore(ts): tighten TypeScript compiler settings (TASK-010)
carlosfebres Feb 20, 2026
695b0c8
feat(errors): add typed error hierarchy (TASK-011)
carlosfebres Feb 20, 2026
e4b42b7
feat(validation): add runtime validation with zod (TASK-012)
carlosfebres Feb 20, 2026
1c81c39
refactor(types): eliminate all any types (TASK-013)
carlosfebres Feb 20, 2026
4a2e313
feat(test): set up Jest configuration properly (TASK-014)
carlosfebres Feb 20, 2026
c7c9753
feat(ci): add GitHub Actions CI and security scan workflows (TASK-015)
carlosfebres Feb 20, 2026
e27aaa2
feat(eslint): strengthen ESLint configuration (TASK-016)
carlosfebres Feb 20, 2026
11f765a
feat(arch): extract chain plugin registry (TASK-020)
carlosfebres Feb 20, 2026
0aad550
refactor(publish): decompose god class into focused modules (TASK-021)
carlosfebres Feb 20, 2026
94aed36
feat(arch): strengthen BasePublisher contract — fix LSP violation (TA…
carlosfebres Feb 20, 2026
d0d16ce
feat(publishers): add dependency injection + fix EVM client lifecycle…
carlosfebres Feb 20, 2026
27cd758
refactor(svm): reorganize SVM module for clarity (TASK-024)
carlosfebres Feb 20, 2026
feabb96
refactor(config): introduce ConfigService to remove global state muta…
carlosfebres Feb 20, 2026
df5a837
fix(publishers): fix concrete publisher behavioral bugs (TASK-026)
carlosfebres Feb 20, 2026
e67d61d
test(address-normalizer): unit tests covering all round-trips and err…
carlosfebres Feb 20, 2026
a0b2d11
test(chain-detector): unit tests covering detect, network, address va…
carlosfebres Feb 20, 2026
bbc8ac6
test(converters): unit tests for IntentConverter and PortalEncoder (T…
carlosfebres Feb 20, 2026
1c4438b
test(quote): unit tests for Quote service — non-200, missing fields, …
carlosfebres Feb 20, 2026
a4164ca
test(config): integration tests for chain and token config loading (T…
carlosfebres Feb 20, 2026
91d83f6
test(evm-publisher): integration tests with mocked clients (TASK-035)
carlosfebres Feb 20, 2026
e558d0d
test(integration): intent publishing flow — 12 tests covering full pi…
carlosfebres Feb 20, 2026
e44d82a
test(e2e): EVM publish and fund on Anvil fork of Base mainnet (TASK-037)
carlosfebres Feb 20, 2026
9751186
docs(architecture): create ARCHITECTURE.md covering address system, i…
carlosfebres Feb 20, 2026
1b96ca6
docs(contributing): create CONTRIBUTING.md with setup, conventions, a…
carlosfebres Feb 20, 2026
421a85c
docs(security): create SECURITY.md with key formats and best practice…
carlosfebres Feb 20, 2026
c4a0705
docs(jsdoc): document all public APIs with JSDoc (TASK-043)
carlosfebres Feb 20, 2026
b8750d2
docs(env): improve .env.example and env validation (TASK-044)
carlosfebres Feb 20, 2026
4cb01b3
docs(cli): improve help text and error messages (TASK-045)
carlosfebres Feb 20, 2026
c633da7
chore(changelog): set up changesets and CHANGELOG.md (TASK-046)
carlosfebres Feb 20, 2026
453ad9a
feat(security): implement KeyHandle for secure key zeroization (TASK-…
carlosfebres Feb 20, 2026
2771d8e
feat(rpc): add RPC endpoint fallback strategy with exponential backof…
carlosfebres Feb 20, 2026
6de90e7
docs(typedoc): add TypeDoc config and GitHub Pages deployment (TASK-052)
carlosfebres Feb 20, 2026
21d8247
feat(security): add chain ID allowlist validation (TASK-053)
carlosfebres Feb 20, 2026
0a86093
chore(progress): final report — ralph loop complete
carlosfebres Feb 20, 2026
2a61adf
docs(design): add NestJS architecture improvement design
carlosfebres Feb 20, 2026
98e8661
docs(plan): add NestJS architecture improvement implementation plan
carlosfebres Feb 20, 2026
7f10bf0
chore(deps): add nestjs + nestjs-commander, remove commander
carlosfebres Feb 20, 2026
cb435b1
refactor: add shared/types (migrated from core/types + core/interfaces)
carlosfebres Feb 20, 2026
de6ca11
feat(security): add async-safe KeyHandle.useAsync()
carlosfebres Feb 20, 2026
8982a9c
refactor: add shared/errors (migrated from core/errors)
carlosfebres Feb 20, 2026
32fa74a
feat(config): add Zod env validation schema with configurable dAppID …
carlosfebres Feb 20, 2026
ab762ed
feat(config): add typed ConfigService with all env getters
carlosfebres Feb 20, 2026
f6c5c96
feat(config): add ConfigModule with global Zod-validated config
carlosfebres Feb 20, 2026
7161dc9
feat(blockchain): add ChainRegistryService with explicit onModuleInit…
carlosfebres Feb 20, 2026
c00ea40
refactor(blockchain): migrate chain handlers, remove self-registratio…
carlosfebres Feb 20, 2026
fb16452
feat(blockchain): add injectable AddressNormalizerService
carlosfebres Feb 20, 2026
f968050
feat(blockchain): add ChainsService with lazy normalization in onModu…
carlosfebres Feb 20, 2026
8f6d713
feat(blockchain): add RpcService with uniform withFallback() for all …
carlosfebres Feb 20, 2026
b1f0037
feat(blockchain): migrate publishers to injectable NestJS services wi…
carlosfebres Feb 20, 2026
bd6d5b4
refactor(blockchain/svm): migrate SVM helpers to new structure
carlosfebres Feb 20, 2026
c1c0178
refactor(blockchain): migrate client factories to co-located chain dirs
carlosfebres Feb 20, 2026
076ae5a
feat(blockchain): add PublisherFactory as injectable NestJS service
carlosfebres Feb 20, 2026
c7dcf44
feat(blockchain): migrate PortalEncoder and IntentConverter to inject…
carlosfebres Feb 20, 2026
49a9367
feat(blockchain): assemble BlockchainModule (global)
carlosfebres Feb 20, 2026
81fa1d8
feat(quote): add injectable QuoteService with configurable endpoint +…
carlosfebres Feb 20, 2026
1ea81ad
feat(intent): add pure IntentBuilder service — no I/O, no prompts
carlosfebres Feb 20, 2026
f24755f
feat(intent): add IntentBuilder + IntentStorage services and IntentMo…
carlosfebres Feb 20, 2026
f2497ce
feat(status): add StatusService routing status checks by chain type
carlosfebres Feb 20, 2026
e7b1ac6
feat(cli): add injectable PromptService wrapping all inquirer calls
carlosfebres Feb 20, 2026
05a2a99
feat(cli): add injectable DisplayService wrapping ora + cli-table3
carlosfebres Feb 20, 2026
83d759f
feat(cli): add PublishCommand as nestjs-commander injectable
carlosfebres Feb 20, 2026
55d268d
feat(cli): add chains, tokens, status, config commands as nestjs-comm…
carlosfebres Feb 20, 2026
e47c766
feat(cli): assemble CliModule (leaf module)
carlosfebres Feb 20, 2026
07b8705
feat: bootstrap NestJS application with CommandFactory
carlosfebres Feb 21, 2026
d5c7121
refactor: remove old src/core, src/commands, src/builders, src/index.ts
carlosfebres Feb 21, 2026
f15ff96
chore: update tsconfig paths for new directory structure
carlosfebres Feb 21, 2026
85678e0
chore: nestjs architecture migration complete — ralph loop done
carlosfebres Feb 21, 2026
ad73b6e
chore: auto-commit before merge (loop slick-tulip)
carlosfebres Feb 21, 2026
fb01e1e
fix(lint): resolve pre-commit hook violations across CLI and blockcha…
carlosfebres Feb 21, 2026
c97c356
fix(config): display friendly error when env validation fails
carlosfebres Feb 22, 2026
25472fc
fix(publish): derive wallet address from private key across all chain…
carlosfebres Feb 22, 2026
b6c7dda
feat(tokens): add ETH with zero address and Ronin WETH support
carlosfebres Feb 22, 2026
f9f6c7f
feat(intent): support native ETH via zero address in reward and route
carlosfebres Feb 22, 2026
ea0c956
feat(display): show quote summary table after fetching quote
carlosfebres Feb 26, 2026
36c52a5
feat(tokens): add WETH token config with Ethereum, Base, and Ronin ad…
carlosfebres Feb 26, 2026
b628e56
fix(quote): gate debug logs behind DEBUG env flag
carlosfebres Feb 26, 2026
25ee6d8
refactor(quote): inject DisplayService for debug logging
carlosfebres Feb 26, 2026
763c900
docs(readme): rewrite as story-driven, action-oriented guide
carlosfebres Feb 26, 2026
e0204be
feat(publish): watch for fulfillment after intent publish
carlosfebres Feb 26, 2026
7fad6a3
build: bundle with ncc for npm publish
carlosfebres Feb 26, 2026
af875c9
feat: clean up
carlosfebres Feb 26, 2026
c072919
fix(status): pass full ChainConfig to getStatus instead of chain ID
carlosfebres Feb 26, 2026
2e9be16
fix(display): remove conflicting outer spinner and add fallbacks to s…
carlosfebres Feb 26, 2026
8a71b87
fix(evm): use correct chain in public client instead of hardcoded mai…
carlosfebres Feb 26, 2026
1ee96e1
feat(publish): require portal and prover addresses via CLI arg or prompt
carlosfebres Feb 26, 2026
b60cbb3
feat(publish): make fulfillment watching opt-in via --watch/-w flag
carlosfebres Feb 26, 2026
201a774
fix(cli): show help and exit 0 when no command is specified
carlosfebres Feb 26, 2026
b923f32
docs(readme): expand publish flags table with full flag set
carlosfebres Feb 26, 2026
a91eddc
feat(publish): add --private-key-tvm and --private-key-svm flags
carlosfebres Feb 26, 2026
5fee376
fix(package): point main field to bundle/index.js
carlosfebres Feb 26, 2026
e5aca31
chore: remove .ralph folder
carlosfebres Feb 26, 2026
605c71d
chore: remove specs folder
carlosfebres Feb 26, 2026
c28c8a4
chore: remove improvement plan, progress, and prompt files
carlosfebres Feb 26, 2026
8b9f267
chore: remove ralph.yml
carlosfebres Feb 26, 2026
c60a21e
docs(readme): update Quick Start and commands for npm-installed users
carlosfebres Feb 26, 2026
3bcf698
chore: bump version to 1.0.1
carlosfebres Feb 26, 2026
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
8 changes: 8 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changesets

Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)

We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
11 changes: 11 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
104 changes: 81 additions & 23 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,23 +1,81 @@
# Private keys for each chain type
EVM_PRIVATE_KEY=0x...
TVM_PRIVATE_KEY=...
SVM_PRIVATE_KEY=...

# RPC endpoints (optional - defaults provided)
EVM_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/...
TVM_RPC_URL=https://api.trongrid.io
SVM_RPC_URL=https://api.mainnet-beta.solana.com

# Quote Service Configuration (optional)
# Use solver-v2 endpoint (takes precedence over quote service)
SOLVER_URL=https://solver.example.com

# Use preprod quote service (only applies if SOLVER_URL not set)
# QUOTES_API_URL=any_value
# QUOTES_PREPROD=any_value

# Portal contract addresses per chain (optional - defaults provided)
PORTAL_ADDRESS_ETH=0x...
PORTAL_ADDRESS_OPTIMISM=0x...
PORTAL_ADDRESS_TRON=...
PORTAL_ADDRESS_SOLANA=...
# =============================================================================
# Routes CLI — Environment Configuration
# =============================================================================
# Copy this file to .env and fill in the values for your setup.
#
# REQUIRED variables must be set before publishing to the corresponding chain.
# OPTIONAL variables override built-in defaults; omitting them is safe.
#
# Private key format summary:
# EVM — 0x followed by 64 hexadecimal characters (66 chars total)
# TVM — 64 hexadecimal characters WITHOUT the 0x prefix (64 chars)
# SVM — base58 string, JSON array [1,2,...], or comma-separated bytes
# =============================================================================


# =============================================================================
# REQUIRED: Private Keys
# Set the key for each chain type you intend to publish intents on.
# =============================================================================

# EVM chains (Ethereum, Base, Optimism, Arbitrum, Polygon, BSC, Ronin, etc.)
# Format : 0x + 64 hexadecimal characters (66 characters total)
# Example: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
EVM_PRIVATE_KEY=

# TVM chain (Tron mainnet / Tron Shasta testnet)
# Format : 64 hexadecimal characters WITHOUT the 0x prefix (64 characters)
# NOTE : Do NOT use your TRX wallet address (starts with T); use the raw hex key
# Example: ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
TVM_PRIVATE_KEY=

# SVM chain (Solana mainnet / Solana Devnet)
# Three accepted formats (choose one):
#
# Base58 string (default export from Phantom, Solana CLI `solana-keygen`):
# SVM_PRIVATE_KEY=5K5K5K...base58EncodedKey
#
# JSON byte array (Solana CLI keypair file format):
# SVM_PRIVATE_KEY=[1,2,3,4,...,64]
#
# Comma-separated byte values:
# SVM_PRIVATE_KEY=1,2,3,4,...,64
SVM_PRIVATE_KEY=


# =============================================================================
# OPTIONAL: RPC Endpoint Overrides
# Each chain has a built-in default RPC URL. Set these to use a private
# or rate-limit-free endpoint (Alchemy, Infura, QuickNode, etc.).
# =============================================================================

# EVM chains — override per chain using EVM_RPC_URL_{CHAIN_ID}:
# EVM_RPC_URL_1=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY # Ethereum
# EVM_RPC_URL_10=https://opt-mainnet.g.alchemy.com/v2/YOUR_KEY # Optimism
# EVM_RPC_URL_8453=https://base-mainnet.g.alchemy.com/v2/YOUR_KEY # Base
# EVM_RPC_URL_42161=https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY # Arbitrum

# Tron — default: https://api.trongrid.io
# TVM_RPC_URL=https://api.trongrid.io

# Solana — default: https://api.mainnet-beta.solana.com
# SVM_RPC_URL=https://api.mainnet-beta.solana.com


# =============================================================================
# OPTIONAL: Quote Service Selection
# Controls which pricing endpoint is used for route quotes.
#
# Priority order (highest first):
# 1. SOLVER_URL — solver-v2 API at {SOLVER_URL}/api/v2/quote/reverse
# 2. QUOTES_PREPROD — preprod service at https://quotes-preprod.eco.com/...
# 3. (default) — production service at https://quotes.eco.com/...
#
# Unset all three to use the default production service.
# =============================================================================

# Solver v2 endpoint (takes precedence over all other quote service settings)
# SOLVER_URL=https://your-solver.example.com

# Set to any non-empty value to force the preprod quote service (ignored if SOLVER_URL is set)
# QUOTES_PREPROD=true
93 changes: 93 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: CI
on:
push:
branches: [main]
tags:
- 'v*'
pull_request:
branches: [main]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm test:coverage
- run: pnpm build
- run: pnpm audit --audit-level=moderate
e2e:
runs-on: ubuntu-latest
needs: quality
env:
FORK_RPC_URL: ${{ secrets.BASE_RPC_URL }}
FORK_BLOCK_NUMBER: '28000000'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm build
- name: Run E2E tests (Anvil managed by Jest global setup/teardown)
run: pnpm test:e2e:ci
release:
runs-on: ubuntu-latest
needs: quality
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
registry-url: 'https://registry.npmjs.org'
- run: pnpm install --frozen-lockfile
- run: pnpm build
- name: Publish to npm
run: pnpm publish --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
docs:
runs-on: ubuntu-latest
needs: quality
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- name: Generate API docs
run: pnpm docs
- uses: actions/configure-pages@v4
- uses: actions/upload-pages-artifact@v3
with:
path: docs/api
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
30 changes: 30 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Security Scan
on:
schedule:
- cron: '0 2 * * *'
push:
branches: [main]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm audit --audit-level=high
secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD
extra_args: --debug --only-verified
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ node_modules/

# Build output
dist/
bundle/

# Generated docs
docs/api/

# Environment files
.env
Expand Down Expand Up @@ -33,3 +37,4 @@ coverage/

CLAUDE.md
thoughts/
.worktrees/
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
npx lint-staged
pnpm typecheck
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18
Loading
Loading