@ainize/core 0.2.3 → 0.3.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/dist/browser.d.ts +1 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +1 -0
- package/dist/browser.js.map +1 -1
- package/dist/config-schema.js +1 -1
- package/dist/delegation.d.ts +30 -8
- package/dist/delegation.d.ts.map +1 -1
- package/dist/delegation.js +23 -16
- package/dist/delegation.js.map +1 -1
- package/dist/identity.d.ts +50 -3
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +68 -15
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/scheme.d.ts +25 -0
- package/dist/scheme.d.ts.map +1 -0
- package/dist/scheme.js +7 -0
- package/dist/scheme.js.map +1 -0
- package/package.json +4 -3
package/dist/browser.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export * from './types.js';
|
|
13
13
|
export { verificationCount } from './catalog.js';
|
|
14
|
+
export * from './scheme.js';
|
|
14
15
|
export * from './delegation.js';
|
|
15
16
|
export type { Ledger, LedgerEvents, LedgerInfo, PayoutRecord, PriceRecord, RecordBody, RetireRecord, SubscriptionRecord, SupersedeRecord, } from './ledger.js';
|
|
16
17
|
//# sourceMappingURL=browser.d.ts.map
|
package/dist/browser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGjD,cAAc,iBAAiB,CAAC;AAChC,YAAY,EACV,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EACvE,YAAY,EAAE,kBAAkB,EAAE,eAAe,GAClD,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGjD,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,YAAY,EACV,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EACvE,YAAY,EAAE,kBAAkB,EAAE,eAAe,GAClD,MAAM,aAAa,CAAC"}
|
package/dist/browser.js
CHANGED
|
@@ -15,5 +15,6 @@ export * from './types.js';
|
|
|
15
15
|
export { verificationCount } from './catalog.js';
|
|
16
16
|
// Delegation, for the AIN Wallet sign-in: `delegation.ts` imports NOTHING — the signature check is a parameter, so
|
|
17
17
|
// the browser passes noble's and the node passes ain-util's, and the boundary above holds either way.
|
|
18
|
+
export * from './scheme.js';
|
|
18
19
|
export * from './delegation.js';
|
|
19
20
|
//# sourceMappingURL=browser.js.map
|
package/dist/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,cAAc,YAAY,CAAC;AAC3B,iHAAiH;AACjH,2GAA2G;AAC3G,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,mHAAmH;AACnH,sGAAsG;AACtG,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,cAAc,YAAY,CAAC;AAC3B,iHAAiH;AACjH,2GAA2G;AAC3G,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,mHAAmH;AACnH,sGAAsG;AACtG,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC"}
|
package/dist/config-schema.js
CHANGED
|
@@ -125,7 +125,7 @@ export const nodeConfigSchema = z.object({
|
|
|
125
125
|
*/
|
|
126
126
|
operatorPasswordHash: z.string().optional(),
|
|
127
127
|
/**
|
|
128
|
-
* Addresses that may sign in as this node's operator
|
|
128
|
+
* Addresses that may sign in as this node's operator, besides the node's own key.
|
|
129
129
|
*
|
|
130
130
|
* The node's OWN address is always allowed and is not listed here — whoever holds the node's key already owns
|
|
131
131
|
* everything the node published, so requiring them to also type a password protects nothing. This list is for
|
package/dist/delegation.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Delegation — an AIN Wallet owner authorising a browser key, signed once.
|
|
3
3
|
*
|
|
4
|
-
* Its own module, and
|
|
5
|
-
* `node:crypto` and ain-js out of the web bundle, and its rule is that a runtime value added there is how
|
|
6
|
-
* guarantee gets lost.
|
|
7
|
-
*
|
|
4
|
+
* Its own module, and importing NO RUNTIME VALUE, because the browser needs it. `browser.ts` is the boundary that
|
|
5
|
+
* keeps `node:crypto` and ain-js out of the web bundle, and its rule is that a runtime value added there is how
|
|
6
|
+
* that guarantee gets lost. `verifyDelegation` takes the signature check as a parameter, so the node passes
|
|
7
|
+
* ain-util's and the browser passes noble's, and neither drags the other in. The one import here is a type, which
|
|
8
|
+
* erases at compile time and cannot carry anything with it.
|
|
8
9
|
*/
|
|
10
|
+
import type { SignatureScheme } from './scheme.js';
|
|
9
11
|
/** Header that carries the delegation, beside the ordinary `x-ainize-auth`. */
|
|
10
12
|
export declare const DELEGATE_HEADER = "x-ainize-delegate";
|
|
11
13
|
/** The longest a node will honour one delegation, however long the owner wrote. */
|
|
@@ -45,11 +47,31 @@ export interface Delegation {
|
|
|
45
47
|
owner: string;
|
|
46
48
|
expires: number;
|
|
47
49
|
signature: string;
|
|
50
|
+
scheme: SignatureScheme;
|
|
48
51
|
}
|
|
49
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Parse `x-ainize-delegate: <owner>:<expires>:<sig>[:<scheme>]`. Returns null on anything malformed.
|
|
54
|
+
*
|
|
55
|
+
* The scheme is a fourth field rather than something read off the signature's length — 97 bytes for `ain`, 65 for
|
|
56
|
+
* `eip191` would in fact tell them apart, and that is exactly the inference this must not make. Whoever presents
|
|
57
|
+
* a signature would then be choosing which rules verify it, and the two rules do not carry the same claim: one
|
|
58
|
+
* says a person approved a prompt, the other says a key acted alone.
|
|
59
|
+
*
|
|
60
|
+
* A header with no fourth field means `ain`, which is what every delegation written before wallets existed is.
|
|
61
|
+
*/
|
|
50
62
|
export declare function parseDelegation(header: string | undefined | null): Delegation | null;
|
|
51
|
-
/**
|
|
52
|
-
|
|
63
|
+
/**
|
|
64
|
+
* The header an owner's wallet produces once, and every delegated request then carries unchanged.
|
|
65
|
+
*
|
|
66
|
+
* An `ain` delegation is written with three fields, byte for byte what it was before there was a fourth. Nothing
|
|
67
|
+
* old has to be re-signed, and nothing old starts failing against a node that has learned to read a fourth field.
|
|
68
|
+
*/
|
|
69
|
+
export declare function delegateHeader(d: {
|
|
70
|
+
owner: string;
|
|
71
|
+
expires: number;
|
|
72
|
+
signature: string;
|
|
73
|
+
scheme?: SignatureScheme;
|
|
74
|
+
}): string;
|
|
53
75
|
/**
|
|
54
76
|
* The address a delegated request acts as, or null.
|
|
55
77
|
*
|
|
@@ -61,7 +83,7 @@ export declare function verifyDelegation(header: string | undefined | null, ctx:
|
|
|
61
83
|
delegate: string;
|
|
62
84
|
now?: number;
|
|
63
85
|
maxMs?: number;
|
|
64
|
-
}, verify: (message: string, signature: string, address: string) => boolean): string | null;
|
|
86
|
+
}, verify: (message: string, signature: string, address: string, scheme: SignatureScheme) => boolean): string | null;
|
|
65
87
|
/**
|
|
66
88
|
* What an operator signs to prove who they are, instead of typing a password.
|
|
67
89
|
*
|
package/dist/delegation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegation.d.ts","sourceRoot":"","sources":["../src/delegation.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"delegation.d.ts","sourceRoot":"","sources":["../src/delegation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,+EAA+E;AAC/E,eAAO,MAAM,eAAe,sBAAsB,CAAC;AACnD,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,QAAmB,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE9F;AAED,MAAM,WAAW,UAAU;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE;AAE1G;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,UAAU,GAAG,IAAI,CASpF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,eAAe,CAAA;CAAE,GAAG,MAAM,CAEzH;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EACjC,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EACrE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,KAAK,OAAO,GAChG,MAAM,GAAG,IAAI,CASf;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE/E;AAED,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,QAAa,CAAC"}
|
package/dist/delegation.js
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Delegation — an AIN Wallet owner authorising a browser key, signed once.
|
|
3
|
-
*
|
|
4
|
-
* Its own module, and IMPORTING NOTHING, because the browser needs it. `browser.ts` is the boundary that keeps
|
|
5
|
-
* `node:crypto` and ain-js out of the web bundle, and its rule is that a runtime value added there is how that
|
|
6
|
-
* guarantee gets lost. This file has no imports to lose it with: `verifyDelegation` takes the signature check as a
|
|
7
|
-
* parameter, so the node passes ain-util's and the browser passes noble's, and neither drags the other in.
|
|
8
|
-
*/
|
|
9
1
|
/** Header that carries the delegation, beside the ordinary `x-ainize-auth`. */
|
|
10
2
|
export const DELEGATE_HEADER = 'x-ainize-delegate';
|
|
11
3
|
/** The longest a node will honour one delegation, however long the owner wrote. */
|
|
@@ -39,22 +31,37 @@ export const DELEGATION_MAX_MS = 24 * 60 * 60_000;
|
|
|
39
31
|
export function delegateMessage(t) {
|
|
40
32
|
return ['delegate', t.node, t.delegate.toLowerCase(), String(t.expires)].join(':');
|
|
41
33
|
}
|
|
42
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Parse `x-ainize-delegate: <owner>:<expires>:<sig>[:<scheme>]`. Returns null on anything malformed.
|
|
36
|
+
*
|
|
37
|
+
* The scheme is a fourth field rather than something read off the signature's length — 97 bytes for `ain`, 65 for
|
|
38
|
+
* `eip191` would in fact tell them apart, and that is exactly the inference this must not make. Whoever presents
|
|
39
|
+
* a signature would then be choosing which rules verify it, and the two rules do not carry the same claim: one
|
|
40
|
+
* says a person approved a prompt, the other says a key acted alone.
|
|
41
|
+
*
|
|
42
|
+
* A header with no fourth field means `ain`, which is what every delegation written before wallets existed is.
|
|
43
|
+
*/
|
|
43
44
|
export function parseDelegation(header) {
|
|
44
45
|
if (!header)
|
|
45
46
|
return null;
|
|
46
47
|
const parts = header.split(':');
|
|
47
|
-
if (parts.length !== 3)
|
|
48
|
+
if (parts.length !== 3 && parts.length !== 4)
|
|
48
49
|
return null;
|
|
49
|
-
const [owner, expStr, signature] = parts;
|
|
50
|
+
const [owner, expStr, signature, schemeStr] = parts;
|
|
50
51
|
const expires = Number(expStr);
|
|
51
|
-
|
|
52
|
+
const scheme = schemeStr === undefined ? 'ain' : schemeStr === 'ain' || schemeStr === 'eip191' ? schemeStr : null;
|
|
53
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(owner ?? '') || !Number.isFinite(expires) || !signature || !scheme)
|
|
52
54
|
return null;
|
|
53
|
-
return { owner, expires, signature };
|
|
55
|
+
return { owner, expires, signature, scheme };
|
|
54
56
|
}
|
|
55
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* The header an owner's wallet produces once, and every delegated request then carries unchanged.
|
|
59
|
+
*
|
|
60
|
+
* An `ain` delegation is written with three fields, byte for byte what it was before there was a fourth. Nothing
|
|
61
|
+
* old has to be re-signed, and nothing old starts failing against a node that has learned to read a fourth field.
|
|
62
|
+
*/
|
|
56
63
|
export function delegateHeader(d) {
|
|
57
|
-
return `${d.owner}:${d.expires}:${d.signature}`;
|
|
64
|
+
return d.scheme === 'eip191' ? `${d.owner}:${d.expires}:${d.signature}:eip191` : `${d.owner}:${d.expires}:${d.signature}`;
|
|
58
65
|
}
|
|
59
66
|
/**
|
|
60
67
|
* The address a delegated request acts as, or null.
|
|
@@ -74,7 +81,7 @@ export function verifyDelegation(header, ctx, verify) {
|
|
|
74
81
|
if (d.owner.toLowerCase() === ctx.delegate.toLowerCase())
|
|
75
82
|
return null; // a key delegating to itself proves nothing
|
|
76
83
|
const message = delegateMessage({ node: ctx.node, delegate: ctx.delegate, expires: d.expires });
|
|
77
|
-
return verify(message, d.signature, d.owner) ? d.owner : null;
|
|
84
|
+
return verify(message, d.signature, d.owner, d.scheme) ? d.owner : null;
|
|
78
85
|
}
|
|
79
86
|
// ------------------------------------------------------------------ operator sign-in by signature
|
|
80
87
|
/**
|
package/dist/delegation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegation.js","sourceRoot":"","sources":["../src/delegation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"delegation.js","sourceRoot":"","sources":["../src/delegation.ts"],"names":[],"mappings":"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"}
|
package/dist/identity.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SignatureScheme } from './scheme.js';
|
|
1
2
|
export interface Identity {
|
|
2
3
|
privateKey: string;
|
|
3
4
|
publicKey: string;
|
|
@@ -7,9 +8,55 @@ export declare function createIdentity(): Identity;
|
|
|
7
8
|
export declare function identityFromPrivateKey(privHex: string): Identity;
|
|
8
9
|
export declare function signMessage(message: string, privHex: string): string;
|
|
9
10
|
export declare function verifyMessage(message: string, signature: string, address: string): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* ─── HUMANS SIGN EIP-191, KEYS SIGN AIN ───────────────────────────────────────────────────────────────────
|
|
13
|
+
*
|
|
14
|
+
* `verifyMessage` above is the product's universal scheme and it is deliberately NOT widened. It verifies
|
|
15
|
+
* teach headers, delegations, publish claims, x402 payment proofs, p2p headers and every local-ledger record —
|
|
16
|
+
* all of them produced by a key this product generated, several of them firing per minute. Making that one
|
|
17
|
+
* function accept a second signature shape would widen every one of those surfaces at once.
|
|
18
|
+
*
|
|
19
|
+
* What a browser wallet gives us is different in kind: a PERSON, present, approving one thing, with a prompt
|
|
20
|
+
* in front of them. That happens a handful of times — sign-in, claiming a node, approving a device — so it
|
|
21
|
+
* gets its own verifier and its own call sites.
|
|
22
|
+
*
|
|
23
|
+
* The two schemes differ twice over, and both differences are fatal to interop:
|
|
24
|
+
*
|
|
25
|
+
* AIN keccak256(keccak256( varint(26) ‖ 'AINetwork Signed Message:\n' ‖ varint(str.length) ‖ bytes ))
|
|
26
|
+
* wire: 0x ‖ hash(32) ‖ r(32) ‖ s(32) ‖ v(1) — the digest travels WITH the signature
|
|
27
|
+
* EIP-191 keccak256( '\x19Ethereum Signed Message:\n' ‖ byteLength ‖ bytes )
|
|
28
|
+
* wire: 0x ‖ r(32) ‖ s(32) ‖ v(1) — 65 bytes, no embedded digest
|
|
29
|
+
*
|
|
30
|
+
* Note the length: AIN counts UTF-16 code units (JS `.length`), EIP-191 counts UTF-8 bytes. For "한글" that is
|
|
31
|
+
* 2 against 6, so a Korean message hashes differently even before the prefix is considered.
|
|
32
|
+
*
|
|
33
|
+
* The ADDRESS is the same in both worlds — same curve, same keccak-of-pubkey derivation — which is the whole
|
|
34
|
+
* reason this works: a MetaMask account names exactly one AIN address. Measured, not assumed: the same private
|
|
35
|
+
* key yields 0x00ADEc28… under both `privateToAddress` and Ethereum's rules.
|
|
36
|
+
*/
|
|
37
|
+
/** The EIP-191 personal-message digest MetaMask signs. Byte length, not string length. */
|
|
38
|
+
export declare function hashEip191(message: string): Buffer;
|
|
39
|
+
/**
|
|
40
|
+
* Did `address` sign `message` with a browser wallet (MetaMask and every EIP-1193 wallet)?
|
|
41
|
+
*
|
|
42
|
+
* Rejects anything that is not a bare 65-byte signature, so an AIN signature — which carries its own 32-byte
|
|
43
|
+
* digest in front and is therefore 97 bytes — cannot be smuggled in here and silently verified under the wrong
|
|
44
|
+
* rules. `v` is accepted as 27/28 (what wallets send) or 0/1 (what some libraries send).
|
|
45
|
+
*/
|
|
46
|
+
export declare function verifyEip191(message: string, signature: string, address: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Which scheme produced a signature. The definition lives in `scheme.ts`, which imports nothing, because
|
|
49
|
+
* `delegation.ts` needs the same name and that file is what keeps node:crypto out of the browser bundle.
|
|
50
|
+
*/
|
|
51
|
+
export type AuthScheme = SignatureScheme;
|
|
52
|
+
/**
|
|
53
|
+
* Verify a signature under a NAMED scheme.
|
|
54
|
+
*
|
|
55
|
+
* The scheme is always stated by the caller and never guessed from the signature's shape. A verifier that
|
|
56
|
+
* tried both would accept whichever passed, which means an attacker picks the scheme — and the two have
|
|
57
|
+
* different security properties at the call site (a wallet prompt a human saw, versus a key acting on its own).
|
|
58
|
+
*/
|
|
59
|
+
export declare function verifyAuth(scheme: AuthScheme, message: string, signature: string, address: string): boolean;
|
|
10
60
|
export declare function isAddress(value: string): boolean;
|
|
11
61
|
export declare function checksum(address: string): string;
|
|
12
|
-
/** Operator password hashing (scrypt) for the web console login. */
|
|
13
|
-
export declare function hashPassword(password: string): string;
|
|
14
|
-
export declare function verifyPassword(password: string, stored: string): boolean;
|
|
15
62
|
//# sourceMappingURL=identity.d.ts.map
|
package/dist/identity.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMnD,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,cAAc,IAAI,QAAQ,CAKzC;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAKhE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAM1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAezF;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,CAAC;AAEzC;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3G;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAMhD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhD"}
|
package/dist/identity.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* so a node's signature over a ledger record is verifiable by any peer with only the address.
|
|
5
5
|
*/
|
|
6
6
|
import { createRequire } from 'node:module';
|
|
7
|
-
import { randomBytes
|
|
7
|
+
import { randomBytes } from 'node:crypto';
|
|
8
8
|
const require = createRequire(import.meta.url);
|
|
9
9
|
// ain-util is CommonJS
|
|
10
10
|
const ainUtil = require('@ainblockchain/ain-util');
|
|
@@ -31,6 +31,73 @@ export function verifyMessage(message, signature, address) {
|
|
|
31
31
|
return false;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* ─── HUMANS SIGN EIP-191, KEYS SIGN AIN ───────────────────────────────────────────────────────────────────
|
|
36
|
+
*
|
|
37
|
+
* `verifyMessage` above is the product's universal scheme and it is deliberately NOT widened. It verifies
|
|
38
|
+
* teach headers, delegations, publish claims, x402 payment proofs, p2p headers and every local-ledger record —
|
|
39
|
+
* all of them produced by a key this product generated, several of them firing per minute. Making that one
|
|
40
|
+
* function accept a second signature shape would widen every one of those surfaces at once.
|
|
41
|
+
*
|
|
42
|
+
* What a browser wallet gives us is different in kind: a PERSON, present, approving one thing, with a prompt
|
|
43
|
+
* in front of them. That happens a handful of times — sign-in, claiming a node, approving a device — so it
|
|
44
|
+
* gets its own verifier and its own call sites.
|
|
45
|
+
*
|
|
46
|
+
* The two schemes differ twice over, and both differences are fatal to interop:
|
|
47
|
+
*
|
|
48
|
+
* AIN keccak256(keccak256( varint(26) ‖ 'AINetwork Signed Message:\n' ‖ varint(str.length) ‖ bytes ))
|
|
49
|
+
* wire: 0x ‖ hash(32) ‖ r(32) ‖ s(32) ‖ v(1) — the digest travels WITH the signature
|
|
50
|
+
* EIP-191 keccak256( '\x19Ethereum Signed Message:\n' ‖ byteLength ‖ bytes )
|
|
51
|
+
* wire: 0x ‖ r(32) ‖ s(32) ‖ v(1) — 65 bytes, no embedded digest
|
|
52
|
+
*
|
|
53
|
+
* Note the length: AIN counts UTF-16 code units (JS `.length`), EIP-191 counts UTF-8 bytes. For "한글" that is
|
|
54
|
+
* 2 against 6, so a Korean message hashes differently even before the prefix is considered.
|
|
55
|
+
*
|
|
56
|
+
* The ADDRESS is the same in both worlds — same curve, same keccak-of-pubkey derivation — which is the whole
|
|
57
|
+
* reason this works: a MetaMask account names exactly one AIN address. Measured, not assumed: the same private
|
|
58
|
+
* key yields 0x00ADEc28… under both `privateToAddress` and Ethereum's rules.
|
|
59
|
+
*/
|
|
60
|
+
/** The EIP-191 personal-message digest MetaMask signs. Byte length, not string length. */
|
|
61
|
+
export function hashEip191(message) {
|
|
62
|
+
const bytes = Buffer.from(message, 'utf8');
|
|
63
|
+
return ainUtil.keccak(Buffer.concat([Buffer.from(`\x19Ethereum Signed Message:\n${bytes.length}`, 'utf8'), bytes]));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Did `address` sign `message` with a browser wallet (MetaMask and every EIP-1193 wallet)?
|
|
67
|
+
*
|
|
68
|
+
* Rejects anything that is not a bare 65-byte signature, so an AIN signature — which carries its own 32-byte
|
|
69
|
+
* digest in front and is therefore 97 bytes — cannot be smuggled in here and silently verified under the wrong
|
|
70
|
+
* rules. `v` is accepted as 27/28 (what wallets send) or 0/1 (what some libraries send).
|
|
71
|
+
*/
|
|
72
|
+
export function verifyEip191(message, signature, address) {
|
|
73
|
+
try {
|
|
74
|
+
const raw = Buffer.from(signature.replace(/^0x/, ''), 'hex');
|
|
75
|
+
if (raw.length !== 65)
|
|
76
|
+
return false;
|
|
77
|
+
const r = raw.subarray(0, 32);
|
|
78
|
+
const s = raw.subarray(32, 64);
|
|
79
|
+
const vRaw = raw[64];
|
|
80
|
+
const v = vRaw >= 27 ? vRaw : vRaw + 27;
|
|
81
|
+
if (v !== 27 && v !== 28)
|
|
82
|
+
return false;
|
|
83
|
+
const pub = ainUtil.ecRecoverPub(hashEip191(message), r, s, v);
|
|
84
|
+
const recovered = ainUtil.toChecksumAddress(ainUtil.bufferToHex(ainUtil.pubToAddress(pub.subarray(1))));
|
|
85
|
+
return recovered.toLowerCase() === address.toLowerCase();
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Verify a signature under a NAMED scheme.
|
|
93
|
+
*
|
|
94
|
+
* The scheme is always stated by the caller and never guessed from the signature's shape. A verifier that
|
|
95
|
+
* tried both would accept whichever passed, which means an attacker picks the scheme — and the two have
|
|
96
|
+
* different security properties at the call site (a wallet prompt a human saw, versus a key acting on its own).
|
|
97
|
+
*/
|
|
98
|
+
export function verifyAuth(scheme, message, signature, address) {
|
|
99
|
+
return scheme === 'eip191' ? verifyEip191(message, signature, address) : verifyMessage(message, signature, address);
|
|
100
|
+
}
|
|
34
101
|
export function isAddress(value) {
|
|
35
102
|
try {
|
|
36
103
|
return ainUtil.isValidAddress(value);
|
|
@@ -42,18 +109,4 @@ export function isAddress(value) {
|
|
|
42
109
|
export function checksum(address) {
|
|
43
110
|
return ainUtil.toChecksumAddress(address);
|
|
44
111
|
}
|
|
45
|
-
/** Operator password hashing (scrypt) for the web console login. */
|
|
46
|
-
export function hashPassword(password) {
|
|
47
|
-
const salt = randomBytes(16);
|
|
48
|
-
const key = scryptSync(password, salt, 32);
|
|
49
|
-
return `scrypt$${salt.toString('hex')}$${key.toString('hex')}`;
|
|
50
|
-
}
|
|
51
|
-
export function verifyPassword(password, stored) {
|
|
52
|
-
const [alg, saltHex, keyHex] = stored.split('$');
|
|
53
|
-
if (alg !== 'scrypt' || !saltHex || !keyHex)
|
|
54
|
-
return false;
|
|
55
|
-
const key = scryptSync(password, Buffer.from(saltHex, 'hex'), 32);
|
|
56
|
-
const expected = Buffer.from(keyHex, 'hex');
|
|
57
|
-
return key.length === expected.length && timingSafeEqual(key, expected);
|
|
58
|
-
}
|
|
59
112
|
//# sourceMappingURL=identity.js.map
|
package/dist/identity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export * from './config-schema.js';
|
|
|
13
13
|
export * from './events.js';
|
|
14
14
|
export * from './bytes.js';
|
|
15
15
|
export * from './teach-auth.js';
|
|
16
|
+
export * from './scheme.js';
|
|
16
17
|
export * from './delegation.js';
|
|
17
18
|
export * from './ops.js';
|
|
18
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ export * from './config-schema.js';
|
|
|
13
13
|
export * from './events.js';
|
|
14
14
|
export * from './bytes.js';
|
|
15
15
|
export * from './teach-auth.js';
|
|
16
|
+
export * from './scheme.js';
|
|
16
17
|
export * from './delegation.js';
|
|
17
18
|
export * from './ops.js';
|
|
18
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC"}
|
package/dist/scheme.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which rules a signature was made under. One name, in a file that imports nothing, because both sides need it.
|
|
3
|
+
*
|
|
4
|
+
* `ain` is `@ainblockchain/ain-util`'s personal-message scheme: keccak256 twice over a length-prefixed message,
|
|
5
|
+
* with the length counted in UTF-16 code units, and a 97-byte wire form that carries its own digest. Every key
|
|
6
|
+
* this product generates signs that way — teaching keys, node identities, the CLI.
|
|
7
|
+
*
|
|
8
|
+
* `eip191` is what a browser wallet produces for `personal_sign`: keccak256 once over
|
|
9
|
+
* `\x19Ethereum Signed Message:\n<byte length>`, UTF-8, and a bare 65-byte r‖s‖v. MetaMask signs only this.
|
|
10
|
+
*
|
|
11
|
+
* Same curve and the same address from one key, so the two are easy to mistake for interchangeable. They are not:
|
|
12
|
+
* a signature valid under one verifies under neither the other's rules. And they do not mean the same thing —
|
|
13
|
+
* `eip191` says a person read a prompt and approved it, `ain` says a key acted on its own — which is why the
|
|
14
|
+
* scheme travels as a NAME beside the signature and is never inferred from its shape. A verifier that tried both
|
|
15
|
+
* would let whoever presents a signature choose which of those two claims gets recorded.
|
|
16
|
+
*
|
|
17
|
+
* It lives here rather than in `identity.ts` because `delegation.ts` needs it and imports nothing on purpose:
|
|
18
|
+
* that file is what keeps `node:crypto` and ain-js out of the browser bundle.
|
|
19
|
+
*/
|
|
20
|
+
export type SignatureScheme = 'ain' | 'eip191';
|
|
21
|
+
/** The scheme a header or body means when it names none. Everything written before schemas existed is `ain`. */
|
|
22
|
+
export declare const DEFAULT_SCHEME: SignatureScheme;
|
|
23
|
+
/** Narrow an untrusted string to a scheme, or null. Never defaults: a caller that sent junk did not mean `ain`. */
|
|
24
|
+
export declare function asScheme(value: unknown): SignatureScheme | null;
|
|
25
|
+
//# sourceMappingURL=scheme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheme.d.ts","sourceRoot":"","sources":["../src/scheme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE/C,gHAAgH;AAChH,eAAO,MAAM,cAAc,EAAE,eAAuB,CAAC;AAErD,mHAAmH;AACnH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAE/D"}
|
package/dist/scheme.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** The scheme a header or body means when it names none. Everything written before schemas existed is `ain`. */
|
|
2
|
+
export const DEFAULT_SCHEME = 'ain';
|
|
3
|
+
/** Narrow an untrusted string to a scheme, or null. Never defaults: a caller that sent junk did not mean `ain`. */
|
|
4
|
+
export function asScheme(value) {
|
|
5
|
+
return value === 'ain' || value === 'eip191' ? value : null;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=scheme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheme.js","sourceRoot":"","sources":["../src/scheme.ts"],"names":[],"mappings":"AAqBA,gHAAgH;AAChH,MAAM,CAAC,MAAM,cAAc,GAAoB,KAAK,CAAC;AAErD,mHAAmH;AACnH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainize/core",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Ainize core
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Ainize core — knowledge-patch schemas, lineage, verification and ledger (AIN) bindings shared by @ainize/node and @ainize/cli",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -42,8 +42,9 @@
|
|
|
42
42
|
"zod": "^4.5.4"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
+
"@noble/secp256k1": "^2.3.0",
|
|
45
46
|
"@types/node": "^24.10.0",
|
|
46
47
|
"tsx": "^4.23.13",
|
|
47
48
|
"typescript": "^5.9.3"
|
|
48
49
|
}
|
|
49
|
-
}
|
|
50
|
+
}
|