@xescure/keeta-utils 0.0.0-stage → 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/LICENSE +373 -0
- package/README.md +6 -2
- package/dist/identity/account.d.ts +22 -0
- package/dist/identity/account.d.ts.map +1 -0
- package/dist/identity/account.js +64 -0
- package/dist/identity/account.js.map +1 -0
- package/dist/identity/assert-never.d.ts +2 -0
- package/dist/identity/assert-never.d.ts.map +1 -0
- package/dist/identity/assert-never.js +4 -0
- package/dist/identity/assert-never.js.map +1 -0
- package/dist/identity/drivers.d.ts +99 -0
- package/dist/identity/drivers.d.ts.map +1 -0
- package/dist/identity/drivers.js +65 -0
- package/dist/identity/drivers.js.map +1 -0
- package/dist/identity/env.d.ts +7 -0
- package/dist/identity/env.d.ts.map +1 -0
- package/dist/identity/env.js +29 -0
- package/dist/identity/env.js.map +1 -0
- package/dist/identity/environment.d.ts +14 -0
- package/dist/identity/environment.d.ts.map +1 -0
- package/dist/identity/environment.js +31 -0
- package/dist/identity/environment.js.map +1 -0
- package/dist/identity/error.d.ts +35 -0
- package/dist/identity/error.d.ts.map +1 -0
- package/dist/identity/error.js +65 -0
- package/dist/identity/error.js.map +1 -0
- package/dist/identity/files.d.ts +13 -0
- package/dist/identity/files.d.ts.map +1 -0
- package/dist/identity/files.js +93 -0
- package/dist/identity/files.js.map +1 -0
- package/dist/identity/index.d.ts +17 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +11 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/keyref.d.ts +55 -0
- package/dist/identity/keyref.d.ts.map +1 -0
- package/dist/identity/keyref.js +213 -0
- package/dist/identity/keyref.js.map +1 -0
- package/dist/identity/load.d.ts +38 -0
- package/dist/identity/load.d.ts.map +1 -0
- package/dist/identity/load.js +167 -0
- package/dist/identity/load.js.map +1 -0
- package/dist/identity/material.d.ts +19 -0
- package/dist/identity/material.d.ts.map +1 -0
- package/dist/identity/material.js +34 -0
- package/dist/identity/material.js.map +1 -0
- package/dist/identity/rules.d.ts +56 -0
- package/dist/identity/rules.d.ts.map +1 -0
- package/dist/identity/rules.js +184 -0
- package/dist/identity/rules.js.map +1 -0
- package/dist/identity/schema.d.ts +131 -0
- package/dist/identity/schema.d.ts.map +1 -0
- package/dist/identity/schema.js +117 -0
- package/dist/identity/schema.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -5
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { accountKeyAlgorithm, isNetwork, parseAddress, publicKeyOf } from './account.js';
|
|
2
|
+
import { defaultKeyFormat, localCapabilities } from './drivers.js';
|
|
3
|
+
import { issue } from './error.js';
|
|
4
|
+
import { formatKeyRef, readKeyRef } from './keyref.js';
|
|
5
|
+
import { fieldsOf } from './schema.js';
|
|
6
|
+
export function fieldIssue(field, code, message) {
|
|
7
|
+
return (issue(code, field.variable, message, field.path));
|
|
8
|
+
}
|
|
9
|
+
function signerCapabilities(ref, registry) {
|
|
10
|
+
if (ref.kind === 'address') {
|
|
11
|
+
return (undefined);
|
|
12
|
+
}
|
|
13
|
+
const driver = registry.driver(ref.scheme);
|
|
14
|
+
if (driver?.kind === 'signer') {
|
|
15
|
+
return (driver.capabilities(ref));
|
|
16
|
+
}
|
|
17
|
+
if ((ref.format ?? defaultKeyFormat) === 'public') {
|
|
18
|
+
return (undefined);
|
|
19
|
+
}
|
|
20
|
+
return (localCapabilities(ref));
|
|
21
|
+
}
|
|
22
|
+
function expectedAlgorithm(ref) {
|
|
23
|
+
if (ref.kind === 'address' || ref.expect === undefined) {
|
|
24
|
+
return (undefined);
|
|
25
|
+
}
|
|
26
|
+
const account = parseAddress(ref.expect);
|
|
27
|
+
if (account === undefined) {
|
|
28
|
+
return (undefined);
|
|
29
|
+
}
|
|
30
|
+
return (accountKeyAlgorithm(account));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The static rules for a ref in a signer position, against the driver's
|
|
34
|
+
* declared capabilities. `network` undefined is unknown, which counts as
|
|
35
|
+
* `main`.
|
|
36
|
+
*/
|
|
37
|
+
export function checkSignerRef(ref, registry, constraints, network) {
|
|
38
|
+
const capabilities = signerCapabilities(ref, registry);
|
|
39
|
+
if (ref.kind === 'address' || capabilities === undefined) {
|
|
40
|
+
return ([{ code: 'SIGNER_REQUIRED', message: 'is public; this role needs a ref that can sign' }]);
|
|
41
|
+
}
|
|
42
|
+
const problems = [];
|
|
43
|
+
if (constraints.interactive === 'forbid' && capabilities.interactive) {
|
|
44
|
+
problems.push({ code: 'INTERACTIVE_FORBIDDEN', message: 'needs a human to sign, which this role forbids' });
|
|
45
|
+
}
|
|
46
|
+
const missingPurposes = constraints.purposes.filter(function (purpose) {
|
|
47
|
+
return (!capabilities.purposes.includes(purpose));
|
|
48
|
+
});
|
|
49
|
+
if (missingPurposes.length > 0) {
|
|
50
|
+
problems.push({ code: 'PURPOSE_UNSUPPORTED', message: `cannot sign for ${missingPurposes.join(', ')}` });
|
|
51
|
+
}
|
|
52
|
+
const expected = expectedAlgorithm(ref);
|
|
53
|
+
const possible = capabilities.algorithms.filter(function (algorithm) {
|
|
54
|
+
if (ref.alg !== undefined && ref.alg !== algorithm) {
|
|
55
|
+
return (false);
|
|
56
|
+
}
|
|
57
|
+
if (expected !== undefined && expected !== algorithm) {
|
|
58
|
+
return (false);
|
|
59
|
+
}
|
|
60
|
+
return (constraints.algorithms.includes(algorithm));
|
|
61
|
+
});
|
|
62
|
+
if (possible.length === 0) {
|
|
63
|
+
problems.push({ code: 'ALGORITHM_UNSUPPORTED', message: `cannot be a ${constraints.algorithms.join(' or ')} key, which this role requires` });
|
|
64
|
+
}
|
|
65
|
+
if (ref.expect === undefined) {
|
|
66
|
+
if (capabilities.publicKeyFrom === 'expect') {
|
|
67
|
+
problems.push({ code: 'EXPECT_REQUIRED', message: 'cannot report its public key, so it needs #expect=keeta_...' });
|
|
68
|
+
}
|
|
69
|
+
else if (network === undefined || network === 'main') {
|
|
70
|
+
problems.push({ code: 'EXPECT_REQUIRED', message: 'has no #expect=keeta_..., which every signer on main needs' });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return (problems);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The static rules for a ref in a signerless position.
|
|
77
|
+
*/
|
|
78
|
+
export function checkPublicRef(ref, registry) {
|
|
79
|
+
if (ref.kind === 'address') {
|
|
80
|
+
return ([]);
|
|
81
|
+
}
|
|
82
|
+
if (registry.driver(ref.scheme)?.kind === 'signer') {
|
|
83
|
+
return ([{ code: 'SIGNER_IN_PUBLIC_POSITION', message: 'is a signer; this role takes a keeta_ address or a #format=public ref' }]);
|
|
84
|
+
}
|
|
85
|
+
if ((ref.format ?? defaultKeyFormat) !== 'public') {
|
|
86
|
+
return ([{ code: 'MATERIAL_IN_PUBLIC_POSITION', message: 'holds key material; this role takes a keeta_ address or a #format=public ref' }]);
|
|
87
|
+
}
|
|
88
|
+
return ([]);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* After loading: whether the key is the one its ref expects. The message
|
|
92
|
+
* names the derived public key, never anything else about the key.
|
|
93
|
+
*/
|
|
94
|
+
export function checkExpectedAccount(account, slot) {
|
|
95
|
+
if (slot.ref.kind === 'address' || slot.ref.expect === undefined || publicKeyOf(account) === slot.ref.expect) {
|
|
96
|
+
return ([]);
|
|
97
|
+
}
|
|
98
|
+
return ([fieldIssue(slot.field, 'EXPECT_MISMATCH', `the key loaded as ${publicKeyOf(account)}, but the ref expects ${slot.ref.expect}`)]);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Every rule that needs only the spec and the refs, so it runs before any
|
|
102
|
+
* secret is read.
|
|
103
|
+
*/
|
|
104
|
+
export function analyzeKeyConfig(spec, config, registry) {
|
|
105
|
+
const issues = [];
|
|
106
|
+
const networks = new Map();
|
|
107
|
+
const slots = [];
|
|
108
|
+
const referencedVariables = new Set();
|
|
109
|
+
for (const field of fieldsOf(spec)) {
|
|
110
|
+
const text = config[field.path];
|
|
111
|
+
if (text === undefined) {
|
|
112
|
+
if (field.required) {
|
|
113
|
+
issues.push(fieldIssue(field, 'MISSING_KEY', 'not set'));
|
|
114
|
+
}
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (field.block.kind === 'network') {
|
|
118
|
+
if (isNetwork(text)) {
|
|
119
|
+
networks.set(field.path, text);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
issues.push(fieldIssue(field, 'INVALID_NETWORK', 'must be one of the known network names'));
|
|
123
|
+
}
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const reading = readKeyRef(text, registry, field.variable, field.path);
|
|
127
|
+
issues.push(...reading.issues);
|
|
128
|
+
const ref = reading.ref;
|
|
129
|
+
if (ref === undefined) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (ref.kind === 'driver') {
|
|
133
|
+
for (const name of registry.driver(ref.scheme)?.readsVariables?.(ref) ?? []) {
|
|
134
|
+
referencedVariables.add(name);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
let problems;
|
|
138
|
+
if (field.block.kind === 'signer') {
|
|
139
|
+
problems = checkSignerRef(ref, registry, field.block.constraints, networkAt(config, field.networkPath));
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
problems = checkPublicRef(ref, registry);
|
|
143
|
+
}
|
|
144
|
+
for (const problem of problems) {
|
|
145
|
+
issues.push(fieldIssue(field, problem.code, `${formatKeyRef(ref)} ${problem.message}`));
|
|
146
|
+
}
|
|
147
|
+
slots.push({ field, ref });
|
|
148
|
+
}
|
|
149
|
+
return ({ issues, networks, slots, referencedVariables });
|
|
150
|
+
}
|
|
151
|
+
function networkAt(config, path) {
|
|
152
|
+
if (path === undefined) {
|
|
153
|
+
return (undefined);
|
|
154
|
+
}
|
|
155
|
+
const text = config[path];
|
|
156
|
+
if (text === undefined || !isNetwork(text)) {
|
|
157
|
+
return (undefined);
|
|
158
|
+
}
|
|
159
|
+
return (text);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Every variable under a declared prefix (`PREFIX_*`, or a bare actor
|
|
163
|
+
* prefix) that neither a role nor a ref reads, so that a typo fails.
|
|
164
|
+
*/
|
|
165
|
+
export function checkUnknownVariables(spec, env, referencedVariables) {
|
|
166
|
+
const fields = fieldsOf(spec);
|
|
167
|
+
const issues = [];
|
|
168
|
+
for (const [name, value] of Object.entries(env)) {
|
|
169
|
+
if (value === undefined || value === '' || referencedVariables.has(name)) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const declared = fields.some(function (field) {
|
|
173
|
+
return (field.variable === name);
|
|
174
|
+
});
|
|
175
|
+
const underPrefix = fields.some(function (field) {
|
|
176
|
+
return (name === field.prefix || name.startsWith(`${field.prefix}_`));
|
|
177
|
+
});
|
|
178
|
+
if (underPrefix && !declared) {
|
|
179
|
+
issues.push(issue('UNKNOWN_VARIABLE', name, 'the variable is under a declared prefix but nothing reads it'));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return (issues);
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/identity/rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Account, GenericAccount, KeyAlgorithm, Network } from './account.js';
|
|
2
|
+
import type { Purpose } from './drivers.js';
|
|
3
|
+
export interface SignerConstraints {
|
|
4
|
+
readonly purposes: readonly Purpose[];
|
|
5
|
+
readonly interactive: 'forbid' | 'allow';
|
|
6
|
+
readonly algorithms: readonly KeyAlgorithm[];
|
|
7
|
+
}
|
|
8
|
+
export interface NetworkBlock {
|
|
9
|
+
readonly kind: 'network';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* An account the program refers to but never signs for: a recipient, a
|
|
13
|
+
* token, a multisig address.
|
|
14
|
+
*/
|
|
15
|
+
export interface PublicAccountBlock {
|
|
16
|
+
readonly kind: 'publicAccount';
|
|
17
|
+
}
|
|
18
|
+
export interface SignerBlock {
|
|
19
|
+
readonly kind: 'signer';
|
|
20
|
+
readonly constraints: SignerConstraints;
|
|
21
|
+
}
|
|
22
|
+
export interface ActorOptions {
|
|
23
|
+
readonly signer: SignerBlock;
|
|
24
|
+
/**
|
|
25
|
+
* Declares `ACCOUNT`, the account the actor acts on; unset, the signer's.
|
|
26
|
+
*/
|
|
27
|
+
readonly account?: PublicAccountBlock;
|
|
28
|
+
/**
|
|
29
|
+
* Declares `FEE_PAYER` and `FEE_ACCOUNT`; the block constrains the fee
|
|
30
|
+
* payer's signer. Both unset, the actor pays its own fees.
|
|
31
|
+
*/
|
|
32
|
+
readonly feePayer?: SignerBlock;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A program identity: a signer on a network, the account it acts on and who
|
|
36
|
+
* pays its fees.
|
|
37
|
+
*/
|
|
38
|
+
export interface ActorBlock<Options extends ActorOptions = ActorOptions> {
|
|
39
|
+
readonly kind: 'actor';
|
|
40
|
+
readonly options: Options;
|
|
41
|
+
}
|
|
42
|
+
export type Block = NetworkBlock | PublicAccountBlock | SignerBlock | ActorBlock;
|
|
43
|
+
export type Roles = Readonly<Record<string, Block>>;
|
|
44
|
+
export interface KeySpec<R extends Roles = Roles> {
|
|
45
|
+
readonly kind: 'keySpec';
|
|
46
|
+
readonly roles: R;
|
|
47
|
+
/**
|
|
48
|
+
* Environment prefixes that replace the ones derived from role names.
|
|
49
|
+
*/
|
|
50
|
+
readonly prefixes: Readonly<Record<string, string>>;
|
|
51
|
+
}
|
|
52
|
+
export interface SignerOptions {
|
|
53
|
+
readonly purposes?: readonly Purpose[];
|
|
54
|
+
readonly interactive?: 'forbid' | 'allow';
|
|
55
|
+
readonly algorithms?: readonly KeyAlgorithm[];
|
|
56
|
+
}
|
|
57
|
+
export declare function network(): NetworkBlock;
|
|
58
|
+
export declare function publicAccount(): PublicAccountBlock;
|
|
59
|
+
/**
|
|
60
|
+
* By default a signer signs blocks, must not need a human, and may use any
|
|
61
|
+
* algorithm.
|
|
62
|
+
*/
|
|
63
|
+
export declare function signer(options?: SignerOptions): SignerBlock;
|
|
64
|
+
export declare function actor<const Options extends ActorOptions>(options: Options): ActorBlock<Options>;
|
|
65
|
+
export interface DefineKeysOptions<R extends Roles> {
|
|
66
|
+
readonly prefixes?: {
|
|
67
|
+
readonly [K in keyof R]?: string;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Declares what a program needs. Throws on a malformed role name or prefix,
|
|
72
|
+
* a prefix for no role, or two roles that would read the same variable.
|
|
73
|
+
*/
|
|
74
|
+
export declare function defineKeys<const R extends Roles>(roles: R, options?: DefineKeysOptions<R>): KeySpec<R>;
|
|
75
|
+
/**
|
|
76
|
+
* One value a spec reads: a role's own, or one field of an actor.
|
|
77
|
+
*/
|
|
78
|
+
export interface Field {
|
|
79
|
+
readonly role: string;
|
|
80
|
+
/**
|
|
81
|
+
* `anchor.signer`, or the role name for a role that is a single value.
|
|
82
|
+
*/
|
|
83
|
+
readonly path: string;
|
|
84
|
+
readonly prefix: string;
|
|
85
|
+
readonly variable: string;
|
|
86
|
+
readonly block: NetworkBlock | PublicAccountBlock | SignerBlock;
|
|
87
|
+
readonly required: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* The path of the network a signer is on: its actor's, or the spec's only
|
|
90
|
+
* top-level network role. Undefined when there is none, which counts as
|
|
91
|
+
* `main`.
|
|
92
|
+
*/
|
|
93
|
+
readonly networkPath: string | undefined;
|
|
94
|
+
}
|
|
95
|
+
export declare function fieldsOf(spec: KeySpec): Field[];
|
|
96
|
+
/**
|
|
97
|
+
* `feeRecipients` to `FEE_RECIPIENTS`, keeping abbreviations whole:
|
|
98
|
+
* `accountID` to `ACCOUNT_ID`, `baseURLPath` to `BASE_URL_PATH`.
|
|
99
|
+
*/
|
|
100
|
+
export declare function screamingSnakeCase(name: string): string;
|
|
101
|
+
/**
|
|
102
|
+
* Who pays an actor's fees: `signer` signs the fee block and `account` pays.
|
|
103
|
+
* A fee payer signer alone pays from its own account; a fee account alone is
|
|
104
|
+
* paid from by the actor's signer.
|
|
105
|
+
*/
|
|
106
|
+
export interface FeePayer {
|
|
107
|
+
readonly signer: Account;
|
|
108
|
+
readonly account: GenericAccount;
|
|
109
|
+
}
|
|
110
|
+
type LoadedFeePayer<O extends ActorOptions> = 'feePayer' extends keyof O ? {
|
|
111
|
+
readonly feePayer: FeePayer | undefined;
|
|
112
|
+
} : Record<never, never>;
|
|
113
|
+
export type LoadedActor<O extends ActorOptions> = {
|
|
114
|
+
readonly signer: Account;
|
|
115
|
+
readonly account: GenericAccount;
|
|
116
|
+
readonly network: Network;
|
|
117
|
+
} & LoadedFeePayer<O>;
|
|
118
|
+
export type LoadedBlock<B extends Block> = B extends NetworkBlock ? Network : B extends PublicAccountBlock ? GenericAccount : B extends SignerBlock ? Account : B extends ActorBlock<infer O> ? LoadedActor<O> : never;
|
|
119
|
+
/**
|
|
120
|
+
* What `loadKeys` returns for a spec.
|
|
121
|
+
*/
|
|
122
|
+
export type Loaded<S extends KeySpec> = S extends KeySpec<infer R> ? {
|
|
123
|
+
readonly [K in keyof R]: LoadedBlock<R[K]>;
|
|
124
|
+
} : never;
|
|
125
|
+
/**
|
|
126
|
+
* A configuration as text, keyed by field path (`anchor.signer`,
|
|
127
|
+
* `treasury`). Unset values are absent.
|
|
128
|
+
*/
|
|
129
|
+
export type ConfigText = Readonly<Record<string, string>>;
|
|
130
|
+
export {};
|
|
131
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/identity/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { keyAlgorithms } from './account.js';
|
|
2
|
+
import { issue, KeyConfigError } from './error.js';
|
|
3
|
+
export function network() {
|
|
4
|
+
return ({ kind: 'network' });
|
|
5
|
+
}
|
|
6
|
+
export function publicAccount() {
|
|
7
|
+
return ({ kind: 'publicAccount' });
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* By default a signer signs blocks, must not need a human, and may use any
|
|
11
|
+
* algorithm.
|
|
12
|
+
*/
|
|
13
|
+
export function signer(options = {}) {
|
|
14
|
+
return ({
|
|
15
|
+
kind: 'signer',
|
|
16
|
+
constraints: {
|
|
17
|
+
purposes: options.purposes ?? ['block'],
|
|
18
|
+
interactive: options.interactive ?? 'forbid',
|
|
19
|
+
algorithms: options.algorithms ?? keyAlgorithms
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export function actor(options) {
|
|
24
|
+
return ({ kind: 'actor', options });
|
|
25
|
+
}
|
|
26
|
+
const roleNamePattern = /^[a-z][a-zA-Z0-9]*$/;
|
|
27
|
+
const prefixPattern = /^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$/;
|
|
28
|
+
/**
|
|
29
|
+
* Declares what a program needs. Throws on a malformed role name or prefix,
|
|
30
|
+
* a prefix for no role, or two roles that would read the same variable.
|
|
31
|
+
*/
|
|
32
|
+
export function defineKeys(roles, options = {}) {
|
|
33
|
+
const prefixes = {};
|
|
34
|
+
const issues = [];
|
|
35
|
+
for (const [role, prefix] of Object.entries(options.prefixes ?? {})) {
|
|
36
|
+
if (!Object.hasOwn(roles, role)) {
|
|
37
|
+
issues.push(issue('INVALID_SCHEMA', role, 'a prefix is given for a role that is not declared'));
|
|
38
|
+
}
|
|
39
|
+
else if (prefix !== undefined) {
|
|
40
|
+
prefixes[role] = prefix;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
for (const role of Object.keys(roles)) {
|
|
44
|
+
if (!roleNamePattern.test(role)) {
|
|
45
|
+
issues.push(issue('INVALID_SCHEMA', role, 'a role name must be camelCase, [a-z][a-zA-Z0-9]*'));
|
|
46
|
+
}
|
|
47
|
+
else if (!prefixPattern.test(prefixes[role] ?? screamingSnakeCase(role))) {
|
|
48
|
+
issues.push(issue('INVALID_SCHEMA', role, 'a prefix must be SCREAMING_SNAKE_CASE, [A-Z][A-Z0-9]*(_[A-Z0-9]+)*'));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const spec = { kind: 'keySpec', roles, prefixes };
|
|
52
|
+
const owners = new Map();
|
|
53
|
+
for (const field of fieldsOf(spec)) {
|
|
54
|
+
const owner = owners.get(field.variable);
|
|
55
|
+
if (owner !== undefined && owner !== field.role) {
|
|
56
|
+
issues.push(issue('INVALID_SCHEMA', field.role, `the role reads ${field.variable}, which the role ${owner} reads too`));
|
|
57
|
+
}
|
|
58
|
+
owners.set(field.variable, field.role);
|
|
59
|
+
}
|
|
60
|
+
KeyConfigError.throwIfAny(issues);
|
|
61
|
+
return (spec);
|
|
62
|
+
}
|
|
63
|
+
export function fieldsOf(spec) {
|
|
64
|
+
const networkRoles = Object.keys(spec.roles).filter(function (role) {
|
|
65
|
+
return (spec.roles[role]?.kind === 'network');
|
|
66
|
+
});
|
|
67
|
+
let schemaNetwork;
|
|
68
|
+
if (networkRoles.length === 1) {
|
|
69
|
+
schemaNetwork = networkRoles[0];
|
|
70
|
+
}
|
|
71
|
+
const fields = [];
|
|
72
|
+
for (const [role, block] of Object.entries(spec.roles)) {
|
|
73
|
+
const prefix = spec.prefixes[role] ?? screamingSnakeCase(role);
|
|
74
|
+
if (block.kind !== 'actor') {
|
|
75
|
+
fields.push({ role, path: role, prefix, variable: prefix, block, required: true, networkPath: schemaNetwork });
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const networkPath = `${role}.network`;
|
|
79
|
+
function add(name, fieldBlock, required) {
|
|
80
|
+
fields.push({ role, path: `${role}.${name}`, prefix, variable: `${prefix}_${screamingSnakeCase(name)}`, block: fieldBlock, required, networkPath });
|
|
81
|
+
}
|
|
82
|
+
add('network', { kind: 'network' }, true);
|
|
83
|
+
add('signer', block.options.signer, true);
|
|
84
|
+
if (block.options.account !== undefined) {
|
|
85
|
+
add('account', block.options.account, false);
|
|
86
|
+
}
|
|
87
|
+
if (block.options.feePayer !== undefined) {
|
|
88
|
+
add('feePayer', block.options.feePayer, false);
|
|
89
|
+
add('feeAccount', { kind: 'publicAccount' }, false);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return (fields);
|
|
93
|
+
}
|
|
94
|
+
function isUpper(character) {
|
|
95
|
+
return (character !== character.toLowerCase());
|
|
96
|
+
}
|
|
97
|
+
function isLower(character) {
|
|
98
|
+
return (character !== character.toUpperCase());
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* `feeRecipients` to `FEE_RECIPIENTS`, keeping abbreviations whole:
|
|
102
|
+
* `accountID` to `ACCOUNT_ID`, `baseURLPath` to `BASE_URL_PATH`.
|
|
103
|
+
*/
|
|
104
|
+
export function screamingSnakeCase(name) {
|
|
105
|
+
let result = '';
|
|
106
|
+
const characters = [...name];
|
|
107
|
+
for (const [position, character] of characters.entries()) {
|
|
108
|
+
const previous = characters[position - 1];
|
|
109
|
+
const next = characters[position + 1] ?? '';
|
|
110
|
+
if (previous !== undefined && isUpper(character) && (!isUpper(previous) || isLower(next))) {
|
|
111
|
+
result += '_';
|
|
112
|
+
}
|
|
113
|
+
result += character.toUpperCase();
|
|
114
|
+
}
|
|
115
|
+
return (result);
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/identity/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@xescure/keeta-utils",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "How a Keeta program gets its keys",
|
|
5
|
+
"license": "MPL-2.0",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"sideEffects": false,
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/xescure/keeta-utils.git"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"!dist/**/*.test.*",
|
|
18
|
+
"!dist/.done"
|
|
19
|
+
],
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./identity": {
|
|
26
|
+
"types": "./dist/identity/index.d.ts",
|
|
27
|
+
"default": "./dist/identity/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"tsc": "tsc",
|
|
32
|
+
"vitest": "vitest"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@keetanetwork/keetanet-client": ">=0.18.7 <0.19"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@keetanetwork/keetanet-client": "0.18.7",
|
|
39
|
+
"@types/node": "24.19.2",
|
|
40
|
+
"typescript": "7.0.2",
|
|
41
|
+
"vite": "8.3.5",
|
|
42
|
+
"vitest": "5.0.5"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=24"
|
|
46
|
+
}
|
|
47
|
+
}
|