This repository contains the Dart implementation of the x402 protocol, a machine-native payment standard designed for the modern web.
This library currently only supports V2 of the protocol. V1 was marked legacy and is unsupported.
x402 enables instant, automatic stablecoin payments directly over HTTP by reviving the HTTP 402 "Payment Required" status code. This implementation provides a suite of client-side libraries to integrate x402 payments into your Dart and Flutter applications.
- Protocol Homepage: x402.org
- Protocol Specification & Reference: github.com/coinbase/x402
This project is organized as a monorepo managed with Melos. It consists of several packages:
| Package | Description |
|---|---|
| x402 | Main entry point. The primary client-side package for most users. |
| x402_core | Core protocol definitions, models, and blockchain-agnostic interfaces. |
| x402_evm | EVM implementation supporting Ethereum and compatible chains (e.g., Base). |
| x402_svm | SVM implementation supporting Solana and compatible chains. |
| x402_dio | Dio-based client library providing an X402Interceptor. |
- Native Dart & Flutter: Built from the ground up for the Dart ecosystem.
- Multi-Chain: Seamlessly handle payments on both EVM and SVM networks.
- Automated Handshake: Use the
X402Clientto automatically parse requirements, negotiate signers, and retry requests. - Type-Safe Models: Robust serialization and validation for all protocol data structures.
For most use cases, you only need to add the main x402 package to your project:
dependencies:
x402: ^0.2.0If you prefer using Dio, you can use the x402_dio package:
dependencies:
x402: ^0.2.0 # For signers (EvmSigner, SvmSigner)
x402_dio: ^0.2.0 # For X402Interceptorimport 'package:x402/x402.dart';
void main() async {
final evmSigner = EvmSigner.fromPrivateKeyHex(chainId: 123, privateKeyHex: 'EVM_PRIVATE_KEY');
final svmSigner = await SvmSigner.fromPrivateKeyHex(privateKeyHex: 'SVM_PRIVATE_KEY', cluster: SolanaCluster.devnet);
final client = X402Client(
signers: [
evmSigner, // The first signer is checked first
svmSigner
],
onPaymentRequired: (req, resource, signer) async {
// Optional: Ask for user confirmation or add condition
return true;
},
);
final response = await client.get(Uri.parse('https://api.example.com/premium'));
if (response.statusCode == 200) {
print('Success: ${response.body}');
// HTTP 402 is automatically handled inside X402Client (payment + retry),
// so it will never reach this point and does not need to be checked here.
} else {
print('Request failed (${response.statusCode}): ${response.body}');
}
}Detailed examples for both automated and manual flows can be found in the examples folder. End-to-end tests can be found in the e2e folder.
This repo uses Melos for workspace management.
# Bootstrap the workspace
melos bootstrap
# Run all tests
melos run test
# Analyze all packages
melos run analyze
# Format all Dart files
melos formatThis project is licensed under the Apache-2.0 License - see the LICENSE file for details.