@stellar-agent-services/protocol 0.0.0-stage → 0.1.1
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 +14 -2
- package/dist/canonical-json.d.ts +18 -0
- package/dist/canonical-json.d.ts.map +1 -0
- package/dist/canonical-json.js +86 -0
- package/dist/canonical-json.js.map +1 -0
- package/dist/errors.d.ts +85 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +46 -0
- package/dist/errors.js.map +1 -0
- package/dist/headers.d.ts +15 -0
- package/dist/headers.d.ts.map +1 -0
- package/dist/headers.js +29 -0
- package/dist/headers.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/jobs.d.ts +62 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +66 -0
- package/dist/jobs.js.map +1 -0
- package/dist/manifest.d.ts +95 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +144 -0
- package/dist/manifest.js.map +1 -0
- package/dist/networks.d.ts +19 -0
- package/dist/networks.d.ts.map +1 -0
- package/dist/networks.js +33 -0
- package/dist/networks.js.map +1 -0
- package/dist/receipts.d.ts +112 -0
- package/dist/receipts.d.ts.map +1 -0
- package/dist/receipts.js +35 -0
- package/dist/receipts.js.map +1 -0
- package/dist/standard.d.ts +25 -0
- package/dist/standard.d.ts.map +1 -0
- package/dist/standard.js +29 -0
- package/dist/standard.js.map +1 -0
- package/dist/strkey.d.ts +7 -0
- package/dist/strkey.d.ts.map +1 -0
- package/dist/strkey.js +56 -0
- package/dist/strkey.js.map +1 -0
- package/dist/validation-request.d.ts +32 -0
- package/dist/validation-request.d.ts.map +1 -0
- package/dist/validation-request.js +29 -0
- package/dist/validation-request.js.map +1 -0
- package/package.json +37 -4
- package/schemas/manifest.schema.json +272 -0
- package/schemas/validation-request.schema.json +43 -0
- package/schemas/verification-receipt.schema.json +149 -0
- package/test-vectors/README.md +45 -0
- package/test-vectors/binding-hash.json +64 -0
- package/test-vectors/canonical-json.json +94 -0
- package/test-vectors/challenges.json +245 -0
- package/test-vectors/headers.json +37 -0
- package/test-vectors/job-states.json +39 -0
- package/test-vectors/manifests.json +1322 -0
- package/test-vectors/problems.json +15 -0
- package/test-vectors/validation-requests.json +98 -0
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// Provider manifest: what a provider publishes about itself (docs/provider-standard.md §2–§4).
|
|
2
|
+
//
|
|
3
|
+
// Validating a manifest takes two steps (§2.4):
|
|
4
|
+
// 1. schemas/manifest.schema.json, with any JSON Schema 2020-12 validator;
|
|
5
|
+
// 2. checkManifestRules(), for the rules JSON Schema can't express.
|
|
6
|
+
// This package has no runtime dependencies, so it ships the schema rather than a validator.
|
|
7
|
+
// test-vectors/manifests.json pins both steps; test-vectors/challenges.json pins checkChallenge().
|
|
8
|
+
import { canonicalJson } from "./canonical-json.js";
|
|
9
|
+
import { createJobUrl } from "./jobs.js";
|
|
10
|
+
import { SERVICE_SCHEMA_MAX_BYTES } from "./standard.js";
|
|
11
|
+
import { stellarAddressKind } from "./strkey.js";
|
|
12
|
+
/**
|
|
13
|
+
* Checks the manifest rules that JSON Schema can't express: M1 (HTTPS manifest URL), M3 (I-JSON),
|
|
14
|
+
* M5 (same origin), M7 (unique service names), S6 (schema size), S9 (examples) and P11 (address
|
|
15
|
+
* checksum). Call it only on a manifest that passed the JSON Schema.
|
|
16
|
+
*/
|
|
17
|
+
export function checkManifestRules(manifest, options) {
|
|
18
|
+
const violations = [];
|
|
19
|
+
const report = (rule, pointer, message) => {
|
|
20
|
+
violations.push({ rule, pointer, message });
|
|
21
|
+
};
|
|
22
|
+
const loneSurrogate = findLoneSurrogate(manifest, "");
|
|
23
|
+
if (loneSurrogate !== undefined) {
|
|
24
|
+
// The size checks below need canonical JSON, which this rules out.
|
|
25
|
+
report("M3", loneSurrogate, "the manifest must be I-JSON (RFC 7493): no lone surrogates");
|
|
26
|
+
return violations;
|
|
27
|
+
}
|
|
28
|
+
const manifestUrl = parseUrl(options.manifestUrl);
|
|
29
|
+
if (manifestUrl?.protocol !== "https:") {
|
|
30
|
+
report("M1", "", "the manifest must be served over HTTPS");
|
|
31
|
+
}
|
|
32
|
+
else if (parseUrl(manifest.baseUrl)?.origin !== manifestUrl.origin) {
|
|
33
|
+
report("M5", "/baseUrl", "baseUrl must have the same origin as the manifest URL");
|
|
34
|
+
}
|
|
35
|
+
if (stellarAddressKind(manifest.payment.accepts[0].payTo) === undefined) {
|
|
36
|
+
report("P11", "/payment/accepts/0/payTo", "payTo must be a G... or C... address with a valid checksum");
|
|
37
|
+
}
|
|
38
|
+
const names = new Set();
|
|
39
|
+
const validateExample = options.validateExample;
|
|
40
|
+
manifest.services.forEach((service, index) => {
|
|
41
|
+
const at = `/services/${index}`;
|
|
42
|
+
if (names.has(service.name))
|
|
43
|
+
report("M7", `${at}/name`, `service name "${service.name}" is used twice`);
|
|
44
|
+
names.add(service.name);
|
|
45
|
+
for (const field of ["inputSchema", "outputSchema"]) {
|
|
46
|
+
const bytes = new TextEncoder().encode(canonicalJson(service[field])).length;
|
|
47
|
+
if (bytes > SERVICE_SCHEMA_MAX_BYTES) {
|
|
48
|
+
report("S6", `${at}/${field}`, `${field} is ${bytes} bytes; the limit is ${SERVICE_SCHEMA_MAX_BYTES}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (validateExample === undefined)
|
|
52
|
+
return;
|
|
53
|
+
service.examples?.forEach((example, i) => {
|
|
54
|
+
if (!validateExample(service.inputSchema, example.input)) {
|
|
55
|
+
report("S9", `${at}/examples/${i}/input`, "the example input does not match inputSchema");
|
|
56
|
+
}
|
|
57
|
+
if (!validateExample(service.outputSchema, example.output)) {
|
|
58
|
+
report("S9", `${at}/examples/${i}/output`, "the example output does not match outputSchema");
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
return violations;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Checks a decoded x402 PAYMENT-REQUIRED challenge for one service against the manifest the user
|
|
66
|
+
* approved ([P3], [P4], [P5]). A client refuses to sign if this returns any violation [P7].
|
|
67
|
+
*/
|
|
68
|
+
export function checkChallenge(manifest, serviceName, challenge) {
|
|
69
|
+
const service = manifest.services.find((candidate) => candidate.name === serviceName);
|
|
70
|
+
if (service === undefined)
|
|
71
|
+
throw new TypeError(`checkChallenge: the manifest has no service "${serviceName}"`);
|
|
72
|
+
if (!isObject(challenge)) {
|
|
73
|
+
return [{ rule: "P3", pointer: "", message: "the challenge must be an x402 PaymentRequired object" }];
|
|
74
|
+
}
|
|
75
|
+
const violations = [];
|
|
76
|
+
const report = (rule, pointer, message) => {
|
|
77
|
+
violations.push({ rule, pointer, message });
|
|
78
|
+
};
|
|
79
|
+
if (challenge["x402Version"] !== 2)
|
|
80
|
+
report("P3", "/x402Version", "the challenge must be x402 version 2");
|
|
81
|
+
const resource = challenge["resource"];
|
|
82
|
+
if (!isObject(resource) || resource["url"] !== createJobUrl(manifest.baseUrl, service.name)) {
|
|
83
|
+
report("P5", "/resource/url", "resource.url must be the service's create-job URL");
|
|
84
|
+
}
|
|
85
|
+
const accepts = challenge["accepts"];
|
|
86
|
+
if (!Array.isArray(accepts) || accepts.length !== 1) {
|
|
87
|
+
report("P4", "/accepts", "accepts must have exactly one entry");
|
|
88
|
+
return violations;
|
|
89
|
+
}
|
|
90
|
+
const entry = accepts[0];
|
|
91
|
+
if (!isObject(entry)) {
|
|
92
|
+
report("P4", "/accepts/0", "the payment option must be an object");
|
|
93
|
+
return violations;
|
|
94
|
+
}
|
|
95
|
+
const option = manifest.payment.accepts[0];
|
|
96
|
+
const expected = {
|
|
97
|
+
scheme: option.scheme,
|
|
98
|
+
network: option.network,
|
|
99
|
+
asset: option.asset,
|
|
100
|
+
payTo: option.payTo,
|
|
101
|
+
amount: service.price.amount,
|
|
102
|
+
maxTimeoutSeconds: option.maxTimeoutSeconds,
|
|
103
|
+
};
|
|
104
|
+
for (const [field, value] of Object.entries(expected)) {
|
|
105
|
+
if (entry[field] !== value)
|
|
106
|
+
report("P4", `/accepts/0/${field}`, `${field} must equal the manifest`);
|
|
107
|
+
}
|
|
108
|
+
const extra = entry["extra"];
|
|
109
|
+
if (!isObject(extra) || extra["areFeesSponsored"] !== true) {
|
|
110
|
+
report("P4", "/accepts/0/extra/areFeesSponsored", "fees must be sponsored");
|
|
111
|
+
}
|
|
112
|
+
return violations;
|
|
113
|
+
}
|
|
114
|
+
// TODO:
|
|
115
|
+
// - parseManifest(): fetch rules (M1, M3: no redirects, at most MANIFEST_MAX_BYTES), then the JSON
|
|
116
|
+
// Schema, then checkManifestRules(). It lives with a validator, in the kit, verifier and client.
|
|
117
|
+
function findLoneSurrogate(value, pointer) {
|
|
118
|
+
const loneSurrogate = /[\uD800-\uDFFF]/u;
|
|
119
|
+
if (typeof value === "string")
|
|
120
|
+
return loneSurrogate.test(value) ? pointer : undefined;
|
|
121
|
+
if (typeof value !== "object" || value === null)
|
|
122
|
+
return undefined;
|
|
123
|
+
for (const [key, member] of Object.entries(value)) {
|
|
124
|
+
const at = `${pointer}/${key.replaceAll("~", "~0").replaceAll("/", "~1")}`;
|
|
125
|
+
if (loneSurrogate.test(key))
|
|
126
|
+
return at;
|
|
127
|
+
const found = findLoneSurrogate(member, at);
|
|
128
|
+
if (found !== undefined)
|
|
129
|
+
return found;
|
|
130
|
+
}
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
function parseUrl(url) {
|
|
134
|
+
try {
|
|
135
|
+
return new URL(url);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function isObject(value) {
|
|
142
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** CAIP-2 ids of the Stellar networks the standard supports. */
|
|
2
|
+
export type StellarNetwork = "stellar:testnet" | "stellar:pubnet";
|
|
3
|
+
export declare const STELLAR_NETWORKS: readonly StellarNetwork[];
|
|
4
|
+
/**
|
|
5
|
+
* The USDC Stellar Asset Contract on each network, the only asset in v1 (provider-standard.md §4.1).
|
|
6
|
+
* This package stays dependency-free, so these are copies: test/networks.test.ts pins them to
|
|
7
|
+
* @x402/stellar (USDC_TESTNET_ADDRESS, USDC_PUBNET_ADDRESS) and to the manifest JSON Schema.
|
|
8
|
+
*/
|
|
9
|
+
export declare const USDC_ASSET: Readonly<Record<StellarNetwork, string>>;
|
|
10
|
+
/** The USDC issuer on each network: USDC_ASSET is its Stellar Asset Contract. A G... payTo needs a trustline to it [P2]. */
|
|
11
|
+
export declare const USDC_ISSUER: Readonly<Record<StellarNetwork, string>>;
|
|
12
|
+
/** Public Horizon servers, for account reads such as the trustline check. */
|
|
13
|
+
export declare const HORIZON_URL: Readonly<Record<StellarNetwork, string>>;
|
|
14
|
+
/**
|
|
15
|
+
* Public Soroban RPC servers, for settlement proofs [J16], reconciliation [J13] and the ledger clock.
|
|
16
|
+
* SDF runs no public mainnet RPC, so pubnet has no default: pass your provider's URL.
|
|
17
|
+
*/
|
|
18
|
+
export declare const SOROBAN_RPC_URL: Readonly<Record<StellarNetwork, string | undefined>>;
|
|
19
|
+
//# sourceMappingURL=networks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"networks.d.ts","sourceRoot":"","sources":["../src/networks.ts"],"names":[],"mappings":"AAEA,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAClE,eAAO,MAAM,gBAAgB,EAAE,SAAS,cAAc,EAA0C,CAAC;AAEjG;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAG/D,CAAC;AAEF,4HAA4H;AAC5H,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAGhE,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAGhE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC,CAGhF,CAAC"}
|
package/dist/networks.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Network constants. The whole build runs on testnet first (IMPLEMENTATION_PLAN.md §4).
|
|
2
|
+
export const STELLAR_NETWORKS = ["stellar:testnet", "stellar:pubnet"];
|
|
3
|
+
/**
|
|
4
|
+
* The USDC Stellar Asset Contract on each network, the only asset in v1 (provider-standard.md §4.1).
|
|
5
|
+
* This package stays dependency-free, so these are copies: test/networks.test.ts pins them to
|
|
6
|
+
* @x402/stellar (USDC_TESTNET_ADDRESS, USDC_PUBNET_ADDRESS) and to the manifest JSON Schema.
|
|
7
|
+
*/
|
|
8
|
+
export const USDC_ASSET = {
|
|
9
|
+
"stellar:testnet": "CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA",
|
|
10
|
+
"stellar:pubnet": "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75",
|
|
11
|
+
};
|
|
12
|
+
/** The USDC issuer on each network: USDC_ASSET is its Stellar Asset Contract. A G... payTo needs a trustline to it [P2]. */
|
|
13
|
+
export const USDC_ISSUER = {
|
|
14
|
+
"stellar:testnet": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5",
|
|
15
|
+
"stellar:pubnet": "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN",
|
|
16
|
+
};
|
|
17
|
+
/** Public Horizon servers, for account reads such as the trustline check. */
|
|
18
|
+
export const HORIZON_URL = {
|
|
19
|
+
"stellar:testnet": "https://horizon-testnet.stellar.org",
|
|
20
|
+
"stellar:pubnet": "https://horizon.stellar.org",
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Public Soroban RPC servers, for settlement proofs [J16], reconciliation [J13] and the ledger clock.
|
|
24
|
+
* SDF runs no public mainnet RPC, so pubnet has no default: pass your provider's URL.
|
|
25
|
+
*/
|
|
26
|
+
export const SOROBAN_RPC_URL = {
|
|
27
|
+
"stellar:testnet": "https://soroban-testnet.stellar.org",
|
|
28
|
+
"stellar:pubnet": undefined,
|
|
29
|
+
};
|
|
30
|
+
// TODO:
|
|
31
|
+
// - 8004 contract ids come from @trionlabs/stellar8004 TESTNET_CONFIG / MAINNET_CONFIG, never
|
|
32
|
+
// retyped.
|
|
33
|
+
//# sourceMappingURL=networks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"networks.js","sourceRoot":"","sources":["../src/networks.ts"],"names":[],"mappings":"AAAA,wFAAwF;AAIxF,MAAM,CAAC,MAAM,gBAAgB,GAA8B,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;AAEjG;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAA6C;IAClE,iBAAiB,EAAE,0DAA0D;IAC7E,gBAAgB,EAAE,0DAA0D;CAC7E,CAAC;AAEF,4HAA4H;AAC5H,MAAM,CAAC,MAAM,WAAW,GAA6C;IACnE,iBAAiB,EAAE,0DAA0D;IAC7E,gBAAgB,EAAE,0DAA0D;CAC7E,CAAC;AAEF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,WAAW,GAA6C;IACnE,iBAAiB,EAAE,qCAAqC;IACxD,gBAAgB,EAAE,6BAA6B;CAChD,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAyD;IACnF,iBAAiB,EAAE,qCAAqC;IACxD,gBAAgB,EAAE,SAAS;CAC5B,CAAC;AAEF,QAAQ;AACR,8FAA8F;AAC9F,aAAa"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { JsonObject } from "./canonical-json.js";
|
|
2
|
+
import type { StellarNetwork } from "./networks.js";
|
|
3
|
+
import type { PROVIDER_STANDARD } from "./standard.js";
|
|
4
|
+
/**
|
|
5
|
+
* JobView.payment, using x402 SettleResponse names where they exist. A receipt is a claim: clients
|
|
6
|
+
* confirm the transaction on chain before showing "paid" [J16].
|
|
7
|
+
*/
|
|
8
|
+
export interface PaymentReceipt {
|
|
9
|
+
network: StellarNetwork;
|
|
10
|
+
asset: string;
|
|
11
|
+
/** Base units, as in the challenge. */
|
|
12
|
+
amount: string;
|
|
13
|
+
payTo: string;
|
|
14
|
+
payer: string;
|
|
15
|
+
/** Stellar transaction hash. */
|
|
16
|
+
transaction: string;
|
|
17
|
+
/** RFC 3339: when the provider saw the settlement. */
|
|
18
|
+
settledAt: string;
|
|
19
|
+
}
|
|
20
|
+
/** The Validation Registry tag of every record this standard's verifiers publish (erc-compatibility.md, T2). */
|
|
21
|
+
export declare const VALIDATION_TAG = "provider-standard-v1";
|
|
22
|
+
export type CheckId = "C1" | "C2" | "C3" | "C4" | "C5" | "C6" | "C7";
|
|
23
|
+
export declare const CHECK_IDS: readonly CheckId[];
|
|
24
|
+
/**
|
|
25
|
+
* A rule a check cites: a rule id such as "P4", or a section such as "§5.5" for a requirement the
|
|
26
|
+
* standard states without an id.
|
|
27
|
+
*/
|
|
28
|
+
export declare const RULE_REFERENCE_PATTERN: RegExp;
|
|
29
|
+
/** One thing a check found: the rule, and what the verifier observed. */
|
|
30
|
+
export interface CheckFinding {
|
|
31
|
+
rule: string;
|
|
32
|
+
/** "fail" breaks the check. "warn" is a SHOULD rule that was not met. */
|
|
33
|
+
severity: "fail" | "warn";
|
|
34
|
+
/** In the verifier's own words: never a secret, and never text copied from the provider. */
|
|
35
|
+
message: string;
|
|
36
|
+
}
|
|
37
|
+
export interface CheckResult {
|
|
38
|
+
check: CheckId;
|
|
39
|
+
/**
|
|
40
|
+
* "skipped" when the check was not run, e.g. C4 without a test payer, or could not finish, e.g. the
|
|
41
|
+
* chain could not be read. A skipped check earns nothing.
|
|
42
|
+
*/
|
|
43
|
+
status: "passed" | "failed" | "skipped";
|
|
44
|
+
/** The rules that failed, such as "P4". Empty unless failed. */
|
|
45
|
+
failedRules: string[];
|
|
46
|
+
/** SHOULD rules that were not met. They never fail the check. */
|
|
47
|
+
warnings?: string[];
|
|
48
|
+
/** Why the check was skipped. */
|
|
49
|
+
reason?: string;
|
|
50
|
+
/** What failed or was warned about, with the verifier's explanation. */
|
|
51
|
+
findings?: CheckFinding[];
|
|
52
|
+
/** What the verifier observed: hashes, the decoded challenge, transaction hashes. Never a secret. */
|
|
53
|
+
evidence?: JsonObject;
|
|
54
|
+
}
|
|
55
|
+
/** 0 when even Described is not reached (provider-standard.md §8). */
|
|
56
|
+
export type ConformanceLevel = 0 | 1 | 2 | 3;
|
|
57
|
+
/** Each level and the checks it needs, including those of the levels below (§8). */
|
|
58
|
+
export declare const CONFORMANCE_LEVELS: readonly {
|
|
59
|
+
level: 1 | 2 | 3;
|
|
60
|
+
name: string;
|
|
61
|
+
checks: readonly CheckId[];
|
|
62
|
+
}[];
|
|
63
|
+
/**
|
|
64
|
+
* The receipt's `score`, and the `response` posted to the Validation Registry, for each level:
|
|
65
|
+
* higher is better, and 100 means fully conformant (erc-compatibility.md, T2).
|
|
66
|
+
*/
|
|
67
|
+
export declare const CONFORMANCE_SCORES: Readonly<Record<ConformanceLevel, number>>;
|
|
68
|
+
/** The highest level whose checks all passed. Registered (C2) and Load-safe (C7) are separate and don't count here. */
|
|
69
|
+
export declare function conformanceLevel(results: readonly CheckResult[]): ConformanceLevel;
|
|
70
|
+
/**
|
|
71
|
+
* What the verifier issues and anchors in the Stellar 8004 Validation Registry. Published as canonical
|
|
72
|
+
* JSON; canonicalSha256(receipt) is the on-chain `response_hash`. schemas/verification-receipt.schema.json
|
|
73
|
+
* describes it.
|
|
74
|
+
*
|
|
75
|
+
* `standard`, `agentId`, `network`, `validator`, `checkedAt`, `score`, `scoreDirection` and `results`
|
|
76
|
+
* are the envelope shared with Stellar ERC-8126 records (erc-compatibility.md, T2).
|
|
77
|
+
*/
|
|
78
|
+
export interface VerificationReceipt {
|
|
79
|
+
standard: typeof PROVIDER_STANDARD;
|
|
80
|
+
/** The provider's Stellar 8004 agent id. Required to publish to the Validation Registry. */
|
|
81
|
+
agentId?: number;
|
|
82
|
+
network: StellarNetwork;
|
|
83
|
+
/** The verifier's G... address, which signs validation_response. */
|
|
84
|
+
validator: string;
|
|
85
|
+
/** RFC 3339. */
|
|
86
|
+
startedAt: string;
|
|
87
|
+
checkedAt: string;
|
|
88
|
+
/** CONFORMANCE_SCORES[level]. */
|
|
89
|
+
score: number;
|
|
90
|
+
scoreDirection: "higher-is-better";
|
|
91
|
+
level: ConformanceLevel;
|
|
92
|
+
/**
|
|
93
|
+
* The manifest that was checked. sha256 is canonicalSha256 of the parsed manifest, absent when the
|
|
94
|
+
* manifest could not be read as JSON.
|
|
95
|
+
*/
|
|
96
|
+
manifest: {
|
|
97
|
+
url: string;
|
|
98
|
+
sha256?: string;
|
|
99
|
+
};
|
|
100
|
+
/** One entry per check, in order from C1 to C7, including skipped ones. */
|
|
101
|
+
results: CheckResult[];
|
|
102
|
+
/** The receipt of the C4 paid call, after the verifier confirmed it on chain. */
|
|
103
|
+
payment?: PaymentReceipt;
|
|
104
|
+
/** The software that issued the receipt, so receipts from a faulty version can be found. */
|
|
105
|
+
tool?: {
|
|
106
|
+
name: string;
|
|
107
|
+
version: string;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/** `$id` of schemas/verification-receipt.schema.json. */
|
|
111
|
+
export declare const VERIFICATION_RECEIPT_SCHEMA_ID = "https://algorialabs.github.io/stellar-agent-services/schemas/provider/1/verification-receipt.schema.json";
|
|
112
|
+
//# sourceMappingURL=receipts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipts.d.ts","sourceRoot":"","sources":["../src/receipts.ts"],"names":[],"mappings":"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"}
|
package/dist/receipts.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Receipts: the payment receipt in a job view (provider-standard.md §5.7) and the verification
|
|
2
|
+
// receipt the verifier issues (docs/verification.md).
|
|
3
|
+
/** The Validation Registry tag of every record this standard's verifiers publish (erc-compatibility.md, T2). */
|
|
4
|
+
export const VALIDATION_TAG = "provider-standard-v1";
|
|
5
|
+
export const CHECK_IDS = ["C1", "C2", "C3", "C4", "C5", "C6", "C7"];
|
|
6
|
+
/**
|
|
7
|
+
* A rule a check cites: a rule id such as "P4", or a section such as "§5.5" for a requirement the
|
|
8
|
+
* standard states without an id.
|
|
9
|
+
*/
|
|
10
|
+
export const RULE_REFERENCE_PATTERN = /^(?:[A-Z][0-9]{1,2}|§[0-9]{1,2}(?:\.[0-9]{1,2})?)$/;
|
|
11
|
+
/** Each level and the checks it needs, including those of the levels below (§8). */
|
|
12
|
+
export const CONFORMANCE_LEVELS = [
|
|
13
|
+
{ level: 1, name: "Described", checks: ["C1", "C6"] },
|
|
14
|
+
{ level: 2, name: "Payable", checks: ["C1", "C6", "C3", "C4"] },
|
|
15
|
+
{ level: 3, name: "Recoverable", checks: ["C1", "C6", "C3", "C4", "C5"] },
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* The receipt's `score`, and the `response` posted to the Validation Registry, for each level:
|
|
19
|
+
* higher is better, and 100 means fully conformant (erc-compatibility.md, T2).
|
|
20
|
+
*/
|
|
21
|
+
export const CONFORMANCE_SCORES = { 0: 0, 1: 33, 2: 67, 3: 100 };
|
|
22
|
+
/** The highest level whose checks all passed. Registered (C2) and Load-safe (C7) are separate and don't count here. */
|
|
23
|
+
export function conformanceLevel(results) {
|
|
24
|
+
const passed = new Set(results.filter((result) => result.status === "passed").map((result) => result.check));
|
|
25
|
+
let reached = 0;
|
|
26
|
+
for (const { level, checks } of CONFORMANCE_LEVELS) {
|
|
27
|
+
if (!checks.every((check) => passed.has(check)))
|
|
28
|
+
break;
|
|
29
|
+
reached = level;
|
|
30
|
+
}
|
|
31
|
+
return reached;
|
|
32
|
+
}
|
|
33
|
+
/** `$id` of schemas/verification-receipt.schema.json. */
|
|
34
|
+
export const VERIFICATION_RECEIPT_SCHEMA_ID = "https://algorialabs.github.io/stellar-agent-services/schemas/provider/1/verification-receipt.schema.json";
|
|
35
|
+
//# sourceMappingURL=receipts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipts.js","sourceRoot":"","sources":["../src/receipts.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,sDAAsD;AAuBtD,gHAAgH;AAChH,MAAM,CAAC,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAGrD,MAAM,CAAC,MAAM,SAAS,GAAuB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAExF;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,oDAAoD,CAAC;AAiC3F,oFAAoF;AACpF,MAAM,CAAC,MAAM,kBAAkB,GAA8E;IAC3G,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;IACrD,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;IAC/D,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;CAC1E,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA+C,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;AAE7G,uHAAuH;AACvH,MAAM,UAAU,gBAAgB,CAAC,OAA+B;IAC9D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7G,IAAI,OAAO,GAAqB,CAAC,CAAC;IAClC,KAAK,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,kBAAkB,EAAE,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAAE,MAAM;QACvD,OAAO,GAAG,KAAK,CAAC;IAClB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAqCD,yDAAyD;AACzD,MAAM,CAAC,MAAM,8BAA8B,GACzC,0GAA0G,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** The manifest's `standard` field. Clients reject a different major version [M8]. */
|
|
2
|
+
export declare const PROVIDER_STANDARD = "stellar-agent-services/provider@1";
|
|
3
|
+
/** Default manifest location on the provider's origin [M2]. */
|
|
4
|
+
export declare const DEFAULT_MANIFEST_PATH = "/.well-known/stellar-agent-services.json";
|
|
5
|
+
/**
|
|
6
|
+
* `$id` of schemas/manifest.schema.json. Provisional until the v1 freeze picks the published URL
|
|
7
|
+
* (IMPLEMENTATION_PLAN.md, open decision 6).
|
|
8
|
+
*/
|
|
9
|
+
export declare const MANIFEST_SCHEMA_ID = "https://algorialabs.github.io/stellar-agent-services/schemas/provider/1/manifest.schema.json";
|
|
10
|
+
/** Largest manifest a client reads [M3]. */
|
|
11
|
+
export declare const MANIFEST_MAX_BYTES: number;
|
|
12
|
+
/** Largest inputSchema or outputSchema, measured as UTF-8 canonical JSON [S6]. */
|
|
13
|
+
export declare const SERVICE_SCHEMA_MAX_BYTES: number;
|
|
14
|
+
/** A service name is a URL path segment, an MCP tool name and an LLM function name (§3.1). */
|
|
15
|
+
export declare const SERVICE_NAME_PATTERN: RegExp;
|
|
16
|
+
/**
|
|
17
|
+
* Base of the problem `type` URIs (§6): `${SPEC_URL}#error-<code>`. Provisional until the v1 freeze
|
|
18
|
+
* picks the published URL (IMPLEMENTATION_PLAN.md, open decision 6).
|
|
19
|
+
*/
|
|
20
|
+
export declare const SPEC_URL = "https://algorialabs.github.io/stellar-agent-services/provider/1";
|
|
21
|
+
/** Longest a provider holds the create-job response open before it must answer 202 [J9]. */
|
|
22
|
+
export declare const CREATE_JOB_HOLD_MAX_SECONDS = 30;
|
|
23
|
+
/** How long finished jobs stay retrievable when the manifest sets no `jobs.retentionSeconds` [J15]. */
|
|
24
|
+
export declare const DEFAULT_RETENTION_SECONDS = 86400;
|
|
25
|
+
//# sourceMappingURL=standard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard.d.ts","sourceRoot":"","sources":["../src/standard.ts"],"names":[],"mappings":"AAKA,sFAAsF;AACtF,eAAO,MAAM,iBAAiB,sCAAsC,CAAC;AAErE,+DAA+D;AAC/D,eAAO,MAAM,qBAAqB,6CAA6C,CAAC;AAEhF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,iGACiE,CAAC;AAEjG,4CAA4C;AAC5C,eAAO,MAAM,kBAAkB,QAAa,CAAC;AAE7C,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,QAAY,CAAC;AAElD,8FAA8F;AAC9F,eAAO,MAAM,oBAAoB,QAA+B,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,QAAQ,oEAAoE,CAAC;AAE1F,4FAA4F;AAC5F,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,uGAAuG;AACvG,eAAO,MAAM,yBAAyB,QAAQ,CAAC"}
|
package/dist/standard.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Standard identity, version and limits (docs/provider-standard.md).
|
|
2
|
+
//
|
|
3
|
+
// Structural limits (field lengths, counts, ranges) live in schemas/manifest.schema.json. This file
|
|
4
|
+
// holds only what code needs.
|
|
5
|
+
/** The manifest's `standard` field. Clients reject a different major version [M8]. */
|
|
6
|
+
export const PROVIDER_STANDARD = "stellar-agent-services/provider@1";
|
|
7
|
+
/** Default manifest location on the provider's origin [M2]. */
|
|
8
|
+
export const DEFAULT_MANIFEST_PATH = "/.well-known/stellar-agent-services.json";
|
|
9
|
+
/**
|
|
10
|
+
* `$id` of schemas/manifest.schema.json. Provisional until the v1 freeze picks the published URL
|
|
11
|
+
* (IMPLEMENTATION_PLAN.md, open decision 6).
|
|
12
|
+
*/
|
|
13
|
+
export const MANIFEST_SCHEMA_ID = "https://algorialabs.github.io/stellar-agent-services/schemas/provider/1/manifest.schema.json";
|
|
14
|
+
/** Largest manifest a client reads [M3]. */
|
|
15
|
+
export const MANIFEST_MAX_BYTES = 256 * 1024;
|
|
16
|
+
/** Largest inputSchema or outputSchema, measured as UTF-8 canonical JSON [S6]. */
|
|
17
|
+
export const SERVICE_SCHEMA_MAX_BYTES = 32 * 1024;
|
|
18
|
+
/** A service name is a URL path segment, an MCP tool name and an LLM function name (§3.1). */
|
|
19
|
+
export const SERVICE_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
20
|
+
/**
|
|
21
|
+
* Base of the problem `type` URIs (§6): `${SPEC_URL}#error-<code>`. Provisional until the v1 freeze
|
|
22
|
+
* picks the published URL (IMPLEMENTATION_PLAN.md, open decision 6).
|
|
23
|
+
*/
|
|
24
|
+
export const SPEC_URL = "https://algorialabs.github.io/stellar-agent-services/provider/1";
|
|
25
|
+
/** Longest a provider holds the create-job response open before it must answer 202 [J9]. */
|
|
26
|
+
export const CREATE_JOB_HOLD_MAX_SECONDS = 30;
|
|
27
|
+
/** How long finished jobs stay retrievable when the manifest sets no `jobs.retentionSeconds` [J15]. */
|
|
28
|
+
export const DEFAULT_RETENTION_SECONDS = 86400;
|
|
29
|
+
//# sourceMappingURL=standard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard.js","sourceRoot":"","sources":["../src/standard.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,oGAAoG;AACpG,8BAA8B;AAE9B,sFAAsF;AACtF,MAAM,CAAC,MAAM,iBAAiB,GAAG,mCAAmC,CAAC;AAErE,+DAA+D;AAC/D,MAAM,CAAC,MAAM,qBAAqB,GAAG,0CAA0C,CAAC;AAEhF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAC7B,8FAA8F,CAAC;AAEjG,4CAA4C;AAC5C,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,GAAG,IAAI,CAAC;AAE7C,kFAAkF;AAClF,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,GAAG,IAAI,CAAC;AAElD,8FAA8F;AAC9F,MAAM,CAAC,MAAM,oBAAoB,GAAG,4BAA4B,CAAC;AAEjE;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,iEAAiE,CAAC;AAE1F,4FAA4F;AAC5F,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAE9C,uGAAuG;AACvG,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAC"}
|
package/dist/strkey.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type StellarAddressKind = "account" | "contract";
|
|
2
|
+
/**
|
|
3
|
+
* Returns "account" for a valid G... address, "contract" for a valid C... address and undefined for
|
|
4
|
+
* anything else, including a wrong checksum. Muxed (M...) addresses and secret seeds are undefined.
|
|
5
|
+
*/
|
|
6
|
+
export declare function stellarAddressKind(address: string): StellarAddressKind | undefined;
|
|
7
|
+
//# sourceMappingURL=strkey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strkey.d.ts","sourceRoot":"","sources":["../src/strkey.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,UAAU,CAAC;AASxD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CASlF"}
|
package/dist/strkey.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Stellar address checks (strkey, SEP-23) for the addresses a manifest names: G... accounts and C...
|
|
2
|
+
// contracts. Dependency-free, so the read-only discovery server can use it; test/strkey.test.ts pins
|
|
3
|
+
// it to @stellar/stellar-sdk.
|
|
4
|
+
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
5
|
+
const ADDRESS_LENGTH = 56; // 1 version byte + 32 bytes + 2 checksum bytes, base32 without padding
|
|
6
|
+
const VERSION_BYTES = new Map([
|
|
7
|
+
[6 << 3, "account"], // "G"
|
|
8
|
+
[2 << 3, "contract"], // "C"
|
|
9
|
+
]);
|
|
10
|
+
/**
|
|
11
|
+
* Returns "account" for a valid G... address, "contract" for a valid C... address and undefined for
|
|
12
|
+
* anything else, including a wrong checksum. Muxed (M...) addresses and secret seeds are undefined.
|
|
13
|
+
*/
|
|
14
|
+
export function stellarAddressKind(address) {
|
|
15
|
+
if (address.length !== ADDRESS_LENGTH)
|
|
16
|
+
return undefined;
|
|
17
|
+
const bytes = decodeBase32(address);
|
|
18
|
+
if (bytes === undefined)
|
|
19
|
+
return undefined;
|
|
20
|
+
const checksum = crc16Xmodem(bytes.subarray(0, 33));
|
|
21
|
+
// The checksum is stored little-endian.
|
|
22
|
+
if (bytes[33] !== (checksum & 0xff) || bytes[34] !== checksum >> 8)
|
|
23
|
+
return undefined;
|
|
24
|
+
return VERSION_BYTES.get(bytes[0] ?? -1);
|
|
25
|
+
}
|
|
26
|
+
function decodeBase32(text) {
|
|
27
|
+
const bytes = new Uint8Array(Math.floor((text.length * 5) / 8));
|
|
28
|
+
let buffer = 0;
|
|
29
|
+
let bits = 0;
|
|
30
|
+
let index = 0;
|
|
31
|
+
for (const char of text) {
|
|
32
|
+
const value = ALPHABET.indexOf(char);
|
|
33
|
+
if (value < 0)
|
|
34
|
+
return undefined;
|
|
35
|
+
buffer = (buffer << 5) | value;
|
|
36
|
+
bits += 5;
|
|
37
|
+
if (bits >= 8) {
|
|
38
|
+
bits -= 8;
|
|
39
|
+
bytes[index++] = (buffer >> bits) & 0xff;
|
|
40
|
+
buffer &= (1 << bits) - 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// 56 characters are exactly 35 bytes, so no bits may be left over.
|
|
44
|
+
return bits === 0 ? bytes : undefined;
|
|
45
|
+
}
|
|
46
|
+
function crc16Xmodem(bytes) {
|
|
47
|
+
let crc = 0;
|
|
48
|
+
for (const byte of bytes) {
|
|
49
|
+
crc ^= byte << 8;
|
|
50
|
+
for (let bit = 0; bit < 8; bit++) {
|
|
51
|
+
crc = crc & 0x8000 ? ((crc << 1) ^ 0x1021) & 0xffff : (crc << 1) & 0xffff;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return crc;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=strkey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strkey.js","sourceRoot":"","sources":["../src/strkey.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,qGAAqG;AACrG,8BAA8B;AAI9B,MAAM,QAAQ,GAAG,kCAAkC,CAAC;AACpD,MAAM,cAAc,GAAG,EAAE,CAAC,CAAC,uEAAuE;AAClG,MAAM,aAAa,GAA4C,IAAI,GAAG,CAAC;IACrE,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM;IAC3B,CAAC,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM;CAC7B,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,IAAI,OAAO,CAAC,MAAM,KAAK,cAAc;QAAE,OAAO,SAAS,CAAC;IACxD,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAE1C,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACpD,wCAAwC;IACxC,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,QAAQ,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACrF,OAAO,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChE,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAChC,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;QAC/B,IAAI,IAAI,CAAC,CAAC;QACV,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACd,IAAI,IAAI,CAAC,CAAC;YACV,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC;YACzC,MAAM,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,mEAAmE;IACnE,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACxC,CAAC;AAED,SAAS,WAAW,CAAC,KAAiB;IACpC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC;QACjB,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC;YACjC,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC;QAC5E,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { StellarNetwork } from "./networks.js";
|
|
2
|
+
import type { PROVIDER_STANDARD } from "./standard.js";
|
|
3
|
+
/** The `type` of a validation request document. */
|
|
4
|
+
export declare const VALIDATION_REQUEST_TYPE = "validation-request";
|
|
5
|
+
/**
|
|
6
|
+
* What a provider's owner asks a verifier to check. `standard`, `agentId`, `network`, `validator` and
|
|
7
|
+
* `manifest.url` are also in the verification receipt that answers it.
|
|
8
|
+
*/
|
|
9
|
+
export interface ValidationRequest {
|
|
10
|
+
standard: typeof PROVIDER_STANDARD;
|
|
11
|
+
type: typeof VALIDATION_REQUEST_TYPE;
|
|
12
|
+
/** The provider's Stellar 8004 agent id. */
|
|
13
|
+
agentId: number;
|
|
14
|
+
network: StellarNetwork;
|
|
15
|
+
/** The manifest to check, at the HTTPS URL the agent's registration names [I1]. */
|
|
16
|
+
manifest: {
|
|
17
|
+
url: string;
|
|
18
|
+
};
|
|
19
|
+
/** The verifier's G... address: the only account that may answer. */
|
|
20
|
+
validator: string;
|
|
21
|
+
/** RFC 3339. It makes each request unique: the registry refuses a request_hash it already has. */
|
|
22
|
+
requestedAt: string;
|
|
23
|
+
}
|
|
24
|
+
/** `$id` of schemas/validation-request.schema.json. */
|
|
25
|
+
export declare const VALIDATION_REQUEST_SCHEMA_ID = "https://algorialabs.github.io/stellar-agent-services/schemas/provider/1/validation-request.schema.json";
|
|
26
|
+
/** The request's bytes: UTF-8 canonical JSON. */
|
|
27
|
+
export declare function validationRequestBytes(request: ValidationRequest): Uint8Array;
|
|
28
|
+
/** sha256 of the request's bytes: the on-chain request_hash. */
|
|
29
|
+
export declare function validationRequestHash(request: ValidationRequest): Promise<string>;
|
|
30
|
+
/** The request_uri that holds the request itself: its bytes in a base64 data: URI, so nothing needs hosting. */
|
|
31
|
+
export declare function validationRequestDataUri(request: ValidationRequest): string;
|
|
32
|
+
//# sourceMappingURL=validation-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-request.d.ts","sourceRoot":"","sources":["../src/validation-request.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,mDAAmD;AACnD,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAE5D;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,iBAAiB,CAAC;IACnC,IAAI,EAAE,OAAO,uBAAuB,CAAC;IACrC,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,cAAc,CAAC;IACxB,mFAAmF;IACnF,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,kGAAkG;IAClG,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,uDAAuD;AACvD,eAAO,MAAM,4BAA4B,2GACiE,CAAC;AAE3G,iDAAiD;AACjD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAE7E;AAED,gEAAgE;AAChE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjF;AAED,gHAAgH;AAChH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAI3E"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// The validation request (docs/verification.md): what a provider's owner asks a verifier to check, in a
|
|
2
|
+
// Stellar 8004 validation_request.
|
|
3
|
+
//
|
|
4
|
+
// The request commits to its document. request_hash is the SHA-256 of the document's RFC 8785 canonical
|
|
5
|
+
// JSON (the contentHash mode of the 8004 SDK's generateRequestNonce), and request_uri is a data: URI holding
|
|
6
|
+
// exactly those bytes, so anyone can decode it, hash it and compare it with the chain, as with a receipt and
|
|
7
|
+
// its response_hash. schemas/validation-request.schema.json describes the document, and
|
|
8
|
+
// test-vectors/validation-requests.json pins the hash and the URI.
|
|
9
|
+
import { canonicalJson, sha256Hex } from "./canonical-json.js";
|
|
10
|
+
/** The `type` of a validation request document. */
|
|
11
|
+
export const VALIDATION_REQUEST_TYPE = "validation-request";
|
|
12
|
+
/** `$id` of schemas/validation-request.schema.json. */
|
|
13
|
+
export const VALIDATION_REQUEST_SCHEMA_ID = "https://algorialabs.github.io/stellar-agent-services/schemas/provider/1/validation-request.schema.json";
|
|
14
|
+
/** The request's bytes: UTF-8 canonical JSON. */
|
|
15
|
+
export function validationRequestBytes(request) {
|
|
16
|
+
return new TextEncoder().encode(canonicalJson(request));
|
|
17
|
+
}
|
|
18
|
+
/** sha256 of the request's bytes: the on-chain request_hash. */
|
|
19
|
+
export function validationRequestHash(request) {
|
|
20
|
+
return sha256Hex(validationRequestBytes(request));
|
|
21
|
+
}
|
|
22
|
+
/** The request_uri that holds the request itself: its bytes in a base64 data: URI, so nothing needs hosting. */
|
|
23
|
+
export function validationRequestDataUri(request) {
|
|
24
|
+
let binary = "";
|
|
25
|
+
for (const byte of validationRequestBytes(request))
|
|
26
|
+
binary += String.fromCharCode(byte);
|
|
27
|
+
return `data:application/json;base64,${btoa(binary)}`;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=validation-request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-request.js","sourceRoot":"","sources":["../src/validation-request.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,mCAAmC;AACnC,EAAE;AACF,wGAAwG;AACxG,6GAA6G;AAC7G,6GAA6G;AAC7G,wFAAwF;AACxF,mEAAmE;AAEnE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAI/D,mDAAmD;AACnD,MAAM,CAAC,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AAoB5D,uDAAuD;AACvD,MAAM,CAAC,MAAM,4BAA4B,GACvC,wGAAwG,CAAC;AAE3G,iDAAiD;AACjD,MAAM,UAAU,sBAAsB,CAAC,OAA0B;IAC/D,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,qBAAqB,CAAC,OAA0B;IAC9D,OAAO,SAAS,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,wBAAwB,CAAC,OAA0B;IACjE,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,sBAAsB,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACxF,OAAO,gCAAgC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AACxD,CAAC"}
|