Skip to content

Commit 0b39ab0

Browse files
Update examples for clients (axios,fetch) and servers(express) to support Stellar
1 parent ec4114f commit 0b39ab0

File tree

8 files changed

+47
-15
lines changed

8 files changed

+47
-15
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
RESOURCE_SERVER_URL=http://localhost:4021
22
ENDPOINT_PATH=/weather
3+
NETWORK=base-sepolia
34
PRIVATE_KEY=

examples/typescript/clients/axios/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { withPaymentInterceptor, decodeXPaymentResponse, createSigner, type Hex
44

55
config();
66

7+
const network = (process.env.NETWORK || "base-sepolia") as string; // e.g. base-sepolia, or solana-devnet, or stellar-testnet
78
const privateKey = process.env.PRIVATE_KEY as Hex | string;
89
const baseURL = process.env.RESOURCE_SERVER_URL as string; // e.g. https://example.com
910
const endpointPath = process.env.ENDPOINT_PATH as string; // e.g. /weather
@@ -20,11 +21,11 @@ if (!baseURL || !privateKey || !endpointPath) {
2021
* - PRIVATE_KEY: The private key of the signer
2122
* - RESOURCE_SERVER_URL: The URL of the resource server
2223
* - ENDPOINT_PATH: The path of the endpoint to call on the resource server
24+
* - NETWORK: The network to use for the signer (e.g. base-sepolia, solana-devnet, stellar-testnet)
2325
*
2426
*/
2527
async function main(): Promise<void> {
26-
// const signer = await createSigner("solana-devnet", privateKey); // uncomment for solana
27-
const signer = await createSigner("base-sepolia", privateKey);
28+
const signer = await createSigner(network, privateKey);
2829

2930
const api = withPaymentInterceptor(
3031
axios.create({
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
RESOURCE_SERVER_URL=http://localhost:4021
22
ENDPOINT_PATH=/weather
3+
NETWORK=base-sepolia
34
PRIVATE_KEY=

examples/typescript/clients/fetch/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { decodeXPaymentResponse, wrapFetchWithPayment, createSigner, type Hex }
33

44
config();
55

6+
const network = (process.env.NETWORK || "base-sepolia") as string; // e.g. base-sepolia, or solana-devnet, or stellar-testnet
67
const privateKey = process.env.PRIVATE_KEY as Hex | string;
78
const baseURL = process.env.RESOURCE_SERVER_URL as string; // e.g. https://example.com
89
const endpointPath = process.env.ENDPOINT_PATH as string; // e.g. /weather
@@ -20,10 +21,11 @@ if (!baseURL || !privateKey || !endpointPath) {
2021
* - PRIVATE_KEY: The private key of the signer
2122
* - RESOURCE_SERVER_URL: The URL of the resource server
2223
* - ENDPOINT_PATH: The path of the endpoint to call on the resource server
24+
* - NETWORK: The network to use for the signer (e.g. base-sepolia, solana-devnet, stellar-testnet)
25+
*
2326
*/
2427
async function main(): Promise<void> {
25-
// const signer = await createSigner("solana-devnet", privateKey); // uncomment for solana
26-
const signer = await createSigner("base-sepolia", privateKey);
28+
const signer = await createSigner(network, privateKey);
2729
const fetchWithPayment = wrapFetchWithPayment(fetch, signer);
2830

2931
const response = await fetchWithPayment(url, { method: "GET" });
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
EVM_PRIVATE_KEY=0xYourPrivateKey
22
SVM_PRIVATE_KEY=base58EncodedSolanaPrivateKey
3+
STELLAR_PRIVATE_KEY=base32EncodedStellarPrivateKey
34
PORT=3002

examples/typescript/facilitator/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ cd facilitator
4444
```env
4545
EVM_PRIVATE_KEY=0xYourPrivateKey
4646
SVM_PRIVATE_KEY=base58EncodedSolanaPrivateKey
47+
STELLAR_PRIVATE_KEY=base32EncodedStellarPrivateKey
4748
```
4849

4950
3. Start the server:

examples/typescript/facilitator/index.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,31 @@ import {
1616
SupportedPaymentKind,
1717
isSvmSignerWallet,
1818
type X402Config,
19+
SupportedStellarNetworks,
20+
StellarConnectedClient,
1921
} from "x402/types";
2022

2123
config();
2224

2325
const EVM_PRIVATE_KEY = process.env.EVM_PRIVATE_KEY || "";
2426
const SVM_PRIVATE_KEY = process.env.SVM_PRIVATE_KEY || "";
2527
const SVM_RPC_URL = process.env.SVM_RPC_URL || "";
28+
const STELLAR_PRIVATE_KEY = process.env.STELLAR_PRIVATE_KEY || "";
29+
const STELLAR_RPC_URL = process.env.STELLAR_RPC_URL || "";
2630

27-
if (!EVM_PRIVATE_KEY && !SVM_PRIVATE_KEY) {
31+
if (!EVM_PRIVATE_KEY && !SVM_PRIVATE_KEY && !STELLAR_PRIVATE_KEY) {
2832
console.error("Missing required environment variables");
2933
process.exit(1);
3034
}
3135

3236
// Create X402 config with custom RPC URL if provided
33-
const x402Config: X402Config | undefined = SVM_RPC_URL
34-
? { svmConfig: { rpcUrl: SVM_RPC_URL } }
35-
: undefined;
37+
const x402Config: X402Config | undefined =
38+
SVM_RPC_URL || STELLAR_RPC_URL
39+
? {
40+
svmConfig: { rpcUrl: SVM_RPC_URL },
41+
stellarConfig: { rpcUrl: STELLAR_RPC_URL },
42+
}
43+
: undefined;
3644

3745
const app = express();
3846

@@ -73,6 +81,8 @@ app.post("/verify", async (req: Request, res: Response) => {
7381
client = createConnectedClient(paymentRequirements.network);
7482
} else if (SupportedSVMNetworks.includes(paymentRequirements.network)) {
7583
client = await createSigner(paymentRequirements.network, SVM_PRIVATE_KEY);
84+
} else if (SupportedStellarNetworks.includes(paymentRequirements.network)) {
85+
client = await createSigner(paymentRequirements.network, STELLAR_PRIVATE_KEY);
7686
} else {
7787
throw new Error("Invalid network");
7888
}
@@ -123,6 +133,22 @@ app.get("/supported", async (req: Request, res: Response) => {
123133
},
124134
});
125135
}
136+
137+
// stellar
138+
if (STELLAR_PRIVATE_KEY) {
139+
const client = createConnectedClient("stellar-testnet", x402Config) as StellarConnectedClient;
140+
const latestLedgerNumber = (await client.getLatestLedger()).sequence;
141+
142+
kinds.push({
143+
x402Version: 1,
144+
scheme: "exact",
145+
network: "stellar-testnet",
146+
extra: {
147+
maxLedger: latestLedgerNumber + 12,
148+
},
149+
});
150+
}
151+
126152
res.json({
127153
kinds,
128154
});
@@ -140,6 +166,8 @@ app.post("/settle", async (req: Request, res: Response) => {
140166
signer = await createSigner(paymentRequirements.network, EVM_PRIVATE_KEY);
141167
} else if (SupportedSVMNetworks.includes(paymentRequirements.network)) {
142168
signer = await createSigner(paymentRequirements.network, SVM_PRIVATE_KEY);
169+
} else if (SupportedStellarNetworks.includes(paymentRequirements.network)) {
170+
signer = await createSigner(paymentRequirements.network, STELLAR_PRIVATE_KEY);
143171
} else {
144172
throw new Error("Invalid network");
145173
}

examples/typescript/servers/express/index.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { config } from "dotenv";
22
import express from "express";
3-
import { paymentMiddleware, Resource, type SolanaAddress } from "x402-express";
3+
import { Network, paymentMiddleware, Resource, type SolanaAddress } from "x402-express";
44
config();
55

6+
const network = (process.env.NETWORK || "base-sepolia") as Network;
67
const facilitatorUrl = process.env.FACILITATOR_URL as Resource;
78
const payTo = process.env.ADDRESS as `0x${string}` | SolanaAddress;
89

@@ -20,9 +21,7 @@ app.use(
2021
"GET /weather": {
2122
// USDC amount in dollars
2223
price: "$0.001",
23-
// network: "base" // uncomment for Base mainnet
24-
// network: "solana" // uncomment for Solana mainnet
25-
network: "base-sepolia",
24+
network,
2625
},
2726
"/premium/*": {
2827
// Define atomic amounts in any EIP-3009 token
@@ -38,9 +37,7 @@ app.use(
3837
},
3938
},
4039
},
41-
// network: "base" // uncomment for Base mainnet
42-
// network: "solana" // uncomment for Solana mainnet
43-
network: "base-sepolia",
40+
network,
4441
},
4542
},
4643
{

0 commit comments

Comments
 (0)