@calimero-network/mero-js 13.4.0 → 15.0.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/dist/admin-api/admin-client.d.ts +10 -5
- package/dist/admin-api/admin-client.js +10 -5
- package/dist/admin-api/admin-types.d.ts +8 -7
- package/dist/events/group.d.ts +1 -1
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +16 -143
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -2
- package/dist/index.mjs +16 -143
- package/dist/index.mjs.map +4 -4
- package/dist/warrant/warrant.d.ts +5 -6
- package/dist/warrant/warrant.js +1 -54
- package/package.json +1 -1
- package/dist/account/index.d.ts +0 -43
- package/dist/account/index.js +0 -139
|
@@ -24,13 +24,12 @@
|
|
|
24
24
|
/** What a warrant authorises. */
|
|
25
25
|
export interface WarrantInput {
|
|
26
26
|
/**
|
|
27
|
-
* The context,
|
|
27
|
+
* The context, hex — the same string every other method here takes.
|
|
28
28
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* than accepting "32 bytes, somehow".
|
|
29
|
+
* Hex like everything else on this interface. It was base58 while the node
|
|
30
|
+
* spelled `ContextId` and `PublicKey` that way and `AccountId` and `DeviceId`
|
|
31
|
+
* in hex; that split is gone, so this module no longer needs a rule per field
|
|
32
|
+
* and no longer needs a base58 decoder to enforce one.
|
|
34
33
|
*/
|
|
35
34
|
context: string;
|
|
36
35
|
/** The author's account, hex — whose consent this is. */
|
package/dist/warrant/warrant.js
CHANGED
|
@@ -28,7 +28,6 @@ const PKCS8_ED25519_PREFIX = new Uint8Array([
|
|
|
28
28
|
0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x04,
|
|
29
29
|
0x22, 0x04, 0x20,
|
|
30
30
|
]);
|
|
31
|
-
const B58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
32
31
|
function hex(bytes) {
|
|
33
32
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
34
33
|
}
|
|
@@ -46,58 +45,6 @@ function fromHex(value, label, expectedBytes) {
|
|
|
46
45
|
}
|
|
47
46
|
return bytes;
|
|
48
47
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Decode base58 to exactly 32 bytes.
|
|
51
|
-
*
|
|
52
|
-
* Hand-rolled rather than pulled in: it is fifteen lines, and a dependency here
|
|
53
|
-
* would be this package's first.
|
|
54
|
-
*/
|
|
55
|
-
function fromBase58(value, label) {
|
|
56
|
-
const clean = value.trim();
|
|
57
|
-
let n = 0n;
|
|
58
|
-
for (const char of clean) {
|
|
59
|
-
const digit = B58.indexOf(char);
|
|
60
|
-
if (digit < 0) {
|
|
61
|
-
throw new Error(`${label} is not base58: unexpected character '${char}'`);
|
|
62
|
-
}
|
|
63
|
-
n = n * 58n + BigInt(digit);
|
|
64
|
-
}
|
|
65
|
-
const out = new Uint8Array(32);
|
|
66
|
-
for (let i = 31; i >= 0; i -= 1) {
|
|
67
|
-
out[i] = Number(n & 0xffn);
|
|
68
|
-
n >>= 8n;
|
|
69
|
-
}
|
|
70
|
-
if (n !== 0n) {
|
|
71
|
-
throw new Error(`${label} decodes to more than 32 bytes`);
|
|
72
|
-
}
|
|
73
|
-
// Round-trip, because decoding alone accepts too much. Hex digits are mostly
|
|
74
|
-
// valid base58 characters, so a context handed over in hex by mistake can
|
|
75
|
-
// decode to a real-looking 32 bytes instead of failing — `'11'.repeat(32)`
|
|
76
|
-
// decodes to all zeros. Re-encoding catches it: the canonical form of those
|
|
77
|
-
// bytes is 32 '1's, not 64.
|
|
78
|
-
if (toBase58(out) !== clean) {
|
|
79
|
-
throw new Error(`${label} is not a canonical base58 32-byte id. If you have it in hex, ` +
|
|
80
|
-
`note that ${label} is base58 here while accounts are hex`);
|
|
81
|
-
}
|
|
82
|
-
return out;
|
|
83
|
-
}
|
|
84
|
-
/** Encode 32 bytes as base58, for the canonical check above. */
|
|
85
|
-
function toBase58(bytes) {
|
|
86
|
-
let n = 0n;
|
|
87
|
-
for (const byte of bytes) {
|
|
88
|
-
n = (n << 8n) | BigInt(byte);
|
|
89
|
-
}
|
|
90
|
-
let out = '';
|
|
91
|
-
while (n > 0n) {
|
|
92
|
-
out = B58[Number(n % 58n)] + out;
|
|
93
|
-
n /= 58n;
|
|
94
|
-
}
|
|
95
|
-
let leadingZeros = 0;
|
|
96
|
-
while (leadingZeros < bytes.length && bytes[leadingZeros] === 0) {
|
|
97
|
-
leadingZeros += 1;
|
|
98
|
-
}
|
|
99
|
-
return '1'.repeat(leadingZeros) + out;
|
|
100
|
-
}
|
|
101
48
|
function u64le(value) {
|
|
102
49
|
const out = new Uint8Array(8);
|
|
103
50
|
new DataView(out.buffer).setBigUint64(0, BigInt(value), true);
|
|
@@ -159,7 +106,7 @@ async function importSigningKey(secretHex) {
|
|
|
159
106
|
* was signed.
|
|
160
107
|
*/
|
|
161
108
|
export async function signWarrant(input) {
|
|
162
|
-
const context =
|
|
109
|
+
const context = fromHex(input.context, 'context', 32);
|
|
163
110
|
const authorAccount = fromHex(input.authorAccount, 'authorAccount', 32);
|
|
164
111
|
const executor = fromHex(input.executor, 'executor', 32);
|
|
165
112
|
const key = await importSigningKey(input.deviceSecret);
|
package/package.json
CHANGED
package/dist/account/index.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Account id encoding.
|
|
3
|
-
*
|
|
4
|
-
* Core names the same account in two encodings, and the split is deliberate:
|
|
5
|
-
* the admin API serves and requires **64 hex characters**, while contract data
|
|
6
|
-
* (`sender`, `get_profiles`, anything stamped by `env::account_id()`) carries
|
|
7
|
-
* **base58**. They are rendered differently on purpose, so that handing one
|
|
8
|
-
* where the other is expected fails loudly instead of resolving to the wrong
|
|
9
|
-
* principal.
|
|
10
|
-
*
|
|
11
|
-
* The cost is that any client reading a member from the admin API and
|
|
12
|
-
* comparing it against a message sender is comparing two spellings of the same
|
|
13
|
-
* value. A raw `===` silently never matches, and passing a contract-sourced id
|
|
14
|
-
* to an admin route answers `400 Invalid account format: expected 64 hex
|
|
15
|
-
* characters (32 bytes)`. Both failure modes are quiet enough to ship.
|
|
16
|
-
*
|
|
17
|
-
* These helpers canonicalise at that boundary. They convert accounts and
|
|
18
|
-
* nothing else: a device key, an alias or any other value is returned
|
|
19
|
-
* unchanged, because converting is this module's job and destroying what it
|
|
20
|
-
* cannot convert is not.
|
|
21
|
-
*/
|
|
22
|
-
/**
|
|
23
|
-
* Canonicalise an account id to hex — the form every admin route expects.
|
|
24
|
-
*
|
|
25
|
-
* Returns the input unchanged if it is not a 32-byte account, so a device key
|
|
26
|
-
* or an alias survives a call to this function intact.
|
|
27
|
-
*/
|
|
28
|
-
export declare function toAccountHex(id: string | null | undefined): string;
|
|
29
|
-
/**
|
|
30
|
-
* Canonicalise an account id to base58 — the form the contract stamps on
|
|
31
|
-
* `sender` and keys `get_profiles` by.
|
|
32
|
-
*
|
|
33
|
-
* Returns the input unchanged if it is not a 32-byte account.
|
|
34
|
-
*/
|
|
35
|
-
export declare function toAccountBase58(id: string | null | undefined): string;
|
|
36
|
-
/**
|
|
37
|
-
* True when both ids name the same account, whichever encoding each is in.
|
|
38
|
-
*
|
|
39
|
-
* This is the comparison to reach for when checking a contract-sourced
|
|
40
|
-
* `sender` against an admin-sourced member id. Two ids that are not accounts
|
|
41
|
-
* compare false rather than accidentally matching as raw strings.
|
|
42
|
-
*/
|
|
43
|
-
export declare function sameAccount(a: string | null | undefined, b: string | null | undefined): boolean;
|
package/dist/account/index.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Account id encoding.
|
|
3
|
-
*
|
|
4
|
-
* Core names the same account in two encodings, and the split is deliberate:
|
|
5
|
-
* the admin API serves and requires **64 hex characters**, while contract data
|
|
6
|
-
* (`sender`, `get_profiles`, anything stamped by `env::account_id()`) carries
|
|
7
|
-
* **base58**. They are rendered differently on purpose, so that handing one
|
|
8
|
-
* where the other is expected fails loudly instead of resolving to the wrong
|
|
9
|
-
* principal.
|
|
10
|
-
*
|
|
11
|
-
* The cost is that any client reading a member from the admin API and
|
|
12
|
-
* comparing it against a message sender is comparing two spellings of the same
|
|
13
|
-
* value. A raw `===` silently never matches, and passing a contract-sourced id
|
|
14
|
-
* to an admin route answers `400 Invalid account format: expected 64 hex
|
|
15
|
-
* characters (32 bytes)`. Both failure modes are quiet enough to ship.
|
|
16
|
-
*
|
|
17
|
-
* These helpers canonicalise at that boundary. They convert accounts and
|
|
18
|
-
* nothing else: a device key, an alias or any other value is returned
|
|
19
|
-
* unchanged, because converting is this module's job and destroying what it
|
|
20
|
-
* cannot convert is not.
|
|
21
|
-
*/
|
|
22
|
-
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
23
|
-
/** A 32-byte account rendered as 64 hex characters. */
|
|
24
|
-
const HEX_ACCOUNT = /^[0-9a-f]{64}$/i;
|
|
25
|
-
/** Bytes → base58. Leading zero bytes become leading '1's, as in bitcoin base58. */
|
|
26
|
-
function encodeBase58(bytes) {
|
|
27
|
-
if (bytes.length === 0)
|
|
28
|
-
return '';
|
|
29
|
-
const digits = [0];
|
|
30
|
-
for (const byte of bytes) {
|
|
31
|
-
let carry = byte;
|
|
32
|
-
for (let i = 0; i < digits.length; i++) {
|
|
33
|
-
carry += digits[i] << 8;
|
|
34
|
-
digits[i] = carry % 58;
|
|
35
|
-
carry = (carry / 58) | 0;
|
|
36
|
-
}
|
|
37
|
-
while (carry > 0) {
|
|
38
|
-
digits.push(carry % 58);
|
|
39
|
-
carry = (carry / 58) | 0;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
let out = '';
|
|
43
|
-
for (const byte of bytes) {
|
|
44
|
-
if (byte !== 0)
|
|
45
|
-
break;
|
|
46
|
-
out += BASE58_ALPHABET[0];
|
|
47
|
-
}
|
|
48
|
-
for (let i = digits.length - 1; i >= 0; i--) {
|
|
49
|
-
out += BASE58_ALPHABET[digits[i]];
|
|
50
|
-
}
|
|
51
|
-
return out;
|
|
52
|
-
}
|
|
53
|
-
/** base58 → bytes. Returns null when the input is not valid base58. */
|
|
54
|
-
function decodeBase58(value) {
|
|
55
|
-
if (value.length === 0)
|
|
56
|
-
return null;
|
|
57
|
-
const bytes = [0];
|
|
58
|
-
for (const char of value) {
|
|
59
|
-
const index = BASE58_ALPHABET.indexOf(char);
|
|
60
|
-
if (index < 0)
|
|
61
|
-
return null;
|
|
62
|
-
let carry = index;
|
|
63
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
64
|
-
carry += bytes[i] * 58;
|
|
65
|
-
bytes[i] = carry & 0xff;
|
|
66
|
-
carry >>= 8;
|
|
67
|
-
}
|
|
68
|
-
while (carry > 0) {
|
|
69
|
-
bytes.push(carry & 0xff);
|
|
70
|
-
carry >>= 8;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
let leadingZeros = 0;
|
|
74
|
-
for (const char of value) {
|
|
75
|
-
if (char !== BASE58_ALPHABET[0])
|
|
76
|
-
break;
|
|
77
|
-
leadingZeros++;
|
|
78
|
-
}
|
|
79
|
-
return Uint8Array.from([
|
|
80
|
-
...new Array(leadingZeros).fill(0),
|
|
81
|
-
...bytes.reverse(),
|
|
82
|
-
]);
|
|
83
|
-
}
|
|
84
|
-
function toHex(bytes) {
|
|
85
|
-
let out = '';
|
|
86
|
-
for (const byte of bytes)
|
|
87
|
-
out += byte.toString(16).padStart(2, '0');
|
|
88
|
-
return out;
|
|
89
|
-
}
|
|
90
|
-
function fromHex(hex) {
|
|
91
|
-
const bytes = new Uint8Array(hex.length / 2);
|
|
92
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
93
|
-
bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
94
|
-
}
|
|
95
|
-
return bytes;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Canonicalise an account id to hex — the form every admin route expects.
|
|
99
|
-
*
|
|
100
|
-
* Returns the input unchanged if it is not a 32-byte account, so a device key
|
|
101
|
-
* or an alias survives a call to this function intact.
|
|
102
|
-
*/
|
|
103
|
-
export function toAccountHex(id) {
|
|
104
|
-
const trimmed = (id ?? '').trim();
|
|
105
|
-
if (!trimmed)
|
|
106
|
-
return '';
|
|
107
|
-
if (HEX_ACCOUNT.test(trimmed))
|
|
108
|
-
return trimmed.toLowerCase();
|
|
109
|
-
const decoded = decodeBase58(trimmed);
|
|
110
|
-
if (!decoded || decoded.length !== 32)
|
|
111
|
-
return trimmed;
|
|
112
|
-
return toHex(decoded);
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Canonicalise an account id to base58 — the form the contract stamps on
|
|
116
|
-
* `sender` and keys `get_profiles` by.
|
|
117
|
-
*
|
|
118
|
-
* Returns the input unchanged if it is not a 32-byte account.
|
|
119
|
-
*/
|
|
120
|
-
export function toAccountBase58(id) {
|
|
121
|
-
const trimmed = (id ?? '').trim();
|
|
122
|
-
if (!trimmed)
|
|
123
|
-
return '';
|
|
124
|
-
if (!HEX_ACCOUNT.test(trimmed))
|
|
125
|
-
return trimmed;
|
|
126
|
-
return encodeBase58(fromHex(trimmed));
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* True when both ids name the same account, whichever encoding each is in.
|
|
130
|
-
*
|
|
131
|
-
* This is the comparison to reach for when checking a contract-sourced
|
|
132
|
-
* `sender` against an admin-sourced member id. Two ids that are not accounts
|
|
133
|
-
* compare false rather than accidentally matching as raw strings.
|
|
134
|
-
*/
|
|
135
|
-
export function sameAccount(a, b) {
|
|
136
|
-
const left = toAccountHex(a);
|
|
137
|
-
const right = toAccountHex(b);
|
|
138
|
-
return HEX_ACCOUNT.test(left) && left === right;
|
|
139
|
-
}
|