402-mcp 3.11.1 → 3.11.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 +3 -3
- package/build/fetch/hns-resolve.d.ts +3 -0
- package/build/fetch/hns-resolve.js +125 -11
- package/build/fetch/hns-resolve.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -143,10 +143,10 @@ Browse live L402 services at [402.pub](https://402.pub) — the decentralised ma
|
|
|
143
143
|
| **[402-mcp](https://github.com/TheCryptoDonkey/402-mcp)** | **MCP client — AI agents discover, pay, and consume L402 + x402 APIs** |
|
|
144
144
|
| [402-announce](https://github.com/TheCryptoDonkey/402-announce) | Publish L402 services on Nostr for decentralised discovery |
|
|
145
145
|
|
|
146
|
-
|
|
147
|
-
<summary>How does this compare to alternatives?</summary>
|
|
146
|
+
402-mcp is the **payment-rail agnostic** alternative to Lightning Labs' [lightning-agent-tools](https://github.com/lightninglabs/lightning-agent-tools) and Coinbase's x402 — no Lightning node required, multiple wallets, encrypted credentials.
|
|
148
147
|
|
|
149
|
-
|
|
148
|
+
<details>
|
|
149
|
+
<summary>Full comparison</summary>
|
|
150
150
|
|
|
151
151
|
| | 402-mcp | Lightning Labs agent tools |
|
|
152
152
|
|---|---|---|
|
|
@@ -5,6 +5,9 @@ export interface ResolvedAddress {
|
|
|
5
5
|
/**
|
|
6
6
|
* Resolve a Handshake (HNS) hostname via a DNS-over-HTTPS gateway.
|
|
7
7
|
*
|
|
8
|
+
* Uses RFC 8484 wire-format DoH (GET with ?dns= parameter), which is
|
|
9
|
+
* supported by the default HDNS gateway (query.hdns.io).
|
|
10
|
+
*
|
|
8
11
|
* Tries an A record first; falls back to AAAA if no A records are returned.
|
|
9
12
|
* Throws if neither resolves, the gateway returns an error, or the request
|
|
10
13
|
* times out.
|
|
@@ -16,22 +16,136 @@ function isValidIpFormat(address, family) {
|
|
|
16
16
|
// IPv6: basic format check — hex digits and colons only, at least one colon
|
|
17
17
|
return IPV6_RE.test(address) && address.includes(':');
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
// ── DNS wire format helpers (RFC 1035 / RFC 8484) ───────────────────
|
|
20
|
+
const DNS_HEADER_SIZE = 12;
|
|
21
|
+
const DNS_TYPE_A = 1;
|
|
22
|
+
const DNS_TYPE_AAAA = 28;
|
|
23
|
+
const DNS_CLASS_IN = 1;
|
|
24
|
+
const DNS_POINTER_MASK = 0xc0;
|
|
25
|
+
/** Encode a hostname as DNS wire-format labels (length-prefixed, null-terminated). */
|
|
26
|
+
function encodeLabels(hostname) {
|
|
27
|
+
const labels = hostname.split('.');
|
|
28
|
+
let totalLen = 1; // null terminator
|
|
29
|
+
for (const label of labels)
|
|
30
|
+
totalLen += 1 + label.length;
|
|
31
|
+
const buf = new Uint8Array(totalLen);
|
|
32
|
+
let offset = 0;
|
|
33
|
+
for (const label of labels) {
|
|
34
|
+
buf[offset++] = label.length;
|
|
35
|
+
for (let i = 0; i < label.length; i++) {
|
|
36
|
+
buf[offset++] = label.charCodeAt(i);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
buf[offset] = 0; // root label
|
|
40
|
+
return buf;
|
|
41
|
+
}
|
|
42
|
+
/** Build a minimal DNS query packet for the given hostname and record type. */
|
|
43
|
+
function buildQuery(hostname, qtype) {
|
|
44
|
+
const labels = encodeLabels(hostname);
|
|
45
|
+
const packet = new Uint8Array(DNS_HEADER_SIZE + labels.length + 4);
|
|
46
|
+
const view = new DataView(packet.buffer);
|
|
47
|
+
// Header: ID=0, flags=0x0100 (RD=1), QDCOUNT=1
|
|
48
|
+
view.setUint16(0, 0); // ID
|
|
49
|
+
view.setUint16(2, 0x0100); // Flags: recursion desired
|
|
50
|
+
view.setUint16(4, 1); // QDCOUNT
|
|
51
|
+
view.setUint16(6, 0); // ANCOUNT
|
|
52
|
+
view.setUint16(8, 0); // NSCOUNT
|
|
53
|
+
view.setUint16(10, 0); // ARCOUNT
|
|
54
|
+
// Question section
|
|
55
|
+
packet.set(labels, DNS_HEADER_SIZE);
|
|
56
|
+
const typeOffset = DNS_HEADER_SIZE + labels.length;
|
|
57
|
+
view.setUint16(typeOffset, qtype);
|
|
58
|
+
view.setUint16(typeOffset + 2, DNS_CLASS_IN);
|
|
59
|
+
return packet;
|
|
60
|
+
}
|
|
61
|
+
/** Skip a DNS name in wire format (handles compression pointers). */
|
|
62
|
+
function skipName(data, offset) {
|
|
63
|
+
while (offset < data.length) {
|
|
64
|
+
const len = data[offset];
|
|
65
|
+
if (len === 0)
|
|
66
|
+
return offset + 1;
|
|
67
|
+
if ((len & DNS_POINTER_MASK) === DNS_POINTER_MASK)
|
|
68
|
+
return offset + 2;
|
|
69
|
+
offset += len + 1;
|
|
70
|
+
}
|
|
71
|
+
throw new Error('Malformed DNS name');
|
|
72
|
+
}
|
|
73
|
+
/** Parse a wire-format DNS response, extracting A and AAAA records. */
|
|
74
|
+
function parseResponse(data) {
|
|
75
|
+
if (data.length < DNS_HEADER_SIZE)
|
|
76
|
+
throw new Error('DNS response too short');
|
|
77
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
78
|
+
const flags = view.getUint16(2);
|
|
79
|
+
const rcode = flags & 0xf;
|
|
80
|
+
if (rcode !== 0) {
|
|
81
|
+
const label = rcode === 3 ? 'NXDOMAIN' : rcode === 2 ? 'SERVFAIL' : `RCODE_${rcode}`;
|
|
82
|
+
throw new Error(`DNS resolution failed: ${label}`);
|
|
83
|
+
}
|
|
84
|
+
const ancount = view.getUint16(6);
|
|
85
|
+
if (ancount === 0)
|
|
86
|
+
return [];
|
|
87
|
+
// Skip question section
|
|
88
|
+
let offset = DNS_HEADER_SIZE;
|
|
89
|
+
const qdcount = view.getUint16(4);
|
|
90
|
+
for (let i = 0; i < qdcount; i++) {
|
|
91
|
+
offset = skipName(data, offset);
|
|
92
|
+
offset += 4; // QTYPE + QCLASS
|
|
93
|
+
}
|
|
94
|
+
// Parse answer section
|
|
95
|
+
const records = [];
|
|
96
|
+
for (let i = 0; i < ancount && offset < data.length; i++) {
|
|
97
|
+
offset = skipName(data, offset);
|
|
98
|
+
if (offset + 10 > data.length)
|
|
99
|
+
break;
|
|
100
|
+
const rtype = view.getUint16(offset);
|
|
101
|
+
offset += 4; // TYPE + CLASS
|
|
102
|
+
offset += 4; // TTL
|
|
103
|
+
const rdlen = view.getUint16(offset);
|
|
104
|
+
offset += 2;
|
|
105
|
+
if (offset + rdlen > data.length)
|
|
106
|
+
break;
|
|
107
|
+
if (rtype === DNS_TYPE_A && rdlen === 4) {
|
|
108
|
+
const ip = `${data[offset]}.${data[offset + 1]}.${data[offset + 2]}.${data[offset + 3]}`;
|
|
109
|
+
records.push({ type: DNS_TYPE_A, data: ip });
|
|
110
|
+
}
|
|
111
|
+
else if (rtype === DNS_TYPE_AAAA && rdlen === 16) {
|
|
112
|
+
const groups = [];
|
|
113
|
+
for (let g = 0; g < 16; g += 2) {
|
|
114
|
+
groups.push(view.getUint16(offset + g).toString(16));
|
|
115
|
+
}
|
|
116
|
+
records.push({ type: DNS_TYPE_AAAA, data: groups.join(':') });
|
|
117
|
+
}
|
|
118
|
+
offset += rdlen;
|
|
119
|
+
}
|
|
120
|
+
return records;
|
|
121
|
+
}
|
|
122
|
+
// ── Base64url encoding ──────────────────────────────────────────────
|
|
123
|
+
function toBase64url(data) {
|
|
124
|
+
const base64 = Buffer.from(data).toString('base64');
|
|
125
|
+
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
126
|
+
}
|
|
127
|
+
// ── Public API ──────────────────────────────────────────────────────
|
|
128
|
+
async function queryDns(hostname, gatewayUrl, qtype, signal) {
|
|
129
|
+
const wire = buildQuery(hostname, qtype);
|
|
130
|
+
const encoded = toBase64url(wire);
|
|
131
|
+
const url = `${gatewayUrl}dns-query?dns=${encoded}`;
|
|
21
132
|
const response = await fetch(url, {
|
|
22
|
-
headers: { Accept: 'application/dns-
|
|
133
|
+
headers: { Accept: 'application/dns-message' },
|
|
23
134
|
signal,
|
|
24
|
-
redirect: 'error',
|
|
135
|
+
redirect: 'error',
|
|
25
136
|
});
|
|
26
137
|
if (!response.ok) {
|
|
27
|
-
throw new Error(`DNS query failed: HTTP ${response.status} for ${hostname}
|
|
138
|
+
throw new Error(`DNS query failed: HTTP ${response.status} for ${hostname}`);
|
|
28
139
|
}
|
|
29
|
-
const
|
|
30
|
-
return
|
|
140
|
+
const buf = await response.arrayBuffer();
|
|
141
|
+
return parseResponse(new Uint8Array(buf));
|
|
31
142
|
}
|
|
32
143
|
/**
|
|
33
144
|
* Resolve a Handshake (HNS) hostname via a DNS-over-HTTPS gateway.
|
|
34
145
|
*
|
|
146
|
+
* Uses RFC 8484 wire-format DoH (GET with ?dns= parameter), which is
|
|
147
|
+
* supported by the default HDNS gateway (query.hdns.io).
|
|
148
|
+
*
|
|
35
149
|
* Tries an A record first; falls back to AAAA if no A records are returned.
|
|
36
150
|
* Throws if neither resolves, the gateway returns an error, or the request
|
|
37
151
|
* times out.
|
|
@@ -41,8 +155,8 @@ export async function resolveHns(hostname, gatewayUrl, timeoutMs = 5000) {
|
|
|
41
155
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
42
156
|
try {
|
|
43
157
|
// Try A record first
|
|
44
|
-
const
|
|
45
|
-
const aRecord =
|
|
158
|
+
const aRecords = await queryDns(hostname, gatewayUrl, DNS_TYPE_A, controller.signal);
|
|
159
|
+
const aRecord = aRecords.find(r => r.type === DNS_TYPE_A);
|
|
46
160
|
if (aRecord) {
|
|
47
161
|
if (!isValidIpFormat(aRecord.data, 4)) {
|
|
48
162
|
throw new Error(`HNS gateway returned invalid IPv4 address for ${hostname}`);
|
|
@@ -50,8 +164,8 @@ export async function resolveHns(hostname, gatewayUrl, timeoutMs = 5000) {
|
|
|
50
164
|
return { address: aRecord.data, family: 4 };
|
|
51
165
|
}
|
|
52
166
|
// Fall back to AAAA
|
|
53
|
-
const
|
|
54
|
-
const aaaaRecord =
|
|
167
|
+
const aaaaRecords = await queryDns(hostname, gatewayUrl, DNS_TYPE_AAAA, controller.signal);
|
|
168
|
+
const aaaaRecord = aaaaRecords.find(r => r.type === DNS_TYPE_AAAA);
|
|
55
169
|
if (aaaaRecord) {
|
|
56
170
|
if (!isValidIpFormat(aaaaRecord.data, 6)) {
|
|
57
171
|
throw new Error(`HNS gateway returned invalid IPv6 address for ${hostname}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hns-resolve.js","sourceRoot":"","sources":["../../src/fetch/hns-resolve.ts"],"names":[],"mappings":"AAKA,iFAAiF;AACjF,MAAM,OAAO,GAAG,8CAA8C,CAAA;AAC9D,+FAA+F;AAC/F,MAAM,OAAO,GAAG,kBAAkB,CAAA;AAElC,SAAS,eAAe,CAAC,OAAe,EAAE,MAAa;IACrD,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC/B,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;QACpB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;YAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;YACvB,0DAA0D;YAC1D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAA;QAClD,CAAC,CAAC,CAAA;IACJ,CAAC;IACD,4EAA4E;IAC5E,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;AACvD,CAAC;
|
|
1
|
+
{"version":3,"file":"hns-resolve.js","sourceRoot":"","sources":["../../src/fetch/hns-resolve.ts"],"names":[],"mappings":"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"}
|