Skip to content

feat: pay to a crypto address using atomic swap#39

Merged
rolznz merged 1 commit into
masterfrom
feat/pay-crypto
May 29, 2026
Merged

feat: pay to a crypto address using atomic swap#39
rolznz merged 1 commit into
masterfrom
feat/pay-crypto

Conversation

@rolznz
Copy link
Copy Markdown
Member

@rolznz rolznz commented May 28, 2026

Closes #29

  • Topup your debit card with your agent
  • Possibly pay for x402/MPP endpoints?
yarn dev pay-crypto 0xXXXXXXXXXXXXXXXXXXXX -a 2 --currency USDC --network arbitrum
{
  "swap_id": "ddb301c6-df67-4dd3-91bb-5c08cd86062a",
  "status": "completed",
  "target": {
    "address": "0x78C01B70e43b7BD68c648cfa456D3c9Af99F67bC",
    "currency": "USDC",
    "network": "Arbitrum",
    "amount": 2
  }
}

Summary by CodeRabbit

  • New Features

    • Introduced a new "pay-crypto" CLI command enabling cross-currency payments, allowing users to send cryptocurrency to blockchain addresses with configurable amounts and networks while validating address formats and supported currency pairs.
  • Tests

    • Added test suite covering validation scenarios for the new command, including address formats, payment amounts, and supported currency-network combinations.

Review Change Stack

@rolznz rolznz requested review from bumi and reneaaron May 28, 2026 16:01
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

📝 Walkthrough

Walkthrough

This PR adds a complete Lightning-to-EVM atomic swap feature. It introduces the Lendaswap SDK dependency, implements a swap orchestration module with pair discovery and validation, registers a new pay-crypto CLI command, and includes integration tests validating the full command flow with mock API responses.

Changes

Lightning to EVM Swap Feature

Layer / File(s) Summary
Lendaswap SDK integration and swap orchestration
src/lendaswap/swap.ts, package.json
Configures SDK client with in-memory storage, discovers supported Lightning→EVM token pairs via API, validates EVM addresses and currency/network combinations, constructs swap requests, and orchestrates the full swap lifecycle: subscription → invoice payment → claim triggering → status monitoring. Adds Lendaswap SDK dependency.
Pay-crypto CLI command implementation
src/commands/pay-crypto.ts
Registers the pay-crypto command with commander, parsing recipient address (required) and --amount/--currency/--network options (with defaults). Validates inputs against supported pairs, invokes the swap via NWC wallet client, and outputs swap completion details.
CLI integration, registration, and validation tests
src/index.ts, src/test/pay-crypto.test.ts
Wires the pay-crypto command into a new "Cross-Currency Payments" command group. Includes integration tests with a mock Lendaswap API server validating unsupported currency/network rejection, malformed address rejection, invalid amount rejection, and the happy-path reaching wallet-load validation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A swap from Lightning bright,
Through Lendaswap's SDK flight,
CLI commands now handle the load,
EVM tokens on the road,
Atomic magic done right! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a feature to pay to a crypto address using atomic swap, which is the primary focus of all modifications.
Linked Issues check ✅ Passed The pull request implements the primary objective from issue #29 by adding functionality to pay with an atomic swap to a crypto address, including validation, swap creation, and invoice payment.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the pay-crypto atomic swap feature: CLI command registration, swap logic, dependencies, and tests for the feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/pay-crypto

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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
Contributor

@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

🧹 Nitpick comments (1)
src/lendaswap/swap.ts (1)

154-154: 💤 Low value

Consider making the referral code configurable.

The referral code is hardcoded. If this code identifies the integration partner or revenue share, it might need to vary by deployment context (staging vs production, different integrators, etc.).

Consider allowing override via environment variable or configuration parameter.

♻️ Optional enhancement to support environment override
+const REFERRAL_CODE = process.env.LENDASWAP_REFERRAL_CODE || "lnds_2c07e38f10a28d47";
+
 async function createPaymentSwap(params: {
   pair: SupportedPair;
   amount: number;
   targetAddress: string;
 }): Promise<LightningToEvmSwapResponse> {
   const client = await getClient();
   const targetAmount = toSmallestUnit(params.amount, params.pair.decimals);

   const targetAsset: Asset = {
     chain: params.pair.chain,
     tokenId: params.pair.tokenId,
   };

   const result = await client.createSwap({
     source: Asset.BTC_LIGHTNING,
     target: targetAsset,
     targetAmount,
     targetAddress: params.targetAddress,
     gasless: true,
-    referralCode: "lnds_2c07e38f10a28d47",
+    referralCode: REFERRAL_CODE,
   });
🤖 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 `@src/lendaswap/swap.ts` at line 154, The referralCode value is hardcoded in
swap.ts (referralCode: "lnds_2c07e38f10a28d47"); make it configurable by reading
a config or environment variable (e.g., process.env.LENDASWAP_REFERRAL_CODE) and
falling back to the current default; update the code that constructs the
payload/object containing referralCode (search for the referralCode symbol in
swap.ts) to use the config/env value and add a brief comment and a
unit/integration test or env-var mention in documentation to ensure deployments
can override it.
🤖 Prompt for all review comments with 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.

Inline comments:
In `@src/lendaswap/swap.ts`:
- Around line 131-133: The toSmallestUnit(amount: number, decimals: number)
function can overflow Number.MAX_SAFE_INTEGER when amount * 10**decimals is
large; update it to either use BigInt/BigNumber math or validate inputs and
reject amounts that would exceed safe integer range. Specifically, compute or
estimate the scaled value bounds (e.g., via Number.MAX_SAFE_INTEGER /
10**decimals) and throw a clear error from toSmallestUnit when amount is too
large or decimals too high, or change the implementation to return a
BigInt/string using BigInt( Math.round(...) ) or a BigNumber library so you
preserve precision for values like 1e12 with 6+ decimals.
- Around line 1-11: The package version for `@lendasat/lendaswap-sdk-pure`
referenced by the imports (Asset, Client, InMemorySwapStorage,
InMemoryWalletStorage, LightningToEvmSwapResponse, SwapStatus,
SwapStatusHandler, toChain, toChainName) appears unpublished; update the
dependency in package.json to a published tag (e.g., a confirmed published
version such as 0.2.24 or the latest published), run npm install to update
lockfile, then verify that all imported symbols (Client, Asset, toChain,
toChainName, InMemorySwapStorage, InMemoryWalletStorage, etc.) still exist in
that released version and adjust imports if names changed, and finally re-run
your advisory/CVE scan against the chosen exact version.

---

Nitpick comments:
In `@src/lendaswap/swap.ts`:
- Line 154: The referralCode value is hardcoded in swap.ts (referralCode:
"lnds_2c07e38f10a28d47"); make it configurable by reading a config or
environment variable (e.g., process.env.LENDASWAP_REFERRAL_CODE) and falling
back to the current default; update the code that constructs the payload/object
containing referralCode (search for the referralCode symbol in swap.ts) to use
the config/env value and add a brief comment and a unit/integration test or
env-var mention in documentation to ensure deployments can override it.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2c9f6e10-43eb-4156-9427-4f085878e8fc

📥 Commits

Reviewing files that changed from the base of the PR and between 3dcc22f and 38b8059.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • package.json
  • src/commands/pay-crypto.ts
  • src/index.ts
  • src/lendaswap/swap.ts
  • src/test/pay-crypto.test.ts

Comment thread src/lendaswap/swap.ts
Comment thread src/lendaswap/swap.ts
@rolznz rolznz merged commit 3084f84 into master May 29, 2026
2 checks passed
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.

Pay with Satora atomic swap

1 participant