@inkd/sdk 0.9.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/README.md +288 -0
- package/dist/InkdClient.d.ts +89 -0
- package/dist/InkdClient.d.ts.map +1 -0
- package/dist/InkdClient.js +398 -0
- package/dist/InkdClient.js.map +1 -0
- package/dist/ProjectRegistry.d.ts +655 -0
- package/dist/ProjectRegistry.d.ts.map +1 -0
- package/dist/ProjectRegistry.js +708 -0
- package/dist/ProjectRegistry.js.map +1 -0
- package/dist/__tests__/InkdClient.advanced.test.d.ts +10 -0
- package/dist/__tests__/InkdClient.advanced.test.d.ts.map +1 -0
- package/dist/__tests__/InkdClient.advanced.test.js +588 -0
- package/dist/__tests__/InkdClient.advanced.test.js.map +1 -0
- package/dist/__tests__/InkdClient.connectArweave.test.d.ts +10 -0
- package/dist/__tests__/InkdClient.connectArweave.test.d.ts.map +1 -0
- package/dist/__tests__/InkdClient.connectArweave.test.js +132 -0
- package/dist/__tests__/InkdClient.connectArweave.test.js.map +1 -0
- package/dist/__tests__/InkdClient.test.d.ts +2 -0
- package/dist/__tests__/InkdClient.test.d.ts.map +1 -0
- package/dist/__tests__/InkdClient.test.js +259 -0
- package/dist/__tests__/InkdClient.test.js.map +1 -0
- package/dist/__tests__/ProjectRegistry.test.d.ts +8 -0
- package/dist/__tests__/ProjectRegistry.test.d.ts.map +1 -0
- package/dist/__tests__/ProjectRegistry.test.js +689 -0
- package/dist/__tests__/ProjectRegistry.test.js.map +1 -0
- package/dist/__tests__/arweave.test.d.ts +9 -0
- package/dist/__tests__/arweave.test.d.ts.map +1 -0
- package/dist/__tests__/arweave.test.js +353 -0
- package/dist/__tests__/arweave.test.js.map +1 -0
- package/dist/__tests__/encryption.test.d.ts +2 -0
- package/dist/__tests__/encryption.test.d.ts.map +1 -0
- package/dist/__tests__/encryption.test.js +154 -0
- package/dist/__tests__/encryption.test.js.map +1 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +136 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/events.test.d.ts +10 -0
- package/dist/__tests__/events.test.d.ts.map +1 -0
- package/dist/__tests__/events.test.js +380 -0
- package/dist/__tests__/events.test.js.map +1 -0
- package/dist/__tests__/index.InkdClient.test.d.ts +8 -0
- package/dist/__tests__/index.InkdClient.test.d.ts.map +1 -0
- package/dist/__tests__/index.InkdClient.test.js +422 -0
- package/dist/__tests__/index.InkdClient.test.js.map +1 -0
- package/dist/__tests__/multicall.test.d.ts +9 -0
- package/dist/__tests__/multicall.test.d.ts.map +1 -0
- package/dist/__tests__/multicall.test.js +362 -0
- package/dist/__tests__/multicall.test.js.map +1 -0
- package/dist/__tests__/types.test.d.ts +2 -0
- package/dist/__tests__/types.test.d.ts.map +1 -0
- package/dist/__tests__/types.test.js +35 -0
- package/dist/__tests__/types.test.js.map +1 -0
- package/dist/abi.d.ts +2632 -0
- package/dist/abi.d.ts.map +1 -0
- package/dist/abi.js +3423 -0
- package/dist/abi.js.map +1 -0
- package/dist/arweave.d.ts +45 -0
- package/dist/arweave.d.ts.map +1 -0
- package/dist/arweave.js +154 -0
- package/dist/arweave.js.map +1 -0
- package/dist/encryption.d.ts +52 -0
- package/dist/encryption.d.ts.map +1 -0
- package/dist/encryption.js +80 -0
- package/dist/encryption.js.map +1 -0
- package/dist/errors.d.ts +63 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +124 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +136 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +131 -0
- package/dist/events.js.map +1 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +12 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useInkd.d.ts +24 -0
- package/dist/hooks/useInkd.d.ts.map +1 -0
- package/dist/hooks/useInkd.js +109 -0
- package/dist/hooks/useInkd.js.map +1 -0
- package/dist/hooks/useInkdHolder.d.ts +16 -0
- package/dist/hooks/useInkdHolder.d.ts.map +1 -0
- package/dist/hooks/useInkdHolder.js +45 -0
- package/dist/hooks/useInkdHolder.js.map +1 -0
- package/dist/hooks/useInscriptions.d.ts +17 -0
- package/dist/hooks/useInscriptions.d.ts.map +1 -0
- package/dist/hooks/useInscriptions.js +46 -0
- package/dist/hooks/useInscriptions.js.map +1 -0
- package/dist/hooks/useToken.d.ts +16 -0
- package/dist/hooks/useToken.d.ts.map +1 -0
- package/dist/hooks/useToken.js +45 -0
- package/dist/hooks/useToken.js.map +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +290 -0
- package/dist/index.js.map +1 -0
- package/dist/multicall.d.ts +134 -0
- package/dist/multicall.d.ts.map +1 -0
- package/dist/multicall.js +182 -0
- package/dist/multicall.js.map +1 -0
- package/dist/types.d.ts +187 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +32 -0
- package/dist/types.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,689 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file ProjectRegistry.test.ts
|
|
4
|
+
* @description Comprehensive unit tests for ProjectRegistry — the on-chain
|
|
5
|
+
* project registry client. Covers all read methods, all write methods,
|
|
6
|
+
* error guards, and edge-case paths.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const vitest_1 = require("vitest");
|
|
10
|
+
const ProjectRegistry_js_1 = require("../ProjectRegistry.js");
|
|
11
|
+
// ─── Fixtures ────────────────────────────────────────────────────────────────
|
|
12
|
+
const REGISTRY_ADDR = "0xRegistryAddress000000000000000000000001";
|
|
13
|
+
const TOKEN_ADDR = "0xTokenAddress00000000000000000000000002";
|
|
14
|
+
const OWNER_ADDR = "0xOwnerAddress0000000000000000000000000003";
|
|
15
|
+
const COLLAB_ADDR = "0xCollabAddress000000000000000000000000004";
|
|
16
|
+
const TX_HASH = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
|
|
17
|
+
const BASE_CONFIG = {
|
|
18
|
+
registryAddress: REGISTRY_ADDR,
|
|
19
|
+
tokenAddress: TOKEN_ADDR,
|
|
20
|
+
chainId: 84532,
|
|
21
|
+
};
|
|
22
|
+
const MOCK_PROJECT = {
|
|
23
|
+
id: 1n,
|
|
24
|
+
name: "agent-brain",
|
|
25
|
+
description: "Persistent memory for AI",
|
|
26
|
+
license: "MIT",
|
|
27
|
+
readmeHash: "ar://readme-hash",
|
|
28
|
+
owner: OWNER_ADDR,
|
|
29
|
+
isPublic: true,
|
|
30
|
+
isAgent: true,
|
|
31
|
+
agentEndpoint: "https://api.myagent.xyz",
|
|
32
|
+
createdAt: 1700000000n,
|
|
33
|
+
versionCount: 3n,
|
|
34
|
+
exists: true,
|
|
35
|
+
};
|
|
36
|
+
const MOCK_VERSION = {
|
|
37
|
+
projectId: 1n,
|
|
38
|
+
arweaveHash: "ar://v1-hash",
|
|
39
|
+
versionTag: "v1.0.0",
|
|
40
|
+
changelog: "Initial release",
|
|
41
|
+
pushedBy: OWNER_ADDR,
|
|
42
|
+
pushedAt: 1700001000n,
|
|
43
|
+
};
|
|
44
|
+
// ─── Mock factory helpers ─────────────────────────────────────────────────────
|
|
45
|
+
function makeMockPublicClient(overrides = {}) {
|
|
46
|
+
return {
|
|
47
|
+
readContract: vitest_1.vi.fn(),
|
|
48
|
+
waitForTransactionReceipt: vitest_1.vi.fn().mockResolvedValue({ logs: [] }),
|
|
49
|
+
...overrides,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function makeMockWalletClient(address = OWNER_ADDR) {
|
|
53
|
+
return {
|
|
54
|
+
account: { address },
|
|
55
|
+
writeContract: vitest_1.vi.fn().mockResolvedValue(TX_HASH),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// ─── Error Classes ────────────────────────────────────────────────────────────
|
|
59
|
+
(0, vitest_1.describe)("RegistryNotConnected", () => {
|
|
60
|
+
(0, vitest_1.it)("is an instance of Error", () => {
|
|
61
|
+
const err = new ProjectRegistry_js_1.RegistryNotConnected();
|
|
62
|
+
(0, vitest_1.expect)(err).toBeInstanceOf(Error);
|
|
63
|
+
});
|
|
64
|
+
(0, vitest_1.it)("has name RegistryNotConnected", () => {
|
|
65
|
+
(0, vitest_1.expect)(new ProjectRegistry_js_1.RegistryNotConnected().name).toBe("RegistryNotConnected");
|
|
66
|
+
});
|
|
67
|
+
(0, vitest_1.it)("message mentions connect()", () => {
|
|
68
|
+
(0, vitest_1.expect)(new ProjectRegistry_js_1.RegistryNotConnected().message).toContain("connect()");
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.describe)("InsufficientInkdBalance", () => {
|
|
72
|
+
(0, vitest_1.it)("is an instance of Error", () => {
|
|
73
|
+
(0, vitest_1.expect)(new ProjectRegistry_js_1.InsufficientInkdBalance(0n, 1000000000000000000n)).toBeInstanceOf(Error);
|
|
74
|
+
});
|
|
75
|
+
(0, vitest_1.it)("has name InsufficientInkdBalance", () => {
|
|
76
|
+
(0, vitest_1.expect)(new ProjectRegistry_js_1.InsufficientInkdBalance(0n, 1000000000000000000n).name).toBe("InsufficientInkdBalance");
|
|
77
|
+
});
|
|
78
|
+
(0, vitest_1.it)("message includes balance and required amounts", () => {
|
|
79
|
+
const err = new ProjectRegistry_js_1.InsufficientInkdBalance(500n, 1000n);
|
|
80
|
+
(0, vitest_1.expect)(err.message).toContain("500");
|
|
81
|
+
(0, vitest_1.expect)(err.message).toContain("1000");
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
(0, vitest_1.describe)("InsufficientEthBalance", () => {
|
|
85
|
+
(0, vitest_1.it)("is an instance of Error", () => {
|
|
86
|
+
(0, vitest_1.expect)(new ProjectRegistry_js_1.InsufficientEthBalance(1000000n)).toBeInstanceOf(Error);
|
|
87
|
+
});
|
|
88
|
+
(0, vitest_1.it)("has name InsufficientEthBalance", () => {
|
|
89
|
+
(0, vitest_1.expect)(new ProjectRegistry_js_1.InsufficientEthBalance(1000000n).name).toBe("InsufficientEthBalance");
|
|
90
|
+
});
|
|
91
|
+
(0, vitest_1.it)("message includes the fee amount", () => {
|
|
92
|
+
const err = new ProjectRegistry_js_1.InsufficientEthBalance(999n);
|
|
93
|
+
(0, vitest_1.expect)(err.message).toContain("999");
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
// ─── Constructor ──────────────────────────────────────────────────────────────
|
|
97
|
+
(0, vitest_1.describe)("ProjectRegistry — constructor", () => {
|
|
98
|
+
(0, vitest_1.it)("creates an instance with Base Sepolia config", () => {
|
|
99
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
100
|
+
(0, vitest_1.expect)(r).toBeInstanceOf(ProjectRegistry_js_1.ProjectRegistry);
|
|
101
|
+
});
|
|
102
|
+
(0, vitest_1.it)("creates an instance with Base mainnet config", () => {
|
|
103
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry({ ...BASE_CONFIG, chainId: 8453 });
|
|
104
|
+
(0, vitest_1.expect)(r).toBeInstanceOf(ProjectRegistry_js_1.ProjectRegistry);
|
|
105
|
+
});
|
|
106
|
+
(0, vitest_1.it)("does not throw on valid config", () => {
|
|
107
|
+
(0, vitest_1.expect)(() => new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG)).not.toThrow();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
// ─── connect() ────────────────────────────────────────────────────────────────
|
|
111
|
+
(0, vitest_1.describe)("ProjectRegistry — connect()", () => {
|
|
112
|
+
(0, vitest_1.it)("enables subsequent read calls", async () => {
|
|
113
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
114
|
+
const pub = makeMockPublicClient();
|
|
115
|
+
pub.readContract.mockResolvedValue(5n);
|
|
116
|
+
const wlt = makeMockWalletClient();
|
|
117
|
+
r.connect(wlt, pub);
|
|
118
|
+
const count = await r.getProjectCount();
|
|
119
|
+
(0, vitest_1.expect)(count).toBe(5n);
|
|
120
|
+
});
|
|
121
|
+
(0, vitest_1.it)("allows reconnect with a different client", async () => {
|
|
122
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
123
|
+
const pub1 = makeMockPublicClient();
|
|
124
|
+
const pub2 = makeMockPublicClient();
|
|
125
|
+
pub1.readContract.mockResolvedValue(1n);
|
|
126
|
+
pub2.readContract.mockResolvedValue(99n);
|
|
127
|
+
const wlt = makeMockWalletClient();
|
|
128
|
+
r.connect(wlt, pub1);
|
|
129
|
+
(0, vitest_1.expect)(await r.getProjectCount()).toBe(1n);
|
|
130
|
+
r.connect(wlt, pub2);
|
|
131
|
+
(0, vitest_1.expect)(await r.getProjectCount()).toBe(99n);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
// ─── Guard (RegistryNotConnected) ─────────────────────────────────────────────
|
|
135
|
+
(0, vitest_1.describe)("ProjectRegistry — connection guard", () => {
|
|
136
|
+
(0, vitest_1.it)("getProject throws without publicClient", async () => {
|
|
137
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
138
|
+
await (0, vitest_1.expect)(r.getProject(1n)).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
139
|
+
});
|
|
140
|
+
(0, vitest_1.it)("getVersion throws without publicClient", async () => {
|
|
141
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
142
|
+
await (0, vitest_1.expect)(r.getVersion(1n, 0n)).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
143
|
+
});
|
|
144
|
+
(0, vitest_1.it)("getAllVersions throws without publicClient", async () => {
|
|
145
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
146
|
+
await (0, vitest_1.expect)(r.getAllVersions(1n)).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
147
|
+
});
|
|
148
|
+
(0, vitest_1.it)("getOwnerProjects throws without publicClient", async () => {
|
|
149
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
150
|
+
await (0, vitest_1.expect)(r.getOwnerProjects(OWNER_ADDR)).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
151
|
+
});
|
|
152
|
+
(0, vitest_1.it)("getVersionFee throws without publicClient", async () => {
|
|
153
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
154
|
+
await (0, vitest_1.expect)(r.getVersionFee()).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
155
|
+
});
|
|
156
|
+
(0, vitest_1.it)("createProject throws without wallet", async () => {
|
|
157
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
158
|
+
await (0, vitest_1.expect)(r.createProject({ name: "foo" })).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
159
|
+
});
|
|
160
|
+
(0, vitest_1.it)("pushVersion throws without wallet", async () => {
|
|
161
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
162
|
+
await (0, vitest_1.expect)(r.pushVersion({ projectId: 1n, arweaveHash: "ar://x", versionTag: "v1" })).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
163
|
+
});
|
|
164
|
+
(0, vitest_1.it)("addCollaborator throws without wallet", async () => {
|
|
165
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
166
|
+
await (0, vitest_1.expect)(r.addCollaborator(1n, COLLAB_ADDR)).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
167
|
+
});
|
|
168
|
+
(0, vitest_1.it)("removeCollaborator throws without wallet", async () => {
|
|
169
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
170
|
+
await (0, vitest_1.expect)(r.removeCollaborator(1n, COLLAB_ADDR)).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
171
|
+
});
|
|
172
|
+
(0, vitest_1.it)("transferProject throws without wallet", async () => {
|
|
173
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
174
|
+
await (0, vitest_1.expect)(r.transferProject(1n, COLLAB_ADDR)).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
175
|
+
});
|
|
176
|
+
(0, vitest_1.it)("setVisibility throws without wallet", async () => {
|
|
177
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
178
|
+
await (0, vitest_1.expect)(r.setVisibility(1n, false)).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
179
|
+
});
|
|
180
|
+
(0, vitest_1.it)("setReadme throws without wallet", async () => {
|
|
181
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
182
|
+
await (0, vitest_1.expect)(r.setReadme(1n, "ar://readme")).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
183
|
+
});
|
|
184
|
+
(0, vitest_1.it)("setAgentEndpoint throws without wallet", async () => {
|
|
185
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
186
|
+
await (0, vitest_1.expect)(r.setAgentEndpoint(1n, "https://api.xyz")).rejects.toThrow(ProjectRegistry_js_1.RegistryNotConnected);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
// ─── Read methods ─────────────────────────────────────────────────────────────
|
|
190
|
+
(0, vitest_1.describe)("ProjectRegistry — getProject()", () => {
|
|
191
|
+
(0, vitest_1.it)("calls readContract with correct args and returns project", async () => {
|
|
192
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
193
|
+
const pub = makeMockPublicClient();
|
|
194
|
+
pub.readContract.mockResolvedValue(MOCK_PROJECT);
|
|
195
|
+
r.connect(makeMockWalletClient(), pub);
|
|
196
|
+
const result = await r.getProject(1n);
|
|
197
|
+
(0, vitest_1.expect)(result).toEqual(MOCK_PROJECT);
|
|
198
|
+
(0, vitest_1.expect)(pub.readContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ functionName: "getProject", args: [1n] }));
|
|
199
|
+
});
|
|
200
|
+
(0, vitest_1.it)("returns null when project does not exist (exists=false)", async () => {
|
|
201
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
202
|
+
const pub = makeMockPublicClient();
|
|
203
|
+
pub.readContract.mockResolvedValue({ ...MOCK_PROJECT, exists: false });
|
|
204
|
+
r.connect(makeMockWalletClient(), pub);
|
|
205
|
+
const result = await r.getProject(999n);
|
|
206
|
+
(0, vitest_1.expect)(result).toBeNull();
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
(0, vitest_1.describe)("ProjectRegistry — getVersion()", () => {
|
|
210
|
+
(0, vitest_1.it)("calls readContract with projectId and index", async () => {
|
|
211
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
212
|
+
const pub = makeMockPublicClient();
|
|
213
|
+
pub.readContract.mockResolvedValue(MOCK_VERSION);
|
|
214
|
+
r.connect(makeMockWalletClient(), pub);
|
|
215
|
+
const result = await r.getVersion(1n, 0n);
|
|
216
|
+
(0, vitest_1.expect)(result).toEqual(MOCK_VERSION);
|
|
217
|
+
(0, vitest_1.expect)(pub.readContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ functionName: "getVersion", args: [1n, 0n] }));
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
(0, vitest_1.describe)("ProjectRegistry — getAllVersions()", () => {
|
|
221
|
+
(0, vitest_1.it)("fetches version count then iterates over all versions", async () => {
|
|
222
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
223
|
+
const pub = makeMockPublicClient();
|
|
224
|
+
const versions = [
|
|
225
|
+
{ ...MOCK_VERSION, versionTag: "v1.0.0" },
|
|
226
|
+
{ ...MOCK_VERSION, versionTag: "v1.1.0" },
|
|
227
|
+
{ ...MOCK_VERSION, versionTag: "v1.2.0" },
|
|
228
|
+
];
|
|
229
|
+
pub.readContract
|
|
230
|
+
.mockResolvedValueOnce(3n) // getVersionCount
|
|
231
|
+
.mockResolvedValueOnce(versions[0])
|
|
232
|
+
.mockResolvedValueOnce(versions[1])
|
|
233
|
+
.mockResolvedValueOnce(versions[2]);
|
|
234
|
+
r.connect(makeMockWalletClient(), pub);
|
|
235
|
+
const result = await r.getAllVersions(1n);
|
|
236
|
+
(0, vitest_1.expect)(result).toHaveLength(3);
|
|
237
|
+
(0, vitest_1.expect)(result[0].versionTag).toBe("v1.0.0");
|
|
238
|
+
(0, vitest_1.expect)(result[2].versionTag).toBe("v1.2.0");
|
|
239
|
+
});
|
|
240
|
+
(0, vitest_1.it)("returns empty array when no versions exist", async () => {
|
|
241
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
242
|
+
const pub = makeMockPublicClient();
|
|
243
|
+
pub.readContract.mockResolvedValue(0n);
|
|
244
|
+
r.connect(makeMockWalletClient(), pub);
|
|
245
|
+
const result = await r.getAllVersions(1n);
|
|
246
|
+
(0, vitest_1.expect)(result).toEqual([]);
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
(0, vitest_1.describe)("ProjectRegistry — getOwnerProjects()", () => {
|
|
250
|
+
(0, vitest_1.it)("returns project IDs for an owner", async () => {
|
|
251
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
252
|
+
const pub = makeMockPublicClient();
|
|
253
|
+
pub.readContract.mockResolvedValue([1n, 2n, 5n]);
|
|
254
|
+
r.connect(makeMockWalletClient(), pub);
|
|
255
|
+
const ids = await r.getOwnerProjects(OWNER_ADDR);
|
|
256
|
+
(0, vitest_1.expect)(ids).toEqual([1n, 2n, 5n]);
|
|
257
|
+
(0, vitest_1.expect)(pub.readContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ functionName: "getOwnerProjects", args: [OWNER_ADDR] }));
|
|
258
|
+
});
|
|
259
|
+
(0, vitest_1.it)("returns empty array when owner has no projects", async () => {
|
|
260
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
261
|
+
const pub = makeMockPublicClient();
|
|
262
|
+
pub.readContract.mockResolvedValue([]);
|
|
263
|
+
r.connect(makeMockWalletClient(), pub);
|
|
264
|
+
(0, vitest_1.expect)(await r.getOwnerProjects(OWNER_ADDR)).toEqual([]);
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
(0, vitest_1.describe)("ProjectRegistry — getCollaborators()", () => {
|
|
268
|
+
(0, vitest_1.it)("returns collaborator addresses", async () => {
|
|
269
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
270
|
+
const pub = makeMockPublicClient();
|
|
271
|
+
pub.readContract.mockResolvedValue([COLLAB_ADDR]);
|
|
272
|
+
r.connect(makeMockWalletClient(), pub);
|
|
273
|
+
const collabs = await r.getCollaborators(1n);
|
|
274
|
+
(0, vitest_1.expect)(collabs).toEqual([COLLAB_ADDR]);
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
(0, vitest_1.describe)("ProjectRegistry — isCollaborator()", () => {
|
|
278
|
+
(0, vitest_1.it)("returns true when address is a collaborator", async () => {
|
|
279
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
280
|
+
const pub = makeMockPublicClient();
|
|
281
|
+
pub.readContract.mockResolvedValue(true);
|
|
282
|
+
r.connect(makeMockWalletClient(), pub);
|
|
283
|
+
(0, vitest_1.expect)(await r.isCollaborator(1n, COLLAB_ADDR)).toBe(true);
|
|
284
|
+
});
|
|
285
|
+
(0, vitest_1.it)("returns false when address is not a collaborator", async () => {
|
|
286
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
287
|
+
const pub = makeMockPublicClient();
|
|
288
|
+
pub.readContract.mockResolvedValue(false);
|
|
289
|
+
r.connect(makeMockWalletClient(), pub);
|
|
290
|
+
(0, vitest_1.expect)(await r.isCollaborator(1n, COLLAB_ADDR)).toBe(false);
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
(0, vitest_1.describe)("ProjectRegistry — isNameTaken()", () => {
|
|
294
|
+
(0, vitest_1.it)("returns true when name is taken", async () => {
|
|
295
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
296
|
+
const pub = makeMockPublicClient();
|
|
297
|
+
pub.readContract.mockResolvedValue(true);
|
|
298
|
+
r.connect(makeMockWalletClient(), pub);
|
|
299
|
+
(0, vitest_1.expect)(await r.isNameTaken("agent-brain")).toBe(true);
|
|
300
|
+
(0, vitest_1.expect)(pub.readContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ functionName: "nameTaken", args: ["agent-brain"] }));
|
|
301
|
+
});
|
|
302
|
+
(0, vitest_1.it)("returns false when name is available", async () => {
|
|
303
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
304
|
+
const pub = makeMockPublicClient();
|
|
305
|
+
pub.readContract.mockResolvedValue(false);
|
|
306
|
+
r.connect(makeMockWalletClient(), pub);
|
|
307
|
+
(0, vitest_1.expect)(await r.isNameTaken("new-project")).toBe(false);
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
(0, vitest_1.describe)("ProjectRegistry — getAgentProjects()", () => {
|
|
311
|
+
(0, vitest_1.it)("calls readContract with pagination args", async () => {
|
|
312
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
313
|
+
const pub = makeMockPublicClient();
|
|
314
|
+
pub.readContract.mockResolvedValue([1n, 3n]);
|
|
315
|
+
r.connect(makeMockWalletClient(), pub);
|
|
316
|
+
const result = await r.getAgentProjects(0n, 10n);
|
|
317
|
+
(0, vitest_1.expect)(result).toEqual([1n, 3n]);
|
|
318
|
+
(0, vitest_1.expect)(pub.readContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ functionName: "getAgentProjects", args: [0n, 10n] }));
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
(0, vitest_1.describe)("ProjectRegistry — getVersionFee()", () => {
|
|
322
|
+
(0, vitest_1.it)("returns fee as bigint", async () => {
|
|
323
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
324
|
+
const pub = makeMockPublicClient();
|
|
325
|
+
pub.readContract.mockResolvedValue(500000000000000n); // 0.0005 ETH
|
|
326
|
+
r.connect(makeMockWalletClient(), pub);
|
|
327
|
+
(0, vitest_1.expect)(await r.getVersionFee()).toBe(500000000000000n);
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
(0, vitest_1.describe)("ProjectRegistry — getTransferFee()", () => {
|
|
331
|
+
(0, vitest_1.it)("returns fee as bigint", async () => {
|
|
332
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
333
|
+
const pub = makeMockPublicClient();
|
|
334
|
+
pub.readContract.mockResolvedValue(1000000000000000n); // 0.001 ETH
|
|
335
|
+
r.connect(makeMockWalletClient(), pub);
|
|
336
|
+
(0, vitest_1.expect)(await r.getTransferFee()).toBe(1000000000000000n);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
(0, vitest_1.describe)("ProjectRegistry — getProjectCount()", () => {
|
|
340
|
+
(0, vitest_1.it)("returns total project count", async () => {
|
|
341
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
342
|
+
const pub = makeMockPublicClient();
|
|
343
|
+
pub.readContract.mockResolvedValue(42n);
|
|
344
|
+
r.connect(makeMockWalletClient(), pub);
|
|
345
|
+
(0, vitest_1.expect)(await r.getProjectCount()).toBe(42n);
|
|
346
|
+
});
|
|
347
|
+
(0, vitest_1.it)("returns 0n when registry is empty", async () => {
|
|
348
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
349
|
+
const pub = makeMockPublicClient();
|
|
350
|
+
pub.readContract.mockResolvedValue(0n);
|
|
351
|
+
r.connect(makeMockWalletClient(), pub);
|
|
352
|
+
(0, vitest_1.expect)(await r.getProjectCount()).toBe(0n);
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
// ─── estimatePushCost / estimateTransferCost ──────────────────────────────────
|
|
356
|
+
(0, vitest_1.describe)("ProjectRegistry — estimatePushCost()", () => {
|
|
357
|
+
(0, vitest_1.it)("delegates to getVersionFee()", async () => {
|
|
358
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
359
|
+
const pub = makeMockPublicClient();
|
|
360
|
+
pub.readContract.mockResolvedValue(500000000000000n);
|
|
361
|
+
r.connect(makeMockWalletClient(), pub);
|
|
362
|
+
(0, vitest_1.expect)(await r.estimatePushCost()).toBe(500000000000000n);
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
(0, vitest_1.describe)("ProjectRegistry — estimateTransferCost()", () => {
|
|
366
|
+
(0, vitest_1.it)("delegates to getTransferFee()", async () => {
|
|
367
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
368
|
+
const pub = makeMockPublicClient();
|
|
369
|
+
pub.readContract.mockResolvedValue(1000000000000000n);
|
|
370
|
+
r.connect(makeMockWalletClient(), pub);
|
|
371
|
+
(0, vitest_1.expect)(await r.estimateTransferCost()).toBe(1000000000000000n);
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
// ─── createProject() ─────────────────────────────────────────────────────────
|
|
375
|
+
(0, vitest_1.describe)("ProjectRegistry — createProject()", () => {
|
|
376
|
+
function setupCreateProjectMocks(pub) {
|
|
377
|
+
// TOKEN_LOCK_AMOUNT (1 INKD = 1e18)
|
|
378
|
+
const LOCK = 1000000000000000000n;
|
|
379
|
+
// call sequence: TOKEN_LOCK_AMOUNT, balanceOf, allowance, then writeContract receipt
|
|
380
|
+
pub.readContract
|
|
381
|
+
.mockResolvedValueOnce(LOCK) // TOKEN_LOCK_AMOUNT
|
|
382
|
+
.mockResolvedValueOnce(LOCK * 2n) // balanceOf (sufficient)
|
|
383
|
+
.mockResolvedValueOnce(LOCK); // allowance (sufficient — no approve needed)
|
|
384
|
+
pub.waitForTransactionReceipt.mockResolvedValue({
|
|
385
|
+
logs: [{ topics: ["0xPROJECT_CREATED", "0x1"] }],
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
(0, vitest_1.it)("calls writeContract with createProject and returns hash + projectId", async () => {
|
|
389
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
390
|
+
const pub = makeMockPublicClient();
|
|
391
|
+
setupCreateProjectMocks(pub);
|
|
392
|
+
const wlt = makeMockWalletClient();
|
|
393
|
+
r.connect(wlt, pub);
|
|
394
|
+
const result = await r.createProject({ name: "agent-brain" });
|
|
395
|
+
(0, vitest_1.expect)(result.hash).toBe(TX_HASH);
|
|
396
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ functionName: "createProject" }));
|
|
397
|
+
});
|
|
398
|
+
(0, vitest_1.it)("passes default values for optional fields", async () => {
|
|
399
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
400
|
+
const pub = makeMockPublicClient();
|
|
401
|
+
setupCreateProjectMocks(pub);
|
|
402
|
+
const wlt = makeMockWalletClient();
|
|
403
|
+
r.connect(wlt, pub);
|
|
404
|
+
await r.createProject({ name: "my-agent" });
|
|
405
|
+
const callArgs = wlt.writeContract.mock.calls[0][0];
|
|
406
|
+
(0, vitest_1.expect)(callArgs.args).toContain("MIT"); // default license
|
|
407
|
+
(0, vitest_1.expect)(callArgs.args).toContain(true); // default isPublic
|
|
408
|
+
});
|
|
409
|
+
(0, vitest_1.it)("respects explicit isAgent and agentEndpoint", async () => {
|
|
410
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
411
|
+
const pub = makeMockPublicClient();
|
|
412
|
+
setupCreateProjectMocks(pub);
|
|
413
|
+
const wlt = makeMockWalletClient();
|
|
414
|
+
r.connect(wlt, pub);
|
|
415
|
+
await r.createProject({
|
|
416
|
+
name: "smart-agent",
|
|
417
|
+
isAgent: true,
|
|
418
|
+
agentEndpoint: "https://agent.example.com",
|
|
419
|
+
});
|
|
420
|
+
const callArgs = wlt.writeContract.mock.calls[0][0];
|
|
421
|
+
(0, vitest_1.expect)(callArgs.args).toContain(true);
|
|
422
|
+
(0, vitest_1.expect)(callArgs.args).toContain("https://agent.example.com");
|
|
423
|
+
});
|
|
424
|
+
(0, vitest_1.it)("throws InsufficientInkdBalance when balance is too low", async () => {
|
|
425
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
426
|
+
const pub = makeMockPublicClient();
|
|
427
|
+
const LOCK = 1000000000000000000n;
|
|
428
|
+
pub.readContract
|
|
429
|
+
.mockResolvedValueOnce(LOCK) // TOKEN_LOCK_AMOUNT
|
|
430
|
+
.mockResolvedValueOnce(0n); // balanceOf (insufficient)
|
|
431
|
+
const wlt = makeMockWalletClient();
|
|
432
|
+
r.connect(wlt, pub);
|
|
433
|
+
await (0, vitest_1.expect)(r.createProject({ name: "broke-agent" })).rejects.toThrow(ProjectRegistry_js_1.InsufficientInkdBalance);
|
|
434
|
+
});
|
|
435
|
+
(0, vitest_1.it)("sends an approve tx when allowance is insufficient", async () => {
|
|
436
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
437
|
+
const pub = makeMockPublicClient();
|
|
438
|
+
const LOCK = 1000000000000000000n;
|
|
439
|
+
pub.readContract
|
|
440
|
+
.mockResolvedValueOnce(LOCK) // TOKEN_LOCK_AMOUNT
|
|
441
|
+
.mockResolvedValueOnce(LOCK * 2n) // balanceOf (sufficient)
|
|
442
|
+
.mockResolvedValueOnce(0n); // allowance (0 — approve needed)
|
|
443
|
+
pub.waitForTransactionReceipt.mockResolvedValue({
|
|
444
|
+
logs: [{ topics: ["0xPROJECT_CREATED", "0x1"] }],
|
|
445
|
+
});
|
|
446
|
+
const wlt = makeMockWalletClient();
|
|
447
|
+
// First call is approve, second is createProject
|
|
448
|
+
wlt.writeContract.mockResolvedValueOnce(TX_HASH).mockResolvedValueOnce(TX_HASH);
|
|
449
|
+
r.connect(wlt, pub);
|
|
450
|
+
await r.createProject({ name: "new-agent" });
|
|
451
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledTimes(2);
|
|
452
|
+
const firstCall = wlt.writeContract.mock.calls[0][0];
|
|
453
|
+
(0, vitest_1.expect)(firstCall.functionName).toBe("approve");
|
|
454
|
+
});
|
|
455
|
+
(0, vitest_1.it)("extracts projectId from transaction log topics", async () => {
|
|
456
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
457
|
+
const pub = makeMockPublicClient();
|
|
458
|
+
const LOCK = 1000000000000000000n;
|
|
459
|
+
pub.readContract
|
|
460
|
+
.mockResolvedValueOnce(LOCK)
|
|
461
|
+
.mockResolvedValueOnce(LOCK)
|
|
462
|
+
.mockResolvedValueOnce(LOCK);
|
|
463
|
+
pub.waitForTransactionReceipt.mockResolvedValue({
|
|
464
|
+
logs: [{ topics: ["0xeventSig", "0x7"] }], // projectId = 7
|
|
465
|
+
});
|
|
466
|
+
const wlt = makeMockWalletClient();
|
|
467
|
+
r.connect(wlt, pub);
|
|
468
|
+
const { projectId } = await r.createProject({ name: "agent-7" });
|
|
469
|
+
(0, vitest_1.expect)(projectId).toBe(7n);
|
|
470
|
+
});
|
|
471
|
+
(0, vitest_1.it)("falls back to 0n when no useful log topics found", async () => {
|
|
472
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
473
|
+
const pub = makeMockPublicClient();
|
|
474
|
+
const LOCK = 1000000000000000000n;
|
|
475
|
+
pub.readContract
|
|
476
|
+
.mockResolvedValueOnce(LOCK)
|
|
477
|
+
.mockResolvedValueOnce(LOCK)
|
|
478
|
+
.mockResolvedValueOnce(LOCK);
|
|
479
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] }); // no logs
|
|
480
|
+
const wlt = makeMockWalletClient();
|
|
481
|
+
r.connect(wlt, pub);
|
|
482
|
+
const { projectId } = await r.createProject({ name: "silent-agent" });
|
|
483
|
+
(0, vitest_1.expect)(projectId).toBe(0n);
|
|
484
|
+
});
|
|
485
|
+
(0, vitest_1.it)("extractProjectIdFromLogs: skips log with invalid topic[1] (catch branch), returns 0n", async () => {
|
|
486
|
+
// Log has 2 topics but topic[1] is not a valid BigInt string → catch fires → continue → return 0n
|
|
487
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
488
|
+
const pub = makeMockPublicClient();
|
|
489
|
+
const LOCK = 1000000000000000000n;
|
|
490
|
+
pub.readContract
|
|
491
|
+
.mockResolvedValueOnce(LOCK)
|
|
492
|
+
.mockResolvedValueOnce(LOCK)
|
|
493
|
+
.mockResolvedValueOnce(LOCK);
|
|
494
|
+
pub.waitForTransactionReceipt.mockResolvedValue({
|
|
495
|
+
logs: [{ topics: ["0xProjectCreated", "not-a-valid-bigint"] }], // ← triggers catch
|
|
496
|
+
});
|
|
497
|
+
const wlt = makeMockWalletClient();
|
|
498
|
+
r.connect(wlt, pub);
|
|
499
|
+
const { projectId } = await r.createProject({ name: "catch-branch-agent" });
|
|
500
|
+
(0, vitest_1.expect)(projectId).toBe(0n);
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
// ─── pushVersion() ────────────────────────────────────────────────────────────
|
|
504
|
+
(0, vitest_1.describe)("ProjectRegistry — pushVersion()", () => {
|
|
505
|
+
(0, vitest_1.it)("reads versionFee and writes pushVersion with correct args", async () => {
|
|
506
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
507
|
+
const pub = makeMockPublicClient();
|
|
508
|
+
pub.readContract
|
|
509
|
+
.mockResolvedValueOnce(500000000000000n) // getVersionFee
|
|
510
|
+
.mockResolvedValueOnce(1n); // getVersionCount (after push)
|
|
511
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
512
|
+
const wlt = makeMockWalletClient();
|
|
513
|
+
r.connect(wlt, pub);
|
|
514
|
+
const result = await r.pushVersion({
|
|
515
|
+
projectId: 1n,
|
|
516
|
+
arweaveHash: "ar://v1-hash",
|
|
517
|
+
versionTag: "v1.0.0",
|
|
518
|
+
changelog: "First push",
|
|
519
|
+
});
|
|
520
|
+
(0, vitest_1.expect)(result.hash).toBe(TX_HASH);
|
|
521
|
+
(0, vitest_1.expect)(result.versionIndex).toBe(0n); // count=1 → index=0
|
|
522
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
|
|
523
|
+
functionName: "pushVersion",
|
|
524
|
+
args: [1n, "ar://v1-hash", "v1.0.0", "First push"],
|
|
525
|
+
value: 500000000000000n,
|
|
526
|
+
}));
|
|
527
|
+
});
|
|
528
|
+
(0, vitest_1.it)("accepts explicit value override (skips fee read)", async () => {
|
|
529
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
530
|
+
const pub = makeMockPublicClient();
|
|
531
|
+
pub.readContract.mockResolvedValue(5n); // getVersionCount
|
|
532
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
533
|
+
const wlt = makeMockWalletClient();
|
|
534
|
+
r.connect(wlt, pub);
|
|
535
|
+
await r.pushVersion({ projectId: 2n, arweaveHash: "ar://x", versionTag: "v2", changelog: "" }, 1000000000000000n);
|
|
536
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ value: 1000000000000000n }));
|
|
537
|
+
});
|
|
538
|
+
(0, vitest_1.it)("uses empty string as default changelog", async () => {
|
|
539
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
540
|
+
const pub = makeMockPublicClient();
|
|
541
|
+
pub.readContract
|
|
542
|
+
.mockResolvedValueOnce(500000000000000n)
|
|
543
|
+
.mockResolvedValueOnce(1n);
|
|
544
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
545
|
+
const wlt = makeMockWalletClient();
|
|
546
|
+
r.connect(wlt, pub);
|
|
547
|
+
await r.pushVersion({ projectId: 1n, arweaveHash: "ar://x", versionTag: "v0.1" });
|
|
548
|
+
const args = wlt.writeContract.mock.calls[0][0].args;
|
|
549
|
+
(0, vitest_1.expect)(args[3]).toBe(""); // changelog defaults to ""
|
|
550
|
+
});
|
|
551
|
+
});
|
|
552
|
+
// ─── addCollaborator() ────────────────────────────────────────────────────────
|
|
553
|
+
(0, vitest_1.describe)("ProjectRegistry — addCollaborator()", () => {
|
|
554
|
+
(0, vitest_1.it)("calls writeContract with correct args and returns hash", async () => {
|
|
555
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
556
|
+
const pub = makeMockPublicClient();
|
|
557
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
558
|
+
const wlt = makeMockWalletClient();
|
|
559
|
+
r.connect(wlt, pub);
|
|
560
|
+
const hash = await r.addCollaborator(1n, COLLAB_ADDR);
|
|
561
|
+
(0, vitest_1.expect)(hash).toBe(TX_HASH);
|
|
562
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
|
|
563
|
+
functionName: "addCollaborator",
|
|
564
|
+
args: [1n, COLLAB_ADDR],
|
|
565
|
+
}));
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
// ─── removeCollaborator() ─────────────────────────────────────────────────────
|
|
569
|
+
(0, vitest_1.describe)("ProjectRegistry — removeCollaborator()", () => {
|
|
570
|
+
(0, vitest_1.it)("calls writeContract with correct args and returns hash", async () => {
|
|
571
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
572
|
+
const pub = makeMockPublicClient();
|
|
573
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
574
|
+
const wlt = makeMockWalletClient();
|
|
575
|
+
r.connect(wlt, pub);
|
|
576
|
+
const hash = await r.removeCollaborator(1n, COLLAB_ADDR);
|
|
577
|
+
(0, vitest_1.expect)(hash).toBe(TX_HASH);
|
|
578
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
|
|
579
|
+
functionName: "removeCollaborator",
|
|
580
|
+
args: [1n, COLLAB_ADDR],
|
|
581
|
+
}));
|
|
582
|
+
});
|
|
583
|
+
});
|
|
584
|
+
// ─── transferProject() ────────────────────────────────────────────────────────
|
|
585
|
+
(0, vitest_1.describe)("ProjectRegistry — transferProject()", () => {
|
|
586
|
+
(0, vitest_1.it)("reads transferFee and calls writeContract with correct value", async () => {
|
|
587
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
588
|
+
const pub = makeMockPublicClient();
|
|
589
|
+
pub.readContract.mockResolvedValue(1000000000000000n); // 0.001 ETH
|
|
590
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
591
|
+
const wlt = makeMockWalletClient();
|
|
592
|
+
r.connect(wlt, pub);
|
|
593
|
+
const hash = await r.transferProject(1n, COLLAB_ADDR);
|
|
594
|
+
(0, vitest_1.expect)(hash).toBe(TX_HASH);
|
|
595
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
|
|
596
|
+
functionName: "transferProject",
|
|
597
|
+
args: [1n, COLLAB_ADDR],
|
|
598
|
+
value: 1000000000000000n,
|
|
599
|
+
}));
|
|
600
|
+
});
|
|
601
|
+
(0, vitest_1.it)("accepts explicit value override", async () => {
|
|
602
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
603
|
+
const pub = makeMockPublicClient();
|
|
604
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
605
|
+
const wlt = makeMockWalletClient();
|
|
606
|
+
r.connect(wlt, pub);
|
|
607
|
+
await r.transferProject(1n, COLLAB_ADDR, 999n);
|
|
608
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ value: 999n }));
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
// ─── setVisibility() ─────────────────────────────────────────────────────────
|
|
612
|
+
(0, vitest_1.describe)("ProjectRegistry — setVisibility()", () => {
|
|
613
|
+
(0, vitest_1.it)("calls writeContract with isPublic=false", async () => {
|
|
614
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
615
|
+
const pub = makeMockPublicClient();
|
|
616
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
617
|
+
const wlt = makeMockWalletClient();
|
|
618
|
+
r.connect(wlt, pub);
|
|
619
|
+
const hash = await r.setVisibility(1n, false);
|
|
620
|
+
(0, vitest_1.expect)(hash).toBe(TX_HASH);
|
|
621
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ functionName: "setVisibility", args: [1n, false] }));
|
|
622
|
+
});
|
|
623
|
+
(0, vitest_1.it)("calls writeContract with isPublic=true", async () => {
|
|
624
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
625
|
+
const pub = makeMockPublicClient();
|
|
626
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
627
|
+
const wlt = makeMockWalletClient();
|
|
628
|
+
r.connect(wlt, pub);
|
|
629
|
+
await r.setVisibility(2n, true);
|
|
630
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ args: [2n, true] }));
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
// ─── setReadme() ──────────────────────────────────────────────────────────────
|
|
634
|
+
(0, vitest_1.describe)("ProjectRegistry — setReadme()", () => {
|
|
635
|
+
(0, vitest_1.it)("calls writeContract with correct args", async () => {
|
|
636
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
637
|
+
const pub = makeMockPublicClient();
|
|
638
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
639
|
+
const wlt = makeMockWalletClient();
|
|
640
|
+
r.connect(wlt, pub);
|
|
641
|
+
const hash = await r.setReadme(1n, "ar://new-readme");
|
|
642
|
+
(0, vitest_1.expect)(hash).toBe(TX_HASH);
|
|
643
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({ functionName: "setReadme", args: [1n, "ar://new-readme"] }));
|
|
644
|
+
});
|
|
645
|
+
});
|
|
646
|
+
// ─── setAgentEndpoint() ───────────────────────────────────────────────────────
|
|
647
|
+
(0, vitest_1.describe)("ProjectRegistry — setAgentEndpoint()", () => {
|
|
648
|
+
(0, vitest_1.it)("calls writeContract with correct args", async () => {
|
|
649
|
+
const r = new ProjectRegistry_js_1.ProjectRegistry(BASE_CONFIG);
|
|
650
|
+
const pub = makeMockPublicClient();
|
|
651
|
+
pub.waitForTransactionReceipt.mockResolvedValue({ logs: [] });
|
|
652
|
+
const wlt = makeMockWalletClient();
|
|
653
|
+
r.connect(wlt, pub);
|
|
654
|
+
const hash = await r.setAgentEndpoint(1n, "https://agent.new.xyz");
|
|
655
|
+
(0, vitest_1.expect)(hash).toBe(TX_HASH);
|
|
656
|
+
(0, vitest_1.expect)(wlt.writeContract).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
|
|
657
|
+
functionName: "setAgentEndpoint",
|
|
658
|
+
args: [1n, "https://agent.new.xyz"],
|
|
659
|
+
}));
|
|
660
|
+
});
|
|
661
|
+
});
|
|
662
|
+
// ─── ABI exports ──────────────────────────────────────────────────────────────
|
|
663
|
+
(0, vitest_1.describe)("INKD_REGISTRY_ABI / INKD_ERC20_ABI exports", () => {
|
|
664
|
+
(0, vitest_1.it)("INKD_REGISTRY_ABI is a non-empty array", () => {
|
|
665
|
+
(0, vitest_1.expect)(Array.isArray(ProjectRegistry_js_1.INKD_REGISTRY_ABI)).toBe(true);
|
|
666
|
+
(0, vitest_1.expect)(ProjectRegistry_js_1.INKD_REGISTRY_ABI.length).toBeGreaterThan(0);
|
|
667
|
+
});
|
|
668
|
+
(0, vitest_1.it)("INKD_ERC20_ABI is a non-empty array", () => {
|
|
669
|
+
(0, vitest_1.expect)(Array.isArray(ProjectRegistry_js_1.INKD_ERC20_ABI)).toBe(true);
|
|
670
|
+
(0, vitest_1.expect)(ProjectRegistry_js_1.INKD_ERC20_ABI.length).toBeGreaterThan(0);
|
|
671
|
+
});
|
|
672
|
+
(0, vitest_1.it)("INKD_REGISTRY_ABI includes createProject function", () => {
|
|
673
|
+
const fns = ProjectRegistry_js_1.INKD_REGISTRY_ABI.filter((e) => e.type === "function").map((e) => e.name);
|
|
674
|
+
(0, vitest_1.expect)(fns).toContain("createProject");
|
|
675
|
+
});
|
|
676
|
+
(0, vitest_1.it)("INKD_REGISTRY_ABI includes pushVersion function", () => {
|
|
677
|
+
const fns = ProjectRegistry_js_1.INKD_REGISTRY_ABI.filter((e) => e.type === "function").map((e) => e.name);
|
|
678
|
+
(0, vitest_1.expect)(fns).toContain("pushVersion");
|
|
679
|
+
});
|
|
680
|
+
(0, vitest_1.it)("INKD_ERC20_ABI includes approve function", () => {
|
|
681
|
+
const fns = ProjectRegistry_js_1.INKD_ERC20_ABI.filter((e) => e.type === "function").map((e) => e.name);
|
|
682
|
+
(0, vitest_1.expect)(fns).toContain("approve");
|
|
683
|
+
});
|
|
684
|
+
(0, vitest_1.it)("INKD_ERC20_ABI includes balanceOf function", () => {
|
|
685
|
+
const fns = ProjectRegistry_js_1.INKD_ERC20_ABI.filter((e) => e.type === "function").map((e) => e.name);
|
|
686
|
+
(0, vitest_1.expect)(fns).toContain("balanceOf");
|
|
687
|
+
});
|
|
688
|
+
});
|
|
689
|
+
//# sourceMappingURL=ProjectRegistry.test.js.map
|