@pybara/pybara-js 0.1.0 → 0.2.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 +5 -1
- package/checkout.schema.json +135 -0
- package/dist/checkout.d.ts.map +1 -1
- package/dist/gate.d.ts +13 -7
- package/dist/gate.d.ts.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/pybara-js.iife.js +4 -4
- package/dist/pybara-js.js +71 -56
- package/package.json +19 -4
package/dist/pybara-js.js
CHANGED
|
@@ -198,62 +198,62 @@ var y = class {
|
|
|
198
198
|
], C = .5, w = {
|
|
199
199
|
widget: "donate-widget",
|
|
200
200
|
recurring: "donate-widget-recurring"
|
|
201
|
-
}, T = (e) => {
|
|
202
|
-
if (!e || !e.includes("-")) return !0;
|
|
203
|
-
let [t = 0, n = 0] = e.split("-").map(Number), [r = 0, i = 0] = "1-0".split("-").map(Number);
|
|
204
|
-
return t < r || t === r && n < i;
|
|
205
201
|
};
|
|
206
|
-
|
|
207
|
-
let
|
|
202
|
+
function T(e, t) {
|
|
203
|
+
let n = (e) => {
|
|
204
|
+
let t = /^(\d+)-(\d+)$/.exec(e);
|
|
205
|
+
return t ? [Number(t[1]), Number(t[2])] : null;
|
|
206
|
+
}, r = n(e), i = n(t);
|
|
207
|
+
return !r || !i ? !1 : r[0] > i[0] || r[0] === i[0] && r[1] >= i[1];
|
|
208
|
+
}
|
|
209
|
+
async function E(e) {
|
|
210
|
+
let t = await fetch(e);
|
|
211
|
+
if (!t.ok) throw Error(`HTTP ${t.status} from ${e}`);
|
|
212
|
+
return await t.json();
|
|
213
|
+
}
|
|
214
|
+
async function D(t, n, r) {
|
|
215
|
+
let i = e[t], a = `https://${i.admin_core}.raw.icp0.io/widget-config`, o = `https://${i.admin_regs}.raw.icp0.io/widget-terms?site_url=${encodeURIComponent(n)}&principal=${encodeURIComponent(r)}`, s, c;
|
|
208
216
|
try {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
show: !1,
|
|
212
|
-
reason: `This integration is temporarily unavailable (${o.key})`
|
|
213
|
-
};
|
|
214
|
-
if (!e.ok) return {
|
|
215
|
-
show: !1,
|
|
216
|
-
reason: `Site not verified (${e.status})`
|
|
217
|
-
};
|
|
218
|
-
let s = await e.json();
|
|
219
|
-
if (s.terms?.signed !== !0 || T(s.terms?.version)) {
|
|
220
|
-
let e = s.terms?.superseded_version;
|
|
221
|
-
return {
|
|
222
|
-
show: !1,
|
|
223
|
-
reason: e ? `Widget terms v${e} now apply — accept them in Pybara Wallet (Manage › Sites)` : "This site has not accepted the widget’s terms in Pybara Wallet (Manage › Sites)"
|
|
224
|
-
};
|
|
225
|
-
}
|
|
217
|
+
[s, c] = await Promise.all([E(a), E(o)]);
|
|
218
|
+
} catch (e) {
|
|
226
219
|
return {
|
|
227
|
-
show: !0,
|
|
228
|
-
reason: null
|
|
229
|
-
};
|
|
230
|
-
} catch {
|
|
231
|
-
return o ? {
|
|
232
220
|
show: !1,
|
|
233
|
-
reason: `
|
|
234
|
-
} : {
|
|
235
|
-
show: !0,
|
|
236
|
-
reason: null
|
|
221
|
+
reason: `could not read the widget's configuration (${e instanceof Error ? e.message : String(e)})`
|
|
237
222
|
};
|
|
238
223
|
}
|
|
224
|
+
let l = s.kill_switch?.plugins ?? {};
|
|
225
|
+
return l[w.widget]?.enabled === !0 ? !c.signed || !c.version ? {
|
|
226
|
+
show: !1,
|
|
227
|
+
reason: `${n} has not accepted the widget's terms in Pybara Wallet (Manage › Sites › Add a site without a plugin)`
|
|
228
|
+
} : T(c.version, "1-0") ? {
|
|
229
|
+
show: !0,
|
|
230
|
+
recurring: l[w.recurring]?.enabled === !0
|
|
231
|
+
} : {
|
|
232
|
+
show: !1,
|
|
233
|
+
reason: `this widget version requires terms 1-0, and ${n} accepted ${c.version}: accept the new terms in Pybara Wallet (Manage › Sites)`
|
|
234
|
+
} : {
|
|
235
|
+
show: !1,
|
|
236
|
+
reason: "the widget is switched off by Pybara for now"
|
|
237
|
+
};
|
|
239
238
|
}
|
|
240
239
|
//#endregion
|
|
241
240
|
//#region src/types.ts
|
|
242
|
-
var
|
|
241
|
+
var O = class extends Error {
|
|
243
242
|
constructor(e, t) {
|
|
244
243
|
super(t), this.name = "PybaraError", this.code = e;
|
|
245
244
|
}
|
|
246
|
-
},
|
|
245
|
+
}, k = class {
|
|
247
246
|
constructor(e) {
|
|
248
|
-
this.adminClient = null, this.fiatRate = 1, this.modal = null, this.gate = null, this.isOpen = !1, this.activePayment = null, this.config =
|
|
247
|
+
this.adminClient = null, this.fiatRate = 1, this.modal = null, this.gate = null, this.isOpen = !1, this.activePayment = null, this.config = M(e), this.ready = this.init();
|
|
249
248
|
}
|
|
250
249
|
async open(e) {
|
|
251
|
-
if (await this.ready, this.gate && !this.gate.show) throw new
|
|
250
|
+
if (await this.ready, this.gate && !this.gate.show) throw new O("GATE_REFUSED", this.gate.reason ?? "This site cannot accept Pybara payments yet.");
|
|
252
251
|
let t = e.amount;
|
|
253
|
-
if (!Number.isFinite(t) || t <= 0) throw new
|
|
252
|
+
if (!Number.isFinite(t) || t <= 0) throw new O("INVALID_CONFIG", `Invalid amount: ${e.amount}`);
|
|
254
253
|
let n = e.currency ?? this.config.currency, r = t * (n === "USD" ? 1 : this.fiatRate);
|
|
255
|
-
if (r < .5) throw new
|
|
256
|
-
let i =
|
|
254
|
+
if (r < .5) throw new O("BELOW_MINIMUM", `Minimum payment is $${C} USD.`);
|
|
255
|
+
let i = A(e);
|
|
256
|
+
if (i && this.gate && this.gate.show && !this.gate.recurring) throw new O("GATE_REFUSED", "Recurring payments are temporarily unavailable.");
|
|
257
257
|
if (this.isOpen) return;
|
|
258
258
|
this.isOpen = !0;
|
|
259
259
|
let a = !1;
|
|
@@ -264,12 +264,12 @@ var D = class extends Error {
|
|
|
264
264
|
}
|
|
265
265
|
this.modal || this.initCheckoutModal();
|
|
266
266
|
let o = this.modal;
|
|
267
|
-
if (!o) throw this.isOpen = !1, new
|
|
267
|
+
if (!o) throw this.isOpen = !1, new O("CHECKOUT_FAILED", "The checkout modal could not be initialised.");
|
|
268
268
|
a ? (this.isOpen = !1, o.renderTerminalState("This recipient is currently unable to accept donations."), this.initCheckoutModal()) : (this.activePayment = e, o.show({
|
|
269
269
|
modalData: {
|
|
270
270
|
amountUSD: r,
|
|
271
271
|
beneficiary: this.config.recipientPrincipal,
|
|
272
|
-
salt:
|
|
272
|
+
salt: N(),
|
|
273
273
|
reference: this.config.siteName
|
|
274
274
|
},
|
|
275
275
|
recurring: i,
|
|
@@ -292,7 +292,7 @@ var D = class extends Error {
|
|
|
292
292
|
} catch (e) {
|
|
293
293
|
r && console.error("🧩 pybara-js: admin client init failed:", e);
|
|
294
294
|
}
|
|
295
|
-
this.config.pluginVersion || (this.gate = await
|
|
295
|
+
this.config.pluginVersion || (this.gate = await D(t, this.config.siteUrl, this.config.recipientPrincipal), !this.gate.show && r && console.warn("🧩 pybara-js: gate refused —", this.gate.reason)), this.preconnectWallet(t), this.initCheckoutModal();
|
|
296
296
|
}
|
|
297
297
|
initCheckoutModal() {
|
|
298
298
|
let e = this.config.staging ? "staging" : "prod", n = this.config, r = this;
|
|
@@ -301,7 +301,7 @@ var D = class extends Error {
|
|
|
301
301
|
context: "donation",
|
|
302
302
|
thankYouMessage: n.thankYouMessage,
|
|
303
303
|
onSuccess: (e) => {
|
|
304
|
-
let t = r.activePayment, i = t ?
|
|
304
|
+
let t = r.activePayment, i = t ? A(t) : void 0, a = {
|
|
305
305
|
blockIndex: e.blockIndex,
|
|
306
306
|
reference: e.reference,
|
|
307
307
|
token: e.token,
|
|
@@ -317,7 +317,7 @@ var D = class extends Error {
|
|
|
317
317
|
onError: (e) => {
|
|
318
318
|
r.isOpen = !1;
|
|
319
319
|
let t = r.activePayment;
|
|
320
|
-
r.activePayment = null, t?.onError?.(
|
|
320
|
+
r.activePayment = null, t?.onError?.(P(e)), r.modal = null, r.initCheckoutModal();
|
|
321
321
|
},
|
|
322
322
|
onClose: () => {
|
|
323
323
|
r.isOpen = !1;
|
|
@@ -360,42 +360,57 @@ var D = class extends Error {
|
|
|
360
360
|
n.rel = "preconnect", n.href = new URL(t[e]).origin, n.crossOrigin = "anonymous", document.head.appendChild(n);
|
|
361
361
|
}
|
|
362
362
|
};
|
|
363
|
-
function
|
|
363
|
+
function A(e) {
|
|
364
364
|
if (!e.frequency) return;
|
|
365
365
|
let t = b[e.frequency], n = e.durationMonths;
|
|
366
366
|
if (n == null) return {
|
|
367
367
|
frequency: e.frequency,
|
|
368
368
|
totalPulls: 0
|
|
369
369
|
};
|
|
370
|
-
if (!S.includes(n)) throw new
|
|
370
|
+
if (!S.includes(n)) throw new O("INVALID_CONFIG", `durationMonths must be one of ${S.join(", ")} — got ${n}.`);
|
|
371
371
|
return {
|
|
372
372
|
frequency: e.frequency,
|
|
373
373
|
totalPulls: Math.ceil(n * x / t),
|
|
374
374
|
durationMonths: n
|
|
375
375
|
};
|
|
376
376
|
}
|
|
377
|
-
function
|
|
378
|
-
|
|
379
|
-
if (!
|
|
380
|
-
|
|
377
|
+
function j(e) {
|
|
378
|
+
let t = e.trim();
|
|
379
|
+
if (!t) return null;
|
|
380
|
+
let n;
|
|
381
|
+
try {
|
|
382
|
+
n = new URL(t.includes("://") ? t : `https://${t}`);
|
|
383
|
+
} catch {
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
return n.protocol !== "https:" && n.protocol !== "http:" ? null : n.origin + n.pathname.replace(/\/+$/, "");
|
|
387
|
+
}
|
|
388
|
+
function M(e) {
|
|
389
|
+
if (!e.recipientPrincipal) throw new O("INVALID_CONFIG", "Pybara.checkout: \"recipientPrincipal\" is required");
|
|
390
|
+
if (!e.siteUrl) throw new O("INVALID_CONFIG", "Pybara.checkout: \"siteUrl\" is required");
|
|
391
|
+
let t = j(e.siteUrl);
|
|
392
|
+
if (!t) throw new O("INVALID_CONFIG", `Pybara.checkout: "siteUrl" is not a valid http(s) URL: ${e.siteUrl}`);
|
|
393
|
+
if (!e.siteName) throw new O("INVALID_CONFIG", "Pybara.checkout: \"siteName\" is required");
|
|
381
394
|
return {
|
|
382
395
|
...e,
|
|
396
|
+
siteUrl: t,
|
|
383
397
|
currency: e.currency ?? "USD",
|
|
384
398
|
staging: e.staging ?? !1,
|
|
385
399
|
debug: e.debug ?? !1
|
|
386
400
|
};
|
|
387
401
|
}
|
|
388
|
-
function
|
|
402
|
+
function N() {
|
|
389
403
|
let e = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16));
|
|
390
404
|
return btoa(String.fromCharCode(...e));
|
|
391
405
|
}
|
|
392
|
-
function
|
|
406
|
+
function P(e) {
|
|
393
407
|
return e instanceof Error ? e : Error(String(e));
|
|
394
408
|
}
|
|
395
409
|
//#endregion
|
|
396
410
|
//#region src/index.ts
|
|
397
|
-
|
|
398
|
-
return new
|
|
399
|
-
}
|
|
411
|
+
function F(e) {
|
|
412
|
+
return new k(e);
|
|
413
|
+
}
|
|
414
|
+
var I = { checkout: F };
|
|
400
415
|
//#endregion
|
|
401
|
-
export {
|
|
416
|
+
export { I as Pybara, k as PybaraCheckout, O as PybaraError, F as checkout };
|
package/package.json
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pybara/pybara-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Accept crypto payments and donations with Pybara on any page — a callable checkout, in the stripe-js / paypal-js convention.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pybara",
|
|
7
|
+
"payment",
|
|
8
|
+
"payments",
|
|
9
|
+
"crypto",
|
|
10
|
+
"crypto-payments",
|
|
11
|
+
"checkout",
|
|
12
|
+
"donations",
|
|
13
|
+
"icp",
|
|
14
|
+
"internet-computer"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://docs.pybara.com/pybara-js/",
|
|
5
17
|
"license": "MIT",
|
|
6
18
|
"type": "module",
|
|
7
19
|
"main": "./dist/pybara-js.js",
|
|
@@ -20,15 +32,18 @@
|
|
|
20
32
|
"./package.json": "./package.json"
|
|
21
33
|
},
|
|
22
34
|
"files": [
|
|
23
|
-
"dist"
|
|
35
|
+
"dist",
|
|
36
|
+
"checkout.schema.json"
|
|
24
37
|
],
|
|
25
38
|
"scripts": {
|
|
26
39
|
"build": "vite build && vite build -c vite.config.iife.ts",
|
|
27
40
|
"prepare": "npm run build",
|
|
28
41
|
"type-check": "tsc --noEmit",
|
|
29
|
-
"update:pybara": "npm install -D @pybara/pybara-
|
|
42
|
+
"update:pybara": "npm install -D @pybara/pybara-ux@github:pybara/pybara-ux",
|
|
30
43
|
"prepublishOnly": "npm run type-check && npm run build",
|
|
31
|
-
"release:tag": "git tag v$npm_package_version && git push origin v$npm_package_version"
|
|
44
|
+
"release:tag": "git tag v$npm_package_version && git push origin v$npm_package_version",
|
|
45
|
+
"demo": "node demo/load-env.mjs && (sleep 1 && open http://localhost:5678 &) && npx serve demo -l 5678",
|
|
46
|
+
"dev": "vite --open /demo/"
|
|
32
47
|
},
|
|
33
48
|
"devDependencies": {
|
|
34
49
|
"@biomejs/biome": "2.5.15",
|