@atproto/lexicon-resolver 0.1.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/CHANGELOG.md +14 -0
- package/LICENSE.txt +7 -0
- package/README.md +79 -0
- package/dist/client/index.d.ts +28 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +118 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/lexicons.d.ts +105 -0
- package/dist/client/lexicons.d.ts.map +1 -0
- package/dist/client/lexicons.js +75 -0
- package/dist/client/lexicons.js.map +1 -0
- package/dist/client/types/com/atproto/sync/getRecord.d.ts +38 -0
- package/dist/client/types/com/atproto/sync/getRecord.d.ts.map +1 -0
- package/dist/client/types/com/atproto/sync/getRecord.js +58 -0
- package/dist/client/types/com/atproto/sync/getRecord.js.map +1 -0
- package/dist/client/util.d.ts +37 -0
- package/dist/client/util.d.ts.map +1 -0
- package/dist/client/util.js +38 -0
- package/dist/client/util.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/lexicon.d.ts +43 -0
- package/dist/lexicon.d.ts.map +1 -0
- package/dist/lexicon.js +98 -0
- package/dist/lexicon.js.map +1 -0
- package/dist/record.d.ts +37 -0
- package/dist/record.d.ts.map +1 -0
- package/dist/record.js +100 -0
- package/dist/record.js.map +1 -0
- package/dist/util.d.ts +2 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +14 -0
- package/dist/util.js.map +1 -0
- package/jest.config.js +7 -0
- package/package.json +46 -0
- package/src/client/index.ts +67 -0
- package/src/client/lexicons.ts +98 -0
- package/src/client/types/com/atproto/sync/getRecord.ts +78 -0
- package/src/client/util.ts +82 -0
- package/src/index.ts +2 -0
- package/src/lexicon.ts +147 -0
- package/src/record.ts +156 -0
- package/src/util.ts +10 -0
- package/tests/lexicon.test.ts +266 -0
- package/tests/record.test.ts +98 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +7 -0
- package/tsconfig.tests.json +8 -0
- package/tsconfig.tests.tsbuildinfo +1 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./record.js"), exports);
|
|
18
|
+
__exportStar(require("./lexicon.js"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA2B;AAC3B,+CAA4B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid';
|
|
2
|
+
import { LexiconDoc } from '@atproto/lexicon';
|
|
3
|
+
import { Commit } from '@atproto/repo';
|
|
4
|
+
import { AtUri, NSID } from '@atproto/syntax';
|
|
5
|
+
import { BuildRecordResolverOptions, ResolveRecordOptions } from './record.js';
|
|
6
|
+
export declare const LEXICON_SCHEMA_NSID = "com.atproto.lexicon.schema";
|
|
7
|
+
/**
|
|
8
|
+
* Resolve Lexicon from an NSID
|
|
9
|
+
*/
|
|
10
|
+
export type LexiconResolver = (nsid: NSID | string) => Promise<LexiconResolution>;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve Lexicon from an NSID using Lexicon DID authority and record resolution
|
|
13
|
+
*/
|
|
14
|
+
export type AtprotoLexiconResolver = (nsid: NSID | string, options?: ResolveLexiconOptions) => Promise<LexiconResolution>;
|
|
15
|
+
export type BuildLexiconResolverOptions = BuildRecordResolverOptions;
|
|
16
|
+
export type ResolveLexiconOptions = ResolveRecordOptions & {
|
|
17
|
+
didAuthority?: string;
|
|
18
|
+
};
|
|
19
|
+
export type LexiconResolution = {
|
|
20
|
+
commit: Commit;
|
|
21
|
+
uri: AtUri;
|
|
22
|
+
cid: CID;
|
|
23
|
+
nsid: NSID;
|
|
24
|
+
lexicon: LexiconDoc & LexiconSchemaRecord;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Build a Lexicon resolver function.
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildLexiconResolver(options?: BuildLexiconResolverOptions): AtprotoLexiconResolver;
|
|
30
|
+
export declare const resolveLexicon: AtprotoLexiconResolver;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the DID authority for a Lexicon from the network using DNS, based on its NSID.
|
|
33
|
+
* @param nsidStr NSID or string representing one for which to lookup its Lexicon DID authority.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveLexiconDidAuthority(nsidStr: NSID | string): Promise<string | undefined>;
|
|
36
|
+
export declare class LexiconResolutionError extends Error {
|
|
37
|
+
constructor(message?: string, options?: ErrorOptions);
|
|
38
|
+
}
|
|
39
|
+
type LexiconSchemaRecord = {
|
|
40
|
+
$type: typeof LEXICON_SCHEMA_NSID;
|
|
41
|
+
};
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=lexicon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexicon.d.ts","sourceRoot":"","sources":["../src/lexicon.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAE,UAAU,EAAmB,MAAM,kBAAkB,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAkB,MAAM,iBAAiB,CAAA;AAC7D,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EAErB,MAAM,aAAa,CAAA;AAKpB,eAAO,MAAM,mBAAmB,+BAA+B,CAAA;AAE/D;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,IAAI,EAAE,IAAI,GAAG,MAAM,KAChB,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAE/B;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACnC,IAAI,EAAE,IAAI,GAAG,MAAM,EACnB,OAAO,CAAC,EAAE,qBAAqB,KAC5B,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAE/B,MAAM,MAAM,2BAA2B,GAAG,0BAA0B,CAAA;AAEpE,MAAM,MAAM,qBAAqB,GAAG,oBAAoB,GAAG;IACzD,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,KAAK,CAAA;IACV,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,IAAI,CAAA;IACV,OAAO,EAAE,UAAU,GAAG,mBAAmB,CAAA;CAC1C,CAAA;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,2BAAgC,GACxC,sBAAsB,CAoCxB;AAED,eAAO,MAAM,cAAc,wBAAyB,CAAA;AAEpD;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,IAAI,GAAG,MAAM,GACrB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAK7B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIrD;AAmCD,KAAK,mBAAmB,GAAG;IAAE,KAAK,EAAE,OAAO,mBAAmB,CAAA;CAAE,CAAA"}
|
package/dist/lexicon.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LexiconResolutionError = exports.resolveLexicon = exports.LEXICON_SCHEMA_NSID = void 0;
|
|
7
|
+
exports.buildLexiconResolver = buildLexiconResolver;
|
|
8
|
+
exports.resolveLexiconDidAuthority = resolveLexiconDidAuthority;
|
|
9
|
+
const promises_1 = __importDefault(require("node:dns/promises"));
|
|
10
|
+
const lexicon_1 = require("@atproto/lexicon");
|
|
11
|
+
const syntax_1 = require("@atproto/syntax");
|
|
12
|
+
const record_js_1 = require("./record.js");
|
|
13
|
+
const util_js_1 = require("./util.js");
|
|
14
|
+
const DNS_SUBDOMAIN = '_lexicon';
|
|
15
|
+
const DNS_PREFIX = 'did=';
|
|
16
|
+
exports.LEXICON_SCHEMA_NSID = 'com.atproto.lexicon.schema';
|
|
17
|
+
/**
|
|
18
|
+
* Build a Lexicon resolver function.
|
|
19
|
+
*/
|
|
20
|
+
function buildLexiconResolver(options = {}) {
|
|
21
|
+
const resolveRecord = (0, record_js_1.buildRecordResolver)(options);
|
|
22
|
+
return async function (nsidStr, opts = {}) {
|
|
23
|
+
const nsid = typeof nsidStr === 'string' ? syntax_1.NSID.parse(nsidStr) : nsidStr;
|
|
24
|
+
const didAuthority = await getDidAuthority(nsid, opts);
|
|
25
|
+
const verified = await resolveRecord(syntax_1.AtUri.make(didAuthority, exports.LEXICON_SCHEMA_NSID, nsid.toString()), { forceRefresh: opts.forceRefresh }).catch((err) => {
|
|
26
|
+
throw new LexiconResolutionError('Could not resolve Lexicon schema record', { cause: err });
|
|
27
|
+
});
|
|
28
|
+
let lexicon;
|
|
29
|
+
try {
|
|
30
|
+
lexicon = (0, lexicon_1.parseLexiconDoc)(verified.record);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
throw new LexiconResolutionError('Invalid Lexicon document', {
|
|
34
|
+
cause: err,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (!isLexiconSchemaRecord(lexicon)) {
|
|
38
|
+
throw new LexiconResolutionError('Invalid Lexicon schema record');
|
|
39
|
+
}
|
|
40
|
+
if (lexicon.id !== nsid.toString()) {
|
|
41
|
+
throw new LexiconResolutionError(`Lexicon schema record id does not match NSID: ${lexicon.id}`);
|
|
42
|
+
}
|
|
43
|
+
const { uri, cid, commit } = verified;
|
|
44
|
+
return { commit, uri, cid, nsid, lexicon };
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
exports.resolveLexicon = buildLexiconResolver();
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the DID authority for a Lexicon from the network using DNS, based on its NSID.
|
|
50
|
+
* @param nsidStr NSID or string representing one for which to lookup its Lexicon DID authority.
|
|
51
|
+
*/
|
|
52
|
+
async function resolveLexiconDidAuthority(nsidStr) {
|
|
53
|
+
const nsid = typeof nsidStr === 'string' ? syntax_1.NSID.parse(nsidStr) : nsidStr;
|
|
54
|
+
const did = await resolveDns(nsid.authority);
|
|
55
|
+
if (did == null || !(0, util_js_1.isValidDid)(did))
|
|
56
|
+
return;
|
|
57
|
+
return did;
|
|
58
|
+
}
|
|
59
|
+
class LexiconResolutionError extends Error {
|
|
60
|
+
constructor(message, options) {
|
|
61
|
+
super(message, options);
|
|
62
|
+
this.name = 'LexiconResolutionError';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.LexiconResolutionError = LexiconResolutionError;
|
|
66
|
+
async function getDidAuthority(nsid, options) {
|
|
67
|
+
if (options.didAuthority) {
|
|
68
|
+
(0, syntax_1.ensureValidDid)(options.didAuthority);
|
|
69
|
+
return options.didAuthority;
|
|
70
|
+
}
|
|
71
|
+
const did = await resolveLexiconDidAuthority(nsid);
|
|
72
|
+
if (!did) {
|
|
73
|
+
throw new LexiconResolutionError(`Could not resolve a DID authority for NSID: ${nsid}`);
|
|
74
|
+
}
|
|
75
|
+
return did;
|
|
76
|
+
}
|
|
77
|
+
async function resolveDns(authority) {
|
|
78
|
+
let chunkedResults;
|
|
79
|
+
try {
|
|
80
|
+
chunkedResults = await promises_1.default.resolveTxt(`${DNS_SUBDOMAIN}.${authority}`);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
return parseDnsResult(chunkedResults);
|
|
86
|
+
}
|
|
87
|
+
function parseDnsResult(chunkedResults) {
|
|
88
|
+
const results = chunkedResults.map((chunks) => chunks.join(''));
|
|
89
|
+
const found = results.filter((i) => i.startsWith(DNS_PREFIX));
|
|
90
|
+
if (found.length !== 1) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
return found[0].slice(DNS_PREFIX.length);
|
|
94
|
+
}
|
|
95
|
+
function isLexiconSchemaRecord(v) {
|
|
96
|
+
return v?.['$type'] === exports.LEXICON_SCHEMA_NSID;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=lexicon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexicon.js","sourceRoot":"","sources":["../src/lexicon.ts"],"names":[],"mappings":"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"}
|
package/dist/record.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid';
|
|
2
|
+
import { IdResolver } from '@atproto/identity';
|
|
3
|
+
import { RepoRecord } from '@atproto/lexicon';
|
|
4
|
+
import { Commit } from '@atproto/repo';
|
|
5
|
+
import { AtUri } from '@atproto/syntax';
|
|
6
|
+
import { BuildFetchHandlerOptions, FetchHandler } from '@atproto/xrpc';
|
|
7
|
+
/**
|
|
8
|
+
* Resolve a record from the network.
|
|
9
|
+
*/
|
|
10
|
+
export type RecordResolver = (uriStr: AtUri | string) => Promise<RecordResolution>;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a record from the network, verifying its authenticity.
|
|
13
|
+
*/
|
|
14
|
+
export type AtprotoRecordResolver = (uriStr: AtUri | string, options?: ResolveRecordOptions) => Promise<RecordResolution>;
|
|
15
|
+
export type BuildRecordResolverOptions = {
|
|
16
|
+
idResolver?: IdResolver;
|
|
17
|
+
rpc?: Partial<BuildFetchHandlerOptions> | FetchHandler;
|
|
18
|
+
};
|
|
19
|
+
export type ResolveRecordOptions = {
|
|
20
|
+
forceRefresh?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export type RecordResolution = {
|
|
23
|
+
commit: Commit;
|
|
24
|
+
uri: AtUri;
|
|
25
|
+
cid: CID;
|
|
26
|
+
record: RepoRecord;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Build a record resolver function.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildRecordResolver(options?: BuildRecordResolverOptions): AtprotoRecordResolver;
|
|
32
|
+
export declare const resolveRecord: AtprotoRecordResolver;
|
|
33
|
+
export declare const safeFetch: (input: string | URL | Request, init?: RequestInit | undefined) => Promise<Response>;
|
|
34
|
+
export declare class RecordResolutionError extends Error {
|
|
35
|
+
constructor(message?: string, options?: ErrorOptions);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EACL,MAAM,EAMP,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,KAAK,EAAkB,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAKtE;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,MAAM,EAAE,KAAK,GAAG,MAAM,KACnB,OAAO,CAAC,gBAAgB,CAAC,CAAA;AAE9B;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,MAAM,EAAE,KAAK,GAAG,MAAM,EACtB,OAAO,CAAC,EAAE,oBAAoB,KAC3B,OAAO,CAAC,gBAAgB,CAAC,CAAA;AAE9B,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC,wBAAwB,CAAC,GAAG,YAAY,CAAA;CACvD,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,KAAK,CAAA;IACV,GAAG,EAAE,GAAG,CAAA;IACR,MAAM,EAAE,UAAU,CAAA;CACnB,CAAA;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,0BAA+B,GACvC,qBAAqB,CAyCvB;AAED,eAAO,MAAM,aAAa,uBAAwB,CAAA;AAElD,eAAO,MAAM,SAAS,sFAIpB,CAAA;AAEF,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIrD"}
|
package/dist/record.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RecordResolutionError = exports.safeFetch = exports.resolveRecord = void 0;
|
|
4
|
+
exports.buildRecordResolver = buildRecordResolver;
|
|
5
|
+
const identity_1 = require("@atproto/identity");
|
|
6
|
+
const repo_1 = require("@atproto/repo");
|
|
7
|
+
const syntax_1 = require("@atproto/syntax");
|
|
8
|
+
const fetch_node_1 = require("@atproto-labs/fetch-node");
|
|
9
|
+
const index_js_1 = require("./client/index.js");
|
|
10
|
+
const util_js_1 = require("./util.js");
|
|
11
|
+
/**
|
|
12
|
+
* Build a record resolver function.
|
|
13
|
+
*/
|
|
14
|
+
function buildRecordResolver(options = {}) {
|
|
15
|
+
const { idResolver = new identity_1.IdResolver(), rpc } = options;
|
|
16
|
+
return async function resolveRecord(uriStr, opts = {}) {
|
|
17
|
+
const uri = typeof uriStr === 'string' ? new syntax_1.AtUri(uriStr) : uriStr;
|
|
18
|
+
const did = await getDidFromUri(uri, { idResolver });
|
|
19
|
+
const identity = await idResolver.did
|
|
20
|
+
.resolveAtprotoData(did, opts.forceRefresh)
|
|
21
|
+
.catch((err) => {
|
|
22
|
+
throw new RecordResolutionError('Could not resolve DID identity data', {
|
|
23
|
+
cause: err,
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
const client = new index_js_1.AtpBaseClient(typeof rpc === 'function'
|
|
27
|
+
? rpc
|
|
28
|
+
: {
|
|
29
|
+
...rpc,
|
|
30
|
+
service: rpc?.service ?? identity.pds,
|
|
31
|
+
fetch: rpc?.fetch ?? exports.safeFetch,
|
|
32
|
+
});
|
|
33
|
+
const { data: proofBytes } = await client.com.atproto.sync
|
|
34
|
+
.getRecord({
|
|
35
|
+
did,
|
|
36
|
+
collection: uri.collection,
|
|
37
|
+
rkey: uri.rkey,
|
|
38
|
+
})
|
|
39
|
+
.catch((err) => {
|
|
40
|
+
throw new RecordResolutionError('Could not fetch record proof', {
|
|
41
|
+
cause: err,
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
const verified = await verifyRecordProof(proofBytes, {
|
|
45
|
+
uri: syntax_1.AtUri.make(did, uri.collection, uri.rkey),
|
|
46
|
+
signingKey: identity.signingKey,
|
|
47
|
+
});
|
|
48
|
+
return verified;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
exports.resolveRecord = buildRecordResolver();
|
|
52
|
+
exports.safeFetch = (0, fetch_node_1.safeFetchWrap)({
|
|
53
|
+
allowIpHost: false,
|
|
54
|
+
allowImplicitRedirect: true,
|
|
55
|
+
responseMaxSize: (1024 + 10) * 1024, // 1MB + 10kB, just a bit larger than max record size
|
|
56
|
+
});
|
|
57
|
+
class RecordResolutionError extends Error {
|
|
58
|
+
constructor(message, options) {
|
|
59
|
+
super(message, options);
|
|
60
|
+
this.name = 'RecordResolutionError';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.RecordResolutionError = RecordResolutionError;
|
|
64
|
+
async function getDidFromUri(uri, { idResolver }) {
|
|
65
|
+
if (uri.host.startsWith('did:')) {
|
|
66
|
+
(0, syntax_1.ensureValidDid)(uri.host);
|
|
67
|
+
return uri.host;
|
|
68
|
+
}
|
|
69
|
+
const resolved = await idResolver.handle.resolve(uri.host);
|
|
70
|
+
if (!resolved || !(0, util_js_1.isValidDid)(resolved)) {
|
|
71
|
+
throw new RecordResolutionError('Could not resolve handle found in AT-URI');
|
|
72
|
+
}
|
|
73
|
+
return resolved;
|
|
74
|
+
}
|
|
75
|
+
async function verifyRecordProof(proofBytes, { uri, signingKey }) {
|
|
76
|
+
const { root, blocks } = await (0, repo_1.readCarWithRoot)(proofBytes).catch((err) => {
|
|
77
|
+
throw new RecordResolutionError('Malformed record proof', { cause: err });
|
|
78
|
+
});
|
|
79
|
+
const blockstore = new repo_1.MemoryBlockstore(blocks);
|
|
80
|
+
const commit = await blockstore.readObj(root, repo_1.def.commit).catch((err) => {
|
|
81
|
+
throw new RecordResolutionError('Invalid commit in record proof', {
|
|
82
|
+
cause: err,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
if (commit.did !== uri.host) {
|
|
86
|
+
throw new RecordResolutionError(`Invalid repo did: ${commit.did}`);
|
|
87
|
+
}
|
|
88
|
+
const validSig = await (0, repo_1.verifyCommitSig)(commit, signingKey);
|
|
89
|
+
if (!validSig) {
|
|
90
|
+
throw new RecordResolutionError(`Invalid signature on commit: ${root.toString()}`);
|
|
91
|
+
}
|
|
92
|
+
const mst = repo_1.MST.load(blockstore, commit.data);
|
|
93
|
+
const cid = await mst.get(`${uri.collection}/${uri.rkey}`);
|
|
94
|
+
if (!cid) {
|
|
95
|
+
throw new RecordResolutionError('Record not found in proof');
|
|
96
|
+
}
|
|
97
|
+
const record = await blockstore.readRecord(cid);
|
|
98
|
+
return { commit, uri, cid, record };
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.js","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"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"}
|
package/dist/util.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,WAOrC"}
|
package/dist/util.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isValidDid = isValidDid;
|
|
4
|
+
const syntax_1 = require("@atproto/syntax");
|
|
5
|
+
function isValidDid(did) {
|
|
6
|
+
try {
|
|
7
|
+
(0, syntax_1.ensureValidDid)(did);
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=util.js.map
|
package/dist/util.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;AAEA,gCAOC;AATD,4CAAgD;AAEhD,SAAgB,UAAU,CAAC,GAAW;IACpC,IAAI,CAAC;QACH,IAAA,uBAAc,EAAC,GAAG,CAAC,CAAA;QACnB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
|
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atproto/lexicon-resolver",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "commonjs",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"description": "ATProto Lexicon resolution",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"atproto",
|
|
9
|
+
"lexicon"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://atproto.com",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/bluesky-social/atproto",
|
|
15
|
+
"directory": "packages/lexicon-resolver"
|
|
16
|
+
},
|
|
17
|
+
"main": "dist/index.js",
|
|
18
|
+
"types": "dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"default": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"multiformats": "^9.9.0",
|
|
27
|
+
"@atproto-labs/fetch-node": "^0.1.9",
|
|
28
|
+
"@atproto/identity": "^0.4.8",
|
|
29
|
+
"@atproto/lexicon": "^0.4.13",
|
|
30
|
+
"@atproto/repo": "^0.8.6",
|
|
31
|
+
"@atproto/syntax": "^0.4.0",
|
|
32
|
+
"@atproto/xrpc": "^0.7.2"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"jest": "^28.1.2",
|
|
36
|
+
"typescript": "^5.6.3",
|
|
37
|
+
"@atproto/common": "^0.4.11",
|
|
38
|
+
"@atproto/lex-cli": "^0.9.2",
|
|
39
|
+
"@atproto/dev-env": "^0.3.165"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"test": "jest",
|
|
43
|
+
"build": "tsc --build tsconfig.json",
|
|
44
|
+
"codegen": "lex gen-api --yes ./src/client ../../lexicons/com/atproto/sync/getRecord.json"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
XrpcClient,
|
|
6
|
+
type FetchHandler,
|
|
7
|
+
type FetchHandlerOptions,
|
|
8
|
+
} from '@atproto/xrpc'
|
|
9
|
+
import { schemas } from './lexicons.js'
|
|
10
|
+
import { CID } from 'multiformats/cid'
|
|
11
|
+
import { type OmitKey, type Un$Typed } from './util.js'
|
|
12
|
+
import * as ComAtprotoSyncGetRecord from './types/com/atproto/sync/getRecord.js'
|
|
13
|
+
|
|
14
|
+
export * as ComAtprotoSyncGetRecord from './types/com/atproto/sync/getRecord.js'
|
|
15
|
+
|
|
16
|
+
export class AtpBaseClient extends XrpcClient {
|
|
17
|
+
com: ComNS
|
|
18
|
+
|
|
19
|
+
constructor(options: FetchHandler | FetchHandlerOptions) {
|
|
20
|
+
super(options, schemas)
|
|
21
|
+
this.com = new ComNS(this)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** @deprecated use `this` instead */
|
|
25
|
+
get xrpc(): XrpcClient {
|
|
26
|
+
return this
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class ComNS {
|
|
31
|
+
_client: XrpcClient
|
|
32
|
+
atproto: ComAtprotoNS
|
|
33
|
+
|
|
34
|
+
constructor(client: XrpcClient) {
|
|
35
|
+
this._client = client
|
|
36
|
+
this.atproto = new ComAtprotoNS(client)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export class ComAtprotoNS {
|
|
41
|
+
_client: XrpcClient
|
|
42
|
+
sync: ComAtprotoSyncNS
|
|
43
|
+
|
|
44
|
+
constructor(client: XrpcClient) {
|
|
45
|
+
this._client = client
|
|
46
|
+
this.sync = new ComAtprotoSyncNS(client)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class ComAtprotoSyncNS {
|
|
51
|
+
_client: XrpcClient
|
|
52
|
+
|
|
53
|
+
constructor(client: XrpcClient) {
|
|
54
|
+
this._client = client
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getRecord(
|
|
58
|
+
params?: ComAtprotoSyncGetRecord.QueryParams,
|
|
59
|
+
opts?: ComAtprotoSyncGetRecord.CallOptions,
|
|
60
|
+
): Promise<ComAtprotoSyncGetRecord.Response> {
|
|
61
|
+
return this._client
|
|
62
|
+
.call('com.atproto.sync.getRecord', params, undefined, opts)
|
|
63
|
+
.catch((e) => {
|
|
64
|
+
throw ComAtprotoSyncGetRecord.toKnownErr(e)
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
type LexiconDoc,
|
|
6
|
+
Lexicons,
|
|
7
|
+
ValidationError,
|
|
8
|
+
type ValidationResult,
|
|
9
|
+
} from '@atproto/lexicon'
|
|
10
|
+
import { type $Typed, is$typed, maybe$typed } from './util.js'
|
|
11
|
+
|
|
12
|
+
export const schemaDict = {
|
|
13
|
+
ComAtprotoSyncGetRecord: {
|
|
14
|
+
lexicon: 1,
|
|
15
|
+
id: 'com.atproto.sync.getRecord',
|
|
16
|
+
defs: {
|
|
17
|
+
main: {
|
|
18
|
+
type: 'query',
|
|
19
|
+
description:
|
|
20
|
+
'Get data blocks needed to prove the existence or non-existence of record in the current version of repo. Does not require auth.',
|
|
21
|
+
parameters: {
|
|
22
|
+
type: 'params',
|
|
23
|
+
required: ['did', 'collection', 'rkey'],
|
|
24
|
+
properties: {
|
|
25
|
+
did: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
format: 'did',
|
|
28
|
+
description: 'The DID of the repo.',
|
|
29
|
+
},
|
|
30
|
+
collection: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
format: 'nsid',
|
|
33
|
+
},
|
|
34
|
+
rkey: {
|
|
35
|
+
type: 'string',
|
|
36
|
+
description: 'Record Key',
|
|
37
|
+
format: 'record-key',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
output: {
|
|
42
|
+
encoding: 'application/vnd.ipld.car',
|
|
43
|
+
},
|
|
44
|
+
errors: [
|
|
45
|
+
{
|
|
46
|
+
name: 'RecordNotFound',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'RepoNotFound',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'RepoTakendown',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'RepoSuspended',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'RepoDeactivated',
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
} as const satisfies Record<string, LexiconDoc>
|
|
65
|
+
export const schemas = Object.values(schemaDict) satisfies LexiconDoc[]
|
|
66
|
+
export const lexicons: Lexicons = new Lexicons(schemas)
|
|
67
|
+
|
|
68
|
+
export function validate<T extends { $type: string }>(
|
|
69
|
+
v: unknown,
|
|
70
|
+
id: string,
|
|
71
|
+
hash: string,
|
|
72
|
+
requiredType: true,
|
|
73
|
+
): ValidationResult<T>
|
|
74
|
+
export function validate<T extends { $type?: string }>(
|
|
75
|
+
v: unknown,
|
|
76
|
+
id: string,
|
|
77
|
+
hash: string,
|
|
78
|
+
requiredType?: false,
|
|
79
|
+
): ValidationResult<T>
|
|
80
|
+
export function validate(
|
|
81
|
+
v: unknown,
|
|
82
|
+
id: string,
|
|
83
|
+
hash: string,
|
|
84
|
+
requiredType?: boolean,
|
|
85
|
+
): ValidationResult {
|
|
86
|
+
return (requiredType ? is$typed : maybe$typed)(v, id, hash)
|
|
87
|
+
? lexicons.validate(`${id}#${hash}`, v)
|
|
88
|
+
: {
|
|
89
|
+
success: false,
|
|
90
|
+
error: new ValidationError(
|
|
91
|
+
`Must be an object with "${hash === 'main' ? id : `${id}#${hash}`}" $type property`,
|
|
92
|
+
),
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const ids = {
|
|
97
|
+
ComAtprotoSyncGetRecord: 'com.atproto.sync.getRecord',
|
|
98
|
+
} as const
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import { HeadersMap, XRPCError } from '@atproto/xrpc'
|
|
5
|
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { CID } from 'multiformats/cid'
|
|
7
|
+
import { validate as _validate } from '../../../../lexicons'
|
|
8
|
+
import {
|
|
9
|
+
type $Typed,
|
|
10
|
+
is$typed as _is$typed,
|
|
11
|
+
type OmitKey,
|
|
12
|
+
} from '../../../../util'
|
|
13
|
+
|
|
14
|
+
const is$typed = _is$typed,
|
|
15
|
+
validate = _validate
|
|
16
|
+
const id = 'com.atproto.sync.getRecord'
|
|
17
|
+
|
|
18
|
+
export type QueryParams = {
|
|
19
|
+
/** The DID of the repo. */
|
|
20
|
+
did: string
|
|
21
|
+
collection: string
|
|
22
|
+
/** Record Key */
|
|
23
|
+
rkey: string
|
|
24
|
+
}
|
|
25
|
+
export type InputSchema = undefined
|
|
26
|
+
|
|
27
|
+
export interface CallOptions {
|
|
28
|
+
signal?: AbortSignal
|
|
29
|
+
headers?: HeadersMap
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface Response {
|
|
33
|
+
success: boolean
|
|
34
|
+
headers: HeadersMap
|
|
35
|
+
data: Uint8Array
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class RecordNotFoundError extends XRPCError {
|
|
39
|
+
constructor(src: XRPCError) {
|
|
40
|
+
super(src.status, src.error, src.message, src.headers, { cause: src })
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class RepoNotFoundError extends XRPCError {
|
|
45
|
+
constructor(src: XRPCError) {
|
|
46
|
+
super(src.status, src.error, src.message, src.headers, { cause: src })
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class RepoTakendownError extends XRPCError {
|
|
51
|
+
constructor(src: XRPCError) {
|
|
52
|
+
super(src.status, src.error, src.message, src.headers, { cause: src })
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export class RepoSuspendedError extends XRPCError {
|
|
57
|
+
constructor(src: XRPCError) {
|
|
58
|
+
super(src.status, src.error, src.message, src.headers, { cause: src })
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class RepoDeactivatedError extends XRPCError {
|
|
63
|
+
constructor(src: XRPCError) {
|
|
64
|
+
super(src.status, src.error, src.message, src.headers, { cause: src })
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function toKnownErr(e: any) {
|
|
69
|
+
if (e instanceof XRPCError) {
|
|
70
|
+
if (e.error === 'RecordNotFound') return new RecordNotFoundError(e)
|
|
71
|
+
if (e.error === 'RepoNotFound') return new RepoNotFoundError(e)
|
|
72
|
+
if (e.error === 'RepoTakendown') return new RepoTakendownError(e)
|
|
73
|
+
if (e.error === 'RepoSuspended') return new RepoSuspendedError(e)
|
|
74
|
+
if (e.error === 'RepoDeactivated') return new RepoDeactivatedError(e)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return e
|
|
78
|
+
}
|