@x1id/resolve 0.3.0 → 0.6.0
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/LICENSE +21 -0
- package/README.md +128 -1
- package/dist/accounts.d.ts +7 -0
- package/dist/accounts.js +8 -1
- package/dist/agent.d.ts +186 -0
- package/dist/agent.js +213 -0
- package/dist/attestation.d.ts +20 -8
- package/dist/attestation.js +22 -10
- package/dist/clearRecords.d.ts +60 -0
- package/dist/clearRecords.js +69 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +15 -2
- package/dist/recordWrite.d.ts +136 -0
- package/dist/recordWrite.js +228 -0
- package/dist/records.d.ts +24 -7
- package/dist/records.js +26 -9
- package/dist/register.d.ts +119 -0
- package/dist/register.js +183 -0
- package/dist/subname.d.ts +5 -0
- package/dist/subname.js +6 -1
- package/dist/textRecords.d.ts +18 -7
- package/dist/textRecords.js +20 -9
- package/dist/x402.d.ts +107 -0
- package/dist/x402.js +76 -0
- package/package.json +45 -9
- package/schema/agent-manifest.json +91 -0
- package/wasm/x1_resolve_wasm.wasm +0 -0
package/dist/x402.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402 ("HTTP 402 Payment Required") payment requirements — the pure,
|
|
3
|
+
* dependency-free half of x1id's x402 support. Types and the
|
|
4
|
+
* `PaymentRequirements` builder live here; actual transaction construction
|
|
5
|
+
* and verification need real Solana transaction parsing (`@solana/web3.js`)
|
|
6
|
+
* and live in `mcp/src/x402/` instead, matching this SDK's established
|
|
7
|
+
* boundary (zero dependencies, no crypto/serialization — see delegate.ts's
|
|
8
|
+
* module docs for the same reasoning applied elsewhere).
|
|
9
|
+
*
|
|
10
|
+
* Field names and the `"exact"` scheme's wire shape are taken verbatim from
|
|
11
|
+
* the x402 Foundation's own SVM scheme spec
|
|
12
|
+
* (x402-foundation/x402, specs/schemes/exact/scheme_exact_svm.md, and the
|
|
13
|
+
* Go reference implementation under go/mechanisms/svm/exact/), verified
|
|
14
|
+
* 2026-09-22 — NOT invented. See `docs/x402.md` for the full design,
|
|
15
|
+
* including what's explicitly OUT of scope here (a facilitator).
|
|
16
|
+
*
|
|
17
|
+
* # The one x1id-specific choice: the network identifier
|
|
18
|
+
*
|
|
19
|
+
* x402's Solana networks use `"solana:<genesis-hash>"` (CAIP-2-shaped). X1
|
|
20
|
+
* is SVM-compatible but its OWN chain — not Solana — so it gets its own
|
|
21
|
+
* namespace under the identical convention: `"x1:<genesis-hash>"`. This is
|
|
22
|
+
* NOT an x402-foundation-registered network; it's a principled extension of
|
|
23
|
+
* their own pattern to a new SVM-compatible chain, not a claim of official
|
|
24
|
+
* support. {@link X1_TESTNET_NETWORK} is the live testnet genesis hash,
|
|
25
|
+
* verified against `getGenesisHash` 2026-09-22.
|
|
26
|
+
*/
|
|
27
|
+
/** X1 testnet's x402 network identifier (`"x1:<genesis-hash>"`, verified
|
|
28
|
+
* live 2026-09-22 via `getGenesisHash`). */
|
|
29
|
+
export declare const X1_TESTNET_NETWORK = "x1:C7ucgdDEhxLTpXHhWSZxavSVmaNTUJWwT5iTdeaviDho";
|
|
30
|
+
/** The x402 scheme x1id implements — "exact": pay a fixed amount of a named
|
|
31
|
+
* asset to a named recipient. (x402 also defines "upto" for usage-based
|
|
32
|
+
* pricing; not implemented here.) */
|
|
33
|
+
export declare const X402_SCHEME_EXACT = "exact";
|
|
34
|
+
export declare const X402_VERSION = 2;
|
|
35
|
+
/** One entry of a 402 response's `accepts[]` — the SVM `"exact"` scheme's
|
|
36
|
+
* `PaymentRequirements`, field names verbatim from the spec. */
|
|
37
|
+
export interface X402PaymentRequirements {
|
|
38
|
+
readonly scheme: "exact";
|
|
39
|
+
/** `"x1:<genesis-hash>"` — see the module docs. */
|
|
40
|
+
readonly network: string;
|
|
41
|
+
/** Smallest-unit amount, as a DECIMAL STRING (e.g. lamports, or an SPL
|
|
42
|
+
* token's atomic units) — never a number (precision). */
|
|
43
|
+
readonly amount: string;
|
|
44
|
+
/** The SPL/Token-2022 mint's base58 address. */
|
|
45
|
+
readonly asset: string;
|
|
46
|
+
/** The recipient's base58 address (a wallet, not the token account —
|
|
47
|
+
* the payer derives the destination ATA from this + `asset`). */
|
|
48
|
+
readonly payTo: string;
|
|
49
|
+
readonly maxTimeoutSeconds: number;
|
|
50
|
+
readonly extra: {
|
|
51
|
+
/** The sponsor that will co-sign as fee payer, base58. REQUIRED by the
|
|
52
|
+
* spec for the client to build a transaction at all — x1id's v1 has
|
|
53
|
+
* no sponsor (see docs/x402.md): this SDK always sets it to the
|
|
54
|
+
* BUYER's own address (self-sponsored, no facilitator, no custody). */
|
|
55
|
+
readonly feePayer: string;
|
|
56
|
+
/** UTF-8, <=256 bytes. Lets a seller correlate the on-chain payment to
|
|
57
|
+
* an invoice without a unique deposit address per sale. */
|
|
58
|
+
readonly memo?: string;
|
|
59
|
+
readonly recentBlockhash?: string;
|
|
60
|
+
readonly lastValidBlockHeight?: string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** The 402 response body's `accepts[]` wrapper — what a resource server
|
|
64
|
+
* actually returns. */
|
|
65
|
+
export interface X402PaymentRequiredResponse {
|
|
66
|
+
readonly x402Version: typeof X402_VERSION;
|
|
67
|
+
readonly accepts: readonly X402PaymentRequirements[];
|
|
68
|
+
}
|
|
69
|
+
/** What the client sends back (as the `payload.transaction` field, once
|
|
70
|
+
* base64-encoded — see `mcp/src/x402/transaction.ts` for actually
|
|
71
|
+
* building and encoding one; this type documents the wire shape only). */
|
|
72
|
+
export interface X402PaymentPayload {
|
|
73
|
+
readonly x402Version: typeof X402_VERSION;
|
|
74
|
+
readonly accepted: X402PaymentRequirements;
|
|
75
|
+
readonly payload: {
|
|
76
|
+
/** Base64-encoded, serialized, partially-signed versioned transaction. */
|
|
77
|
+
readonly transaction: string;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export interface BuildX402RequirementsParams {
|
|
81
|
+
/** The recipient's base58 address. */
|
|
82
|
+
readonly payTo: string;
|
|
83
|
+
/** The SPL/Token-2022 mint's base58 address. */
|
|
84
|
+
readonly asset: string;
|
|
85
|
+
/** Smallest-unit amount as a decimal string. */
|
|
86
|
+
readonly amount: string;
|
|
87
|
+
/** X1id v1 has no sponsoring facilitator (see the module docs):
|
|
88
|
+
* the buyer pays their own transaction fee, so `extra.feePayer` is
|
|
89
|
+
* always set to this same buyer address. Pass the address the caller
|
|
90
|
+
* expects to pay from. */
|
|
91
|
+
readonly buyer: string;
|
|
92
|
+
readonly network?: string;
|
|
93
|
+
readonly maxTimeoutSeconds?: number;
|
|
94
|
+
readonly memo?: string;
|
|
95
|
+
readonly recentBlockhash?: string;
|
|
96
|
+
readonly lastValidBlockHeight?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Build one `accepts[]` entry — the resource-server side of a 402 response.
|
|
100
|
+
* Pure data; does not touch chain, does not fetch a blockhash (pass
|
|
101
|
+
* `recentBlockhash`/`lastValidBlockHeight` if you have one fresh, or omit
|
|
102
|
+
* and let the buyer fetch their own — the spec allows either).
|
|
103
|
+
*/
|
|
104
|
+
export declare function buildX402Requirements(p: BuildX402RequirementsParams): X402PaymentRequirements;
|
|
105
|
+
/** Parse a 402 response body, returning null if it doesn't look like one
|
|
106
|
+
* (missing/wrong `x402Version`, `accepts` not an array). Never throws. */
|
|
107
|
+
export declare function parseX402Response(body: unknown): X402PaymentRequiredResponse | null;
|
package/dist/x402.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402 ("HTTP 402 Payment Required") payment requirements — the pure,
|
|
3
|
+
* dependency-free half of x1id's x402 support. Types and the
|
|
4
|
+
* `PaymentRequirements` builder live here; actual transaction construction
|
|
5
|
+
* and verification need real Solana transaction parsing (`@solana/web3.js`)
|
|
6
|
+
* and live in `mcp/src/x402/` instead, matching this SDK's established
|
|
7
|
+
* boundary (zero dependencies, no crypto/serialization — see delegate.ts's
|
|
8
|
+
* module docs for the same reasoning applied elsewhere).
|
|
9
|
+
*
|
|
10
|
+
* Field names and the `"exact"` scheme's wire shape are taken verbatim from
|
|
11
|
+
* the x402 Foundation's own SVM scheme spec
|
|
12
|
+
* (x402-foundation/x402, specs/schemes/exact/scheme_exact_svm.md, and the
|
|
13
|
+
* Go reference implementation under go/mechanisms/svm/exact/), verified
|
|
14
|
+
* 2026-09-22 — NOT invented. See `docs/x402.md` for the full design,
|
|
15
|
+
* including what's explicitly OUT of scope here (a facilitator).
|
|
16
|
+
*
|
|
17
|
+
* # The one x1id-specific choice: the network identifier
|
|
18
|
+
*
|
|
19
|
+
* x402's Solana networks use `"solana:<genesis-hash>"` (CAIP-2-shaped). X1
|
|
20
|
+
* is SVM-compatible but its OWN chain — not Solana — so it gets its own
|
|
21
|
+
* namespace under the identical convention: `"x1:<genesis-hash>"`. This is
|
|
22
|
+
* NOT an x402-foundation-registered network; it's a principled extension of
|
|
23
|
+
* their own pattern to a new SVM-compatible chain, not a claim of official
|
|
24
|
+
* support. {@link X1_TESTNET_NETWORK} is the live testnet genesis hash,
|
|
25
|
+
* verified against `getGenesisHash` 2026-09-22.
|
|
26
|
+
*/
|
|
27
|
+
/** X1 testnet's x402 network identifier (`"x1:<genesis-hash>"`, verified
|
|
28
|
+
* live 2026-09-22 via `getGenesisHash`). */
|
|
29
|
+
export const X1_TESTNET_NETWORK = "x1:C7ucgdDEhxLTpXHhWSZxavSVmaNTUJWwT5iTdeaviDho";
|
|
30
|
+
/** The x402 scheme x1id implements — "exact": pay a fixed amount of a named
|
|
31
|
+
* asset to a named recipient. (x402 also defines "upto" for usage-based
|
|
32
|
+
* pricing; not implemented here.) */
|
|
33
|
+
export const X402_SCHEME_EXACT = "exact";
|
|
34
|
+
export const X402_VERSION = 2;
|
|
35
|
+
/**
|
|
36
|
+
* Build one `accepts[]` entry — the resource-server side of a 402 response.
|
|
37
|
+
* Pure data; does not touch chain, does not fetch a blockhash (pass
|
|
38
|
+
* `recentBlockhash`/`lastValidBlockHeight` if you have one fresh, or omit
|
|
39
|
+
* and let the buyer fetch their own — the spec allows either).
|
|
40
|
+
*/
|
|
41
|
+
export function buildX402Requirements(p) {
|
|
42
|
+
if (!/^\d+$/.test(p.amount)) {
|
|
43
|
+
throw new Error("amount must be a decimal string of smallest units (e.g. \"1000000\")");
|
|
44
|
+
}
|
|
45
|
+
if (p.memo !== undefined && new TextEncoder().encode(p.memo).length > 256) {
|
|
46
|
+
throw new Error("memo must be <=256 UTF-8 bytes");
|
|
47
|
+
}
|
|
48
|
+
const extra = { feePayer: p.buyer };
|
|
49
|
+
if (p.memo !== undefined)
|
|
50
|
+
extra.memo = p.memo;
|
|
51
|
+
if (p.recentBlockhash !== undefined) {
|
|
52
|
+
extra.recentBlockhash = p.recentBlockhash;
|
|
53
|
+
}
|
|
54
|
+
if (p.lastValidBlockHeight !== undefined) {
|
|
55
|
+
extra.lastValidBlockHeight = p.lastValidBlockHeight;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
scheme: X402_SCHEME_EXACT,
|
|
59
|
+
network: p.network ?? X1_TESTNET_NETWORK,
|
|
60
|
+
amount: p.amount,
|
|
61
|
+
asset: p.asset,
|
|
62
|
+
payTo: p.payTo,
|
|
63
|
+
maxTimeoutSeconds: p.maxTimeoutSeconds ?? 60,
|
|
64
|
+
extra,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Parse a 402 response body, returning null if it doesn't look like one
|
|
68
|
+
* (missing/wrong `x402Version`, `accepts` not an array). Never throws. */
|
|
69
|
+
export function parseX402Response(body) {
|
|
70
|
+
if (typeof body !== "object" || body === null)
|
|
71
|
+
return null;
|
|
72
|
+
const b = body;
|
|
73
|
+
if (b.x402Version !== X402_VERSION || !Array.isArray(b.accepts))
|
|
74
|
+
return null;
|
|
75
|
+
return { x402Version: X402_VERSION, accepts: b.accepts };
|
|
76
|
+
}
|
package/package.json
CHANGED
|
@@ -1,34 +1,70 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x1id/resolve",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Resolve @handles and X1NS names on X1. Never silently picks between namespaces.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
|
-
".": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
10
13
|
"./wasm/x1_resolve_wasm.wasm": "./wasm/x1_resolve_wasm.wasm",
|
|
11
14
|
"./wasm/*": "./wasm/*",
|
|
12
15
|
"./package.json": "./package.json"
|
|
13
16
|
},
|
|
14
|
-
"files": [
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"wasm",
|
|
20
|
+
"schema",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
15
23
|
"scripts": {
|
|
16
24
|
"build:wasm": "cargo build --release -p x1-resolve-wasm --target wasm32-unknown-unknown && cp target/wasm32-unknown-unknown/release/x1_resolve_wasm.wasm wasm/",
|
|
17
25
|
"build": "tsc -p tsconfig.json",
|
|
18
26
|
"test": "node --test test/*.test.js",
|
|
19
27
|
"lint:package": "publint",
|
|
20
|
-
"prepublishOnly": "
|
|
28
|
+
"prepublishOnly": "npm run build"
|
|
21
29
|
},
|
|
22
|
-
"keywords": [
|
|
30
|
+
"keywords": [
|
|
31
|
+
"x1",
|
|
32
|
+
"x1id",
|
|
33
|
+
"solana",
|
|
34
|
+
"svm",
|
|
35
|
+
"naming",
|
|
36
|
+
"x1ns",
|
|
37
|
+
"handles",
|
|
38
|
+
"wallet",
|
|
39
|
+
"resolver",
|
|
40
|
+
"web3"
|
|
41
|
+
],
|
|
23
42
|
"homepage": "https://x1id.io",
|
|
24
43
|
"license": "MIT",
|
|
25
|
-
"publishConfig": {
|
|
26
|
-
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
},
|
|
27
50
|
"devDependencies": {
|
|
28
51
|
"typescript": "^5.6.0",
|
|
29
52
|
"@types/node": "^22.0.0",
|
|
30
53
|
"publint": "^0.2.0"
|
|
31
54
|
},
|
|
32
|
-
"peerDependencies": {
|
|
33
|
-
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"@solana/web3.js": "^1.95.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependenciesMeta": {
|
|
59
|
+
"@solana/web3.js": {
|
|
60
|
+
"optional": true
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"repository": {
|
|
64
|
+
"type": "git",
|
|
65
|
+
"url": "git+https://github.com/fortiblox/x1id-sdk.git"
|
|
66
|
+
},
|
|
67
|
+
"bugs": {
|
|
68
|
+
"url": "https://x1id.io"
|
|
69
|
+
}
|
|
34
70
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://x1id.io/schema/agent-manifest.json",
|
|
4
|
+
"title": "x1id agent manifest",
|
|
5
|
+
"description": "A machine-readable description of an @handle operating as an AI agent — what it does, how to reach it, and how to pay it. Nothing here is a payment fact: payment.addresses[] is a mirror of the on-chain address Record(s) and payment.x402 is a pre-flight hint; the chain and the live 402 response always win. See docs/agent-records.md.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["x1id"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"x1id": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"additionalProperties": false,
|
|
13
|
+
"required": ["version", "name", "network", "handle"],
|
|
14
|
+
"properties": {
|
|
15
|
+
"version": { "const": 1 },
|
|
16
|
+
"name": { "type": "string", "minLength": 1, "maxLength": 260, "description": "The canonical @handle name, without the @." },
|
|
17
|
+
"network": { "type": "string", "enum": ["testnet", "mainnet"] },
|
|
18
|
+
"handle": { "type": "string", "pattern": "^[1-9A-HJ-NP-Za-km-z]{32,44}$", "description": "The Handle PDA account address, base58 — the uniqueness anchor. A manifest served for the wrong name/handle is discarded on read." }
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"identity": {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"additionalProperties": false,
|
|
24
|
+
"properties": {
|
|
25
|
+
"attestation": { "type": "string", "pattern": "^[1-9A-HJ-NP-Za-km-z]{32,44}$", "description": "Base58 address of a non-stale Attestation account on this handle (kind DNS or SOCIAL). See docs/agent-records.md §4 for what L1 does and does not prove." },
|
|
26
|
+
"description": { "type": "string", "maxLength": 2048 }
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"endpoints": {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"maxItems": 32,
|
|
32
|
+
"items": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"additionalProperties": false,
|
|
35
|
+
"required": ["type", "url"],
|
|
36
|
+
"properties": {
|
|
37
|
+
"type": { "type": "string", "enum": ["x402", "mcp", "a2a", "http"] },
|
|
38
|
+
"url": { "$ref": "#/$defs/HttpsUrl" }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"capabilities": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"additionalProperties": false,
|
|
45
|
+
"required": ["url"],
|
|
46
|
+
"properties": {
|
|
47
|
+
"schema": { "$ref": "#/$defs/HttpsUrl" },
|
|
48
|
+
"url": { "$ref": "#/$defs/HttpsUrl" }
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"payment": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"additionalProperties": false,
|
|
54
|
+
"properties": {
|
|
55
|
+
"addresses": {
|
|
56
|
+
"type": "array",
|
|
57
|
+
"maxItems": 16,
|
|
58
|
+
"items": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"additionalProperties": false,
|
|
61
|
+
"required": ["coinType", "address"],
|
|
62
|
+
"properties": {
|
|
63
|
+
"coinType": { "type": "integer", "minimum": 0 },
|
|
64
|
+
"address": { "type": "string", "minLength": 1, "maxLength": 128 },
|
|
65
|
+
"verified": { "type": "boolean" }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"x402": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"additionalProperties": false,
|
|
72
|
+
"required": ["network"],
|
|
73
|
+
"properties": {
|
|
74
|
+
"network": { "type": "string", "minLength": 1, "description": "e.g. \"x1-testnet\" or \"x1-mainnet\" — an x1id-defined network tag, not a CAIP-2 EVM chain id." },
|
|
75
|
+
"asset": { "type": "string", "maxLength": 128 },
|
|
76
|
+
"scheme": { "type": "string", "minLength": 1, "maxLength": 32 },
|
|
77
|
+
"facilitator": { "$ref": "#/$defs/HttpsUrl" },
|
|
78
|
+
"extra": { "type": "object" }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"$defs": {
|
|
85
|
+
"HttpsUrl": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"pattern": "^https://[^\\s@/]+(/[^\\s]*)?$",
|
|
88
|
+
"maxLength": 2048
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
Binary file
|