@iqlabs-official/git-sdk 0.1.12 → 0.1.15
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/index.d.ts +2 -1
- package/dist/browser/index.js +3 -459
- package/dist/browser/index.js.map +1 -1
- package/dist/chunk-EZNMA5NJ.js +635 -0
- package/dist/chunk-EZNMA5NJ.js.map +1 -0
- package/dist/chunk-WHYUXIRW.js +120 -0
- package/dist/chunk-WHYUXIRW.js.map +1 -0
- package/dist/eth-BQ57E7OY.js +88 -0
- package/dist/eth-BQ57E7OY.js.map +1 -0
- package/dist/node/index.d.ts +2 -1
- package/dist/node/index.js +3 -458
- package/dist/node/index.js.map +1 -1
- package/dist/shared/index.d.ts +150 -32
- package/dist/shared/index.js +2 -447
- package/dist/shared/index.js.map +1 -1
- package/package.json +16 -4
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
import { IQGIT_ROOT_ID, commitTableHint, notifyGateways, repoListHint, pagesDeployId, IQPAGES_CONFIG_FILENAME, IQPAGES_DEPLOYED_HINT, setSolanaGatewayNetwork, REGISTRY_HINT, IQPAGES_ROOT_ID, readCodeInViaGateway, readRowsViaGateway, IQPAGES_PROFILE_FILENAME, PAGES_FEE_WEI, PAGES_FEE_RECIPIENT_EVM, PAGES_FEE_LAMPORTS, PAGES_FEE_RECIPIENT, setEthGatewayNetwork } from './chunk-WHYUXIRW.js';
|
|
2
|
+
import { setRpcUrl } from '@iqlabs-official/solana-sdk';
|
|
3
|
+
import { Transaction, SystemProgram, PublicKey, Keypair } from '@solana/web3.js';
|
|
4
|
+
import { getDbRootPda, createInstructionBuilder, initializeDbRootInstruction, getTablePda } from '@iqlabs-official/solana-sdk/contract';
|
|
5
|
+
import { readCodeIn as readCodeIn$1, readTableRows } from '@iqlabs-official/solana-sdk/reader';
|
|
6
|
+
import { toSeedBytes } from '@iqlabs-official/solana-sdk/utils';
|
|
7
|
+
export { DEFAULT_SESSION_SPEED, SESSION_SPEED_PROFILES, resolveSessionSpeed } from '@iqlabs-official/solana-sdk/utils';
|
|
8
|
+
import { writeRow as writeRow$1, createTable as createTable$1, codeIn as codeIn$1 } from '@iqlabs-official/solana-sdk/writer';
|
|
9
|
+
|
|
10
|
+
// src/core/hash.ts
|
|
11
|
+
var impl;
|
|
12
|
+
function setSha256(fn) {
|
|
13
|
+
if (impl) {
|
|
14
|
+
throw new Error(
|
|
15
|
+
"@iqlabs-official/git-sdk: sha256 implementation already installed. Import exactly one of '@iqlabs-official/git-sdk/node' or '@iqlabs-official/git-sdk/browser'."
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
impl = fn;
|
|
19
|
+
}
|
|
20
|
+
async function sha256Hex(input) {
|
|
21
|
+
if (!impl) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"@iqlabs-official/git-sdk: sha256 not installed. Import '@iqlabs-official/git-sdk/node' (Node) or '@iqlabs-official/git-sdk/browser' (browser) before using the SDK."
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return impl(input);
|
|
27
|
+
}
|
|
28
|
+
var DB_ROOT_SEED = toSeedBytes(IQGIT_ROOT_ID);
|
|
29
|
+
var DB_ROOT = getDbRootPda(DB_ROOT_SEED);
|
|
30
|
+
var connection = null;
|
|
31
|
+
function conn() {
|
|
32
|
+
if (!connection) {
|
|
33
|
+
throw new Error("solana adapter not initialized \u2014 call init({ chain: 'solana', connection })");
|
|
34
|
+
}
|
|
35
|
+
return connection;
|
|
36
|
+
}
|
|
37
|
+
function asSolana(signer) {
|
|
38
|
+
return signer;
|
|
39
|
+
}
|
|
40
|
+
async function signTx(signer, tx) {
|
|
41
|
+
if (signer instanceof Keypair || "secretKey" in signer) {
|
|
42
|
+
tx.partialSign(signer);
|
|
43
|
+
return tx;
|
|
44
|
+
}
|
|
45
|
+
return signer.signTransaction(tx);
|
|
46
|
+
}
|
|
47
|
+
function dbRootPda(dbRootId) {
|
|
48
|
+
return dbRootId === IQGIT_ROOT_ID ? DB_ROOT : getDbRootPda(toSeedBytes(dbRootId));
|
|
49
|
+
}
|
|
50
|
+
function tablePda(hint, dbRootId = IQGIT_ROOT_ID) {
|
|
51
|
+
return getTablePda(dbRootPda(dbRootId), toSeedBytes(hint));
|
|
52
|
+
}
|
|
53
|
+
async function accountExists(pda) {
|
|
54
|
+
return await conn().getAccountInfo(pda) !== null;
|
|
55
|
+
}
|
|
56
|
+
async function readRowsByPda(pda, options) {
|
|
57
|
+
const viaGateway = await readRowsViaGateway(pda.toBase58(), options);
|
|
58
|
+
if (viaGateway !== null) return viaGateway;
|
|
59
|
+
return readTableRows(pda, options);
|
|
60
|
+
}
|
|
61
|
+
var solanaAdapter = {
|
|
62
|
+
kind: "solana",
|
|
63
|
+
init(cfg) {
|
|
64
|
+
if (cfg.chain !== "solana") return;
|
|
65
|
+
connection = cfg.connection;
|
|
66
|
+
},
|
|
67
|
+
async codeIn(signer, data, filename, filetype, onProgress, speed = "light") {
|
|
68
|
+
return codeIn$1(
|
|
69
|
+
{ connection: conn(), signer: asSolana(signer) },
|
|
70
|
+
data,
|
|
71
|
+
filename,
|
|
72
|
+
0,
|
|
73
|
+
filetype,
|
|
74
|
+
onProgress,
|
|
75
|
+
speed
|
|
76
|
+
);
|
|
77
|
+
},
|
|
78
|
+
async readCodeIn(txSig) {
|
|
79
|
+
const viaGateway = await readCodeInViaGateway(txSig);
|
|
80
|
+
if (viaGateway !== null) return viaGateway;
|
|
81
|
+
return readCodeIn$1(txSig);
|
|
82
|
+
},
|
|
83
|
+
async readRows(hint, options) {
|
|
84
|
+
return readRowsByPda(tablePda(hint), options);
|
|
85
|
+
},
|
|
86
|
+
async readRowsByRef(ref, options) {
|
|
87
|
+
return readRowsByPda(ref, options);
|
|
88
|
+
},
|
|
89
|
+
async readLatestRow(hint) {
|
|
90
|
+
const rows = await this.readRows(hint, { limit: 1 });
|
|
91
|
+
return rows[0] ?? null;
|
|
92
|
+
},
|
|
93
|
+
async signerAddress(signer) {
|
|
94
|
+
return asSolana(signer).publicKey.toBase58();
|
|
95
|
+
},
|
|
96
|
+
async ensureDbRoot(signer, dbRootId = IQGIT_ROOT_ID) {
|
|
97
|
+
const s = asSolana(signer);
|
|
98
|
+
const rootPda = dbRootPda(dbRootId);
|
|
99
|
+
if (await accountExists(rootPda)) return null;
|
|
100
|
+
const builder = createInstructionBuilder();
|
|
101
|
+
const ix = initializeDbRootInstruction(
|
|
102
|
+
builder,
|
|
103
|
+
{
|
|
104
|
+
db_root: rootPda,
|
|
105
|
+
signer: s.publicKey,
|
|
106
|
+
system_program: SystemProgram.programId
|
|
107
|
+
},
|
|
108
|
+
{ db_root_id: toSeedBytes(dbRootId) }
|
|
109
|
+
);
|
|
110
|
+
const tx = new Transaction().add(ix);
|
|
111
|
+
const c = conn();
|
|
112
|
+
const { blockhash, lastValidBlockHeight } = await c.getLatestBlockhash();
|
|
113
|
+
tx.recentBlockhash = blockhash;
|
|
114
|
+
tx.feePayer = s.publicKey;
|
|
115
|
+
const signed = await signTx(s, tx);
|
|
116
|
+
const signature = await c.sendRawTransaction(signed.serialize());
|
|
117
|
+
await c.confirmTransaction({ signature, blockhash, lastValidBlockHeight });
|
|
118
|
+
return signature;
|
|
119
|
+
},
|
|
120
|
+
async createTable(signer, hint, columns, idColumn, options) {
|
|
121
|
+
const s = asSolana(signer);
|
|
122
|
+
const writers = options?.writers?.map((w) => new PublicKey(w));
|
|
123
|
+
return createTable$1(
|
|
124
|
+
conn(),
|
|
125
|
+
s,
|
|
126
|
+
options?.dbRootId ?? IQGIT_ROOT_ID,
|
|
127
|
+
hint,
|
|
128
|
+
hint,
|
|
129
|
+
columns,
|
|
130
|
+
idColumn,
|
|
131
|
+
[],
|
|
132
|
+
void 0,
|
|
133
|
+
writers,
|
|
134
|
+
hint
|
|
135
|
+
);
|
|
136
|
+
},
|
|
137
|
+
async writeRow(signer, hint, rowJson, dbRootId = IQGIT_ROOT_ID) {
|
|
138
|
+
return writeRow$1(conn(), asSolana(signer), dbRootId, hint, rowJson);
|
|
139
|
+
},
|
|
140
|
+
async transferNative(signer, to, amount) {
|
|
141
|
+
const s = asSolana(signer);
|
|
142
|
+
const c = conn();
|
|
143
|
+
const tx = new Transaction().add(
|
|
144
|
+
SystemProgram.transfer({
|
|
145
|
+
fromPubkey: s.publicKey,
|
|
146
|
+
toPubkey: new PublicKey(to),
|
|
147
|
+
lamports: Number(amount)
|
|
148
|
+
})
|
|
149
|
+
);
|
|
150
|
+
tx.feePayer = s.publicKey;
|
|
151
|
+
const { blockhash, lastValidBlockHeight } = await c.getLatestBlockhash();
|
|
152
|
+
tx.recentBlockhash = blockhash;
|
|
153
|
+
const signed = await signTx(s, tx);
|
|
154
|
+
const signature = await c.sendRawTransaction(signed.serialize());
|
|
155
|
+
await c.confirmTransaction(
|
|
156
|
+
{ signature, blockhash, lastValidBlockHeight },
|
|
157
|
+
"confirmed"
|
|
158
|
+
);
|
|
159
|
+
return signature;
|
|
160
|
+
},
|
|
161
|
+
async tableExists(hint, dbRootId = IQGIT_ROOT_ID) {
|
|
162
|
+
return accountExists(tablePda(hint, dbRootId));
|
|
163
|
+
},
|
|
164
|
+
tableRef(hint, dbRootId = IQGIT_ROOT_ID) {
|
|
165
|
+
return tablePda(hint, dbRootId);
|
|
166
|
+
},
|
|
167
|
+
tableKey(hint, dbRootId = IQGIT_ROOT_ID) {
|
|
168
|
+
return tablePda(hint, dbRootId).toBase58();
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// src/layers/chain/eth-lazy.ts
|
|
173
|
+
var real = null;
|
|
174
|
+
var pending = null;
|
|
175
|
+
async function load() {
|
|
176
|
+
if (!real) {
|
|
177
|
+
real = (await import('./eth-BQ57E7OY.js')).ethAdapter;
|
|
178
|
+
if (pending) real.init(pending);
|
|
179
|
+
}
|
|
180
|
+
return real;
|
|
181
|
+
}
|
|
182
|
+
var ethAdapter = {
|
|
183
|
+
kind: "eth",
|
|
184
|
+
init(cfg) {
|
|
185
|
+
pending = cfg;
|
|
186
|
+
if (cfg.chain === "eth") setEthGatewayNetwork(cfg.network);
|
|
187
|
+
if (real) real.init(cfg);
|
|
188
|
+
},
|
|
189
|
+
async codeIn(signer, data, filename, filetype, onProgress, speed) {
|
|
190
|
+
return (await load()).codeIn(signer, data, filename, filetype, onProgress, speed);
|
|
191
|
+
},
|
|
192
|
+
async readCodeIn(txId) {
|
|
193
|
+
return (await load()).readCodeIn(txId);
|
|
194
|
+
},
|
|
195
|
+
async readRows(hint, options) {
|
|
196
|
+
return (await load()).readRows(hint, options);
|
|
197
|
+
},
|
|
198
|
+
async readRowsByRef(ref, options) {
|
|
199
|
+
return (await load()).readRowsByRef(ref, options);
|
|
200
|
+
},
|
|
201
|
+
async readLatestRow(hint) {
|
|
202
|
+
return (await load()).readLatestRow(hint);
|
|
203
|
+
},
|
|
204
|
+
async signerAddress(signer) {
|
|
205
|
+
return (await load()).signerAddress(signer);
|
|
206
|
+
},
|
|
207
|
+
async ensureDbRoot(signer, dbRootId) {
|
|
208
|
+
return (await load()).ensureDbRoot(signer, dbRootId);
|
|
209
|
+
},
|
|
210
|
+
async createTable(signer, hint, columns, idColumn, options) {
|
|
211
|
+
return (await load()).createTable(signer, hint, columns, idColumn, options);
|
|
212
|
+
},
|
|
213
|
+
async writeRow(signer, hint, rowJson, dbRootId) {
|
|
214
|
+
return (await load()).writeRow(signer, hint, rowJson, dbRootId);
|
|
215
|
+
},
|
|
216
|
+
async transferNative(signer, to, amount) {
|
|
217
|
+
return (await load()).transferNative(signer, to, amount);
|
|
218
|
+
},
|
|
219
|
+
async tableExists(hint, dbRootId) {
|
|
220
|
+
return (await load()).tableExists(hint, dbRootId);
|
|
221
|
+
},
|
|
222
|
+
// Sync — same coordinates the real adapter returns, no ethereum-sdk needed.
|
|
223
|
+
tableRef(hint, dbRootId = IQGIT_ROOT_ID) {
|
|
224
|
+
return { dbRootId, tableName: hint };
|
|
225
|
+
},
|
|
226
|
+
tableKey(hint) {
|
|
227
|
+
return hint;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// src/layers/chain/index.ts
|
|
232
|
+
var active = solanaAdapter;
|
|
233
|
+
function setChain(kind) {
|
|
234
|
+
active = kind === "eth" ? ethAdapter : solanaAdapter;
|
|
235
|
+
}
|
|
236
|
+
function initChain(cfg) {
|
|
237
|
+
active.init(cfg);
|
|
238
|
+
}
|
|
239
|
+
function activeChain() {
|
|
240
|
+
return active.kind;
|
|
241
|
+
}
|
|
242
|
+
function codeIn(signer, data, filename, filetype, onProgress, speed) {
|
|
243
|
+
return active.codeIn(signer, data, filename, filetype, onProgress, speed);
|
|
244
|
+
}
|
|
245
|
+
function readCodeIn(txId) {
|
|
246
|
+
return active.readCodeIn(txId);
|
|
247
|
+
}
|
|
248
|
+
function readRows(hint, options) {
|
|
249
|
+
return active.readRows(hint, options);
|
|
250
|
+
}
|
|
251
|
+
function readRowsByRef(ref, options) {
|
|
252
|
+
return active.readRowsByRef(ref, options);
|
|
253
|
+
}
|
|
254
|
+
function signerAddress(signer) {
|
|
255
|
+
return active.signerAddress(signer);
|
|
256
|
+
}
|
|
257
|
+
function ensureDbRoot(signer, dbRootId) {
|
|
258
|
+
return active.ensureDbRoot(signer, dbRootId);
|
|
259
|
+
}
|
|
260
|
+
function createTable(signer, hint, columns, idColumn, options) {
|
|
261
|
+
return active.createTable(signer, hint, columns, idColumn, options);
|
|
262
|
+
}
|
|
263
|
+
function writeRow(signer, hint, rowJson, dbRootId) {
|
|
264
|
+
return active.writeRow(signer, hint, rowJson, dbRootId);
|
|
265
|
+
}
|
|
266
|
+
function transferNative(signer, to, amount) {
|
|
267
|
+
return active.transferNative(signer, to, amount);
|
|
268
|
+
}
|
|
269
|
+
function tableExists(hint, dbRootId) {
|
|
270
|
+
return active.tableExists(hint, dbRootId);
|
|
271
|
+
}
|
|
272
|
+
function tableRef(hint, dbRootId) {
|
|
273
|
+
return active.tableRef(hint, dbRootId);
|
|
274
|
+
}
|
|
275
|
+
function tableKey(hint, dbRootId) {
|
|
276
|
+
return active.tableKey(hint, dbRootId);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// src/layers/commit.ts
|
|
280
|
+
var COMMIT_COLUMNS = [
|
|
281
|
+
"id",
|
|
282
|
+
"message",
|
|
283
|
+
"treeTxId",
|
|
284
|
+
"parentCommitId",
|
|
285
|
+
"timestamp",
|
|
286
|
+
"author"
|
|
287
|
+
];
|
|
288
|
+
async function ensureCommitTable(signer, repo) {
|
|
289
|
+
await ensureDbRoot(signer);
|
|
290
|
+
const owner = await signerAddress(signer);
|
|
291
|
+
const hint = commitTableHint(owner, repo);
|
|
292
|
+
if (await tableExists(hint)) return null;
|
|
293
|
+
return createTable(signer, hint, COMMIT_COLUMNS, "id", { writers: [owner] });
|
|
294
|
+
}
|
|
295
|
+
async function writeCommit(signer, repo, commit) {
|
|
296
|
+
const owner = await signerAddress(signer);
|
|
297
|
+
const hint = commitTableHint(owner, repo);
|
|
298
|
+
const sig = await writeRow(signer, hint, JSON.stringify(commit));
|
|
299
|
+
notifyGateways(tableKey(hint), sig, commit, owner);
|
|
300
|
+
return sig;
|
|
301
|
+
}
|
|
302
|
+
function commitTableRef(owner, repo) {
|
|
303
|
+
return tableRef(commitTableHint(owner, repo));
|
|
304
|
+
}
|
|
305
|
+
async function readLatestCommit(ref) {
|
|
306
|
+
const rows = await readRowsByRef(ref, { limit: 1 });
|
|
307
|
+
return rows[0] ?? null;
|
|
308
|
+
}
|
|
309
|
+
async function readCommitHistory(ref, options) {
|
|
310
|
+
const rows = await readRowsByRef(ref, options);
|
|
311
|
+
return rows;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// src/layers/repo.ts
|
|
315
|
+
var REPO_COLUMNS = ["name", "description", "isPublic", "timestamp"];
|
|
316
|
+
var REGISTRY_COLUMNS = ["owner", "repo", "description", "timestamp"];
|
|
317
|
+
async function createRepo(signer, meta) {
|
|
318
|
+
await ensureDbRoot(signer);
|
|
319
|
+
const owner = await signerAddress(signer);
|
|
320
|
+
const listHint = repoListHint(owner);
|
|
321
|
+
const writes = [];
|
|
322
|
+
if (!await tableExists(listHint)) {
|
|
323
|
+
await createTable(signer, listHint, REPO_COLUMNS, "name", { writers: [owner] });
|
|
324
|
+
}
|
|
325
|
+
const sig = await writeRow(signer, listHint, JSON.stringify(meta));
|
|
326
|
+
writes.push({ tableHint: listHint, sig, row: meta });
|
|
327
|
+
notifyGateways(tableKey(listHint), sig, meta, owner);
|
|
328
|
+
if (meta.isPublic) {
|
|
329
|
+
if (!await tableExists(REGISTRY_HINT)) {
|
|
330
|
+
await createTable(signer, REGISTRY_HINT, REGISTRY_COLUMNS, "owner");
|
|
331
|
+
}
|
|
332
|
+
const entry = {
|
|
333
|
+
owner,
|
|
334
|
+
repo: meta.name,
|
|
335
|
+
description: meta.description,
|
|
336
|
+
timestamp: meta.timestamp
|
|
337
|
+
};
|
|
338
|
+
const regSig = await writeRow(signer, REGISTRY_HINT, JSON.stringify(entry));
|
|
339
|
+
writes.push({ tableHint: REGISTRY_HINT, sig: regSig, row: entry });
|
|
340
|
+
notifyGateways(tableKey(REGISTRY_HINT), regSig, entry, owner);
|
|
341
|
+
}
|
|
342
|
+
return writes;
|
|
343
|
+
}
|
|
344
|
+
async function readOwnerRepos(owner) {
|
|
345
|
+
return await readRows(repoListHint(owner));
|
|
346
|
+
}
|
|
347
|
+
async function readRegistryPage(options) {
|
|
348
|
+
return await readRows(REGISTRY_HINT, options);
|
|
349
|
+
}
|
|
350
|
+
async function bootstrapRegistry(signer) {
|
|
351
|
+
await ensureDbRoot(signer);
|
|
352
|
+
if (await tableExists(REGISTRY_HINT)) {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
return createTable(signer, REGISTRY_HINT, REGISTRY_COLUMNS, "owner");
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// src/layers/storage.ts
|
|
359
|
+
async function uploadBlob(signer, relativePath, base64Content, reuse, onProgress, speed) {
|
|
360
|
+
const hash = await sha256Hex(base64Content);
|
|
361
|
+
const prior = reuse[relativePath];
|
|
362
|
+
if (prior && prior.hash === hash) return prior;
|
|
363
|
+
const basename = relativePath.split("/").pop() || relativePath;
|
|
364
|
+
const txId = await codeIn(
|
|
365
|
+
signer,
|
|
366
|
+
base64Content,
|
|
367
|
+
`iqgit-blob:${basename}`,
|
|
368
|
+
"application/octet-stream",
|
|
369
|
+
onProgress,
|
|
370
|
+
speed
|
|
371
|
+
);
|
|
372
|
+
return { txId, hash };
|
|
373
|
+
}
|
|
374
|
+
async function uploadTree(signer, tree, speed) {
|
|
375
|
+
return codeIn(
|
|
376
|
+
signer,
|
|
377
|
+
JSON.stringify(tree),
|
|
378
|
+
"iqgit-tree",
|
|
379
|
+
"application/json",
|
|
380
|
+
void 0,
|
|
381
|
+
speed
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
async function loadTree(treeTxId) {
|
|
385
|
+
const { data } = await readCodeIn(treeTxId);
|
|
386
|
+
if (data === null) {
|
|
387
|
+
throw new Error(`tree.json not found for tx ${treeTxId}`);
|
|
388
|
+
}
|
|
389
|
+
return JSON.parse(data);
|
|
390
|
+
}
|
|
391
|
+
async function loadBlob(txId) {
|
|
392
|
+
const { data } = await readCodeIn(txId);
|
|
393
|
+
if (data === null) {
|
|
394
|
+
throw new Error(`blob not found for tx ${txId}`);
|
|
395
|
+
}
|
|
396
|
+
return data;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// src/layers/client.ts
|
|
400
|
+
var GitClient = class {
|
|
401
|
+
constructor(cfg) {
|
|
402
|
+
this.cfg = cfg;
|
|
403
|
+
this.signer = cfg.signer;
|
|
404
|
+
if (cfg.chain === "eth") {
|
|
405
|
+
setChain("eth");
|
|
406
|
+
initChain({ chain: "eth", network: cfg.network, rpcUrl: cfg.rpcUrl });
|
|
407
|
+
} else {
|
|
408
|
+
setChain("solana");
|
|
409
|
+
initChain({ chain: "solana", connection: cfg.connection });
|
|
410
|
+
setRpcUrl(cfg.connection.rpcEndpoint);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
cfg;
|
|
414
|
+
/** The configured signer, as the chain-neutral union the layers consume. */
|
|
415
|
+
signer;
|
|
416
|
+
/**
|
|
417
|
+
* Create a new repo. Wraps repo.createRepo + pre-creating the commit table
|
|
418
|
+
* so the first `commit()` call doesn't need to pay createTable cost.
|
|
419
|
+
*/
|
|
420
|
+
async createRepo(meta) {
|
|
421
|
+
const writes = await createRepo(this.signer, meta);
|
|
422
|
+
await ensureCommitTable(this.signer, meta.name);
|
|
423
|
+
this.fireOnWrite(writes);
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Incremental commit against a scanned directory snapshot.
|
|
427
|
+
*
|
|
428
|
+
* input: repoName, message, scan — a `{ [path]: base64Content }` map that
|
|
429
|
+
* the caller produced (Node: fs walk + base64; browser: File input).
|
|
430
|
+
* output: newly written Commit
|
|
431
|
+
*/
|
|
432
|
+
async commit(repoName, message, scan, options) {
|
|
433
|
+
const owner = await signerAddress(this.signer);
|
|
434
|
+
const speed = options?.speed ?? this.cfg.speed;
|
|
435
|
+
const latest = await readLatestCommit(commitTableRef(owner, repoName));
|
|
436
|
+
const oldTree = latest ? await loadTree(latest.treeTxId) : {};
|
|
437
|
+
const newTree = {};
|
|
438
|
+
for (const [path, content] of Object.entries(scan)) {
|
|
439
|
+
newTree[path] = await uploadBlob(
|
|
440
|
+
this.signer,
|
|
441
|
+
path,
|
|
442
|
+
content,
|
|
443
|
+
oldTree,
|
|
444
|
+
void 0,
|
|
445
|
+
speed
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
const treeTxId = await uploadTree(this.signer, newTree, speed);
|
|
449
|
+
const commit = {
|
|
450
|
+
id: crypto.randomUUID(),
|
|
451
|
+
message,
|
|
452
|
+
treeTxId,
|
|
453
|
+
parentCommitId: latest?.id,
|
|
454
|
+
timestamp: Date.now(),
|
|
455
|
+
author: owner
|
|
456
|
+
};
|
|
457
|
+
const sig = await writeCommit(this.signer, repoName, commit);
|
|
458
|
+
this.fireOnWrite([{ tableHint: commitTableHint(owner, repoName), sig, row: commit }]);
|
|
459
|
+
return commit;
|
|
460
|
+
}
|
|
461
|
+
/** Resolve the table hint to a PDA and forward each write to `onWrite`.
|
|
462
|
+
* Wrapped in try/catch per call so a misbehaving notify can't fail the
|
|
463
|
+
* whole batch — but we still surface the error so the consumer knows. */
|
|
464
|
+
fireOnWrite(writes) {
|
|
465
|
+
if (!this.cfg.onWrite) return;
|
|
466
|
+
for (const w of writes) {
|
|
467
|
+
const tablePda2 = tableKey(w.tableHint);
|
|
468
|
+
this.cfg.onWrite({ tablePda: tablePda2, tableHint: w.tableHint, sig: w.sig, row: w.row });
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Restore a commit's files into a caller-provided sink. Runtime-neutral
|
|
473
|
+
* shape mirrors `commit`: the caller decides how to write bytes to disk /
|
|
474
|
+
* to a File System Access API handle / anywhere else. `content` is the
|
|
475
|
+
* raw base64 string — the sink decodes.
|
|
476
|
+
*/
|
|
477
|
+
async checkout(repoName, commitId, sink) {
|
|
478
|
+
const owner = await signerAddress(this.signer);
|
|
479
|
+
const ref = commitTableRef(owner, repoName);
|
|
480
|
+
let target;
|
|
481
|
+
if (commitId === "latest") {
|
|
482
|
+
target = await readLatestCommit(ref);
|
|
483
|
+
} else {
|
|
484
|
+
const history = await readCommitHistory(ref);
|
|
485
|
+
target = history.find((c) => c.id === commitId) ?? null;
|
|
486
|
+
}
|
|
487
|
+
if (!target) {
|
|
488
|
+
throw new Error(`commit not found: ${commitId} in ${owner}/${repoName}`);
|
|
489
|
+
}
|
|
490
|
+
const tree = await loadTree(target.treeTxId);
|
|
491
|
+
for (const [path, entry] of Object.entries(tree)) {
|
|
492
|
+
const content = await loadBlob(entry.txId);
|
|
493
|
+
await sink(path, content);
|
|
494
|
+
}
|
|
495
|
+
return target;
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Whole-repo snapshot download — convenience on top of checkout("latest")
|
|
499
|
+
* but reading from someone else's `owner`. We do not require signer to
|
|
500
|
+
* equal owner for reads.
|
|
501
|
+
*/
|
|
502
|
+
async clone(repoName, owner, sink) {
|
|
503
|
+
const target = await readLatestCommit(commitTableRef(owner, repoName));
|
|
504
|
+
if (!target) {
|
|
505
|
+
throw new Error(`no commits in ${owner}/${repoName}`);
|
|
506
|
+
}
|
|
507
|
+
const tree = await loadTree(target.treeTxId);
|
|
508
|
+
for (const [path, entry] of Object.entries(tree)) {
|
|
509
|
+
const content = await loadBlob(entry.txId);
|
|
510
|
+
await sink(path, content);
|
|
511
|
+
}
|
|
512
|
+
return target;
|
|
513
|
+
}
|
|
514
|
+
/** Commit history for a repo. */
|
|
515
|
+
async log(owner, repoName, options) {
|
|
516
|
+
return readCommitHistory(commitTableRef(owner, repoName), options);
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Compare a current directory snapshot to the latest commit's tree.
|
|
520
|
+
*/
|
|
521
|
+
async status(owner, repoName, scan) {
|
|
522
|
+
const latest = await readLatestCommit(commitTableRef(owner, repoName));
|
|
523
|
+
const tree = latest ? await loadTree(latest.treeTxId) : {};
|
|
524
|
+
const added = [];
|
|
525
|
+
const modified = [];
|
|
526
|
+
const unchanged = [];
|
|
527
|
+
for (const [path, content] of Object.entries(scan)) {
|
|
528
|
+
const prior = tree[path];
|
|
529
|
+
if (!prior) {
|
|
530
|
+
added.push(path);
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
const hash = await sha256Hex(content);
|
|
534
|
+
(prior.hash === hash ? unchanged : modified).push(path);
|
|
535
|
+
}
|
|
536
|
+
return { added, modified, unchanged };
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
// src/layers/pages.ts
|
|
541
|
+
var DEPLOYED_COLUMNS = ["id", "owner", "repo", "deployedAt"];
|
|
542
|
+
function pagesTableRef() {
|
|
543
|
+
return tableRef(IQPAGES_DEPLOYED_HINT, IQPAGES_ROOT_ID);
|
|
544
|
+
}
|
|
545
|
+
function pagesTableKey() {
|
|
546
|
+
return tableKey(IQPAGES_DEPLOYED_HINT, IQPAGES_ROOT_ID);
|
|
547
|
+
}
|
|
548
|
+
async function listPagesDeployments() {
|
|
549
|
+
const rows = await readRowsByRef(pagesTableRef());
|
|
550
|
+
return rows;
|
|
551
|
+
}
|
|
552
|
+
async function isPagesDeployed(owner, repo) {
|
|
553
|
+
const id = pagesDeployId(owner, repo);
|
|
554
|
+
const all = await listPagesDeployments();
|
|
555
|
+
return all.some((r) => r.id === id);
|
|
556
|
+
}
|
|
557
|
+
async function readJsonFromLatest(owner, repo, filename) {
|
|
558
|
+
const latest = await readLatestCommit(commitTableRef(owner, repo));
|
|
559
|
+
if (!latest) return null;
|
|
560
|
+
const tree = await loadTree(latest.treeTxId);
|
|
561
|
+
const entry = tree[filename];
|
|
562
|
+
if (!entry?.txId) return null;
|
|
563
|
+
const base64 = await loadBlob(entry.txId);
|
|
564
|
+
return JSON.parse(Buffer.from(base64, "base64").toString("utf8"));
|
|
565
|
+
}
|
|
566
|
+
async function readPagesConfig(owner, repo) {
|
|
567
|
+
return readJsonFromLatest(owner, repo, IQPAGES_CONFIG_FILENAME);
|
|
568
|
+
}
|
|
569
|
+
async function readPagesProfile(owner, repo) {
|
|
570
|
+
return readJsonFromLatest(owner, repo, IQPAGES_PROFILE_FILENAME);
|
|
571
|
+
}
|
|
572
|
+
async function ensureGallery(signer) {
|
|
573
|
+
await ensureDbRoot(signer, IQPAGES_ROOT_ID);
|
|
574
|
+
if (await tableExists(IQPAGES_DEPLOYED_HINT, IQPAGES_ROOT_ID)) return;
|
|
575
|
+
await createTable(signer, IQPAGES_DEPLOYED_HINT, DEPLOYED_COLUMNS, "id", {
|
|
576
|
+
dbRootId: IQPAGES_ROOT_ID
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
async function chargeFee(signer) {
|
|
580
|
+
if (activeChain() === "eth") {
|
|
581
|
+
await transferNative(signer, PAGES_FEE_RECIPIENT_EVM, PAGES_FEE_WEI);
|
|
582
|
+
} else {
|
|
583
|
+
await transferNative(signer, PAGES_FEE_RECIPIENT, PAGES_FEE_LAMPORTS);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
async function deployPages(signer, repo) {
|
|
587
|
+
const owner = await signerAddress(signer);
|
|
588
|
+
if (await isPagesDeployed(owner, repo)) {
|
|
589
|
+
throw new Error(`already deployed: ${owner}/${repo}`);
|
|
590
|
+
}
|
|
591
|
+
const config = await readPagesConfig(owner, repo);
|
|
592
|
+
if (!config) {
|
|
593
|
+
throw new Error(
|
|
594
|
+
`${IQPAGES_CONFIG_FILENAME} missing in ${repo}. Commit it first, then deploy.`
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
await ensureGallery(signer);
|
|
598
|
+
const row = {
|
|
599
|
+
id: pagesDeployId(owner, repo),
|
|
600
|
+
owner,
|
|
601
|
+
repo,
|
|
602
|
+
deployedAt: Date.now()
|
|
603
|
+
};
|
|
604
|
+
const sig = await writeRow(
|
|
605
|
+
signer,
|
|
606
|
+
IQPAGES_DEPLOYED_HINT,
|
|
607
|
+
JSON.stringify(row),
|
|
608
|
+
IQPAGES_ROOT_ID
|
|
609
|
+
);
|
|
610
|
+
notifyGateways(pagesTableKey(), sig, row, owner);
|
|
611
|
+
await chargeFee(signer);
|
|
612
|
+
return { sig, config };
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// src/layers/network.ts
|
|
616
|
+
var EVM_TOKENS = {
|
|
617
|
+
eth: "sepolia",
|
|
618
|
+
sepolia: "sepolia",
|
|
619
|
+
monad: "monad",
|
|
620
|
+
monadTestnet: "monadTestnet"
|
|
621
|
+
};
|
|
622
|
+
function setNetwork(token, options) {
|
|
623
|
+
const evm = EVM_TOKENS[token];
|
|
624
|
+
if (evm) {
|
|
625
|
+
setChain("eth");
|
|
626
|
+
initChain({ chain: "eth", network: evm, rpcUrl: options?.rpcUrl });
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
setChain("solana");
|
|
630
|
+
setSolanaGatewayNetwork(token);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
export { GitClient, bootstrapRegistry, commitTableRef, deployPages, isPagesDeployed, listPagesDeployments, loadBlob, loadTree, pagesTableRef, readCommitHistory, readLatestCommit, readOwnerRepos, readPagesConfig, readPagesProfile, readRegistryPage, setNetwork, setSha256, uploadBlob, uploadTree, writeCommit };
|
|
634
|
+
//# sourceMappingURL=chunk-EZNMA5NJ.js.map
|
|
635
|
+
//# sourceMappingURL=chunk-EZNMA5NJ.js.map
|