feat(hedera): add initial @x402/hedera package#1360
feat(hedera): add initial @x402/hedera package#1360piotrswierzy wants to merge 12 commits intox402-foundation:mainfrom
Conversation
🟡 Heimdall Review Status
|
|
@piotrswierzy is attempting to deploy a commit to the Coinbase Team on Vercel. A member of the Team first needs to authorize it. |
|
Review Error for skurzyp-blockydevs @ 2026-03-12 14:43:04 UTC |
typescript/packages/mechanisms/hedera/src/exact/client/register.ts
Outdated
Show resolved
Hide resolved
| if (requirementsValidation !== null) { | ||
| return requirementsValidation; | ||
| } | ||
| const feePayer = requirements.extra.feePayer as string; |
There was a problem hiding this comment.
I don't like this casting. Maybe we should extend PaymentRequirements with own type and guards to be sure that extra.feePayer exist?
There was a problem hiding this comment.
SVM does it the same way
typescript/packages/mechanisms/hedera/src/exact/facilitator/register.ts
Outdated
Show resolved
Hide resolved
|
Review Error for kierzniak @ 2026-03-16 11:45:39 UTC |
|
Thanks a lot for the contribution @piotrswierzy, I'll begin reviewing shortly. A few initial comments:
|
|
@phdargen |
|
|
||
| Example client demonstrating how to use `@x402/fetch` to make HTTP requests to endpoints protected by the x402 payment protocol. | ||
|
|
||
| ```typescript |
There was a problem hiding this comment.
please revert changes in this file, seems unrelated
|
|
||
| Example client demonstrating how to use `@x402/axios` to make HTTP requests to endpoints protected by the x402 payment protocol. | ||
|
|
||
| ```typescript |
| @@ -0,0 +1,358 @@ | |||
| import { beforeEach, describe, expect, it } from "vitest"; | |||
There was a problem hiding this comment.
In the TS package root package.json please add hedera integration test here:
"test:integration": "pnpm --filter @x402/core --filter @x402/evm --filter @x402/svm --filter @x402/aptos --filter @x402/stellar test:integration",
| price: string | { amount: string; asset: string; extra?: Record<string, unknown> }; | ||
| network: `${string}:${string}`; |
There was a problem hiding this comment.
| price: string | { amount: string; asset: string; extra?: Record<string, unknown> }; | |
| network: `${string}:${string}`; | |
| price: Price; | |
| network: Network; |
with import type { Network, Price } from "@x402/core/types";
| @@ -1,4 +1,5 @@ | |||
| EVM_ADDRESS= | |||
| SVM_ADDRESS= | |||
| HEDERA_ADDRESS= | |||
There was a problem hiding this comment.
Took me a while to get the examples/e2e tests running, they fail when using an address like
HEDERA_ADDRESS=0x3f376c1e06b5495f2a015975671cc53f61e8e351
This address was accepted by the faucet (https://portal.hedera.com/faucet), so seems to be a valid address. I created it with PrivateKey.generateECDSA() from @hiero-ledger/sdk
I then had claude write me a script to fetch the accountId from the API
https://testnet.mirrornode.hedera.com/api/v1/accounts/ (any easier, more straightforward way to setup the accounts?)
With this the examples/e2e tests ran successfully
HEDERA_ADDRESS=0.0.8450511
Is HEDERA_ADDRESS supposed to accept both formats? Or just account ids? Then env vars should be renamed to HEDERA_ACCOUNT_ID
There was a problem hiding this comment.
Please also put a link to the faucet in the appropriate READMEs
|
There have been some changes to the e2e route structure, see https://github.com/coinbase/x402/pull/1779. Please also add e2e tests for the remaining server packages hono/next/fastify |
| } | ||
|
|
||
| tx.setTransactionId(TransactionId.generate(AccountId.fromString(feePayer))); | ||
| tx.setTransactionMemo(`x402:${Date.now().toString(36)}`); |
There was a problem hiding this comment.
A transaction memo isnt mentioned in the specs, is this needed? Does it incur any additional tx costs? Should there be any constraints enforced by the facilitator on memo format and size?
| payer: "", | ||
| }; | ||
| } | ||
| const inspectedValidation = this.validateInspectedTransaction(inspected); |
There was a problem hiding this comment.
I think we should check the client set txFee here and reject if above a reasonable threshold, similar to SVM. Otherwise malicious client could set it arbitrarily large and grief the facilitator
| if (payToValidation !== null) { | ||
| return payToValidation; | ||
| } | ||
|
|
There was a problem hiding this comment.
Could we add tx simulation here or at least a balance check to protect the server from doing work for invalid requests?
| * @param transactionId - Hedera transaction id | ||
| * @returns Failed verify response or null | ||
| */ | ||
| private async validateReplay(transactionId: string): Promise<VerifyResponse | null> { |
There was a problem hiding this comment.
Not sure about this replay protection mechanism.
Could you please elaborate why this is needed in the first place? Is this security critical or an optimization?
If a client sends the exact same tx multiple times, and the tx hasn't reached a confirmed state onchain yet, would settle return success for all even though only one actually settles and client pays only once?
If that's the case, could we align the implementation with the in-memory cache introduced for SVM in
https://github.com/coinbase/x402/pull/1468?
If a client sends a request and tx confirms onchain, then sends a request with exact same payload again, would settle fail? If we add simulation to verify would it fail for the duplicate tx? If so, do we still need the replay mechanism?
| * @param network - Hedera network | ||
| * @returns AssetAmount in configured default HTS token | ||
| */ | ||
| private defaultMoneyConversion(amount: number, network: Network): AssetAmount { |
There was a problem hiding this comment.
could we define any default stablecoin for the moneyParser here as for all the other networks?
|
Hi @piotrswierzy, nice work! Made a first pass through the code and manually tested the examples/e2e tests, please find a few comments/suggestions above |
…eme support- Introduced the @x402/hedera package implementing the x402 v2 exact payment scheme for Hedera.- Added client, server, and facilitator implementations along with necessary utilities and types.- Included configuration files for ESLint, Prettier, and Vitest.- Created documentation in README and CHANGELOG for package usage and features.- Established a .prettierignore file to exclude specific directories and file types from formatting checks. Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
- Introduced a new .env.test file for configuring ECDSA keys required for live integration tests. - Updated README to include instructions for setting up the environment and running integration tests. - Modified the createClientHederaSigner function to accept PrivateKey objects instead of strings for better type safety. - Enhanced error handling in ExactHederaScheme to manage unsupported network values and unexpected HBAR transfers. Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
…d clean up unused dependencies Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
…ilitators- Added support for Hedera payments in advanced clients (axios, fetch, advanced).- Updated environment variables to include HEDERA_ACCOUNT_ID, HEDERA_PRIVATE_KEY, and HEDERA_NETWORK.- Implemented Hedera signing and transaction handling in all relevant files.- Enhanced README documentation to reflect new Hedera configurations and requirements.This update allows users to interact with the Hedera network alongside existing EVM and SVM functionalities. Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
…ross all relevant files - Updated imports in various client and facilitator files to use @hiero-ledger/sdk instead of @hashgraph/sdk. - Adjusted README documentation to reflect the new SDK usage. - Removed obsolete .env.test file related to Hedera integration tests. - Updated pnpm-lock.yaml to reflect the new dependency version for @hiero-ledger/sdk. This change enhances compatibility and aligns with the latest SDK updates. Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
…ted pnpm-lock.yaml to reflect the new versioning for axios and @hiero-ledger/sdk.- Replaced instances of @hashgraph/sdk with @hiero-ledger/sdk in package.json files across clients and facilitators.- Enhanced network handling in the Hedera signer and utility functions to assert supported networks.- Refactored code to improve clarity and maintainability, including the removal of unused functions.This update ensures better compatibility with the latest SDK and improves the overall robustness of the Hedera integration. Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
…essary line breaks in imports within , , and .- Added a newline at the end of to comply with formatting standards. Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
…f to comply with formatting standards. Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
…age- Removed unnecessary imports from utils.ts.- Updated parameter naming in createPaymentPayload method for clarity.Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com> Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
…payment capabilities across various components including clients, facilitators, and servers.- Updated environment variables and configurations to include Hedera account and private key.- Enhanced README and documentation to reflect new Hedera protocol support.- Modified test configurations to include Hedera endpoints and payment requirements.This update expands the multi-chain support of the application, allowing for seamless integration with the Hedera network. Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
Expand Hedera e2e test coverage to Hono and Next.js servers, aligning
with the new /exact/{chain} route naming convention from x402-foundation#1779.
- Hono: add ExactHederaScheme import, env vars, registration, guard,
middleware config, route handler, and test.config.json endpoint
- Next.js: add proxy route (/api/exact/hedera), withX402 wrapper route,
scheme registration in proxy.ts, and test.config.json endpoints
- Update package.json dependencies for both servers
- Update .env-local templates with HEDERA_PAYEE_ADDRESS
Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
c4dff0d to
3c868fa
Compare
- Revert unrelated README changes in axios/fetch client examples
- Add @x402/hedera to root test:integration filter
- Use imported Network/Price types in server example instead of inline
- Rename HEDERA_ADDRESS to HEDERA_ACCOUNT_ID for clarity, add faucet link
- Add USDC as default stablecoin for Hedera money conversion
(testnet: 0.0.429274, mainnet: 0.0.456858, 6 decimals)
Signed-off-by: Piotr Swierzy <piotr.swierzy@blockydevs.com>
add initial @x402/hedera package with exact payment scheme support
Description
Tests
Checklist