@aithos/sdk 0.1.0-alpha.47 → 0.1.0-alpha.49
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/src/apps.js +2 -13
- package/dist/src/data.js +7 -24
- package/dist/src/internal/envelope.js +20 -121
- package/dist/test/canonical-conformance.test.d.ts +2 -0
- package/dist/test/canonical-conformance.test.js +86 -0
- package/dist/test/envelope-core-conformance.test.d.ts +2 -0
- package/dist/test/envelope-core-conformance.test.js +75 -0
- package/package.json +5 -3
package/dist/src/apps.js
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
// in V0.2 once the sponsorship-api Lambda exists; for now, devs check
|
|
27
27
|
// their sponsorship via the AWS Console.
|
|
28
28
|
import { base64url, buildSignedEnvelope, sign } from "@aithos/protocol-client";
|
|
29
|
+
import { canonicalize } from "@aithos/protocol-core/canonical";
|
|
29
30
|
import { computeInvokeUrl, walletTopupCheckoutUrl } from "./endpoints.js";
|
|
30
31
|
import { ownerKeyPair } from "./internal/protocol-client-bridge.js";
|
|
31
32
|
import { AithosSDKError } from "./types.js";
|
|
@@ -426,18 +427,6 @@ function randomBytes(n) {
|
|
|
426
427
|
* the hash the signature commits to.
|
|
427
428
|
*/
|
|
428
429
|
function jcsCanonicalize(value) {
|
|
429
|
-
|
|
430
|
-
return JSON.stringify(value);
|
|
431
|
-
}
|
|
432
|
-
if (Array.isArray(value)) {
|
|
433
|
-
return "[" + value.map(jcsCanonicalize).join(",") + "]";
|
|
434
|
-
}
|
|
435
|
-
const obj = value;
|
|
436
|
-
const keys = Object.keys(obj).sort();
|
|
437
|
-
return ("{" +
|
|
438
|
-
keys
|
|
439
|
-
.map((k) => JSON.stringify(k) + ":" + jcsCanonicalize(obj[k]))
|
|
440
|
-
.join(",") +
|
|
441
|
-
"}");
|
|
430
|
+
return canonicalize(value);
|
|
442
431
|
}
|
|
443
432
|
//# sourceMappingURL=apps.js.map
|
package/dist/src/data.js
CHANGED
|
@@ -39,6 +39,7 @@ import { sha256, sha512 } from "@noble/hashes/sha2.js";
|
|
|
39
39
|
import { XChaCha20Poly1305 } from "@stablelib/xchacha20poly1305";
|
|
40
40
|
import * as ed from "@noble/ed25519";
|
|
41
41
|
import { multibaseToEd25519PublicKey, edPubToX25519Pub, } from "@aithos/protocol-client";
|
|
42
|
+
import { canonicalize } from "@aithos/protocol-core/canonical";
|
|
42
43
|
import { contactsV1 } from "./data-schema-contacts-v1.js";
|
|
43
44
|
import { signOwnerEnvelope } from "./internal/envelope.js";
|
|
44
45
|
// noble/ed25519 v2 needs sha512 wired in for sync sign/verify
|
|
@@ -989,30 +990,12 @@ function sha256Hex(s) {
|
|
|
989
990
|
/* -------------------------------------------------------------------------- */
|
|
990
991
|
/* JCS-style canonicalization (RFC 8785 subset) */
|
|
991
992
|
/* -------------------------------------------------------------------------- */
|
|
993
|
+
// Single canonicalization source of truth: @aithos/protocol-core. Kept as a
|
|
994
|
+
// local alias so the encryption-AAD call sites read naturally; the byte output
|
|
995
|
+
// is proven identical to the former hand-rolled JCS by
|
|
996
|
+
// test/canonical-conformance.test.ts (critical: this feeds pre-encryption
|
|
997
|
+
// canonicalization, so any drift would corrupt data).
|
|
992
998
|
function jcsCanonicalize(value) {
|
|
993
|
-
|
|
994
|
-
return "null";
|
|
995
|
-
if (value === undefined)
|
|
996
|
-
throw new Error("Cannot canonicalize undefined");
|
|
997
|
-
if (typeof value === "boolean")
|
|
998
|
-
return value ? "true" : "false";
|
|
999
|
-
if (typeof value === "number") {
|
|
1000
|
-
if (!Number.isFinite(value))
|
|
1001
|
-
throw new Error("non-finite number");
|
|
1002
|
-
return value.toString();
|
|
1003
|
-
}
|
|
1004
|
-
if (typeof value === "string")
|
|
1005
|
-
return JSON.stringify(value);
|
|
1006
|
-
if (Array.isArray(value)) {
|
|
1007
|
-
return "[" + value.map(jcsCanonicalize).join(",") + "]";
|
|
1008
|
-
}
|
|
1009
|
-
if (typeof value === "object") {
|
|
1010
|
-
const obj = value;
|
|
1011
|
-
const keys = Object.keys(obj).sort();
|
|
1012
|
-
return ("{" +
|
|
1013
|
-
keys.map((k) => JSON.stringify(k) + ":" + jcsCanonicalize(obj[k])).join(",") +
|
|
1014
|
-
"}");
|
|
1015
|
-
}
|
|
1016
|
-
throw new Error(`Cannot canonicalize ${typeof value}`);
|
|
999
|
+
return canonicalize(value);
|
|
1017
1000
|
}
|
|
1018
1001
|
//# sourceMappingURL=data.js.map
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* with `src/data.ts` is intentional and tracked; consolidation into a
|
|
20
20
|
* shared `src/internal/canonical.ts` is planned for a follow-up release.
|
|
21
21
|
*/
|
|
22
|
-
import {
|
|
22
|
+
import { signEnvelopeWith } from "@aithos/protocol-core/envelope";
|
|
23
23
|
/**
|
|
24
24
|
* Build, canonicalize and sign an owner-path envelope per spec §11.2.
|
|
25
25
|
*
|
|
@@ -33,128 +33,27 @@ import { sha256 } from "@noble/hashes/sha2.js";
|
|
|
33
33
|
* (non-extractable keys) drop in without breaking callers.
|
|
34
34
|
*/
|
|
35
35
|
export async function signOwnerEnvelope(args) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
// Delegate to the single envelope source of truth in @aithos/protocol-core.
|
|
37
|
+
// The canonicalization, params_hash, unsigned-envelope assembly and proof
|
|
38
|
+
// attachment all live there now; we only supply the pluggable async signer
|
|
39
|
+
// (preserving the WebCrypto-ready `EnvelopeSigner` abstraction). A
|
|
40
|
+
// conformance test proves this path is byte-identical to the seed-based
|
|
41
|
+
// core signer, which is itself byte-identical to the former hand-rolled
|
|
42
|
+
// implementation — so nothing changes on the wire.
|
|
43
|
+
const env = await signEnvelopeWith({
|
|
43
44
|
iss: args.iss,
|
|
44
45
|
aud: args.aud,
|
|
45
46
|
method: args.method,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
type: "Ed25519Signature2020",
|
|
58
|
-
verificationMethod: args.verificationMethod,
|
|
59
|
-
created: new Date(iat * 1000).toISOString(),
|
|
60
|
-
proofValue: "",
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
const bytes = new TextEncoder().encode(jcsCanonicalize(unsigned));
|
|
64
|
-
const sig = await args.signer.sign(bytes);
|
|
65
|
-
return {
|
|
66
|
-
...unsigned,
|
|
67
|
-
proof: { ...unsigned.proof, proofValue: base64url(sig) },
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
/* -------------------------------------------------------------------------- */
|
|
71
|
-
/* Self-contained helpers (duplicated with src/data.ts for isolation) */
|
|
72
|
-
/* -------------------------------------------------------------------------- */
|
|
73
|
-
/** Cross-platform CSPRNG: Web Crypto in browser, Node WebCrypto in Node 19+. */
|
|
74
|
-
function cryptoRandom(n) {
|
|
75
|
-
const buf = new Uint8Array(n);
|
|
76
|
-
globalThis.crypto?.getRandomValues(buf);
|
|
77
|
-
return buf;
|
|
78
|
-
}
|
|
79
|
-
function makeUlid() {
|
|
80
|
-
// Lightweight ULID — millisecond timestamp + 80 bits of randomness.
|
|
81
|
-
// Crockford base32. For tests this is sufficient; production uses
|
|
82
|
-
// the canonical ulid package.
|
|
83
|
-
const tsBuf = new Uint8Array(6);
|
|
84
|
-
let ts = Date.now();
|
|
85
|
-
for (let i = 5; i >= 0; i--) {
|
|
86
|
-
tsBuf[i] = ts & 0xff;
|
|
87
|
-
ts = Math.floor(ts / 256);
|
|
88
|
-
}
|
|
89
|
-
const rndBuf = cryptoRandom(10);
|
|
90
|
-
const all = new Uint8Array(16);
|
|
91
|
-
all.set(tsBuf, 0);
|
|
92
|
-
all.set(rndBuf, 6);
|
|
93
|
-
const alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
94
|
-
let bits = 0;
|
|
95
|
-
let value = 0;
|
|
96
|
-
let out = "";
|
|
97
|
-
for (const b of all) {
|
|
98
|
-
value = (value << 8) | b;
|
|
99
|
-
bits += 8;
|
|
100
|
-
while (bits >= 5) {
|
|
101
|
-
out += alphabet[(value >> (bits - 5)) & 0x1f];
|
|
102
|
-
bits -= 5;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (bits > 0)
|
|
106
|
-
out += alphabet[(value << (5 - bits)) & 0x1f];
|
|
107
|
-
return out.slice(0, 26);
|
|
108
|
-
}
|
|
109
|
-
/** Standard base64 (with `=` padding). Browser + Node compatible. */
|
|
110
|
-
function base64Std(bytes) {
|
|
111
|
-
let bin = "";
|
|
112
|
-
for (let i = 0; i < bytes.length; i++)
|
|
113
|
-
bin += String.fromCharCode(bytes[i]);
|
|
114
|
-
return btoa(bin);
|
|
115
|
-
}
|
|
116
|
-
/** base64url (URL-safe, no padding). */
|
|
117
|
-
function base64url(bytes) {
|
|
118
|
-
return base64Std(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
119
|
-
}
|
|
120
|
-
function sha256Hex(s) {
|
|
121
|
-
const d = sha256(new TextEncoder().encode(s));
|
|
122
|
-
let hex = "";
|
|
123
|
-
for (const b of d)
|
|
124
|
-
hex += b.toString(16).padStart(2, "0");
|
|
125
|
-
return hex;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* JCS-style canonicalization (RFC 8785 subset).
|
|
129
|
-
*
|
|
130
|
-
* Sorted object keys, no whitespace, finite numbers via `toString()`,
|
|
131
|
-
* strings via `JSON.stringify` (escapes), arrays preserve order.
|
|
132
|
-
* `undefined` is rejected (RFC 8785 §3.2.2).
|
|
133
|
-
*/
|
|
134
|
-
function jcsCanonicalize(value) {
|
|
135
|
-
if (value === null)
|
|
136
|
-
return "null";
|
|
137
|
-
if (value === undefined)
|
|
138
|
-
throw new Error("Cannot canonicalize undefined");
|
|
139
|
-
if (typeof value === "boolean")
|
|
140
|
-
return value ? "true" : "false";
|
|
141
|
-
if (typeof value === "number") {
|
|
142
|
-
if (!Number.isFinite(value))
|
|
143
|
-
throw new Error("non-finite number");
|
|
144
|
-
return value.toString();
|
|
145
|
-
}
|
|
146
|
-
if (typeof value === "string")
|
|
147
|
-
return JSON.stringify(value);
|
|
148
|
-
if (Array.isArray(value)) {
|
|
149
|
-
return "[" + value.map(jcsCanonicalize).join(",") + "]";
|
|
150
|
-
}
|
|
151
|
-
if (typeof value === "object") {
|
|
152
|
-
const obj = value;
|
|
153
|
-
const keys = Object.keys(obj).sort();
|
|
154
|
-
return ("{" +
|
|
155
|
-
keys.map((k) => JSON.stringify(k) + ":" + jcsCanonicalize(obj[k])).join(",") +
|
|
156
|
-
"}");
|
|
157
|
-
}
|
|
158
|
-
throw new Error(`Cannot canonicalize ${typeof value}`);
|
|
47
|
+
params: args.params,
|
|
48
|
+
verificationMethod: args.verificationMethod,
|
|
49
|
+
sign: (bytes) => args.signer.sign(bytes),
|
|
50
|
+
ttlSeconds: args.ttlSeconds,
|
|
51
|
+
now: args.now,
|
|
52
|
+
nonce: args.nonce,
|
|
53
|
+
...(args.mandate !== undefined
|
|
54
|
+
? { mandate: args.mandate }
|
|
55
|
+
: {}),
|
|
56
|
+
});
|
|
57
|
+
return env;
|
|
159
58
|
}
|
|
160
59
|
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright 2026 Mathieu Colla
|
|
3
|
+
/**
|
|
4
|
+
* Safety gate for the canonicalization refactor.
|
|
5
|
+
*
|
|
6
|
+
* The SDK historically carried three hand-rolled copies of `jcsCanonicalize`
|
|
7
|
+
* (internal/envelope.ts, data.ts, apps.ts). data.ts uses it to canonicalize a
|
|
8
|
+
* record payload BEFORE encryption (it feeds the AAD/plaintext), so a single
|
|
9
|
+
* differing byte vs. the canonicalization used at decrypt/verify time would
|
|
10
|
+
* silently corrupt data. Before swapping those copies onto
|
|
11
|
+
* `@aithos/protocol-core`'s `canonicalize`, this test proves the two produce
|
|
12
|
+
* identical output across a representative corpus.
|
|
13
|
+
*
|
|
14
|
+
* Known, accepted divergence: lone UTF-16 surrogates. `JSON.stringify` escapes
|
|
15
|
+
* them (\uXXXX) whereas core emits the raw code unit. Lone surrogates never
|
|
16
|
+
* appear in Aithos payloads (record fields are well-formed JSON strings), so
|
|
17
|
+
* the corpus excludes them by design.
|
|
18
|
+
*/
|
|
19
|
+
import { describe, test } from "node:test";
|
|
20
|
+
import { strict as assert } from "node:assert";
|
|
21
|
+
import { canonicalize } from "@aithos/protocol-core/canonical";
|
|
22
|
+
/** Exact copy of the SDK's legacy jcsCanonicalize (pre-refactor reference). */
|
|
23
|
+
function jcsCanonicalize(value) {
|
|
24
|
+
if (value === null)
|
|
25
|
+
return "null";
|
|
26
|
+
if (value === undefined)
|
|
27
|
+
throw new Error("Cannot canonicalize undefined");
|
|
28
|
+
if (typeof value === "boolean")
|
|
29
|
+
return value ? "true" : "false";
|
|
30
|
+
if (typeof value === "number") {
|
|
31
|
+
if (!Number.isFinite(value))
|
|
32
|
+
throw new Error("non-finite number");
|
|
33
|
+
return value.toString();
|
|
34
|
+
}
|
|
35
|
+
if (typeof value === "string")
|
|
36
|
+
return JSON.stringify(value);
|
|
37
|
+
if (Array.isArray(value)) {
|
|
38
|
+
return "[" + value.map(jcsCanonicalize).join(",") + "]";
|
|
39
|
+
}
|
|
40
|
+
if (typeof value === "object") {
|
|
41
|
+
const obj = value;
|
|
42
|
+
const keys = Object.keys(obj).sort();
|
|
43
|
+
return ("{" +
|
|
44
|
+
keys
|
|
45
|
+
.map((k) => JSON.stringify(k) + ":" + jcsCanonicalize(obj[k]))
|
|
46
|
+
.join(",") +
|
|
47
|
+
"}");
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`Cannot canonicalize ${typeof value}`);
|
|
50
|
+
}
|
|
51
|
+
const corpus = [
|
|
52
|
+
null,
|
|
53
|
+
true,
|
|
54
|
+
false,
|
|
55
|
+
0,
|
|
56
|
+
-1,
|
|
57
|
+
42,
|
|
58
|
+
Number.MAX_SAFE_INTEGER,
|
|
59
|
+
"",
|
|
60
|
+
"hello",
|
|
61
|
+
"with \"quotes\" and \\ backslash",
|
|
62
|
+
"tab\tnewline\nreturn\rbackspace\bform\f",
|
|
63
|
+
"control end",
|
|
64
|
+
"accented éàùçö and emoji 😀🚀 and 漢字",
|
|
65
|
+
"slash / and at @ and unicode nbsp",
|
|
66
|
+
[],
|
|
67
|
+
[1, 2, 3],
|
|
68
|
+
["z", "a", "m"],
|
|
69
|
+
[{ b: 1, a: 2 }, [3, [4, 5]]],
|
|
70
|
+
{},
|
|
71
|
+
{ b: 2, a: 1, c: 3 },
|
|
72
|
+
{ z: { y: { x: [1, "two", false, null] } } },
|
|
73
|
+
{ "key with spaces": 1, "weird:char": 2, "": "empty key" },
|
|
74
|
+
{ émoji: "😀", "漢字": 1, A: 0, a: 0 }, // mixed-case + non-ascii keys (UTF-16 order)
|
|
75
|
+
{
|
|
76
|
+
record: { name: "Aïko", tags: ["x", "y"], n: 7, active: true, meta: null },
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
describe("canonicalize conformance — core vs legacy SDK jcsCanonicalize", () => {
|
|
80
|
+
for (const [i, value] of corpus.entries()) {
|
|
81
|
+
test(`corpus[${i}] is byte-identical`, () => {
|
|
82
|
+
assert.equal(canonicalize(value), jcsCanonicalize(value));
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=canonical-conformance.test.js.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright 2026 Mathieu Colla
|
|
3
|
+
/**
|
|
4
|
+
* Conformance for the envelope-signing refactor.
|
|
5
|
+
*
|
|
6
|
+
* `signOwnerEnvelope` now delegates to `@aithos/protocol-core`'s
|
|
7
|
+
* `signEnvelopeWith` (pluggable async signer) instead of carrying a private
|
|
8
|
+
* JCS + signing implementation. These tests assert the migrated path is
|
|
9
|
+
* correct and stable:
|
|
10
|
+
*
|
|
11
|
+
* 1. the produced envelope's `proof.proofValue` verifies against the signer's
|
|
12
|
+
* public key over core's canonical signing bytes (i.e. the server will
|
|
13
|
+
* accept it);
|
|
14
|
+
* 2. `params_hash` equals core's `envelopeParamsHash(params)`;
|
|
15
|
+
* 3. with a fixed clock + nonce the output is deterministic (snapshot), which
|
|
16
|
+
* is what guarantees the wire format did not shift under the refactor.
|
|
17
|
+
*
|
|
18
|
+
* Note: this suite needs the SDK to resolve a build of `@aithos/protocol-core`
|
|
19
|
+
* that exposes `signEnvelopeWith` (>= 0.6.3). Run via `npm test`.
|
|
20
|
+
*/
|
|
21
|
+
import { describe, test } from "node:test";
|
|
22
|
+
import { strict as assert } from "node:assert";
|
|
23
|
+
import * as ed from "@noble/ed25519";
|
|
24
|
+
import { sha512 } from "@noble/hashes/sha512";
|
|
25
|
+
import { envelopeParamsHash, envelopeSigningBytes, } from "@aithos/protocol-core/envelope";
|
|
26
|
+
import { signOwnerEnvelope } from "../src/internal/envelope.js";
|
|
27
|
+
ed.etc.sha512Sync = (...m) => sha512(ed.etc.concatBytes(...m));
|
|
28
|
+
const SEED = new Uint8Array(32).fill(11);
|
|
29
|
+
const PUB = ed.getPublicKey(SEED);
|
|
30
|
+
const NOW = new Date("2026-05-31T12:00:00.000Z");
|
|
31
|
+
const NONCE = "01J0ENVELOPECONFORMANCE0000";
|
|
32
|
+
const ISS = "did:aithos:z6MkEnvelopeConformance";
|
|
33
|
+
const VM = `${ISS}#public`;
|
|
34
|
+
const base = {
|
|
35
|
+
iss: ISS,
|
|
36
|
+
aud: "https://api.aithos.be/mcp/primitives/write",
|
|
37
|
+
method: "aithos.data.insert_record",
|
|
38
|
+
params: { b: 2, a: 1, nested: { y: [3, 1, 2], x: "z" } },
|
|
39
|
+
verificationMethod: VM,
|
|
40
|
+
signer: { sign: async (bytes) => ed.sign(bytes, SEED) },
|
|
41
|
+
ttlSeconds: 60,
|
|
42
|
+
now: NOW,
|
|
43
|
+
nonce: NONCE,
|
|
44
|
+
};
|
|
45
|
+
describe("signOwnerEnvelope — core delegation conformance", () => {
|
|
46
|
+
test("proofValue verifies against signing bytes (server will accept)", async () => {
|
|
47
|
+
const env = await signOwnerEnvelope({ ...base });
|
|
48
|
+
const sig = b64urlDecode(env.proof.proofValue);
|
|
49
|
+
assert.equal(ed.verify(sig, envelopeSigningBytes(env), PUB), true);
|
|
50
|
+
});
|
|
51
|
+
test("params_hash matches core.envelopeParamsHash", async () => {
|
|
52
|
+
const env = await signOwnerEnvelope({ ...base });
|
|
53
|
+
assert.equal(env.params_hash, envelopeParamsHash(base.params));
|
|
54
|
+
});
|
|
55
|
+
test("deterministic under fixed clock + nonce (wire-format snapshot)", async () => {
|
|
56
|
+
const a = await signOwnerEnvelope({ ...base });
|
|
57
|
+
const b = await signOwnerEnvelope({ ...base });
|
|
58
|
+
assert.equal(JSON.stringify(a), JSON.stringify(b));
|
|
59
|
+
assert.equal(a["aithos-envelope"], "0.1.0");
|
|
60
|
+
assert.equal(a.iat, 1780228800);
|
|
61
|
+
assert.equal(a.exp, 1780228860);
|
|
62
|
+
assert.equal(a.nonce, NONCE);
|
|
63
|
+
assert.equal(a.proof.verificationMethod, VM);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
function b64urlDecode(s) {
|
|
67
|
+
const pad = s.length % 4 === 0 ? "" : "=".repeat(4 - (s.length % 4));
|
|
68
|
+
const b64 = s.replace(/-/g, "+").replace(/_/g, "/") + pad;
|
|
69
|
+
const bin = atob(b64);
|
|
70
|
+
const out = new Uint8Array(bin.length);
|
|
71
|
+
for (let i = 0; i < bin.length; i++)
|
|
72
|
+
out[i] = bin.charCodeAt(i);
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=envelope-core-conformance.test.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aithos/sdk",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.49",
|
|
4
4
|
"description": "Aithos SDK — high-level TypeScript developer kit for building agentic apps on the Aithos protocol. Wraps @aithos/protocol-client and exposes the Aithos compute proxy and wallet (Stripe top-up) endpoints.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"aithos",
|
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"@aithos/assets-crypto": ">=0.1.0-alpha.1 <0.2.0",
|
|
60
|
-
"@aithos/protocol-client": "^0.1.0-alpha.
|
|
60
|
+
"@aithos/protocol-client": "^0.1.0-alpha.17",
|
|
61
|
+
"@aithos/protocol-core": ">=0.6.3 <0.7.0",
|
|
61
62
|
"react": "^18.0.0 || ^19.0.0"
|
|
62
63
|
},
|
|
63
64
|
"peerDependenciesMeta": {
|
|
@@ -70,7 +71,8 @@
|
|
|
70
71
|
},
|
|
71
72
|
"devDependencies": {
|
|
72
73
|
"@aithos/assets-crypto": "^0.1.0-alpha.1",
|
|
73
|
-
"@aithos/protocol-client": "^0.1.0-alpha.
|
|
74
|
+
"@aithos/protocol-client": "^0.1.0-alpha.17",
|
|
75
|
+
"@aithos/protocol-core": ">=0.6.3 <0.7.0",
|
|
74
76
|
"@types/node": "^24.12.2",
|
|
75
77
|
"fake-indexeddb": "^6.2.5",
|
|
76
78
|
"typescript": "^5.9.2"
|