@fractalshq/sync 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/api-CQqyHbnT.d.mts +136 -0
- package/dist/api-CQqyHbnT.d.ts +136 -0
- package/dist/chunk-I4E63NIC.mjs +24 -0
- package/dist/chunk-N3276DIZ.mjs +480 -0
- package/dist/chunk-TCJM2GIK.mjs +25 -0
- package/dist/core/index.d.mts +11 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.js +56 -0
- package/dist/core/index.mjs +17 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +551 -0
- package/dist/index.mjs +29 -0
- package/dist/react/index.d.mts +40 -0
- package/dist/react/index.d.ts +40 -0
- package/dist/react/index.js +227 -0
- package/dist/react/index.mjs +182 -0
- package/dist/server/index.d.mts +67 -0
- package/dist/server/index.d.ts +67 -0
- package/dist/server/index.js +522 -0
- package/dist/server/index.mjs +15 -0
- package/dist/widgets/index.d.mts +2 -0
- package/dist/widgets/index.d.ts +2 -0
- package/dist/widgets/index.js +18 -0
- package/dist/widgets/index.mjs +0 -0
- package/package.json +92 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
|
+
var __export = (target, all) => {
|
|
24
|
+
for (var name in all)
|
|
25
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
26
|
+
};
|
|
27
|
+
var __copyProps = (to, from, except, desc) => {
|
|
28
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
29
|
+
for (let key of __getOwnPropNames(from))
|
|
30
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
31
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
32
|
+
}
|
|
33
|
+
return to;
|
|
34
|
+
};
|
|
35
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
|
+
|
|
37
|
+
// src/index.ts
|
|
38
|
+
var index_exports = {};
|
|
39
|
+
__export(index_exports, {
|
|
40
|
+
DEFAULT_RPC_ENDPOINT: () => DEFAULT_RPC_ENDPOINT,
|
|
41
|
+
DISTRIBUTION_MEMO_PREFIX: () => DISTRIBUTION_MEMO_PREFIX,
|
|
42
|
+
GET: () => GET,
|
|
43
|
+
MEMO_PROGRAM_ID: () => MEMO_PROGRAM_ID,
|
|
44
|
+
POST: () => POST,
|
|
45
|
+
SyncServerClient: () => SyncServerClient,
|
|
46
|
+
XNET_2022_MINT: () => XNET_2022_MINT,
|
|
47
|
+
assertTruthy: () => assertTruthy,
|
|
48
|
+
buildDistributionMemoTag: () => buildDistributionMemoTag,
|
|
49
|
+
createMethodHandler: () => createMethodHandler,
|
|
50
|
+
syncRouteHandler: () => syncRouteHandler
|
|
51
|
+
});
|
|
52
|
+
module.exports = __toCommonJS(index_exports);
|
|
53
|
+
|
|
54
|
+
// src/server/client.ts
|
|
55
|
+
var SyncServerClient = class _SyncServerClient {
|
|
56
|
+
constructor(options) {
|
|
57
|
+
this.options = options;
|
|
58
|
+
}
|
|
59
|
+
static fromRequest(req, baseURL = process.env.SYNC_BASE_URL || "") {
|
|
60
|
+
const copyHeaders = () => {
|
|
61
|
+
const headers = {};
|
|
62
|
+
const cookie = req.headers.get("cookie");
|
|
63
|
+
if (cookie) headers["cookie"] = cookie;
|
|
64
|
+
const auth = req.headers.get("authorization");
|
|
65
|
+
if (auth) headers["authorization"] = auth;
|
|
66
|
+
const ua = req.headers.get("user-agent");
|
|
67
|
+
if (ua) headers["user-agent"] = ua;
|
|
68
|
+
const xff = req.headers.get("x-forwarded-for");
|
|
69
|
+
if (xff) headers["x-forwarded-for"] = xff;
|
|
70
|
+
return headers;
|
|
71
|
+
};
|
|
72
|
+
return new _SyncServerClient({ baseURL, getHeaders: copyHeaders });
|
|
73
|
+
}
|
|
74
|
+
static fromApiKey(apiKey, baseURL = process.env.SYNC_BASE_URL || "") {
|
|
75
|
+
return new _SyncServerClient({
|
|
76
|
+
baseURL,
|
|
77
|
+
getHeaders: () => apiKey ? { "x-internal-api-key": apiKey } : {}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
async request(path, init) {
|
|
81
|
+
const headersInit = typeof this.options.getHeaders === "function" ? await this.options.getHeaders() : {};
|
|
82
|
+
const headers = new Headers(__spreadValues(__spreadValues({ "content-type": "application/json" }, headersInit), (init == null ? void 0 : init.headers) || {}));
|
|
83
|
+
const res = await fetch(`${this.options.baseURL}${path}`, __spreadProps(__spreadValues({}, init), { headers, credentials: "include" }));
|
|
84
|
+
if (!res.ok) {
|
|
85
|
+
const text = await res.text().catch(() => "");
|
|
86
|
+
throw new Error(text || `Request failed: ${res.status}`);
|
|
87
|
+
}
|
|
88
|
+
if (res.status === 204) return void 0;
|
|
89
|
+
return await res.json();
|
|
90
|
+
}
|
|
91
|
+
buildQueryString(query) {
|
|
92
|
+
if (!query) return "";
|
|
93
|
+
if (typeof query === "string") return query.startsWith("?") ? query.slice(1) : query;
|
|
94
|
+
if (query instanceof URLSearchParams) return query.toString();
|
|
95
|
+
const params = new URLSearchParams();
|
|
96
|
+
for (const [key, value] of Object.entries(query)) {
|
|
97
|
+
if (value === void 0 || value === null) continue;
|
|
98
|
+
params.set(key, String(value));
|
|
99
|
+
}
|
|
100
|
+
return params.toString();
|
|
101
|
+
}
|
|
102
|
+
withQuery(path, query) {
|
|
103
|
+
const qs = this.buildQueryString(query);
|
|
104
|
+
if (!qs) return path;
|
|
105
|
+
return `${path}?${qs}`;
|
|
106
|
+
}
|
|
107
|
+
listDistributions(params) {
|
|
108
|
+
const search = new URLSearchParams();
|
|
109
|
+
if (params == null ? void 0 : params.orgId) search.set("orgId", params.orgId);
|
|
110
|
+
if (params == null ? void 0 : params.status) search.set("status", params.status);
|
|
111
|
+
if (params == null ? void 0 : params.mint) search.set("mint", params.mint);
|
|
112
|
+
if (params == null ? void 0 : params.limit) search.set("limit", String(params.limit));
|
|
113
|
+
if (params == null ? void 0 : params.cursor) search.set("cursor", params.cursor);
|
|
114
|
+
const qs = search.toString();
|
|
115
|
+
return this.request(`/api/v1/distributions${qs ? `?${qs}` : ""}`);
|
|
116
|
+
}
|
|
117
|
+
createDistribution(body) {
|
|
118
|
+
return this.request(`/api/v1/distributions/create-transaction`, {
|
|
119
|
+
method: "POST",
|
|
120
|
+
body: JSON.stringify(body)
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
createDistributionWithId(distributionId, body) {
|
|
124
|
+
return this.request(
|
|
125
|
+
`/api/v1/distributions/${encodeURIComponent(distributionId)}/create-transaction`,
|
|
126
|
+
{
|
|
127
|
+
method: "POST",
|
|
128
|
+
body: JSON.stringify(body)
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
commitDistribution(distributionId, body) {
|
|
133
|
+
return this.request(`/api/v1/distributions/${encodeURIComponent(distributionId)}/commit`, {
|
|
134
|
+
method: "POST",
|
|
135
|
+
body: JSON.stringify(body)
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
buildClaimTransaction(body) {
|
|
139
|
+
return this.request(`/api/v1/claims/${encodeURIComponent(body.distributionId)}/create-transaction`, {
|
|
140
|
+
method: "POST",
|
|
141
|
+
body: JSON.stringify(body)
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
commitClaim(body) {
|
|
145
|
+
return this.request(`/api/v1/claims/${encodeURIComponent(body.distributionId)}/commit`, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
body: JSON.stringify(body)
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
getClaimable() {
|
|
151
|
+
return this.request(`/api/test-xnet-claims`);
|
|
152
|
+
}
|
|
153
|
+
getClaimsMe(query) {
|
|
154
|
+
return this.request(this.withQuery(`/api/v1/claims/me`, query));
|
|
155
|
+
}
|
|
156
|
+
getDistributionsMe(query) {
|
|
157
|
+
return this.request(this.withQuery(`/api/v1/distributions/me`, query));
|
|
158
|
+
}
|
|
159
|
+
getDistributionMeById(distributionId) {
|
|
160
|
+
return this.request(`/api/v1/distributions/me/${encodeURIComponent(distributionId)}`);
|
|
161
|
+
}
|
|
162
|
+
getClaimHistory() {
|
|
163
|
+
return this.request(`/api/v1/claims/history`);
|
|
164
|
+
}
|
|
165
|
+
health() {
|
|
166
|
+
return this.request(`/api/v1/health`);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// src/server/handler/errors.ts
|
|
171
|
+
var SyncHandlerError = class extends Error {
|
|
172
|
+
constructor(status, code, message, details) {
|
|
173
|
+
super(message || code);
|
|
174
|
+
this.status = status;
|
|
175
|
+
this.code = code;
|
|
176
|
+
this.details = details;
|
|
177
|
+
this.name = "SyncHandlerError";
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// src/server/handler/roles.ts
|
|
182
|
+
var ORG_DEPLOYER_ROLES = /* @__PURE__ */ new Set(["owner", "admin", "deployer"]);
|
|
183
|
+
var PLATFORM_DEPLOYER_ROLES = /* @__PURE__ */ new Set(["admin", "deployer"]);
|
|
184
|
+
function normalizeRole(role) {
|
|
185
|
+
if (!role) return "";
|
|
186
|
+
return String(role).trim().toLowerCase();
|
|
187
|
+
}
|
|
188
|
+
function resolveWalletFromMe(me) {
|
|
189
|
+
var _a, _b, _c, _d, _e;
|
|
190
|
+
if (!me || typeof me !== "object") return null;
|
|
191
|
+
const candidate = (me == null ? void 0 : me.wallet) || ((_a = me == null ? void 0 : me.user) == null ? void 0 : _a.wallet) || ((_b = me == null ? void 0 : me.user) == null ? void 0 : _b.pubkey) || ((_c = me == null ? void 0 : me.user) == null ? void 0 : _c.name) || ((_d = me == null ? void 0 : me.user) == null ? void 0 : _d.id) || null;
|
|
192
|
+
if (candidate && typeof candidate === "string" && candidate.length > 0) return candidate;
|
|
193
|
+
const accounts = Array.isArray(me == null ? void 0 : me.accounts) ? me.accounts : [];
|
|
194
|
+
const walletAccount = accounts.find((acct) => typeof (acct == null ? void 0 : acct.pubkey) === "string" && acct.pubkey.length > 0);
|
|
195
|
+
return (_e = walletAccount == null ? void 0 : walletAccount.pubkey) != null ? _e : null;
|
|
196
|
+
}
|
|
197
|
+
function requireLoggedIn(req) {
|
|
198
|
+
const auth = req.apiAuth;
|
|
199
|
+
if (auth && auth.ok) return auth;
|
|
200
|
+
throw new SyncHandlerError(401, "unauthorized");
|
|
201
|
+
}
|
|
202
|
+
function requireDeployer(req) {
|
|
203
|
+
const auth = requireLoggedIn(req);
|
|
204
|
+
if (ORG_DEPLOYER_ROLES.has(normalizeRole(auth.orgRole)) || PLATFORM_DEPLOYER_ROLES.has(normalizeRole(auth.platformRole))) {
|
|
205
|
+
return auth;
|
|
206
|
+
}
|
|
207
|
+
throw new SyncHandlerError(403, "forbidden_deployer_role");
|
|
208
|
+
}
|
|
209
|
+
function getSessionWallet(req) {
|
|
210
|
+
var _a, _b;
|
|
211
|
+
const direct = typeof req.wallet === "string" && req.wallet.length > 0 ? req.wallet : null;
|
|
212
|
+
if (direct) return direct;
|
|
213
|
+
const authWallet = typeof ((_a = req.apiAuth) == null ? void 0 : _a.wallet) === "string" && req.apiAuth.wallet.length > 0 ? req.apiAuth.wallet : null;
|
|
214
|
+
if (authWallet) return authWallet;
|
|
215
|
+
return resolveWalletFromMe((_b = req.apiAuth) == null ? void 0 : _b.me);
|
|
216
|
+
}
|
|
217
|
+
function requireSessionWallet(req, expected) {
|
|
218
|
+
const wallet = getSessionWallet(req);
|
|
219
|
+
if (!wallet) {
|
|
220
|
+
throw new SyncHandlerError(401, "unauthorized");
|
|
221
|
+
}
|
|
222
|
+
if (expected && expected.length > 0 && expected !== wallet) {
|
|
223
|
+
throw new SyncHandlerError(403, "forbidden_wallet_mismatch");
|
|
224
|
+
}
|
|
225
|
+
return wallet;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/server/handler/utils.ts
|
|
229
|
+
var BODY_SYMBOL = Symbol.for("fractals.sync.handler.body");
|
|
230
|
+
async function readJsonBody(req) {
|
|
231
|
+
const existing = req[BODY_SYMBOL];
|
|
232
|
+
if (existing !== void 0) return existing;
|
|
233
|
+
try {
|
|
234
|
+
const parsed = await req.json();
|
|
235
|
+
req[BODY_SYMBOL] = parsed;
|
|
236
|
+
return parsed;
|
|
237
|
+
} catch (error) {
|
|
238
|
+
throw new SyncHandlerError(400, "invalid_json", "Request body must be valid JSON");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function coerceString(value) {
|
|
242
|
+
if (typeof value === "string" && value.trim().length > 0) return value;
|
|
243
|
+
return void 0;
|
|
244
|
+
}
|
|
245
|
+
function toOptionalNumber(value) {
|
|
246
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
247
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
248
|
+
const parsed = Number(value);
|
|
249
|
+
if (!Number.isNaN(parsed)) return parsed;
|
|
250
|
+
}
|
|
251
|
+
return void 0;
|
|
252
|
+
}
|
|
253
|
+
function decodePathSegment(value) {
|
|
254
|
+
if (typeof value !== "string") return "";
|
|
255
|
+
try {
|
|
256
|
+
return decodeURIComponent(value);
|
|
257
|
+
} catch (e) {
|
|
258
|
+
return value;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/server/handler/claims.ts
|
|
263
|
+
async function handleClaimsRoute(ctx) {
|
|
264
|
+
if (ctx.segments.length < 2) return null;
|
|
265
|
+
const [rawDistributionId, action] = ctx.segments;
|
|
266
|
+
const distributionId = decodePathSegment(rawDistributionId);
|
|
267
|
+
if (!distributionId) {
|
|
268
|
+
throw new SyncHandlerError(400, "distribution_id_required");
|
|
269
|
+
}
|
|
270
|
+
if (ctx.method !== "POST") return null;
|
|
271
|
+
if (action === "create-transaction") {
|
|
272
|
+
return handleClaimBuild(ctx, distributionId);
|
|
273
|
+
}
|
|
274
|
+
if (action === "commit") {
|
|
275
|
+
return handleClaimCommit(ctx, distributionId);
|
|
276
|
+
}
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
async function handleClaimBuild(ctx, distributionId) {
|
|
280
|
+
const raw = await readJsonBody(ctx.req);
|
|
281
|
+
const body = __spreadValues({}, raw);
|
|
282
|
+
const explicitWallet = coerceString(body.claimant) || coerceString(body.claimantPubkey) || coerceString(body.wallet);
|
|
283
|
+
const claimant = requireSessionWallet(ctx.req, explicitWallet);
|
|
284
|
+
body.distributionId = distributionId;
|
|
285
|
+
body.claimant = claimant;
|
|
286
|
+
const normalizedIndex = toOptionalNumber(raw.index);
|
|
287
|
+
if (typeof normalizedIndex === "number") body.index = normalizedIndex;
|
|
288
|
+
const normalizedUnlocked = toOptionalNumber(raw.unlockedAmount);
|
|
289
|
+
if (typeof normalizedUnlocked === "number") body.unlockedAmount = normalizedUnlocked;
|
|
290
|
+
const normalizedLocked = toOptionalNumber(raw.lockedAmount);
|
|
291
|
+
if (typeof normalizedLocked === "number") body.lockedAmount = normalizedLocked;
|
|
292
|
+
if (!body.distributorPda) {
|
|
293
|
+
const distributorPda = coerceString(raw.distributorPDA);
|
|
294
|
+
if (distributorPda) body.distributorPda = distributorPda;
|
|
295
|
+
}
|
|
296
|
+
const result = await ctx.client.buildClaimTransaction(body);
|
|
297
|
+
return Response.json(result);
|
|
298
|
+
}
|
|
299
|
+
async function handleClaimCommit(ctx, distributionId) {
|
|
300
|
+
var _a, _b, _c;
|
|
301
|
+
const body = await readJsonBody(ctx.req);
|
|
302
|
+
const explicitWallet = coerceString(body.claimantPubkey) || coerceString(body.claimant) || coerceString(body.wallet);
|
|
303
|
+
const claimant = requireSessionWallet(ctx.req, explicitWallet);
|
|
304
|
+
const payload = __spreadValues({}, body);
|
|
305
|
+
payload.distributionId = distributionId;
|
|
306
|
+
payload.claimantPubkey = claimant;
|
|
307
|
+
const signature = (_a = coerceString(payload.signature)) != null ? _a : coerceString(body.signature);
|
|
308
|
+
if (signature) payload.signature = signature;
|
|
309
|
+
const signedTransactionBase64 = coerceString(body.signedTransactionBase64);
|
|
310
|
+
const transaction = (_c = (_b = coerceString(payload.transaction)) != null ? _b : coerceString(body.transaction)) != null ? _c : signedTransactionBase64;
|
|
311
|
+
if (transaction) payload.transaction = transaction;
|
|
312
|
+
if (signedTransactionBase64) payload.signedTransactionBase64 = signedTransactionBase64;
|
|
313
|
+
const hasSignature = typeof payload.signature === "string" && payload.signature.length > 0;
|
|
314
|
+
const hasTxn = typeof payload.transaction === "string" && payload.transaction.length > 0;
|
|
315
|
+
const hasTxnBase64 = typeof payload.signedTransactionBase64 === "string" && payload.signedTransactionBase64.length > 0;
|
|
316
|
+
if (!hasSignature && !hasTxn && !hasTxnBase64) {
|
|
317
|
+
throw new SyncHandlerError(400, "transaction_or_signature_required");
|
|
318
|
+
}
|
|
319
|
+
const result = await ctx.client.commitClaim(payload);
|
|
320
|
+
return Response.json(result);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// src/server/handler/distributions.ts
|
|
324
|
+
async function handleDistributionsRoute(ctx) {
|
|
325
|
+
if (ctx.segments.length === 0) return null;
|
|
326
|
+
const [first, second] = ctx.segments;
|
|
327
|
+
if (ctx.method === "POST" && first === "create-transaction" && !second) {
|
|
328
|
+
requireDeployer(ctx.req);
|
|
329
|
+
const body = await readJsonBody(ctx.req);
|
|
330
|
+
const result = await ctx.client.createDistribution(body);
|
|
331
|
+
return Response.json(result);
|
|
332
|
+
}
|
|
333
|
+
const distributionId = decodePathSegment(first);
|
|
334
|
+
if (!distributionId) {
|
|
335
|
+
throw new SyncHandlerError(400, "distribution_id_required");
|
|
336
|
+
}
|
|
337
|
+
if (ctx.method === "POST" && second === "create-transaction") {
|
|
338
|
+
requireDeployer(ctx.req);
|
|
339
|
+
const body = await readJsonBody(ctx.req);
|
|
340
|
+
const result = await ctx.client.createDistributionWithId(distributionId, body);
|
|
341
|
+
return Response.json(result);
|
|
342
|
+
}
|
|
343
|
+
if (ctx.method === "POST" && second === "commit") {
|
|
344
|
+
requireDeployer(ctx.req);
|
|
345
|
+
const body = await readJsonBody(ctx.req);
|
|
346
|
+
const result = await ctx.client.commitDistribution(distributionId, body);
|
|
347
|
+
return Response.json(result);
|
|
348
|
+
}
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// src/server/handler/me.ts
|
|
353
|
+
async function handleClaimsMeRoute(ctx) {
|
|
354
|
+
var _a, _b;
|
|
355
|
+
if (ctx.method !== "GET") return null;
|
|
356
|
+
if (ctx.segments.length > 0) return null;
|
|
357
|
+
requireLoggedIn(ctx.req);
|
|
358
|
+
const result = await ctx.client.getClaimsMe((_b = (_a = ctx.url) == null ? void 0 : _a.searchParams) != null ? _b : void 0);
|
|
359
|
+
return Response.json(result);
|
|
360
|
+
}
|
|
361
|
+
async function handleDistributionsMeRoute(ctx) {
|
|
362
|
+
var _a, _b;
|
|
363
|
+
if (ctx.method !== "GET") return null;
|
|
364
|
+
requireLoggedIn(ctx.req);
|
|
365
|
+
if (ctx.segments.length === 0) {
|
|
366
|
+
const result = await ctx.client.getDistributionsMe((_b = (_a = ctx.url) == null ? void 0 : _a.searchParams) != null ? _b : void 0);
|
|
367
|
+
return Response.json(result);
|
|
368
|
+
}
|
|
369
|
+
if (ctx.segments.length === 1) {
|
|
370
|
+
const distributionId = decodePathSegment(ctx.segments[0]);
|
|
371
|
+
const result = await ctx.client.getDistributionMeById(distributionId);
|
|
372
|
+
return Response.json(result);
|
|
373
|
+
}
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// src/server/handler.ts
|
|
378
|
+
var ALLOWED_METHODS = /* @__PURE__ */ new Set(["GET", "POST"]);
|
|
379
|
+
var ALLOW_HEADER = "GET, POST";
|
|
380
|
+
async function syncRouteHandler(req, context = {}, options = {}) {
|
|
381
|
+
var _a;
|
|
382
|
+
const method = (req.method || "GET").toUpperCase();
|
|
383
|
+
if (!ALLOWED_METHODS.has(method)) {
|
|
384
|
+
return new Response(JSON.stringify({ error: "method_not_allowed" }), {
|
|
385
|
+
status: 405,
|
|
386
|
+
headers: { "content-type": "application/json", allow: ALLOW_HEADER }
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
const url = resolveUrl(req);
|
|
390
|
+
const segments = await resolveSegments(req, context, url);
|
|
391
|
+
if (segments.length === 0) {
|
|
392
|
+
return notFound();
|
|
393
|
+
}
|
|
394
|
+
const logger = (_a = options.logger) != null ? _a : console;
|
|
395
|
+
let client;
|
|
396
|
+
try {
|
|
397
|
+
client = resolveClient(req, options);
|
|
398
|
+
} catch (error) {
|
|
399
|
+
return handleError(error, req, options, logger);
|
|
400
|
+
}
|
|
401
|
+
const [resource, ...rest] = segments;
|
|
402
|
+
const baseContext = { req, client, method, url, segments: rest };
|
|
403
|
+
try {
|
|
404
|
+
let response = null;
|
|
405
|
+
if (resource === "claims") {
|
|
406
|
+
if (rest[0] === "me") {
|
|
407
|
+
response = await handleClaimsMeRoute(__spreadProps(__spreadValues({}, baseContext), { segments: rest.slice(1) }));
|
|
408
|
+
} else {
|
|
409
|
+
response = await handleClaimsRoute(baseContext);
|
|
410
|
+
}
|
|
411
|
+
} else if (resource === "distributions") {
|
|
412
|
+
if (rest[0] === "me") {
|
|
413
|
+
response = await handleDistributionsMeRoute(__spreadProps(__spreadValues({}, baseContext), { segments: rest.slice(1) }));
|
|
414
|
+
} else {
|
|
415
|
+
response = await handleDistributionsRoute(baseContext);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (response) return response;
|
|
419
|
+
return notFound();
|
|
420
|
+
} catch (error) {
|
|
421
|
+
return handleError(error, req, options, logger);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
function createMethodHandler(method) {
|
|
425
|
+
return (req, context, options) => {
|
|
426
|
+
const incoming = (req.method || "").toUpperCase();
|
|
427
|
+
if (incoming && incoming !== method) {
|
|
428
|
+
return new Response(JSON.stringify({ error: "method_not_allowed" }), {
|
|
429
|
+
status: 405,
|
|
430
|
+
headers: { "content-type": "application/json", allow: method }
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
return syncRouteHandler(req, context, options);
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
var GET = createMethodHandler("GET");
|
|
437
|
+
var POST = createMethodHandler("POST");
|
|
438
|
+
function notFound() {
|
|
439
|
+
return Response.json({ error: "not_found" }, { status: 404 });
|
|
440
|
+
}
|
|
441
|
+
function resolveClient(req, options) {
|
|
442
|
+
var _a, _b, _c;
|
|
443
|
+
if (options.client) return options.client;
|
|
444
|
+
const baseURL = (_c = (_b = (_a = options.baseURL) != null ? _a : process.env.SYNC_BASE_URL) != null ? _b : process.env.NEXT_PUBLIC_SYNC_BASE_URL) != null ? _c : "";
|
|
445
|
+
if (!baseURL) {
|
|
446
|
+
throw new SyncHandlerError(500, "sync_base_url_missing", "SYNC_BASE_URL is not configured");
|
|
447
|
+
}
|
|
448
|
+
if (options.getHeadersFromRequest) {
|
|
449
|
+
return new SyncServerClient({
|
|
450
|
+
baseURL,
|
|
451
|
+
getHeaders: () => options.getHeadersFromRequest(req)
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
return SyncServerClient.fromRequest(req, baseURL);
|
|
455
|
+
}
|
|
456
|
+
async function resolveSegments(req, context, url) {
|
|
457
|
+
var _a;
|
|
458
|
+
const params = await resolveParams(context == null ? void 0 : context.params);
|
|
459
|
+
if (params == null ? void 0 : params.fractalsSync) {
|
|
460
|
+
return sanitizeSegments(params.fractalsSync);
|
|
461
|
+
}
|
|
462
|
+
const pathname = (_a = url == null ? void 0 : url.pathname) != null ? _a : typeof req.url === "string" ? safePathname(req.url) : "";
|
|
463
|
+
if (!pathname) return [];
|
|
464
|
+
const parts = pathname.split("/").filter(Boolean);
|
|
465
|
+
if (parts.length === 0) return [];
|
|
466
|
+
const catchAllIndex = parts.findIndex((part) => part === "fractals-sync" || part === "[...fractals-sync]");
|
|
467
|
+
if (catchAllIndex >= 0) {
|
|
468
|
+
return sanitizeSegments(parts.slice(catchAllIndex + 1));
|
|
469
|
+
}
|
|
470
|
+
return [];
|
|
471
|
+
}
|
|
472
|
+
async function resolveParams(params) {
|
|
473
|
+
var _a;
|
|
474
|
+
if (!params) return null;
|
|
475
|
+
if (typeof (params == null ? void 0 : params.then) === "function") {
|
|
476
|
+
return (_a = await params) != null ? _a : null;
|
|
477
|
+
}
|
|
478
|
+
return params != null ? params : null;
|
|
479
|
+
}
|
|
480
|
+
function sanitizeSegments(segments) {
|
|
481
|
+
return segments.map((segment) => decodePathSegment(String(segment || ""))).filter((segment) => segment.length > 0);
|
|
482
|
+
}
|
|
483
|
+
function resolveUrl(req) {
|
|
484
|
+
if (req.nextUrl instanceof URL) {
|
|
485
|
+
return req.nextUrl;
|
|
486
|
+
}
|
|
487
|
+
const rawUrl = typeof req.url === "string" ? req.url : null;
|
|
488
|
+
if (!rawUrl) return null;
|
|
489
|
+
try {
|
|
490
|
+
return new URL(rawUrl, "http://localhost");
|
|
491
|
+
} catch (e) {
|
|
492
|
+
return null;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
function safePathname(url) {
|
|
496
|
+
try {
|
|
497
|
+
return new URL(url, "http://localhost").pathname;
|
|
498
|
+
} catch (e) {
|
|
499
|
+
return "";
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
async function handleError(error, req, options, logger) {
|
|
503
|
+
var _a, _b;
|
|
504
|
+
if (error instanceof SyncHandlerError) {
|
|
505
|
+
if (error.code === "unauthorized" && options.onUnauthorized) {
|
|
506
|
+
try {
|
|
507
|
+
const custom = await options.onUnauthorized(req);
|
|
508
|
+
if (custom) return custom;
|
|
509
|
+
} catch (hookError) {
|
|
510
|
+
(_a = logger == null ? void 0 : logger.warn) == null ? void 0 : _a.call(logger, "[syncRouteHandler] onUnauthorized hook failed", hookError);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
const payload = { error: error.code };
|
|
514
|
+
if (error.message && error.message !== error.code) payload.message = error.message;
|
|
515
|
+
if (error.details !== void 0) payload.details = error.details;
|
|
516
|
+
return Response.json(payload, { status: error.status });
|
|
517
|
+
}
|
|
518
|
+
(_b = logger == null ? void 0 : logger.error) == null ? void 0 : _b.call(logger, "[syncRouteHandler] unhandled_error", error);
|
|
519
|
+
return Response.json({ error: "sync_handler_error" }, { status: 500 });
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// src/core/constants.ts
|
|
523
|
+
var MEMO_PROGRAM_ID = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr";
|
|
524
|
+
var XNET_2022_MINT = "xNETbUB7cRb3AAu2pNG2pUwQcJ2BHcktfvSB8x1Pq6L";
|
|
525
|
+
var DEFAULT_RPC_ENDPOINT = process.env.NEXT_PUBLIC_SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
|
|
526
|
+
var DISTRIBUTION_MEMO_PREFIX = "dist";
|
|
527
|
+
|
|
528
|
+
// src/core/helpers.ts
|
|
529
|
+
function buildDistributionMemoTag(distributionId, action = "claim") {
|
|
530
|
+
return `${DISTRIBUTION_MEMO_PREFIX}:${distributionId}:${action}`;
|
|
531
|
+
}
|
|
532
|
+
function assertTruthy(value, message) {
|
|
533
|
+
if (value === null || value === void 0) {
|
|
534
|
+
throw new Error(message);
|
|
535
|
+
}
|
|
536
|
+
return value;
|
|
537
|
+
}
|
|
538
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
539
|
+
0 && (module.exports = {
|
|
540
|
+
DEFAULT_RPC_ENDPOINT,
|
|
541
|
+
DISTRIBUTION_MEMO_PREFIX,
|
|
542
|
+
GET,
|
|
543
|
+
MEMO_PROGRAM_ID,
|
|
544
|
+
POST,
|
|
545
|
+
SyncServerClient,
|
|
546
|
+
XNET_2022_MINT,
|
|
547
|
+
assertTruthy,
|
|
548
|
+
buildDistributionMemoTag,
|
|
549
|
+
createMethodHandler,
|
|
550
|
+
syncRouteHandler
|
|
551
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_RPC_ENDPOINT,
|
|
3
|
+
DISTRIBUTION_MEMO_PREFIX,
|
|
4
|
+
MEMO_PROGRAM_ID,
|
|
5
|
+
XNET_2022_MINT,
|
|
6
|
+
assertTruthy,
|
|
7
|
+
buildDistributionMemoTag
|
|
8
|
+
} from "./chunk-TCJM2GIK.mjs";
|
|
9
|
+
import {
|
|
10
|
+
GET,
|
|
11
|
+
POST,
|
|
12
|
+
SyncServerClient,
|
|
13
|
+
createMethodHandler,
|
|
14
|
+
syncRouteHandler
|
|
15
|
+
} from "./chunk-N3276DIZ.mjs";
|
|
16
|
+
import "./chunk-I4E63NIC.mjs";
|
|
17
|
+
export {
|
|
18
|
+
DEFAULT_RPC_ENDPOINT,
|
|
19
|
+
DISTRIBUTION_MEMO_PREFIX,
|
|
20
|
+
GET,
|
|
21
|
+
MEMO_PROGRAM_ID,
|
|
22
|
+
POST,
|
|
23
|
+
SyncServerClient,
|
|
24
|
+
XNET_2022_MINT,
|
|
25
|
+
assertTruthy,
|
|
26
|
+
buildDistributionMemoTag,
|
|
27
|
+
createMethodHandler,
|
|
28
|
+
syncRouteHandler
|
|
29
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { UseQueryOptions, UseQueryResult, UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
|
|
4
|
+
import { g as ListDistributionsResponse, a as Distribution, o as ClaimableResponse, q as ClaimHistoryResponse, B as BuildClaimTransactionRequest, l as BuildClaimTransactionResponse, m as CommitClaimRequest, n as CommitClaimResponse } from '../api-CQqyHbnT.mjs';
|
|
5
|
+
|
|
6
|
+
type Fetcher = typeof fetch;
|
|
7
|
+
interface SyncContextValue {
|
|
8
|
+
basePath: string;
|
|
9
|
+
fetcher?: Fetcher;
|
|
10
|
+
}
|
|
11
|
+
interface SyncProviderProps {
|
|
12
|
+
basePath?: string;
|
|
13
|
+
fetcher?: Fetcher;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
declare function SyncProvider({ basePath, fetcher, children }: SyncProviderProps): react.FunctionComponentElement<react.ProviderProps<SyncContextValue>>;
|
|
17
|
+
interface SyncClient {
|
|
18
|
+
basePath: string;
|
|
19
|
+
request<T>(path: string, init?: RequestInit): Promise<T>;
|
|
20
|
+
get<T>(path: string, init?: RequestInit): Promise<T>;
|
|
21
|
+
post<T>(path: string, body?: unknown, init?: RequestInit): Promise<T>;
|
|
22
|
+
}
|
|
23
|
+
declare function useSyncClient(): SyncClient;
|
|
24
|
+
declare class SyncReactError extends Error {
|
|
25
|
+
readonly status: number;
|
|
26
|
+
readonly code?: string | undefined;
|
|
27
|
+
readonly details?: unknown | undefined;
|
|
28
|
+
constructor(status: number, code?: string | undefined, details?: unknown | undefined);
|
|
29
|
+
}
|
|
30
|
+
type QueryOptions<T> = Omit<UseQueryOptions<T, SyncReactError, T>, "queryKey" | "queryFn">;
|
|
31
|
+
declare function useDistributions<TResponse = ListDistributionsResponse>(options?: QueryOptions<TResponse>): UseQueryResult<TResponse, SyncReactError>;
|
|
32
|
+
declare function useDistribution<TResponse = Distribution>(distributionId: string | null | undefined, options?: QueryOptions<TResponse>): UseQueryResult<TResponse, SyncReactError>;
|
|
33
|
+
declare function useClaimableDistributions<TResponse = ClaimableResponse>(options?: QueryOptions<TResponse>): UseQueryResult<TResponse, SyncReactError>;
|
|
34
|
+
declare function useClaimHistory<TResponse = ClaimHistoryResponse>(options?: QueryOptions<TResponse>): UseQueryResult<TResponse, SyncReactError>;
|
|
35
|
+
type ClaimTransactionInput = Partial<Omit<BuildClaimTransactionRequest, "distributionId" | "claimant">>;
|
|
36
|
+
declare function useClaimTransaction(distributionId: string | null | undefined, options?: UseMutationOptions<BuildClaimTransactionResponse, SyncReactError, ClaimTransactionInput>): UseMutationResult<BuildClaimTransactionResponse, SyncReactError, ClaimTransactionInput>;
|
|
37
|
+
type ClaimCommitInput = Omit<CommitClaimRequest, "distributionId">;
|
|
38
|
+
declare function useCommitClaim(distributionId: string | null | undefined, options?: UseMutationOptions<CommitClaimResponse, SyncReactError, ClaimCommitInput>): UseMutationResult<CommitClaimResponse, SyncReactError, ClaimCommitInput>;
|
|
39
|
+
|
|
40
|
+
export { type ClaimCommitInput, type ClaimTransactionInput, type SyncClient, SyncProvider, type SyncProviderProps, SyncReactError, useClaimHistory, useClaimTransaction, useClaimableDistributions, useCommitClaim, useDistribution, useDistributions, useSyncClient };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { UseQueryOptions, UseQueryResult, UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
|
|
4
|
+
import { g as ListDistributionsResponse, a as Distribution, o as ClaimableResponse, q as ClaimHistoryResponse, B as BuildClaimTransactionRequest, l as BuildClaimTransactionResponse, m as CommitClaimRequest, n as CommitClaimResponse } from '../api-CQqyHbnT.js';
|
|
5
|
+
|
|
6
|
+
type Fetcher = typeof fetch;
|
|
7
|
+
interface SyncContextValue {
|
|
8
|
+
basePath: string;
|
|
9
|
+
fetcher?: Fetcher;
|
|
10
|
+
}
|
|
11
|
+
interface SyncProviderProps {
|
|
12
|
+
basePath?: string;
|
|
13
|
+
fetcher?: Fetcher;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
declare function SyncProvider({ basePath, fetcher, children }: SyncProviderProps): react.FunctionComponentElement<react.ProviderProps<SyncContextValue>>;
|
|
17
|
+
interface SyncClient {
|
|
18
|
+
basePath: string;
|
|
19
|
+
request<T>(path: string, init?: RequestInit): Promise<T>;
|
|
20
|
+
get<T>(path: string, init?: RequestInit): Promise<T>;
|
|
21
|
+
post<T>(path: string, body?: unknown, init?: RequestInit): Promise<T>;
|
|
22
|
+
}
|
|
23
|
+
declare function useSyncClient(): SyncClient;
|
|
24
|
+
declare class SyncReactError extends Error {
|
|
25
|
+
readonly status: number;
|
|
26
|
+
readonly code?: string | undefined;
|
|
27
|
+
readonly details?: unknown | undefined;
|
|
28
|
+
constructor(status: number, code?: string | undefined, details?: unknown | undefined);
|
|
29
|
+
}
|
|
30
|
+
type QueryOptions<T> = Omit<UseQueryOptions<T, SyncReactError, T>, "queryKey" | "queryFn">;
|
|
31
|
+
declare function useDistributions<TResponse = ListDistributionsResponse>(options?: QueryOptions<TResponse>): UseQueryResult<TResponse, SyncReactError>;
|
|
32
|
+
declare function useDistribution<TResponse = Distribution>(distributionId: string | null | undefined, options?: QueryOptions<TResponse>): UseQueryResult<TResponse, SyncReactError>;
|
|
33
|
+
declare function useClaimableDistributions<TResponse = ClaimableResponse>(options?: QueryOptions<TResponse>): UseQueryResult<TResponse, SyncReactError>;
|
|
34
|
+
declare function useClaimHistory<TResponse = ClaimHistoryResponse>(options?: QueryOptions<TResponse>): UseQueryResult<TResponse, SyncReactError>;
|
|
35
|
+
type ClaimTransactionInput = Partial<Omit<BuildClaimTransactionRequest, "distributionId" | "claimant">>;
|
|
36
|
+
declare function useClaimTransaction(distributionId: string | null | undefined, options?: UseMutationOptions<BuildClaimTransactionResponse, SyncReactError, ClaimTransactionInput>): UseMutationResult<BuildClaimTransactionResponse, SyncReactError, ClaimTransactionInput>;
|
|
37
|
+
type ClaimCommitInput = Omit<CommitClaimRequest, "distributionId">;
|
|
38
|
+
declare function useCommitClaim(distributionId: string | null | undefined, options?: UseMutationOptions<CommitClaimResponse, SyncReactError, ClaimCommitInput>): UseMutationResult<CommitClaimResponse, SyncReactError, ClaimCommitInput>;
|
|
39
|
+
|
|
40
|
+
export { type ClaimCommitInput, type ClaimTransactionInput, type SyncClient, SyncProvider, type SyncProviderProps, SyncReactError, useClaimHistory, useClaimTransaction, useClaimableDistributions, useCommitClaim, useDistribution, useDistributions, useSyncClient };
|