@alleyboss/micropay-solana-x402-paywall 3.3.0 → 3.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/client/index.cjs +17 -5
- package/dist/client/index.js +17 -5
- package/dist/index.cjs +17 -5
- package/dist/index.js +17 -5
- package/dist/next/index.cjs +33 -5
- package/dist/next/index.js +33 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -186,6 +186,7 @@ function PaywallBanner({ priceInLamports }) {
|
|
|
186
186
|
|
|
187
187
|
We're actively working on these exciting features:
|
|
188
188
|
|
|
189
|
+
### Core Features
|
|
189
190
|
| Feature | Status | Description |
|
|
190
191
|
|---------|--------|-------------|
|
|
191
192
|
| ⚡ **Jupiter Swap-on-Pay** | 🔜 Coming Soon | Pay with any token, auto-swap to SOL/USDC |
|
|
@@ -194,6 +195,20 @@ We're actively working on these exciting features:
|
|
|
194
195
|
| 🌳 **Compressed NFTs** | 🔜 Planned | Scalable access tokens via cNFTs |
|
|
195
196
|
| 🔄 **Payment Streaming** | 🔜 Planned | Pay-as-you-consume for APIs |
|
|
196
197
|
|
|
198
|
+
### For Solana Power Users
|
|
199
|
+
| Feature | Status | Description |
|
|
200
|
+
|---------|--------|-------------|
|
|
201
|
+
| 🚀 **Jito Bundle Support** | 🔜 Planned | Guaranteed transaction inclusion via MEV |
|
|
202
|
+
| 📡 **WebSocket Confirmations** | 🔜 Planned | Real-time confirmation, no polling |
|
|
203
|
+
| 📋 **Lookup Tables** | 🔜 Planned | Batch payments efficiency for agents |
|
|
204
|
+
|
|
205
|
+
### For x402 Protocol Ecosystem
|
|
206
|
+
| Feature | Status | Description |
|
|
207
|
+
|---------|--------|-------------|
|
|
208
|
+
| 💳 **Coinbase Commerce** | 🔜 Planned | Accept payments via Coinbase Pay |
|
|
209
|
+
| 🤖 **CDP Agent Wallets** | 🔜 Planned | Coinbase Developer Platform integration |
|
|
210
|
+
| 🔷 **Base Network Support** | 🔜 Planned | EVM x402 payments on Base L2 |
|
|
211
|
+
|
|
197
212
|
Want to contribute or sponsor a feature? Open an issue on [GitHub](https://github.com/AlleyBo55/micropay-solana-x402-paywall)!
|
|
198
213
|
|
|
199
214
|
## 📚 Documentation
|
package/dist/client/index.cjs
CHANGED
|
@@ -179,17 +179,29 @@ function usePaywallResource({
|
|
|
179
179
|
const res = await fetch(url, { headers });
|
|
180
180
|
if (res.status === 402) {
|
|
181
181
|
const wwwAuth = res.headers.get("WWW-Authenticate");
|
|
182
|
+
console.log("[usePaywallResource] 402 Response. WWW-Authenticate:", wwwAuth);
|
|
182
183
|
if (wwwAuth) {
|
|
183
184
|
setPaymentHeader(wwwAuth);
|
|
184
185
|
try {
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
const { decodePaymentRequiredHeader: decodePaymentRequiredHeader2 } = await import('@x402/core/http');
|
|
187
|
+
const cleanHeader = wwwAuth.replace(/^[Xx]402\s+/, "");
|
|
188
|
+
const decoded = decodePaymentRequiredHeader2(cleanHeader);
|
|
189
|
+
console.log("[usePaywallResource] Decoded header:", decoded);
|
|
190
|
+
const accepts = Array.isArray(decoded.accepts) ? decoded.accepts[0] : decoded.accepts;
|
|
191
|
+
console.log("[usePaywallResource] Accepts:", accepts);
|
|
192
|
+
if (accepts) {
|
|
193
|
+
const amountStr = accepts.amount || accepts.price || accepts.maxAmountRequired || "0";
|
|
194
|
+
setPrice(BigInt(amountStr));
|
|
195
|
+
setRecipient(accepts.payTo);
|
|
196
|
+
console.log("[usePaywallResource] Set price:", amountStr, "recipient:", accepts.payTo);
|
|
197
|
+
} else {
|
|
198
|
+
console.warn("[usePaywallResource] No accepts found in header");
|
|
189
199
|
}
|
|
190
200
|
} catch (e) {
|
|
191
|
-
console.warn("Failed to parse
|
|
201
|
+
console.warn("[usePaywallResource] Failed to parse x402 header:", e);
|
|
192
202
|
}
|
|
203
|
+
} else {
|
|
204
|
+
console.warn("[usePaywallResource] 402 response missing WWW-Authenticate header");
|
|
193
205
|
}
|
|
194
206
|
setIsLocked(true);
|
|
195
207
|
setData(null);
|
package/dist/client/index.js
CHANGED
|
@@ -177,17 +177,29 @@ function usePaywallResource({
|
|
|
177
177
|
const res = await fetch(url, { headers });
|
|
178
178
|
if (res.status === 402) {
|
|
179
179
|
const wwwAuth = res.headers.get("WWW-Authenticate");
|
|
180
|
+
console.log("[usePaywallResource] 402 Response. WWW-Authenticate:", wwwAuth);
|
|
180
181
|
if (wwwAuth) {
|
|
181
182
|
setPaymentHeader(wwwAuth);
|
|
182
183
|
try {
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
184
|
+
const { decodePaymentRequiredHeader: decodePaymentRequiredHeader2 } = await import('@x402/core/http');
|
|
185
|
+
const cleanHeader = wwwAuth.replace(/^[Xx]402\s+/, "");
|
|
186
|
+
const decoded = decodePaymentRequiredHeader2(cleanHeader);
|
|
187
|
+
console.log("[usePaywallResource] Decoded header:", decoded);
|
|
188
|
+
const accepts = Array.isArray(decoded.accepts) ? decoded.accepts[0] : decoded.accepts;
|
|
189
|
+
console.log("[usePaywallResource] Accepts:", accepts);
|
|
190
|
+
if (accepts) {
|
|
191
|
+
const amountStr = accepts.amount || accepts.price || accepts.maxAmountRequired || "0";
|
|
192
|
+
setPrice(BigInt(amountStr));
|
|
193
|
+
setRecipient(accepts.payTo);
|
|
194
|
+
console.log("[usePaywallResource] Set price:", amountStr, "recipient:", accepts.payTo);
|
|
195
|
+
} else {
|
|
196
|
+
console.warn("[usePaywallResource] No accepts found in header");
|
|
187
197
|
}
|
|
188
198
|
} catch (e) {
|
|
189
|
-
console.warn("Failed to parse
|
|
199
|
+
console.warn("[usePaywallResource] Failed to parse x402 header:", e);
|
|
190
200
|
}
|
|
201
|
+
} else {
|
|
202
|
+
console.warn("[usePaywallResource] 402 response missing WWW-Authenticate header");
|
|
191
203
|
}
|
|
192
204
|
setIsLocked(true);
|
|
193
205
|
setData(null);
|
package/dist/index.cjs
CHANGED
|
@@ -191,17 +191,29 @@ function usePaywallResource({
|
|
|
191
191
|
const res = await fetch(url, { headers });
|
|
192
192
|
if (res.status === 402) {
|
|
193
193
|
const wwwAuth = res.headers.get("WWW-Authenticate");
|
|
194
|
+
console.log("[usePaywallResource] 402 Response. WWW-Authenticate:", wwwAuth);
|
|
194
195
|
if (wwwAuth) {
|
|
195
196
|
setPaymentHeader(wwwAuth);
|
|
196
197
|
try {
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
198
|
+
const { decodePaymentRequiredHeader: decodePaymentRequiredHeader2 } = await import('@x402/core/http');
|
|
199
|
+
const cleanHeader = wwwAuth.replace(/^[Xx]402\s+/, "");
|
|
200
|
+
const decoded = decodePaymentRequiredHeader2(cleanHeader);
|
|
201
|
+
console.log("[usePaywallResource] Decoded header:", decoded);
|
|
202
|
+
const accepts = Array.isArray(decoded.accepts) ? decoded.accepts[0] : decoded.accepts;
|
|
203
|
+
console.log("[usePaywallResource] Accepts:", accepts);
|
|
204
|
+
if (accepts) {
|
|
205
|
+
const amountStr = accepts.amount || accepts.price || accepts.maxAmountRequired || "0";
|
|
206
|
+
setPrice(BigInt(amountStr));
|
|
207
|
+
setRecipient(accepts.payTo);
|
|
208
|
+
console.log("[usePaywallResource] Set price:", amountStr, "recipient:", accepts.payTo);
|
|
209
|
+
} else {
|
|
210
|
+
console.warn("[usePaywallResource] No accepts found in header");
|
|
201
211
|
}
|
|
202
212
|
} catch (e) {
|
|
203
|
-
console.warn("Failed to parse
|
|
213
|
+
console.warn("[usePaywallResource] Failed to parse x402 header:", e);
|
|
204
214
|
}
|
|
215
|
+
} else {
|
|
216
|
+
console.warn("[usePaywallResource] 402 response missing WWW-Authenticate header");
|
|
205
217
|
}
|
|
206
218
|
setIsLocked(true);
|
|
207
219
|
setData(null);
|
package/dist/index.js
CHANGED
|
@@ -185,17 +185,29 @@ function usePaywallResource({
|
|
|
185
185
|
const res = await fetch(url, { headers });
|
|
186
186
|
if (res.status === 402) {
|
|
187
187
|
const wwwAuth = res.headers.get("WWW-Authenticate");
|
|
188
|
+
console.log("[usePaywallResource] 402 Response. WWW-Authenticate:", wwwAuth);
|
|
188
189
|
if (wwwAuth) {
|
|
189
190
|
setPaymentHeader(wwwAuth);
|
|
190
191
|
try {
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
192
|
+
const { decodePaymentRequiredHeader: decodePaymentRequiredHeader2 } = await import('@x402/core/http');
|
|
193
|
+
const cleanHeader = wwwAuth.replace(/^[Xx]402\s+/, "");
|
|
194
|
+
const decoded = decodePaymentRequiredHeader2(cleanHeader);
|
|
195
|
+
console.log("[usePaywallResource] Decoded header:", decoded);
|
|
196
|
+
const accepts = Array.isArray(decoded.accepts) ? decoded.accepts[0] : decoded.accepts;
|
|
197
|
+
console.log("[usePaywallResource] Accepts:", accepts);
|
|
198
|
+
if (accepts) {
|
|
199
|
+
const amountStr = accepts.amount || accepts.price || accepts.maxAmountRequired || "0";
|
|
200
|
+
setPrice(BigInt(amountStr));
|
|
201
|
+
setRecipient(accepts.payTo);
|
|
202
|
+
console.log("[usePaywallResource] Set price:", amountStr, "recipient:", accepts.payTo);
|
|
203
|
+
} else {
|
|
204
|
+
console.warn("[usePaywallResource] No accepts found in header");
|
|
195
205
|
}
|
|
196
206
|
} catch (e) {
|
|
197
|
-
console.warn("Failed to parse
|
|
207
|
+
console.warn("[usePaywallResource] Failed to parse x402 header:", e);
|
|
198
208
|
}
|
|
209
|
+
} else {
|
|
210
|
+
console.warn("[usePaywallResource] 402 response missing WWW-Authenticate header");
|
|
199
211
|
}
|
|
200
212
|
setIsLocked(true);
|
|
201
213
|
setData(null);
|
package/dist/next/index.cjs
CHANGED
|
@@ -20,20 +20,48 @@ var LocalSvmFacilitator = class {
|
|
|
20
20
|
* Get supported payment kinds
|
|
21
21
|
* Mocking the response of the /supported endpoint
|
|
22
22
|
*/
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Network Constants - CAIP-2 format for x402 v2
|
|
25
|
+
* These match the official Solana chain IDs used by x402 protocol
|
|
26
|
+
*/
|
|
24
27
|
NETWORKS = {
|
|
25
28
|
DEVNET: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
|
|
26
29
|
MAINNET: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
|
|
27
30
|
};
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
/**
|
|
32
|
+
* DUMMY_FEE_PAYER Explanation (for auditors):
|
|
33
|
+
*
|
|
34
|
+
* In a HOSTED facilitator (like x402.org), the `feePayer` field in the
|
|
35
|
+
* SupportedResponse.extra specifies which address will pay transaction fees
|
|
36
|
+
* when the facilitator submits transactions on behalf of users.
|
|
37
|
+
*
|
|
38
|
+
* In LOCAL/SELF-SOVEREIGN mode (this implementation):
|
|
39
|
+
* - The USER pays their own transaction fees directly
|
|
40
|
+
* - The facilitator NEVER submits transactions - it only VERIFIES them
|
|
41
|
+
* - Therefore, no fee payer address is actually used
|
|
42
|
+
*
|
|
43
|
+
* However, the x402 protocol REQUIRES this field in the response schema.
|
|
44
|
+
* We use the System Program address (all 1s) as a placeholder because:
|
|
45
|
+
* 1. It's clearly not a real wallet (obvious placeholder)
|
|
46
|
+
* 2. It cannot receive funds or sign transactions
|
|
47
|
+
* 3. It signals to developers that fee paying is handled differently
|
|
48
|
+
*
|
|
49
|
+
* SECURITY NOTE: This is NOT a security risk because:
|
|
50
|
+
* - The fee payer is never used in verify() or settle() methods
|
|
51
|
+
* - Users sign and pay for their own transactions
|
|
52
|
+
* - The address is just a protocol-required placeholder
|
|
53
|
+
*
|
|
54
|
+
* @see https://docs.x402.org for protocol specification
|
|
55
|
+
*/
|
|
30
56
|
DUMMY_FEE_PAYER = "11111111111111111111111111111111";
|
|
31
57
|
/**
|
|
32
58
|
* Get supported payment kinds
|
|
33
59
|
* Returns x402 v2 compatible response with CAIP-2 network identifiers
|
|
60
|
+
*
|
|
61
|
+
* NOTE: The feePayer in extra.feePayer is a placeholder only.
|
|
62
|
+
* In self-sovereign mode, users pay their own transaction fees.
|
|
34
63
|
*/
|
|
35
64
|
async getSupported(_extensionKeys = []) {
|
|
36
|
-
console.log("[LocalSvmFacilitator] getSupported called");
|
|
37
65
|
const supported = {
|
|
38
66
|
kinds: [
|
|
39
67
|
{
|
|
@@ -51,10 +79,10 @@ var LocalSvmFacilitator = class {
|
|
|
51
79
|
],
|
|
52
80
|
extensions: [],
|
|
53
81
|
signers: {
|
|
82
|
+
// Placeholder - in self-sovereign mode, users are their own signers
|
|
54
83
|
"solana:*": [this.DUMMY_FEE_PAYER]
|
|
55
84
|
}
|
|
56
85
|
};
|
|
57
|
-
console.log("[LocalSvmFacilitator] Returning supported:", JSON.stringify(supported));
|
|
58
86
|
return supported;
|
|
59
87
|
}
|
|
60
88
|
/**
|
package/dist/next/index.js
CHANGED
|
@@ -19,20 +19,48 @@ var LocalSvmFacilitator = class {
|
|
|
19
19
|
* Get supported payment kinds
|
|
20
20
|
* Mocking the response of the /supported endpoint
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Network Constants - CAIP-2 format for x402 v2
|
|
24
|
+
* These match the official Solana chain IDs used by x402 protocol
|
|
25
|
+
*/
|
|
23
26
|
NETWORKS = {
|
|
24
27
|
DEVNET: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
|
|
25
28
|
MAINNET: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
|
|
26
29
|
};
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
/**
|
|
31
|
+
* DUMMY_FEE_PAYER Explanation (for auditors):
|
|
32
|
+
*
|
|
33
|
+
* In a HOSTED facilitator (like x402.org), the `feePayer` field in the
|
|
34
|
+
* SupportedResponse.extra specifies which address will pay transaction fees
|
|
35
|
+
* when the facilitator submits transactions on behalf of users.
|
|
36
|
+
*
|
|
37
|
+
* In LOCAL/SELF-SOVEREIGN mode (this implementation):
|
|
38
|
+
* - The USER pays their own transaction fees directly
|
|
39
|
+
* - The facilitator NEVER submits transactions - it only VERIFIES them
|
|
40
|
+
* - Therefore, no fee payer address is actually used
|
|
41
|
+
*
|
|
42
|
+
* However, the x402 protocol REQUIRES this field in the response schema.
|
|
43
|
+
* We use the System Program address (all 1s) as a placeholder because:
|
|
44
|
+
* 1. It's clearly not a real wallet (obvious placeholder)
|
|
45
|
+
* 2. It cannot receive funds or sign transactions
|
|
46
|
+
* 3. It signals to developers that fee paying is handled differently
|
|
47
|
+
*
|
|
48
|
+
* SECURITY NOTE: This is NOT a security risk because:
|
|
49
|
+
* - The fee payer is never used in verify() or settle() methods
|
|
50
|
+
* - Users sign and pay for their own transactions
|
|
51
|
+
* - The address is just a protocol-required placeholder
|
|
52
|
+
*
|
|
53
|
+
* @see https://docs.x402.org for protocol specification
|
|
54
|
+
*/
|
|
29
55
|
DUMMY_FEE_PAYER = "11111111111111111111111111111111";
|
|
30
56
|
/**
|
|
31
57
|
* Get supported payment kinds
|
|
32
58
|
* Returns x402 v2 compatible response with CAIP-2 network identifiers
|
|
59
|
+
*
|
|
60
|
+
* NOTE: The feePayer in extra.feePayer is a placeholder only.
|
|
61
|
+
* In self-sovereign mode, users pay their own transaction fees.
|
|
33
62
|
*/
|
|
34
63
|
async getSupported(_extensionKeys = []) {
|
|
35
|
-
console.log("[LocalSvmFacilitator] getSupported called");
|
|
36
64
|
const supported = {
|
|
37
65
|
kinds: [
|
|
38
66
|
{
|
|
@@ -50,10 +78,10 @@ var LocalSvmFacilitator = class {
|
|
|
50
78
|
],
|
|
51
79
|
extensions: [],
|
|
52
80
|
signers: {
|
|
81
|
+
// Placeholder - in self-sovereign mode, users are their own signers
|
|
53
82
|
"solana:*": [this.DUMMY_FEE_PAYER]
|
|
54
83
|
}
|
|
55
84
|
};
|
|
56
|
-
console.log("[LocalSvmFacilitator] Returning supported:", JSON.stringify(supported));
|
|
57
85
|
return supported;
|
|
58
86
|
}
|
|
59
87
|
/**
|
package/package.json
CHANGED