@nibgate/sdk 0.2.19 → 0.2.21
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 +74 -2
- package/SKILL.md +93 -3
- package/dist/nibgate.js +782 -751
- package/dist/nibgate.js.map +4 -4
- package/dist/nibgate.min.js +76 -81
- package/dist/nibgate.min.js.map +4 -4
- package/package.json +1 -1
- package/src/browser/default-ui.js +79 -56
package/dist/nibgate.js
CHANGED
|
@@ -423,6 +423,211 @@ var Nibgate = (() => {
|
|
|
423
423
|
}
|
|
424
424
|
});
|
|
425
425
|
|
|
426
|
+
// src/browser/track.js
|
|
427
|
+
function trackResourcePage(resource, options = {}) {
|
|
428
|
+
const item = createGate(resource, options.gateOptions || {});
|
|
429
|
+
const validation = validateResourceMetadata(item.resource, options.validation || {});
|
|
430
|
+
if ((validation.warnings.length || validation.errors.length) && options.warn !== false && browserWindow()?.console?.warn) {
|
|
431
|
+
browserWindow().console.warn("Nibgate content metadata needs attention", validation);
|
|
432
|
+
}
|
|
433
|
+
item.content({ source: options.source, metadataQuality: { score: validation.score, warnings: validation.warnings, errors: validation.errors }, ...options.content || {} });
|
|
434
|
+
item.view({
|
|
435
|
+
source: options.source,
|
|
436
|
+
path: options.path || browserWindow()?.location?.pathname || item.resource.path,
|
|
437
|
+
referrer: options.referrer ?? browserWindow()?.document?.referrer ?? "",
|
|
438
|
+
...options.view || {}
|
|
439
|
+
});
|
|
440
|
+
return item;
|
|
441
|
+
}
|
|
442
|
+
function setupResourcePage(resource, options = {}) {
|
|
443
|
+
const item = trackResourcePage(resource, options);
|
|
444
|
+
const win = browserWindow();
|
|
445
|
+
if (!win) return item;
|
|
446
|
+
const button = typeof options.button === "string" ? win.document.querySelector(options.button) : options.button;
|
|
447
|
+
const statusElement = typeof options.status === "string" ? win.document.querySelector(options.status) : options.status;
|
|
448
|
+
const setStatus = options.onStatus || ((message) => {
|
|
449
|
+
if (statusElement) statusElement.textContent = message || "";
|
|
450
|
+
});
|
|
451
|
+
if (button) {
|
|
452
|
+
button.addEventListener("click", async () => {
|
|
453
|
+
button.disabled = true;
|
|
454
|
+
try {
|
|
455
|
+
await checkResourceAccess(resource, { ...options, onStatus: setStatus });
|
|
456
|
+
} finally {
|
|
457
|
+
button.disabled = false;
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
return item;
|
|
462
|
+
}
|
|
463
|
+
var init_track = __esm({
|
|
464
|
+
"src/browser/track.js"() {
|
|
465
|
+
init_resource();
|
|
466
|
+
init_env();
|
|
467
|
+
init_gate();
|
|
468
|
+
init_access();
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// src/browser/access.js
|
|
473
|
+
async function checkResourceAccess(resource, options = {}) {
|
|
474
|
+
const item = createGate(resource, options.gateOptions || {});
|
|
475
|
+
const accessPath = options.accessPath || item.resource.accessPath || "/api/nibgate/access";
|
|
476
|
+
const status2 = typeof options.onStatus === "function" ? options.onStatus : () => {
|
|
477
|
+
};
|
|
478
|
+
status2(options.checkingMessage || "Checking access route...");
|
|
479
|
+
item.unlockStarted({ source: options.source, paymentProvider: options.paymentProvider || "nibgate-access-route" });
|
|
480
|
+
const response = await fetch(accessPath, {
|
|
481
|
+
method: options.method || "GET",
|
|
482
|
+
headers: {
|
|
483
|
+
accept: "application/json",
|
|
484
|
+
...getPaymentProof(item.resource) ? { "x-nibgate-payment-proof": getPaymentProof(item.resource) } : {},
|
|
485
|
+
...options.headers || {}
|
|
486
|
+
},
|
|
487
|
+
body: options.body
|
|
488
|
+
});
|
|
489
|
+
const payload = await response.json().catch(() => ({}));
|
|
490
|
+
if (response.status === 402) {
|
|
491
|
+
item.track("payment_challenge_returned", { source: options.source, challenge: payload, resource: item.resource });
|
|
492
|
+
status2(options.challengeMessage || "Payment challenge returned. Continue with checkout.");
|
|
493
|
+
if (typeof options.createPaymentSignature === "function" || typeof options.checkout === "function") {
|
|
494
|
+
return payWithPaymentSignature(resource, {
|
|
495
|
+
...options,
|
|
496
|
+
challenge: payload,
|
|
497
|
+
paymentRequiredHeader: response.headers.get("PAYMENT-REQUIRED") || response.headers.get("payment-required") || ""
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
if (options.autoPay && options.payPath) {
|
|
501
|
+
const paymentResult = await payAndUnlockResource(resource, options);
|
|
502
|
+
if (paymentResult.ok && options.retryAfterPay !== false) {
|
|
503
|
+
return checkResourceAccess(resource, { ...options, autoPay: false });
|
|
504
|
+
}
|
|
505
|
+
return paymentResult;
|
|
506
|
+
}
|
|
507
|
+
return { ok: false, status: response.status, challenge: payload, resource: item.resource, response };
|
|
508
|
+
}
|
|
509
|
+
if (!response.ok) {
|
|
510
|
+
status2(payload.error || options.errorMessage || "Access check failed");
|
|
511
|
+
return { ok: false, status: response.status, error: payload.error || "Access check failed", payload, resource: item.resource, response };
|
|
512
|
+
}
|
|
513
|
+
const payment = options.payment || payload.payment || null;
|
|
514
|
+
if (payment) {
|
|
515
|
+
item.unlockCompleted(payment);
|
|
516
|
+
item.paymentCompleted(payment);
|
|
517
|
+
}
|
|
518
|
+
status2(options.successMessage || "Access allowed and Nibgate events emitted.");
|
|
519
|
+
return { ok: true, status: response.status, payload, payment, resource: item.resource, response };
|
|
520
|
+
}
|
|
521
|
+
async function payWithPaymentSignature(resource, options = {}) {
|
|
522
|
+
const item = createGate(resource, options.gateOptions || {});
|
|
523
|
+
const accessPath = options.accessPath || item.resource.accessPath || "/api/nibgate/access";
|
|
524
|
+
const status2 = typeof options.onStatus === "function" ? options.onStatus : () => {
|
|
525
|
+
};
|
|
526
|
+
status2(options.paymentMessage || "Waiting for wallet payment approval...");
|
|
527
|
+
item.unlockStarted({ source: options.source, paymentProvider: options.paymentProvider || "wallet-gateway" });
|
|
528
|
+
let paymentSignature = options.paymentSignature || "";
|
|
529
|
+
let paymentMemo = options.memo || "";
|
|
530
|
+
let paymentMetadata = options.payment || {};
|
|
531
|
+
if (!paymentSignature) {
|
|
532
|
+
const paymentRequiredHeader = options.paymentRequiredHeader || "";
|
|
533
|
+
const challenge2 = options.challenge || null;
|
|
534
|
+
const checkout = options.createPaymentSignature || options.checkout;
|
|
535
|
+
const result = await checkout({
|
|
536
|
+
resource: item.resource,
|
|
537
|
+
challenge: challenge2,
|
|
538
|
+
paymentRequiredHeader,
|
|
539
|
+
accessPath
|
|
540
|
+
});
|
|
541
|
+
paymentSignature = result?.paymentSignature || result?.signature || result?.payment || "";
|
|
542
|
+
paymentMemo = result?.memo || result?.paymentMemo || "";
|
|
543
|
+
paymentMetadata = result?.metadata || result?.paymentMetadata || result || {};
|
|
544
|
+
}
|
|
545
|
+
if (!paymentSignature) {
|
|
546
|
+
const error = "Wallet did not return a payment signature.";
|
|
547
|
+
item.track("payment_failed", { source: options.source, error });
|
|
548
|
+
status2(error);
|
|
549
|
+
return { ok: false, status: 400, error, resource: item.resource };
|
|
550
|
+
}
|
|
551
|
+
const response = await fetch(accessPath, {
|
|
552
|
+
method: options.method || "GET",
|
|
553
|
+
headers: {
|
|
554
|
+
accept: "application/json",
|
|
555
|
+
"payment-signature": paymentSignature,
|
|
556
|
+
...paymentMemo ? { "payment-memo": paymentMemo } : {},
|
|
557
|
+
...options.headers || {}
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
const responseText = await response.text();
|
|
561
|
+
let payload = {};
|
|
562
|
+
try {
|
|
563
|
+
payload = responseText ? JSON.parse(responseText) : {};
|
|
564
|
+
} catch (_error) {
|
|
565
|
+
payload = { error: responseText || "Payment verification failed" };
|
|
566
|
+
}
|
|
567
|
+
if (!response.ok) {
|
|
568
|
+
const detail = payload.detail || payload.reason || payload.invalidReason || payload.error || responseText || "Payment verification failed";
|
|
569
|
+
const error = typeof detail === "string" ? detail : stringifyJson(detail);
|
|
570
|
+
item.track("payment_failed", { source: options.source, status: response.status, error, ...paymentMetadata });
|
|
571
|
+
status2(options.paymentErrorMessage || error);
|
|
572
|
+
return { ok: false, status: response.status, error, payload, resource: item.resource, response };
|
|
573
|
+
}
|
|
574
|
+
const payment = payload.payment || {
|
|
575
|
+
paymentProvider: options.paymentProvider || "wallet-gateway",
|
|
576
|
+
paymentId: paymentSignature,
|
|
577
|
+
memo: paymentMemo,
|
|
578
|
+
amount: Number(item.resource.price || 0),
|
|
579
|
+
revenue: Number(item.resource.price || 0),
|
|
580
|
+
currency: item.resource.currency || "USDC",
|
|
581
|
+
...paymentMetadata
|
|
582
|
+
};
|
|
583
|
+
storePaymentProof(item.resource, payload.unlockProof);
|
|
584
|
+
item.markUnlocked(payment);
|
|
585
|
+
status2(options.paymentSuccessMessage || "Payment verified. Content unlocked.");
|
|
586
|
+
return { ok: true, status: response.status, payload, payment, resource: item.resource, response };
|
|
587
|
+
}
|
|
588
|
+
async function payAndUnlockResource(resource, options = {}) {
|
|
589
|
+
const item = createGate(resource, options.gateOptions || {});
|
|
590
|
+
const payPath = options.payPath || item.resource.payPath || "/api/nibgate/pay";
|
|
591
|
+
const status2 = typeof options.onStatus === "function" ? options.onStatus : () => {
|
|
592
|
+
};
|
|
593
|
+
status2(options.paymentMessage || "Starting payment...");
|
|
594
|
+
item.unlockStarted({ source: options.source, paymentProvider: options.paymentProvider || "circle-gateway" });
|
|
595
|
+
const response = await fetch(payPath, {
|
|
596
|
+
method: options.payMethod || "POST",
|
|
597
|
+
headers: {
|
|
598
|
+
accept: "application/json",
|
|
599
|
+
"content-type": "application/json",
|
|
600
|
+
...options.payHeaders || {}
|
|
601
|
+
},
|
|
602
|
+
body: JSON.stringify({ resource: item.resource, ...options.payPayload || {} })
|
|
603
|
+
});
|
|
604
|
+
const payload = await response.json().catch(() => ({}));
|
|
605
|
+
if (!response.ok || !payload.ok) {
|
|
606
|
+
item.track("payment_failed", { source: options.source, status: response.status, error: payload.error || "Payment failed", detail: payload.detail || "" });
|
|
607
|
+
status2(payload.detail || payload.error || options.paymentErrorMessage || "Payment failed.");
|
|
608
|
+
return { ok: false, status: response.status, payload, resource: item.resource, response };
|
|
609
|
+
}
|
|
610
|
+
const payment = payload.payment || {
|
|
611
|
+
paymentProvider: options.paymentProvider || "circle-gateway",
|
|
612
|
+
paymentId: payload.paymentId || `nibgate_payment_${Date.now()}`,
|
|
613
|
+
amount: Number(item.resource.price || 0),
|
|
614
|
+
revenue: Number(item.resource.price || 0),
|
|
615
|
+
currency: item.resource.currency || "USDC"
|
|
616
|
+
};
|
|
617
|
+
storePaymentProof(item.resource, payload.unlockProof);
|
|
618
|
+
item.markUnlocked(payment);
|
|
619
|
+
status2(options.paymentSuccessMessage || "Payment verified. Content unlocked.");
|
|
620
|
+
return { ok: true, status: response.status, payload, payment, resource: item.resource, response };
|
|
621
|
+
}
|
|
622
|
+
var init_access = __esm({
|
|
623
|
+
"src/browser/access.js"() {
|
|
624
|
+
init_events();
|
|
625
|
+
init_storage();
|
|
626
|
+
init_json();
|
|
627
|
+
init_gate();
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
|
|
426
631
|
// src/core/rating.js
|
|
427
632
|
function normalizeRating(input = {}) {
|
|
428
633
|
const value = typeof input === "number" ? input : input.rating ?? input.stars ?? input.ratingValue ?? input.score;
|
|
@@ -26601,40 +26806,238 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
26601
26806
|
}
|
|
26602
26807
|
});
|
|
26603
26808
|
|
|
26604
|
-
// src/browser/
|
|
26605
|
-
function
|
|
26606
|
-
|
|
26607
|
-
|
|
26608
|
-
function wordRight(hex = "") {
|
|
26609
|
-
const clean2 = stripHex(hex);
|
|
26610
|
-
if (clean2.length > 64) throw new Error("ABI word is too long.");
|
|
26611
|
-
return clean2.padEnd(64, "0");
|
|
26612
|
-
}
|
|
26613
|
-
function numberWord(value = 0) {
|
|
26614
|
-
return Number(value || 0).toString(16).padStart(64, "0");
|
|
26615
|
-
}
|
|
26616
|
-
function utf8Hex(value = "") {
|
|
26617
|
-
return Array.from(new TextEncoder().encode(String(value || ""))).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
26618
|
-
}
|
|
26619
|
-
function encodeString3(value = "") {
|
|
26620
|
-
const hex = utf8Hex(value);
|
|
26621
|
-
const byteLength = hex.length / 2;
|
|
26622
|
-
const paddedLength = Math.ceil(byteLength / 32) * 64;
|
|
26623
|
-
return numberWord(byteLength) + hex.padEnd(paddedLength, "0");
|
|
26809
|
+
// src/browser/evm-gateway.js
|
|
26810
|
+
async function createCircleGatewayBrowserAdapter2(options = {}) {
|
|
26811
|
+
const gateway = await Promise.resolve().then(() => (init_gateway(), gateway_exports));
|
|
26812
|
+
return gateway.createCircleGatewayBrowserAdapter(options);
|
|
26624
26813
|
}
|
|
26625
|
-
function
|
|
26626
|
-
|
|
26814
|
+
function resolveAccessPath(resource, options) {
|
|
26815
|
+
if (options.hosted || options.accessPath === "hosted") return HOSTED_PAY_URL;
|
|
26816
|
+
return options.accessPath || resource.accessPath || "/api/nibgate/access";
|
|
26627
26817
|
}
|
|
26628
|
-
function
|
|
26629
|
-
const
|
|
26630
|
-
|
|
26631
|
-
|
|
26818
|
+
function createEvmGatewayUnlock(resource, options = {}) {
|
|
26819
|
+
const item = createGate(resource, options.gateOptions || {});
|
|
26820
|
+
const win = browserWindow();
|
|
26821
|
+
const accessPath = resolveAccessPath(item.resource, options);
|
|
26822
|
+
const source = options.source || "nibgate-evm-gateway";
|
|
26823
|
+
const network = options.network || "eip155:5042002";
|
|
26824
|
+
const statusTarget = typeof options.status === "string" ? win?.document.querySelector(options.status) : options.status;
|
|
26825
|
+
const connectButton = typeof options.connectButton === "string" ? win?.document.querySelector(options.connectButton) : options.connectButton;
|
|
26826
|
+
const disconnectButton = typeof options.disconnectButton === "string" ? win?.document.querySelector(options.disconnectButton) : options.disconnectButton;
|
|
26827
|
+
const unlockButton = typeof options.unlockButton === "string" ? win?.document.querySelector(options.unlockButton) : options.unlockButton;
|
|
26828
|
+
const clearButton = typeof options.clearButton === "string" ? win?.document.querySelector(options.clearButton) : options.clearButton;
|
|
26829
|
+
const walletLabel = typeof options.walletLabel === "string" ? win?.document.querySelector(options.walletLabel) : options.walletLabel;
|
|
26830
|
+
const unlockedTarget = typeof options.unlockedTarget === "string" ? win?.document.querySelector(options.unlockedTarget) : options.unlockedTarget;
|
|
26831
|
+
let walletAddress = "";
|
|
26832
|
+
let busy = false;
|
|
26833
|
+
function setStatus(message) {
|
|
26834
|
+
if (typeof options.onStatus === "function") options.onStatus(message);
|
|
26835
|
+
if (statusTarget) statusTarget.textContent = message || "";
|
|
26632
26836
|
}
|
|
26633
|
-
|
|
26634
|
-
|
|
26635
|
-
|
|
26636
|
-
|
|
26637
|
-
|
|
26837
|
+
function shortAddress(address) {
|
|
26838
|
+
return address ? `${address.slice(0, 6)}...${address.slice(-4)}` : "";
|
|
26839
|
+
}
|
|
26840
|
+
function provider() {
|
|
26841
|
+
return win?.ethereum || options.provider || null;
|
|
26842
|
+
}
|
|
26843
|
+
function setBusy(value) {
|
|
26844
|
+
busy = Boolean(value);
|
|
26845
|
+
[connectButton, disconnectButton, unlockButton, clearButton].forEach((button) => {
|
|
26846
|
+
if (button && "disabled" in button) {
|
|
26847
|
+
button.disabled = busy || button === connectButton && !provider() || button === disconnectButton && !walletAddress;
|
|
26848
|
+
}
|
|
26849
|
+
});
|
|
26850
|
+
}
|
|
26851
|
+
function renderWallet() {
|
|
26852
|
+
const hasProvider = Boolean(provider());
|
|
26853
|
+
if (walletLabel) walletLabel.textContent = walletAddress ? shortAddress(walletAddress) : hasProvider ? "Ready to connect" : "No wallet detected";
|
|
26854
|
+
if (connectButton) connectButton.textContent = walletAddress ? "Connected" : "Connect wallet";
|
|
26855
|
+
if (disconnectButton) disconnectButton.textContent = "Disconnect";
|
|
26856
|
+
if (connectButton && "disabled" in connectButton) connectButton.disabled = busy || !hasProvider;
|
|
26857
|
+
if (disconnectButton && "disabled" in disconnectButton) disconnectButton.disabled = busy || !walletAddress;
|
|
26858
|
+
}
|
|
26859
|
+
function setUnlocked(isUnlocked, payment = {}) {
|
|
26860
|
+
if (unlockButton) unlockButton.textContent = isUnlocked ? "Unlocked" : `Unlock for ${item.resource.price} ${item.resource.currency || "USDC"}`;
|
|
26861
|
+
if (unlockedTarget) {
|
|
26862
|
+
if ("hidden" in unlockedTarget) unlockedTarget.hidden = !isUnlocked;
|
|
26863
|
+
unlockedTarget.setAttribute("aria-hidden", isUnlocked ? "false" : "true");
|
|
26864
|
+
}
|
|
26865
|
+
if (isUnlocked) item.markUnlocked(payment);
|
|
26866
|
+
}
|
|
26867
|
+
async function connect() {
|
|
26868
|
+
setBusy(true);
|
|
26869
|
+
setStatus("Opening wallet connection...");
|
|
26870
|
+
try {
|
|
26871
|
+
const evm = provider();
|
|
26872
|
+
if (!evm) throw new Error(options.noWalletMessage || "Install or open an EVM wallet to continue.");
|
|
26873
|
+
const accounts = await evm.request({ method: "eth_requestAccounts" });
|
|
26874
|
+
walletAddress = Array.isArray(accounts) ? accounts[0] || "" : "";
|
|
26875
|
+
if (!walletAddress) throw new Error("No wallet account selected.");
|
|
26876
|
+
renderWallet();
|
|
26877
|
+
setStatus("Wallet connected. You can unlock now.");
|
|
26878
|
+
return walletAddress;
|
|
26879
|
+
} finally {
|
|
26880
|
+
setBusy(false);
|
|
26881
|
+
}
|
|
26882
|
+
}
|
|
26883
|
+
async function disconnect() {
|
|
26884
|
+
setBusy(true);
|
|
26885
|
+
try {
|
|
26886
|
+
const evm = provider();
|
|
26887
|
+
if (evm?.request && walletAddress) {
|
|
26888
|
+
try {
|
|
26889
|
+
await evm.request({ method: "wallet_revokePermissions", params: [{ eth_accounts: {} }] });
|
|
26890
|
+
} catch (_error) {
|
|
26891
|
+
}
|
|
26892
|
+
}
|
|
26893
|
+
walletAddress = "";
|
|
26894
|
+
renderWallet();
|
|
26895
|
+
setStatus(options.disconnectMessage || "Wallet disconnected for this page.");
|
|
26896
|
+
return true;
|
|
26897
|
+
} finally {
|
|
26898
|
+
setBusy(false);
|
|
26899
|
+
}
|
|
26900
|
+
}
|
|
26901
|
+
async function checkout(input) {
|
|
26902
|
+
const evm = provider();
|
|
26903
|
+
if (!evm) throw new Error(options.noWalletMessage || "Install or open an EVM wallet to continue.");
|
|
26904
|
+
const currentAccounts = await evm.request({ method: "eth_accounts" }).catch(() => walletAddress ? [walletAddress] : []);
|
|
26905
|
+
const currentAddress = Array.isArray(currentAccounts) && currentAccounts[0] ? currentAccounts[0] : walletAddress || await connect();
|
|
26906
|
+
if (currentAddress !== walletAddress) walletAddress = currentAddress;
|
|
26907
|
+
const gatewayWallet = await createCircleGatewayBrowserAdapter2({
|
|
26908
|
+
network,
|
|
26909
|
+
signer: {
|
|
26910
|
+
address: currentAddress,
|
|
26911
|
+
signTypedData: async (typedData) => {
|
|
26912
|
+
const { createWalletClient: createWalletClient2, custom: custom2 } = await Promise.resolve().then(() => (init_esm(), esm_exports));
|
|
26913
|
+
const wc = createWalletClient2({ transport: custom2(evm) });
|
|
26914
|
+
return wc.signTypedData({
|
|
26915
|
+
account: currentAddress,
|
|
26916
|
+
domain: typedData.domain,
|
|
26917
|
+
types: typedData.types,
|
|
26918
|
+
primaryType: typedData.primaryType,
|
|
26919
|
+
message: typedData.message
|
|
26920
|
+
});
|
|
26921
|
+
}
|
|
26922
|
+
},
|
|
26923
|
+
clientModule: options.circleClientModule
|
|
26924
|
+
});
|
|
26925
|
+
return gatewayWallet.pay(input);
|
|
26926
|
+
}
|
|
26927
|
+
async function unlock() {
|
|
26928
|
+
setBusy(true);
|
|
26929
|
+
try {
|
|
26930
|
+
if (!walletAddress) await connect();
|
|
26931
|
+
setBusy(true);
|
|
26932
|
+
setStatus("Requesting Gateway unlock...");
|
|
26933
|
+
const result = await checkResourceAccess(item.resource, {
|
|
26934
|
+
accessPath,
|
|
26935
|
+
source,
|
|
26936
|
+
paymentProvider: options.paymentProvider || "circle-gateway-browser",
|
|
26937
|
+
challengeMessage: options.challengeMessage || "Gateway payment required. Connect your wallet to continue...",
|
|
26938
|
+
paymentMessage: options.paymentMessage || "Approve the Gateway payment proof in your wallet...",
|
|
26939
|
+
successMessage: options.successMessage || `Unlocked ${item.resource.title || "content"}.`,
|
|
26940
|
+
method: options.method,
|
|
26941
|
+
headers: options.headers,
|
|
26942
|
+
body: options.body,
|
|
26943
|
+
checkout,
|
|
26944
|
+
onStatus: setStatus
|
|
26945
|
+
});
|
|
26946
|
+
if (result.ok) {
|
|
26947
|
+
setUnlocked(true, result.payment || {});
|
|
26948
|
+
if (typeof options.onUnlock === "function") options.onUnlock(result);
|
|
26949
|
+
}
|
|
26950
|
+
return result;
|
|
26951
|
+
} catch (error) {
|
|
26952
|
+
const message = error?.message || "Unlock failed. Please try again.";
|
|
26953
|
+
setStatus(message);
|
|
26954
|
+
return { ok: false, status: 0, error: message, resource: item.resource };
|
|
26955
|
+
} finally {
|
|
26956
|
+
setBusy(false);
|
|
26957
|
+
renderWallet();
|
|
26958
|
+
}
|
|
26959
|
+
}
|
|
26960
|
+
function clear() {
|
|
26961
|
+
clearPaymentProof(item.resource);
|
|
26962
|
+
setUnlocked(false);
|
|
26963
|
+
setStatus("Local payment proof cleared. The next unlock will require Gateway payment again.");
|
|
26964
|
+
}
|
|
26965
|
+
async function hydrate() {
|
|
26966
|
+
const evm = provider();
|
|
26967
|
+
try {
|
|
26968
|
+
const accounts = evm ? await evm.request({ method: "eth_accounts" }) : [];
|
|
26969
|
+
walletAddress = Array.isArray(accounts) ? accounts[0] || "" : "";
|
|
26970
|
+
} catch {
|
|
26971
|
+
}
|
|
26972
|
+
renderWallet();
|
|
26973
|
+
setUnlocked(false);
|
|
26974
|
+
}
|
|
26975
|
+
function mount() {
|
|
26976
|
+
connectButton?.addEventListener?.("click", () => connect().catch((error) => setStatus(error?.message || "Could not connect wallet.")));
|
|
26977
|
+
disconnectButton?.addEventListener?.("click", () => disconnect().catch((error) => setStatus(error?.message || "Could not disconnect wallet.")));
|
|
26978
|
+
unlockButton?.addEventListener?.("click", () => unlock());
|
|
26979
|
+
clearButton?.addEventListener?.("click", clear);
|
|
26980
|
+
hydrate();
|
|
26981
|
+
trackResourcePage(item.resource, { source });
|
|
26982
|
+
return controller;
|
|
26983
|
+
}
|
|
26984
|
+
const controller = { resource: item.resource, connect, disconnect, unlock, clear, hydrate, mount, getWalletAddress: () => walletAddress };
|
|
26985
|
+
if (options.autoMount !== false) mount();
|
|
26986
|
+
return controller;
|
|
26987
|
+
}
|
|
26988
|
+
function createHostedUnlock(resource, options = {}) {
|
|
26989
|
+
return createEvmGatewayUnlock(resource, {
|
|
26990
|
+
...options,
|
|
26991
|
+
hosted: true,
|
|
26992
|
+
noWalletMessage: options.noWalletMessage || "Install MetaMask or another EVM wallet to unlock premium content."
|
|
26993
|
+
});
|
|
26994
|
+
}
|
|
26995
|
+
var HOSTED_PAY_URL;
|
|
26996
|
+
var init_evm_gateway = __esm({
|
|
26997
|
+
"src/browser/evm-gateway.js"() {
|
|
26998
|
+
init_env();
|
|
26999
|
+
init_storage();
|
|
27000
|
+
init_gate();
|
|
27001
|
+
init_access();
|
|
27002
|
+
init_track();
|
|
27003
|
+
HOSTED_PAY_URL = "https://api.nibgate.xyz/api/hub/pay";
|
|
27004
|
+
}
|
|
27005
|
+
});
|
|
27006
|
+
|
|
27007
|
+
// src/browser/reputation.js
|
|
27008
|
+
function stripHex(value = "") {
|
|
27009
|
+
return String(value || "").replace(/^0x/i, "").replace(/[^0-9a-fA-F]/g, "").toLowerCase();
|
|
27010
|
+
}
|
|
27011
|
+
function wordRight(hex = "") {
|
|
27012
|
+
const clean2 = stripHex(hex);
|
|
27013
|
+
if (clean2.length > 64) throw new Error("ABI word is too long.");
|
|
27014
|
+
return clean2.padEnd(64, "0");
|
|
27015
|
+
}
|
|
27016
|
+
function numberWord(value = 0) {
|
|
27017
|
+
return Number(value || 0).toString(16).padStart(64, "0");
|
|
27018
|
+
}
|
|
27019
|
+
function utf8Hex(value = "") {
|
|
27020
|
+
return Array.from(new TextEncoder().encode(String(value || ""))).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
27021
|
+
}
|
|
27022
|
+
function encodeString3(value = "") {
|
|
27023
|
+
const hex = utf8Hex(value);
|
|
27024
|
+
const byteLength = hex.length / 2;
|
|
27025
|
+
const paddedLength = Math.ceil(byteLength / 32) * 64;
|
|
27026
|
+
return numberWord(byteLength) + hex.padEnd(paddedLength, "0");
|
|
27027
|
+
}
|
|
27028
|
+
function encodeRateContent({ contentId, ratingValue, reviewHash, unlockRef }) {
|
|
27029
|
+
return RATE_CONTENT_SELECTOR + wordRight(contentId) + numberWord(ratingValue) + wordRight(reviewHash || ZERO_HASH) + numberWord(128) + encodeString3(unlockRef || "");
|
|
27030
|
+
}
|
|
27031
|
+
function contentRatingHash(_resource, options = {}) {
|
|
27032
|
+
const contentId = options.contentId || options.contentHash;
|
|
27033
|
+
if (!contentId) {
|
|
27034
|
+
throw new Error("contentId/contentHash is required. Use the Nibgate backend prepare endpoint or pass a known content hash.");
|
|
27035
|
+
}
|
|
27036
|
+
return contentId;
|
|
27037
|
+
}
|
|
27038
|
+
function reviewTextHash(review = "") {
|
|
27039
|
+
if (!review) return ZERO_HASH;
|
|
27040
|
+
throw new Error("Text review hashing is not available in direct-browser mode. Pass reviewHash from your app/backend.");
|
|
26638
27041
|
}
|
|
26639
27042
|
async function prepareOnchainRating(resource, options = {}) {
|
|
26640
27043
|
if (options.contentId || options.contentHash) return { contentId: options.contentId || options.contentHash };
|
|
@@ -26884,654 +27287,13 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
26884
27287
|
}
|
|
26885
27288
|
});
|
|
26886
27289
|
|
|
26887
|
-
// src/browser/
|
|
26888
|
-
var
|
|
26889
|
-
__export(
|
|
26890
|
-
ACCESS_MODES: () => ACCESS_MODES,
|
|
26891
|
-
CONTENT_TYPES: () => CONTENT_TYPES,
|
|
26892
|
-
NIBGATE_CONTENT_HASH_NAMESPACE: () => NIBGATE_CONTENT_HASH_NAMESPACE,
|
|
26893
|
-
NIBGATE_CONTENT_SETTING_FIELDS: () => NIBGATE_CONTENT_SETTING_FIELDS,
|
|
26894
|
-
NIBGATE_REPUTATION_ABI: () => NIBGATE_REPUTATION_ABI,
|
|
26895
|
-
NIBGATE_REPUTATION_CHAIN_ID: () => NIBGATE_REPUTATION_CHAIN_ID,
|
|
26896
|
-
NIBGATE_REPUTATION_CHAIN_NAME: () => NIBGATE_REPUTATION_CHAIN_NAME,
|
|
26897
|
-
NIBGATE_REPUTATION_CONTRACT: () => NIBGATE_REPUTATION_CONTRACT,
|
|
26898
|
-
NIBGATE_REPUTATION_RPC_URL: () => NIBGATE_REPUTATION_RPC_URL,
|
|
26899
|
-
PAYMENT_RAILS: () => PAYMENT_RAILS,
|
|
26900
|
-
UNLOCK_MODES: () => UNLOCK_MODES,
|
|
26901
|
-
checkResourceAccess: () => checkResourceAccess,
|
|
26902
|
-
contentRatingHash: () => contentRatingHash,
|
|
26903
|
-
createCircleGatewayBrowserAdapter: () => createCircleGatewayBrowserAdapter2,
|
|
26904
|
-
createEvmGatewayUnlock: () => createEvmGatewayUnlock,
|
|
26905
|
-
createGate: () => createGate,
|
|
26906
|
-
createHostedUnlock: () => createHostedUnlock,
|
|
26907
|
-
createNibgate: () => createNibgate,
|
|
26908
|
-
createNibgateContentSettings: () => createNibgateContentSettings,
|
|
26909
|
-
createOnchainRating: () => createOnchainRating,
|
|
26910
|
-
createTransferCheckout: () => createTransferCheckout,
|
|
26911
|
-
createWalletCheckout: () => createWalletCheckout,
|
|
26912
|
-
mountRatingUI: () => mountRatingUI,
|
|
26913
|
-
nibgate: () => nibgate,
|
|
26914
|
-
normalizeAccessPolicy: () => normalizeAccessPolicy,
|
|
26915
|
-
normalizeContentType: () => normalizeContentType,
|
|
26916
|
-
normalizePaymentRail: () => normalizePaymentRail,
|
|
26917
|
-
normalizeResource: () => normalizeResource,
|
|
26918
|
-
normalizeUnlockPolicy: () => normalizeUnlockPolicy,
|
|
26919
|
-
payAndUnlockResource: () => payAndUnlockResource,
|
|
26920
|
-
payWithPaymentSignature: () => payWithPaymentSignature,
|
|
26921
|
-
payWithTransfer: () => payWithTransfer,
|
|
26922
|
-
rateContentOnchain: () => rateContentOnchain,
|
|
26923
|
-
rateResource: () => rateResource,
|
|
27290
|
+
// src/browser/default-ui.js
|
|
27291
|
+
var default_ui_exports = {};
|
|
27292
|
+
__export(default_ui_exports, {
|
|
26924
27293
|
renderDefaultGatewayWalletUI: () => renderDefaultGatewayWalletUI,
|
|
26925
27294
|
renderDefaultRatingUI: () => renderDefaultRatingUI,
|
|
26926
|
-
renderDefaultUnlockUI: () => renderDefaultUnlockUI
|
|
26927
|
-
reviewTextHash: () => reviewTextHash,
|
|
26928
|
-
settingsToAccessPolicy: () => settingsToAccessPolicy,
|
|
26929
|
-
settingsToUnlockPolicy: () => settingsToUnlockPolicy,
|
|
26930
|
-
setupResourcePage: () => setupResourcePage,
|
|
26931
|
-
trackResourcePage: () => trackResourcePage,
|
|
26932
|
-
validateResourceMetadata: () => validateResourceMetadata
|
|
27295
|
+
renderDefaultUnlockUI: () => renderDefaultUnlockUI
|
|
26933
27296
|
});
|
|
26934
|
-
init_gate();
|
|
26935
|
-
|
|
26936
|
-
// src/browser/access.js
|
|
26937
|
-
init_events();
|
|
26938
|
-
init_storage();
|
|
26939
|
-
init_json();
|
|
26940
|
-
init_gate();
|
|
26941
|
-
|
|
26942
|
-
// src/browser/track.js
|
|
26943
|
-
init_resource();
|
|
26944
|
-
init_env();
|
|
26945
|
-
init_gate();
|
|
26946
|
-
function trackResourcePage(resource, options = {}) {
|
|
26947
|
-
const item = createGate(resource, options.gateOptions || {});
|
|
26948
|
-
const validation = validateResourceMetadata(item.resource, options.validation || {});
|
|
26949
|
-
if ((validation.warnings.length || validation.errors.length) && options.warn !== false && browserWindow()?.console?.warn) {
|
|
26950
|
-
browserWindow().console.warn("Nibgate content metadata needs attention", validation);
|
|
26951
|
-
}
|
|
26952
|
-
item.content({ source: options.source, metadataQuality: { score: validation.score, warnings: validation.warnings, errors: validation.errors }, ...options.content || {} });
|
|
26953
|
-
item.view({
|
|
26954
|
-
source: options.source,
|
|
26955
|
-
path: options.path || browserWindow()?.location?.pathname || item.resource.path,
|
|
26956
|
-
referrer: options.referrer ?? browserWindow()?.document?.referrer ?? "",
|
|
26957
|
-
...options.view || {}
|
|
26958
|
-
});
|
|
26959
|
-
return item;
|
|
26960
|
-
}
|
|
26961
|
-
function setupResourcePage(resource, options = {}) {
|
|
26962
|
-
const item = trackResourcePage(resource, options);
|
|
26963
|
-
const win = browserWindow();
|
|
26964
|
-
if (!win) return item;
|
|
26965
|
-
const button = typeof options.button === "string" ? win.document.querySelector(options.button) : options.button;
|
|
26966
|
-
const statusElement = typeof options.status === "string" ? win.document.querySelector(options.status) : options.status;
|
|
26967
|
-
const setStatus = options.onStatus || ((message) => {
|
|
26968
|
-
if (statusElement) statusElement.textContent = message || "";
|
|
26969
|
-
});
|
|
26970
|
-
if (button) {
|
|
26971
|
-
button.addEventListener("click", async () => {
|
|
26972
|
-
button.disabled = true;
|
|
26973
|
-
try {
|
|
26974
|
-
await checkResourceAccess(resource, { ...options, onStatus: setStatus });
|
|
26975
|
-
} finally {
|
|
26976
|
-
button.disabled = false;
|
|
26977
|
-
}
|
|
26978
|
-
});
|
|
26979
|
-
}
|
|
26980
|
-
return item;
|
|
26981
|
-
}
|
|
26982
|
-
|
|
26983
|
-
// src/browser/access.js
|
|
26984
|
-
async function checkResourceAccess(resource, options = {}) {
|
|
26985
|
-
const item = createGate(resource, options.gateOptions || {});
|
|
26986
|
-
const accessPath = options.accessPath || item.resource.accessPath || "/api/nibgate/access";
|
|
26987
|
-
const status2 = typeof options.onStatus === "function" ? options.onStatus : () => {
|
|
26988
|
-
};
|
|
26989
|
-
status2(options.checkingMessage || "Checking access route...");
|
|
26990
|
-
item.unlockStarted({ source: options.source, paymentProvider: options.paymentProvider || "nibgate-access-route" });
|
|
26991
|
-
const response = await fetch(accessPath, {
|
|
26992
|
-
method: options.method || "GET",
|
|
26993
|
-
headers: {
|
|
26994
|
-
accept: "application/json",
|
|
26995
|
-
...getPaymentProof(item.resource) ? { "x-nibgate-payment-proof": getPaymentProof(item.resource) } : {},
|
|
26996
|
-
...options.headers || {}
|
|
26997
|
-
},
|
|
26998
|
-
body: options.body
|
|
26999
|
-
});
|
|
27000
|
-
const payload = await response.json().catch(() => ({}));
|
|
27001
|
-
if (response.status === 402) {
|
|
27002
|
-
item.track("payment_challenge_returned", { source: options.source, challenge: payload, resource: item.resource });
|
|
27003
|
-
status2(options.challengeMessage || "Payment challenge returned. Continue with checkout.");
|
|
27004
|
-
if (typeof options.createPaymentSignature === "function" || typeof options.checkout === "function") {
|
|
27005
|
-
return payWithPaymentSignature(resource, {
|
|
27006
|
-
...options,
|
|
27007
|
-
challenge: payload,
|
|
27008
|
-
paymentRequiredHeader: response.headers.get("PAYMENT-REQUIRED") || response.headers.get("payment-required") || ""
|
|
27009
|
-
});
|
|
27010
|
-
}
|
|
27011
|
-
if (options.autoPay && options.payPath) {
|
|
27012
|
-
const paymentResult = await payAndUnlockResource(resource, options);
|
|
27013
|
-
if (paymentResult.ok && options.retryAfterPay !== false) {
|
|
27014
|
-
return checkResourceAccess(resource, { ...options, autoPay: false });
|
|
27015
|
-
}
|
|
27016
|
-
return paymentResult;
|
|
27017
|
-
}
|
|
27018
|
-
return { ok: false, status: response.status, challenge: payload, resource: item.resource, response };
|
|
27019
|
-
}
|
|
27020
|
-
if (!response.ok) {
|
|
27021
|
-
status2(payload.error || options.errorMessage || "Access check failed");
|
|
27022
|
-
return { ok: false, status: response.status, error: payload.error || "Access check failed", payload, resource: item.resource, response };
|
|
27023
|
-
}
|
|
27024
|
-
const payment = options.payment || payload.payment || null;
|
|
27025
|
-
if (payment) {
|
|
27026
|
-
item.unlockCompleted(payment);
|
|
27027
|
-
item.paymentCompleted(payment);
|
|
27028
|
-
}
|
|
27029
|
-
status2(options.successMessage || "Access allowed and Nibgate events emitted.");
|
|
27030
|
-
return { ok: true, status: response.status, payload, payment, resource: item.resource, response };
|
|
27031
|
-
}
|
|
27032
|
-
async function payWithPaymentSignature(resource, options = {}) {
|
|
27033
|
-
const item = createGate(resource, options.gateOptions || {});
|
|
27034
|
-
const accessPath = options.accessPath || item.resource.accessPath || "/api/nibgate/access";
|
|
27035
|
-
const status2 = typeof options.onStatus === "function" ? options.onStatus : () => {
|
|
27036
|
-
};
|
|
27037
|
-
status2(options.paymentMessage || "Waiting for wallet payment approval...");
|
|
27038
|
-
item.unlockStarted({ source: options.source, paymentProvider: options.paymentProvider || "wallet-gateway" });
|
|
27039
|
-
let paymentSignature = options.paymentSignature || "";
|
|
27040
|
-
let paymentMemo = options.memo || "";
|
|
27041
|
-
let paymentMetadata = options.payment || {};
|
|
27042
|
-
if (!paymentSignature) {
|
|
27043
|
-
const paymentRequiredHeader = options.paymentRequiredHeader || "";
|
|
27044
|
-
const challenge2 = options.challenge || null;
|
|
27045
|
-
const checkout = options.createPaymentSignature || options.checkout;
|
|
27046
|
-
const result = await checkout({
|
|
27047
|
-
resource: item.resource,
|
|
27048
|
-
challenge: challenge2,
|
|
27049
|
-
paymentRequiredHeader,
|
|
27050
|
-
accessPath
|
|
27051
|
-
});
|
|
27052
|
-
paymentSignature = result?.paymentSignature || result?.signature || result?.payment || "";
|
|
27053
|
-
paymentMemo = result?.memo || result?.paymentMemo || "";
|
|
27054
|
-
paymentMetadata = result?.metadata || result?.paymentMetadata || result || {};
|
|
27055
|
-
}
|
|
27056
|
-
if (!paymentSignature) {
|
|
27057
|
-
const error = "Wallet did not return a payment signature.";
|
|
27058
|
-
item.track("payment_failed", { source: options.source, error });
|
|
27059
|
-
status2(error);
|
|
27060
|
-
return { ok: false, status: 400, error, resource: item.resource };
|
|
27061
|
-
}
|
|
27062
|
-
const response = await fetch(accessPath, {
|
|
27063
|
-
method: options.method || "GET",
|
|
27064
|
-
headers: {
|
|
27065
|
-
accept: "application/json",
|
|
27066
|
-
"payment-signature": paymentSignature,
|
|
27067
|
-
...paymentMemo ? { "payment-memo": paymentMemo } : {},
|
|
27068
|
-
...options.headers || {}
|
|
27069
|
-
}
|
|
27070
|
-
});
|
|
27071
|
-
const responseText = await response.text();
|
|
27072
|
-
let payload = {};
|
|
27073
|
-
try {
|
|
27074
|
-
payload = responseText ? JSON.parse(responseText) : {};
|
|
27075
|
-
} catch (_error) {
|
|
27076
|
-
payload = { error: responseText || "Payment verification failed" };
|
|
27077
|
-
}
|
|
27078
|
-
if (!response.ok) {
|
|
27079
|
-
const detail = payload.detail || payload.reason || payload.invalidReason || payload.error || responseText || "Payment verification failed";
|
|
27080
|
-
const error = typeof detail === "string" ? detail : stringifyJson(detail);
|
|
27081
|
-
item.track("payment_failed", { source: options.source, status: response.status, error, ...paymentMetadata });
|
|
27082
|
-
status2(options.paymentErrorMessage || error);
|
|
27083
|
-
return { ok: false, status: response.status, error, payload, resource: item.resource, response };
|
|
27084
|
-
}
|
|
27085
|
-
const payment = payload.payment || {
|
|
27086
|
-
paymentProvider: options.paymentProvider || "wallet-gateway",
|
|
27087
|
-
paymentId: paymentSignature,
|
|
27088
|
-
memo: paymentMemo,
|
|
27089
|
-
amount: Number(item.resource.price || 0),
|
|
27090
|
-
revenue: Number(item.resource.price || 0),
|
|
27091
|
-
currency: item.resource.currency || "USDC",
|
|
27092
|
-
...paymentMetadata
|
|
27093
|
-
};
|
|
27094
|
-
storePaymentProof(item.resource, payload.unlockProof);
|
|
27095
|
-
item.markUnlocked(payment);
|
|
27096
|
-
status2(options.paymentSuccessMessage || "Payment verified. Content unlocked.");
|
|
27097
|
-
return { ok: true, status: response.status, payload, payment, resource: item.resource, response };
|
|
27098
|
-
}
|
|
27099
|
-
async function payAndUnlockResource(resource, options = {}) {
|
|
27100
|
-
const item = createGate(resource, options.gateOptions || {});
|
|
27101
|
-
const payPath = options.payPath || item.resource.payPath || "/api/nibgate/pay";
|
|
27102
|
-
const status2 = typeof options.onStatus === "function" ? options.onStatus : () => {
|
|
27103
|
-
};
|
|
27104
|
-
status2(options.paymentMessage || "Starting payment...");
|
|
27105
|
-
item.unlockStarted({ source: options.source, paymentProvider: options.paymentProvider || "circle-gateway" });
|
|
27106
|
-
const response = await fetch(payPath, {
|
|
27107
|
-
method: options.payMethod || "POST",
|
|
27108
|
-
headers: {
|
|
27109
|
-
accept: "application/json",
|
|
27110
|
-
"content-type": "application/json",
|
|
27111
|
-
...options.payHeaders || {}
|
|
27112
|
-
},
|
|
27113
|
-
body: JSON.stringify({ resource: item.resource, ...options.payPayload || {} })
|
|
27114
|
-
});
|
|
27115
|
-
const payload = await response.json().catch(() => ({}));
|
|
27116
|
-
if (!response.ok || !payload.ok) {
|
|
27117
|
-
item.track("payment_failed", { source: options.source, status: response.status, error: payload.error || "Payment failed", detail: payload.detail || "" });
|
|
27118
|
-
status2(payload.detail || payload.error || options.paymentErrorMessage || "Payment failed.");
|
|
27119
|
-
return { ok: false, status: response.status, payload, resource: item.resource, response };
|
|
27120
|
-
}
|
|
27121
|
-
const payment = payload.payment || {
|
|
27122
|
-
paymentProvider: options.paymentProvider || "circle-gateway",
|
|
27123
|
-
paymentId: payload.paymentId || `nibgate_payment_${Date.now()}`,
|
|
27124
|
-
amount: Number(item.resource.price || 0),
|
|
27125
|
-
revenue: Number(item.resource.price || 0),
|
|
27126
|
-
currency: item.resource.currency || "USDC"
|
|
27127
|
-
};
|
|
27128
|
-
storePaymentProof(item.resource, payload.unlockProof);
|
|
27129
|
-
item.markUnlocked(payment);
|
|
27130
|
-
status2(options.paymentSuccessMessage || "Payment verified. Content unlocked.");
|
|
27131
|
-
return { ok: true, status: response.status, payload, payment, resource: item.resource, response };
|
|
27132
|
-
}
|
|
27133
|
-
|
|
27134
|
-
// src/browser/checkout.js
|
|
27135
|
-
init_resource();
|
|
27136
|
-
init_env();
|
|
27137
|
-
function setElementText(target, message) {
|
|
27138
|
-
const win = browserWindow();
|
|
27139
|
-
if (!target || !win) return;
|
|
27140
|
-
const element = typeof target === "string" ? win.document.querySelector(target) : target;
|
|
27141
|
-
if (element) element.textContent = message || "";
|
|
27142
|
-
}
|
|
27143
|
-
function setElementDisabled(target, disabled) {
|
|
27144
|
-
const win = browserWindow();
|
|
27145
|
-
if (!target || !win) return;
|
|
27146
|
-
const element = typeof target === "string" ? win.document.querySelector(target) : target;
|
|
27147
|
-
if (element && "disabled" in element) element.disabled = Boolean(disabled);
|
|
27148
|
-
}
|
|
27149
|
-
function createWalletCheckout(resource, options = {}) {
|
|
27150
|
-
const normalized = normalizeResource(resource);
|
|
27151
|
-
const accessPath = options.accessPath || normalized.accessPath || "/api/nibgate/access";
|
|
27152
|
-
const button = options.button || null;
|
|
27153
|
-
const statusTarget = options.status || null;
|
|
27154
|
-
const status2 = typeof options.onStatus === "function" ? options.onStatus : (message) => setElementText(statusTarget, message);
|
|
27155
|
-
const checkout = options.checkout || options.createPaymentSignature || options.pay;
|
|
27156
|
-
if (typeof checkout !== "function") {
|
|
27157
|
-
throw new Error("createWalletCheckout requires checkout/createPaymentSignature/pay callback for the active wallet or Gateway adapter.");
|
|
27158
|
-
}
|
|
27159
|
-
async function unlock(extra = {}) {
|
|
27160
|
-
setElementDisabled(button, true);
|
|
27161
|
-
try {
|
|
27162
|
-
return await checkResourceAccess(normalized, {
|
|
27163
|
-
...options,
|
|
27164
|
-
...extra,
|
|
27165
|
-
accessPath,
|
|
27166
|
-
createPaymentSignature: checkout,
|
|
27167
|
-
onStatus: status2
|
|
27168
|
-
});
|
|
27169
|
-
} finally {
|
|
27170
|
-
setElementDisabled(button, false);
|
|
27171
|
-
}
|
|
27172
|
-
}
|
|
27173
|
-
function mount() {
|
|
27174
|
-
const win = browserWindow();
|
|
27175
|
-
if (!win || !button) return { unlock };
|
|
27176
|
-
const element = typeof button === "string" ? win.document.querySelector(button) : button;
|
|
27177
|
-
if (element) element.addEventListener("click", () => unlock().catch((error) => status2(error.message || "Checkout failed.")));
|
|
27178
|
-
return { unlock };
|
|
27179
|
-
}
|
|
27180
|
-
return { resource: normalized, unlock, mount };
|
|
27181
|
-
}
|
|
27182
|
-
|
|
27183
|
-
// src/browser/client.js
|
|
27184
|
-
init_resource();
|
|
27185
|
-
init_rating();
|
|
27186
|
-
init_events();
|
|
27187
|
-
init_gate();
|
|
27188
|
-
init_gate();
|
|
27189
|
-
|
|
27190
|
-
// src/browser/evm-gateway.js
|
|
27191
|
-
init_env();
|
|
27192
|
-
init_storage();
|
|
27193
|
-
init_gate();
|
|
27194
|
-
async function createCircleGatewayBrowserAdapter2(options = {}) {
|
|
27195
|
-
const gateway = await Promise.resolve().then(() => (init_gateway(), gateway_exports));
|
|
27196
|
-
return gateway.createCircleGatewayBrowserAdapter(options);
|
|
27197
|
-
}
|
|
27198
|
-
var HOSTED_PAY_URL = "https://api.nibgate.xyz/api/hub/pay";
|
|
27199
|
-
function resolveAccessPath(resource, options) {
|
|
27200
|
-
if (options.hosted || options.accessPath === "hosted") return HOSTED_PAY_URL;
|
|
27201
|
-
return options.accessPath || resource.accessPath || "/api/nibgate/access";
|
|
27202
|
-
}
|
|
27203
|
-
function createEvmGatewayUnlock(resource, options = {}) {
|
|
27204
|
-
const item = createGate(resource, options.gateOptions || {});
|
|
27205
|
-
const win = browserWindow();
|
|
27206
|
-
const accessPath = resolveAccessPath(item.resource, options);
|
|
27207
|
-
const source = options.source || "nibgate-evm-gateway";
|
|
27208
|
-
const network = options.network || "eip155:5042002";
|
|
27209
|
-
const statusTarget = typeof options.status === "string" ? win?.document.querySelector(options.status) : options.status;
|
|
27210
|
-
const connectButton = typeof options.connectButton === "string" ? win?.document.querySelector(options.connectButton) : options.connectButton;
|
|
27211
|
-
const disconnectButton = typeof options.disconnectButton === "string" ? win?.document.querySelector(options.disconnectButton) : options.disconnectButton;
|
|
27212
|
-
const unlockButton = typeof options.unlockButton === "string" ? win?.document.querySelector(options.unlockButton) : options.unlockButton;
|
|
27213
|
-
const clearButton = typeof options.clearButton === "string" ? win?.document.querySelector(options.clearButton) : options.clearButton;
|
|
27214
|
-
const walletLabel = typeof options.walletLabel === "string" ? win?.document.querySelector(options.walletLabel) : options.walletLabel;
|
|
27215
|
-
const unlockedTarget = typeof options.unlockedTarget === "string" ? win?.document.querySelector(options.unlockedTarget) : options.unlockedTarget;
|
|
27216
|
-
let walletAddress = "";
|
|
27217
|
-
let busy = false;
|
|
27218
|
-
function setStatus(message) {
|
|
27219
|
-
if (typeof options.onStatus === "function") options.onStatus(message);
|
|
27220
|
-
if (statusTarget) statusTarget.textContent = message || "";
|
|
27221
|
-
}
|
|
27222
|
-
function shortAddress(address) {
|
|
27223
|
-
return address ? `${address.slice(0, 6)}...${address.slice(-4)}` : "";
|
|
27224
|
-
}
|
|
27225
|
-
function provider() {
|
|
27226
|
-
return win?.ethereum || options.provider || null;
|
|
27227
|
-
}
|
|
27228
|
-
function setBusy(value) {
|
|
27229
|
-
busy = Boolean(value);
|
|
27230
|
-
[connectButton, disconnectButton, unlockButton, clearButton].forEach((button) => {
|
|
27231
|
-
if (button && "disabled" in button) {
|
|
27232
|
-
button.disabled = busy || button === connectButton && !provider() || button === disconnectButton && !walletAddress;
|
|
27233
|
-
}
|
|
27234
|
-
});
|
|
27235
|
-
}
|
|
27236
|
-
function renderWallet() {
|
|
27237
|
-
const hasProvider = Boolean(provider());
|
|
27238
|
-
if (walletLabel) walletLabel.textContent = walletAddress ? shortAddress(walletAddress) : hasProvider ? "Ready to connect" : "No wallet detected";
|
|
27239
|
-
if (connectButton) connectButton.textContent = walletAddress ? "Connected" : "Connect wallet";
|
|
27240
|
-
if (disconnectButton) disconnectButton.textContent = "Disconnect";
|
|
27241
|
-
if (connectButton && "disabled" in connectButton) connectButton.disabled = busy || !hasProvider;
|
|
27242
|
-
if (disconnectButton && "disabled" in disconnectButton) disconnectButton.disabled = busy || !walletAddress;
|
|
27243
|
-
}
|
|
27244
|
-
function setUnlocked(isUnlocked, payment = {}) {
|
|
27245
|
-
if (unlockButton) unlockButton.textContent = isUnlocked ? "Unlocked" : `Unlock for ${item.resource.price} ${item.resource.currency || "USDC"}`;
|
|
27246
|
-
if (unlockedTarget) {
|
|
27247
|
-
if ("hidden" in unlockedTarget) unlockedTarget.hidden = !isUnlocked;
|
|
27248
|
-
unlockedTarget.setAttribute("aria-hidden", isUnlocked ? "false" : "true");
|
|
27249
|
-
}
|
|
27250
|
-
if (isUnlocked) item.markUnlocked(payment);
|
|
27251
|
-
}
|
|
27252
|
-
async function connect() {
|
|
27253
|
-
setBusy(true);
|
|
27254
|
-
setStatus("Opening wallet connection...");
|
|
27255
|
-
try {
|
|
27256
|
-
const evm = provider();
|
|
27257
|
-
if (!evm) throw new Error(options.noWalletMessage || "Install or open an EVM wallet to continue.");
|
|
27258
|
-
const accounts = await evm.request({ method: "eth_requestAccounts" });
|
|
27259
|
-
walletAddress = Array.isArray(accounts) ? accounts[0] || "" : "";
|
|
27260
|
-
if (!walletAddress) throw new Error("No wallet account selected.");
|
|
27261
|
-
renderWallet();
|
|
27262
|
-
setStatus("Wallet connected. You can unlock now.");
|
|
27263
|
-
return walletAddress;
|
|
27264
|
-
} finally {
|
|
27265
|
-
setBusy(false);
|
|
27266
|
-
}
|
|
27267
|
-
}
|
|
27268
|
-
async function disconnect() {
|
|
27269
|
-
setBusy(true);
|
|
27270
|
-
try {
|
|
27271
|
-
const evm = provider();
|
|
27272
|
-
if (evm?.request && walletAddress) {
|
|
27273
|
-
try {
|
|
27274
|
-
await evm.request({ method: "wallet_revokePermissions", params: [{ eth_accounts: {} }] });
|
|
27275
|
-
} catch (_error) {
|
|
27276
|
-
}
|
|
27277
|
-
}
|
|
27278
|
-
walletAddress = "";
|
|
27279
|
-
renderWallet();
|
|
27280
|
-
setStatus(options.disconnectMessage || "Wallet disconnected for this page.");
|
|
27281
|
-
return true;
|
|
27282
|
-
} finally {
|
|
27283
|
-
setBusy(false);
|
|
27284
|
-
}
|
|
27285
|
-
}
|
|
27286
|
-
async function checkout(input) {
|
|
27287
|
-
const evm = provider();
|
|
27288
|
-
if (!evm) throw new Error(options.noWalletMessage || "Install or open an EVM wallet to continue.");
|
|
27289
|
-
const currentAccounts = await evm.request({ method: "eth_accounts" }).catch(() => walletAddress ? [walletAddress] : []);
|
|
27290
|
-
const currentAddress = Array.isArray(currentAccounts) && currentAccounts[0] ? currentAccounts[0] : walletAddress || await connect();
|
|
27291
|
-
if (currentAddress !== walletAddress) walletAddress = currentAddress;
|
|
27292
|
-
const gatewayWallet = await createCircleGatewayBrowserAdapter2({
|
|
27293
|
-
network,
|
|
27294
|
-
signer: {
|
|
27295
|
-
address: currentAddress,
|
|
27296
|
-
signTypedData: async (typedData) => {
|
|
27297
|
-
const { createWalletClient: createWalletClient2, custom: custom2 } = await Promise.resolve().then(() => (init_esm(), esm_exports));
|
|
27298
|
-
const wc = createWalletClient2({ transport: custom2(evm) });
|
|
27299
|
-
return wc.signTypedData({
|
|
27300
|
-
account: currentAddress,
|
|
27301
|
-
domain: typedData.domain,
|
|
27302
|
-
types: typedData.types,
|
|
27303
|
-
primaryType: typedData.primaryType,
|
|
27304
|
-
message: typedData.message
|
|
27305
|
-
});
|
|
27306
|
-
}
|
|
27307
|
-
},
|
|
27308
|
-
clientModule: options.circleClientModule
|
|
27309
|
-
});
|
|
27310
|
-
return gatewayWallet.pay(input);
|
|
27311
|
-
}
|
|
27312
|
-
async function unlock() {
|
|
27313
|
-
setBusy(true);
|
|
27314
|
-
try {
|
|
27315
|
-
if (!walletAddress) await connect();
|
|
27316
|
-
setBusy(true);
|
|
27317
|
-
setStatus("Requesting Gateway unlock...");
|
|
27318
|
-
const result = await checkResourceAccess(item.resource, {
|
|
27319
|
-
accessPath,
|
|
27320
|
-
source,
|
|
27321
|
-
paymentProvider: options.paymentProvider || "circle-gateway-browser",
|
|
27322
|
-
challengeMessage: options.challengeMessage || "Gateway payment required. Connect your wallet to continue...",
|
|
27323
|
-
paymentMessage: options.paymentMessage || "Approve the Gateway payment proof in your wallet...",
|
|
27324
|
-
successMessage: options.successMessage || `Unlocked ${item.resource.title || "content"}.`,
|
|
27325
|
-
method: options.method,
|
|
27326
|
-
headers: options.headers,
|
|
27327
|
-
body: options.body,
|
|
27328
|
-
checkout,
|
|
27329
|
-
onStatus: setStatus
|
|
27330
|
-
});
|
|
27331
|
-
if (result.ok) {
|
|
27332
|
-
setUnlocked(true, result.payment || {});
|
|
27333
|
-
if (typeof options.onUnlock === "function") options.onUnlock(result);
|
|
27334
|
-
}
|
|
27335
|
-
return result;
|
|
27336
|
-
} catch (error) {
|
|
27337
|
-
const message = error?.message || "Unlock failed. Please try again.";
|
|
27338
|
-
setStatus(message);
|
|
27339
|
-
return { ok: false, status: 0, error: message, resource: item.resource };
|
|
27340
|
-
} finally {
|
|
27341
|
-
setBusy(false);
|
|
27342
|
-
renderWallet();
|
|
27343
|
-
}
|
|
27344
|
-
}
|
|
27345
|
-
function clear() {
|
|
27346
|
-
clearPaymentProof(item.resource);
|
|
27347
|
-
setUnlocked(false);
|
|
27348
|
-
setStatus("Local payment proof cleared. The next unlock will require Gateway payment again.");
|
|
27349
|
-
}
|
|
27350
|
-
async function hydrate() {
|
|
27351
|
-
const evm = provider();
|
|
27352
|
-
try {
|
|
27353
|
-
const accounts = evm ? await evm.request({ method: "eth_accounts" }) : [];
|
|
27354
|
-
walletAddress = Array.isArray(accounts) ? accounts[0] || "" : "";
|
|
27355
|
-
} catch {
|
|
27356
|
-
}
|
|
27357
|
-
renderWallet();
|
|
27358
|
-
setUnlocked(false);
|
|
27359
|
-
}
|
|
27360
|
-
function mount() {
|
|
27361
|
-
connectButton?.addEventListener?.("click", () => connect().catch((error) => setStatus(error?.message || "Could not connect wallet.")));
|
|
27362
|
-
disconnectButton?.addEventListener?.("click", () => disconnect().catch((error) => setStatus(error?.message || "Could not disconnect wallet.")));
|
|
27363
|
-
unlockButton?.addEventListener?.("click", () => unlock());
|
|
27364
|
-
clearButton?.addEventListener?.("click", clear);
|
|
27365
|
-
hydrate();
|
|
27366
|
-
trackResourcePage(item.resource, { source });
|
|
27367
|
-
return controller;
|
|
27368
|
-
}
|
|
27369
|
-
const controller = { resource: item.resource, connect, disconnect, unlock, clear, hydrate, mount, getWalletAddress: () => walletAddress };
|
|
27370
|
-
if (options.autoMount !== false) mount();
|
|
27371
|
-
return controller;
|
|
27372
|
-
}
|
|
27373
|
-
function createHostedUnlock(resource, options = {}) {
|
|
27374
|
-
return createEvmGatewayUnlock(resource, {
|
|
27375
|
-
...options,
|
|
27376
|
-
hosted: true,
|
|
27377
|
-
noWalletMessage: options.noWalletMessage || "Install MetaMask or another EVM wallet to unlock premium content."
|
|
27378
|
-
});
|
|
27379
|
-
}
|
|
27380
|
-
|
|
27381
|
-
// src/browser/client.js
|
|
27382
|
-
init_rating_ui();
|
|
27383
|
-
|
|
27384
|
-
// src/browser/transfer.js
|
|
27385
|
-
init_resource();
|
|
27386
|
-
function createTransferCheckout(resource, options = {}) {
|
|
27387
|
-
const normalized = normalizeResource({ ...resource, paymentRail: "transfer" });
|
|
27388
|
-
const sendTransfer = options.sendTransfer || options.transfer;
|
|
27389
|
-
if (typeof sendTransfer !== "function") {
|
|
27390
|
-
throw new Error("createTransferCheckout requires sendTransfer({ resource, recipient, amount, currency, network }) and a server verifyTransfer hook.");
|
|
27391
|
-
}
|
|
27392
|
-
return {
|
|
27393
|
-
resource: normalized,
|
|
27394
|
-
async pay(input = {}) {
|
|
27395
|
-
const recipient = normalized.recipient || normalized.payTo;
|
|
27396
|
-
const amount = String(normalized.price || normalized.amount || "0");
|
|
27397
|
-
const currency = normalized.currency || "USDC";
|
|
27398
|
-
const network = options.network || input.challenge?.accepts?.[0]?.network || "eip155:5042002";
|
|
27399
|
-
const result = await sendTransfer({ resource: normalized, recipient, amount, currency, network, challenge: input.challenge });
|
|
27400
|
-
const txHash = result?.txHash || result?.hash || result?.transactionHash || result?.paymentId || "";
|
|
27401
|
-
if (!txHash) throw new Error("Transfer checkout did not return a txHash.");
|
|
27402
|
-
return {
|
|
27403
|
-
paymentSignature: txHash,
|
|
27404
|
-
signature: txHash,
|
|
27405
|
-
memo: result.memo || "",
|
|
27406
|
-
metadata: {
|
|
27407
|
-
paymentProvider: "direct-transfer",
|
|
27408
|
-
paymentId: txHash,
|
|
27409
|
-
txHash,
|
|
27410
|
-
recipient,
|
|
27411
|
-
amount: Number(amount),
|
|
27412
|
-
currency,
|
|
27413
|
-
network,
|
|
27414
|
-
...result.metadata || result
|
|
27415
|
-
}
|
|
27416
|
-
};
|
|
27417
|
-
}
|
|
27418
|
-
};
|
|
27419
|
-
}
|
|
27420
|
-
async function payWithTransfer(resource, options = {}) {
|
|
27421
|
-
const checkout = options.checkout || createTransferCheckout(resource, options).pay;
|
|
27422
|
-
const result = await checkout({ resource: normalizeResource(resource), challenge: options.challenge || null });
|
|
27423
|
-
const txHash = result?.metadata?.txHash || result?.txHash || result?.paymentSignature || result?.signature || "";
|
|
27424
|
-
if (!txHash) throw new Error("Transfer checkout did not return a txHash.");
|
|
27425
|
-
return checkResourceAccess(resource, {
|
|
27426
|
-
...options,
|
|
27427
|
-
headers: {
|
|
27428
|
-
...options.headers || {},
|
|
27429
|
-
"x-nibgate-transfer-tx": txHash
|
|
27430
|
-
},
|
|
27431
|
-
payment: result.metadata || { paymentProvider: "direct-transfer", txHash, paymentId: txHash }
|
|
27432
|
-
});
|
|
27433
|
-
}
|
|
27434
|
-
|
|
27435
|
-
// src/browser/client.js
|
|
27436
|
-
function createNibgate(defaults = {}) {
|
|
27437
|
-
const defaultResource = defaults.resource ? normalizeResource(defaults.resource) : null;
|
|
27438
|
-
function resourceWithDefaults(resource = {}) {
|
|
27439
|
-
return normalizeResource({
|
|
27440
|
-
...defaultResource || {},
|
|
27441
|
-
...typeof resource === "string" ? { id: resource } : resource
|
|
27442
|
-
});
|
|
27443
|
-
}
|
|
27444
|
-
return {
|
|
27445
|
-
content(resource, extra = {}) {
|
|
27446
|
-
return emit("content_registered", payloadWithResource(resourceWithDefaults(resource), extra));
|
|
27447
|
-
},
|
|
27448
|
-
registerContent(resource, extra = {}) {
|
|
27449
|
-
return emit("content_registered", payloadWithResource(resourceWithDefaults(resource), extra));
|
|
27450
|
-
},
|
|
27451
|
-
view(resource, extra = {}) {
|
|
27452
|
-
return emit("resource_view", payloadWithResource(resourceWithDefaults(resource), extra));
|
|
27453
|
-
},
|
|
27454
|
-
track(eventName, payload = {}) {
|
|
27455
|
-
return emit(eventName || "custom", payload);
|
|
27456
|
-
},
|
|
27457
|
-
unlockStarted(resource, extra = {}) {
|
|
27458
|
-
return emit("unlock_started", payloadWithResource(resourceWithDefaults(resource), extra));
|
|
27459
|
-
},
|
|
27460
|
-
unlockCompleted(resource, payment = {}) {
|
|
27461
|
-
return emit("unlock_completed", payloadWithResource(resourceWithDefaults(resource), payment));
|
|
27462
|
-
},
|
|
27463
|
-
paymentCompleted(resource, payment = {}) {
|
|
27464
|
-
return emit("payment_completed", payloadWithResource(resourceWithDefaults(resource), payment));
|
|
27465
|
-
},
|
|
27466
|
-
rateResource(resource, rating = {}, extra = {}) {
|
|
27467
|
-
return rateResource(resourceWithDefaults(resource), rating, extra);
|
|
27468
|
-
},
|
|
27469
|
-
ratingMessage(resource, rating = {}, messageOptions = {}) {
|
|
27470
|
-
return ratingMessage(resourceWithDefaults(resource), rating, messageOptions);
|
|
27471
|
-
},
|
|
27472
|
-
gate(resource, options = {}) {
|
|
27473
|
-
return createGate(resourceWithDefaults(resource), { ...options, client: this });
|
|
27474
|
-
},
|
|
27475
|
-
trackResourcePage(resource, options = {}) {
|
|
27476
|
-
return trackResourcePage(resourceWithDefaults(resource), options);
|
|
27477
|
-
},
|
|
27478
|
-
checkResourceAccess(resource, options = {}) {
|
|
27479
|
-
return checkResourceAccess(resourceWithDefaults(resource), options);
|
|
27480
|
-
},
|
|
27481
|
-
payWithPaymentSignature(resource, options = {}) {
|
|
27482
|
-
return payWithPaymentSignature(resourceWithDefaults(resource), options);
|
|
27483
|
-
},
|
|
27484
|
-
createWalletCheckout(resource, options = {}) {
|
|
27485
|
-
return createWalletCheckout(resourceWithDefaults(resource), options);
|
|
27486
|
-
},
|
|
27487
|
-
createCircleGatewayBrowserAdapter(options = {}) {
|
|
27488
|
-
return createCircleGatewayBrowserAdapter2(options);
|
|
27489
|
-
},
|
|
27490
|
-
createTransferCheckout(resource, options = {}) {
|
|
27491
|
-
return createTransferCheckout(resourceWithDefaults(resource), options);
|
|
27492
|
-
},
|
|
27493
|
-
payWithTransfer(resource, options = {}) {
|
|
27494
|
-
return payWithTransfer(resourceWithDefaults(resource), options);
|
|
27495
|
-
},
|
|
27496
|
-
createEvmGatewayUnlock(resource, options = {}) {
|
|
27497
|
-
return createEvmGatewayUnlock(resourceWithDefaults(resource), options);
|
|
27498
|
-
},
|
|
27499
|
-
createOnchainRating(resource, options = {}) {
|
|
27500
|
-
return createOnchainRating(resourceWithDefaults(resource), options);
|
|
27501
|
-
},
|
|
27502
|
-
mountRatingUI(resource, options = {}) {
|
|
27503
|
-
return mountRatingUI(resourceWithDefaults(resource), options);
|
|
27504
|
-
},
|
|
27505
|
-
payAndUnlockResource(resource, options = {}) {
|
|
27506
|
-
return payAndUnlockResource(resourceWithDefaults(resource), options);
|
|
27507
|
-
},
|
|
27508
|
-
setupResourcePage(resource, options = {}) {
|
|
27509
|
-
return setupResourcePage(resourceWithDefaults(resource), options);
|
|
27510
|
-
},
|
|
27511
|
-
normalizeResource: resourceWithDefaults,
|
|
27512
|
-
normalizeContentType,
|
|
27513
|
-
flush: flushQueue
|
|
27514
|
-
};
|
|
27515
|
-
}
|
|
27516
|
-
var nibgate = createNibgate();
|
|
27517
|
-
setDefaultClient(nibgate);
|
|
27518
|
-
|
|
27519
|
-
// src/browser/index.js
|
|
27520
|
-
init_rating_ui();
|
|
27521
|
-
init_reputation();
|
|
27522
|
-
|
|
27523
|
-
// src/browser/default-ui.js
|
|
27524
|
-
var SID = "nibgate-ui-styles";
|
|
27525
|
-
var theme = {
|
|
27526
|
-
bg: "var(--bg, #f4f4f0)",
|
|
27527
|
-
fg: "var(--fg, #0a0a0a)",
|
|
27528
|
-
muted: "var(--muted, #6b6862)",
|
|
27529
|
-
border: "var(--border, #cecdc3)",
|
|
27530
|
-
accent: "var(--accent, #7c9a6d)",
|
|
27531
|
-
accentSoft: "var(--accent-soft, #d8e8d3)",
|
|
27532
|
-
cardHover: "var(--card-hover, #e0ddd3)"
|
|
27533
|
-
};
|
|
27534
|
-
var css = (s) => Object.entries(s).map(([k, v]) => `${k.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase())}:${v}`).join(";");
|
|
27535
27297
|
function h(tag, attrs, children) {
|
|
27536
27298
|
const e = document.createElement(tag);
|
|
27537
27299
|
for (const [k, v] of Object.entries(attrs || {})) {
|
|
@@ -27552,7 +27314,6 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
27552
27314
|
const s = h("style", { id: SID }, `
|
|
27553
27315
|
@keyframes nfade { from { opacity:0;transform:translateY(6px) } to { opacity:1;transform:translateY(0) } }
|
|
27554
27316
|
@keyframes nscale { from { opacity:0;transform:scale(0.96) } to { opacity:1;transform:scale(1) } }
|
|
27555
|
-
@keyframes nshimmer { 0% { transform:translateX(-100%) } 100% { transform:translateX(100%) } }
|
|
27556
27317
|
|
|
27557
27318
|
.nui { font-family:var(--font-content,'Kumbh Sans','ABC Favorit',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif);color:${theme.fg};line-height:1.5;-webkit-font-smoothing:antialiased;font-size:19px }
|
|
27558
27319
|
.nui *,.nui *::before,.nui *::after { box-sizing:border-box }
|
|
@@ -27582,74 +27343,25 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
27582
27343
|
if (!el2) return;
|
|
27583
27344
|
el2.textContent = msg || "";
|
|
27584
27345
|
}
|
|
27585
|
-
function esc(s) {
|
|
27586
|
-
const d = document.createElement("div");
|
|
27587
|
-
d.textContent = String(s ?? "");
|
|
27588
|
-
return d.innerHTML;
|
|
27589
|
-
}
|
|
27590
27346
|
function renderDefaultUnlockUI(container, resource, options = {}) {
|
|
27591
27347
|
inject();
|
|
27592
27348
|
const card = el("div", { cls: "nui", style: { animation: "nfade .2s ease-out" } });
|
|
27593
|
-
const
|
|
27349
|
+
const unlockSVG = '<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:6px"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 9.9-1"/></svg>';
|
|
27594
27350
|
card.innerHTML = `
|
|
27595
|
-
<div style="display:flex;flex-direction:column;align-items:center;text-align:center;max-width:
|
|
27596
|
-
<div
|
|
27597
|
-
<div style="
|
|
27598
|
-
|
|
27599
|
-
|
|
27600
|
-
<div
|
|
27601
|
-
<div data-nibgate-unlock-progress style="position:absolute;inset:0;width:0%;background:linear-gradient(90deg,rgba(255,255,255,0.1),rgba(255,255,255,0.45));border-radius:12px;transition:width .05s linear;z-index:2"></div>
|
|
27602
|
-
<div data-nibgate-shimmer style="position:absolute;inset:0;width:100%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,0.12),transparent);border-radius:12px;transform:translateX(-100%);z-index:3;pointer-events:none"></div>
|
|
27603
|
-
<button type="button" data-nibgate-unlock disabled class="nui-btn nui-btn-primary" style="width:100%;padding:24px 32px;font-size:24px;position:relative;z-index:4;background:${theme.accent};transition:transform .1s,opacity .15s;display:flex">${lockSVG}Hold to pay ${esc(resource.price)} USDC</button></div>
|
|
27604
|
-
<div class="nui-stat" style="text-align:center;margin-top:16px" data-nibgate-status></div>
|
|
27351
|
+
<div style="display:flex;flex-direction:column;align-items:center;text-align:center;max-width:420px;margin:0 auto;padding:24px 20px">
|
|
27352
|
+
<div data-nibgate-wallet-label class="nui-mono" style="font-size:15px;color:${theme.muted};margin-bottom:16px;min-height:24px">Connect wallet</div>
|
|
27353
|
+
<div data-nibgate-unlock-wrap style="width:100%;position:relative;border-radius:10px;overflow:hidden;cursor:pointer">
|
|
27354
|
+
<div data-nibgate-unlock-progress style="position:absolute;inset:0;width:0%;background:${theme.accent};opacity:0.15;border-radius:10px;transition:width .05s linear;z-index:2"></div>
|
|
27355
|
+
<button type="button" data-nibgate-unlock disabled style="width:100%;padding:12px 0;font-size:16px;font-weight:500;line-height:19px;border:0;border-radius:10px;outline:none;cursor:pointer;position:relative;z-index:4;color:${theme.accent};background:rgba(124,154,109,0.08);transition:box-shadow .3s,transform .3s;font-family:inherit">${unlockSVG}Hold to pay</button></div>
|
|
27356
|
+
<div class="nui-stat" style="text-align:center;margin-top:12px" data-nibgate-status></div>
|
|
27605
27357
|
</div>
|
|
27606
|
-
<div data-nibgate-premium hidden style="margin-top:
|
|
27358
|
+
<div data-nibgate-premium hidden style="margin-top:24px;border-top:1px solid ${theme.border};padding-top:24px">${options.premiumContentHTML || ""}</div>
|
|
27607
27359
|
`;
|
|
27608
|
-
(typeof container === "string" ? document.querySelector(container) : container)?.appendChild(card);
|
|
27609
|
-
(function loadLottie() {
|
|
27610
|
-
if (!document.getElementById("nibgate-lottie")) return;
|
|
27611
|
-
function startAnim(data) {
|
|
27612
|
-
var d = document.getElementById("nibgate-lottie");
|
|
27613
|
-
if (d && window.lottie) {
|
|
27614
|
-
window.lottie.loadAnimation({ container: d, animationData: data, loop: true, autoplay: true });
|
|
27615
|
-
}
|
|
27616
|
-
}
|
|
27617
|
-
if (window.lottie) {
|
|
27618
|
-
if (window._lottieData) {
|
|
27619
|
-
startAnim(window._lottieData);
|
|
27620
|
-
} else {
|
|
27621
|
-
fetch("/nibgate-unlock-key.json?t=1").then(function(r) {
|
|
27622
|
-
if (!r.ok) throw new Error();
|
|
27623
|
-
return r.json();
|
|
27624
|
-
}).then(function(d) {
|
|
27625
|
-
window._lottieData = d;
|
|
27626
|
-
startAnim(d);
|
|
27627
|
-
}).catch(function() {
|
|
27628
|
-
});
|
|
27629
|
-
}
|
|
27630
|
-
return;
|
|
27631
|
-
}
|
|
27632
|
-
if (window._lottieLoading) return;
|
|
27633
|
-
window._lottieLoading = true;
|
|
27634
|
-
var s = document.createElement("script");
|
|
27635
|
-
s.src = "https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js";
|
|
27636
|
-
s.onload = function() {
|
|
27637
|
-
fetch("/nibgate-unlock-key.json?t=1").then(function(r) {
|
|
27638
|
-
if (!r.ok) throw new Error();
|
|
27639
|
-
return r.json();
|
|
27640
|
-
}).then(function(d) {
|
|
27641
|
-
window._lottieData = d;
|
|
27642
|
-
startAnim(d);
|
|
27643
|
-
}).catch(function() {
|
|
27644
|
-
});
|
|
27645
|
-
};
|
|
27646
|
-
document.head.appendChild(s);
|
|
27647
|
-
})();
|
|
27360
|
+
(typeof container === "string" ? document.querySelector(container) : container)?.appendChild(card);
|
|
27648
27361
|
const st = card.querySelector("[data-nibgate-status]");
|
|
27649
27362
|
const label = card.querySelector("[data-nibgate-wallet-label]");
|
|
27650
27363
|
const wrap3 = card.querySelector("[data-nibgate-unlock-wrap]");
|
|
27651
27364
|
const prog = card.querySelector("[data-nibgate-unlock-progress]");
|
|
27652
|
-
const shimmer = card.querySelector("[data-nibgate-shimmer]");
|
|
27653
27365
|
const btn = card.querySelector("[data-nibgate-unlock]");
|
|
27654
27366
|
const HOLD_MS = 1500;
|
|
27655
27367
|
let holdTimer = null, holdActive = false, holdComplete = false;
|
|
@@ -27688,21 +27400,20 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
27688
27400
|
label.textContent = "Connect wallet";
|
|
27689
27401
|
btn.disabled = true;
|
|
27690
27402
|
btn.style.cursor = "default";
|
|
27691
|
-
btn.innerHTML =
|
|
27403
|
+
btn.innerHTML = unlockSVG + "Hold to pay";
|
|
27692
27404
|
}
|
|
27693
27405
|
}
|
|
27694
27406
|
function setBtnText(t) {
|
|
27695
|
-
btn.innerHTML =
|
|
27407
|
+
btn.innerHTML = unlockSVG + t;
|
|
27696
27408
|
}
|
|
27697
27409
|
function resetHold() {
|
|
27698
27410
|
holdActive = false;
|
|
27699
27411
|
holdComplete = false;
|
|
27700
27412
|
holdTimer = null;
|
|
27701
27413
|
btn.style.transform = "scale(1)";
|
|
27414
|
+
btn.style.boxShadow = "0 4px 12px rgba(0,0,0,0.08)";
|
|
27702
27415
|
prog.style.width = "0%";
|
|
27703
|
-
|
|
27704
|
-
shimmer.style.transform = "translateX(-100%)";
|
|
27705
|
-
if (!btn.disabled) setBtnText("Hold to pay " + esc(resource.price) + " USDC");
|
|
27416
|
+
if (!btn.disabled) setBtnText("Hold to pay");
|
|
27706
27417
|
}
|
|
27707
27418
|
function startHold(e) {
|
|
27708
27419
|
if (btn.disabled || holdActive) return;
|
|
@@ -27710,28 +27421,19 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
27710
27421
|
holdActive = true;
|
|
27711
27422
|
holdComplete = false;
|
|
27712
27423
|
btn.style.transform = "scale(.97)";
|
|
27424
|
+
btn.style.boxShadow = "0 2px 6px rgba(0,0,0,0.12)";
|
|
27713
27425
|
prog.style.transition = "none";
|
|
27714
27426
|
prog.style.width = "0%";
|
|
27715
|
-
shimmer.style.animation = "nshimmer 1s ease-in-out infinite";
|
|
27716
|
-
shimmer.style.transform = "none";
|
|
27717
27427
|
setBtnText("Hold\u2026");
|
|
27718
27428
|
requestAnimationFrame(() => {
|
|
27719
27429
|
prog.style.transition = "width " + HOLD_MS + "ms linear";
|
|
27720
27430
|
prog.style.width = "100%";
|
|
27721
27431
|
});
|
|
27722
|
-
const t1 = setTimeout(() => {
|
|
27723
|
-
if (holdActive && !holdComplete) setBtnText("Keep holding\u2026");
|
|
27724
|
-
}, HOLD_MS * 0.4);
|
|
27725
|
-
const t2 = setTimeout(() => {
|
|
27726
|
-
if (holdActive && !holdComplete) setBtnText("Almost there\u2026");
|
|
27727
|
-
}, HOLD_MS * 0.75);
|
|
27728
27432
|
holdTimer = setTimeout(() => {
|
|
27729
27433
|
holdComplete = true;
|
|
27730
27434
|
holdActive = false;
|
|
27731
|
-
clearTimeout(t1);
|
|
27732
|
-
clearTimeout(t2);
|
|
27733
27435
|
btn.style.transform = "scale(1)";
|
|
27734
|
-
|
|
27436
|
+
btn.style.boxShadow = "0 4px 12px rgba(0,0,0,0.08)";
|
|
27735
27437
|
prog.style.transition = "width .05s linear";
|
|
27736
27438
|
setBtnText("Processing\u2026");
|
|
27737
27439
|
btn.disabled = true;
|
|
@@ -27761,9 +27463,70 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
27761
27463
|
document.removeEventListener("touchend", cancelHold);
|
|
27762
27464
|
};
|
|
27763
27465
|
card.addEventListener("remove", cleanup);
|
|
27466
|
+
let gwOverlayEl = null;
|
|
27467
|
+
let balTimer = null;
|
|
27468
|
+
let balEl = null;
|
|
27469
|
+
function depositIconHTML() {
|
|
27470
|
+
return '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:inline;vertical-align:baseline"><path d="M12 17V3"/><path d="m6 11 6 6 6-6"/><path d="M19 21H5"/></svg>';
|
|
27471
|
+
}
|
|
27472
|
+
async function showGatewayWallet() {
|
|
27473
|
+
if (gwOverlayEl) return;
|
|
27474
|
+
gwOverlayEl = el("div", { style: "position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center;padding:20px;animation:nfade .15s ease-out" });
|
|
27475
|
+
const modal = el("div", { style: "background:" + theme.bg + ";border-radius:16px;max-width:540px;width:100%;max-height:90vh;overflow:auto;position:relative;box-shadow:0 8px 32px rgba(0,0,0,0.12);animation:nscale .15s ease-out" });
|
|
27476
|
+
const close = el("button", { style: "position:absolute;top:12px;right:16px;z-index:20;background:none;border:none;font-size:28px;cursor:pointer;color:" + theme.muted + ";font-family:inherit;line-height:1" }, "\xD7");
|
|
27477
|
+
close.addEventListener("click", closeGatewayWallet);
|
|
27478
|
+
modal.appendChild(close);
|
|
27479
|
+
gwOverlayEl.appendChild(modal);
|
|
27480
|
+
gwOverlayEl.addEventListener("click", (e) => {
|
|
27481
|
+
if (e.target === gwOverlayEl) closeGatewayWallet();
|
|
27482
|
+
});
|
|
27483
|
+
document.body.appendChild(gwOverlayEl);
|
|
27484
|
+
document.addEventListener("keydown", onGwKey);
|
|
27485
|
+
const gw = await Promise.resolve().then(() => (init_default_ui(), default_ui_exports));
|
|
27486
|
+
gw.renderDefaultGatewayWalletUI(modal, options.gatewayOptions || {});
|
|
27487
|
+
}
|
|
27488
|
+
function closeGatewayWallet() {
|
|
27489
|
+
if (!gwOverlayEl) return;
|
|
27490
|
+
gwOverlayEl.remove();
|
|
27491
|
+
gwOverlayEl = null;
|
|
27492
|
+
document.removeEventListener("keydown", onGwKey);
|
|
27493
|
+
}
|
|
27494
|
+
function onGwKey(e) {
|
|
27495
|
+
if (e.key === "Escape") closeGatewayWallet();
|
|
27496
|
+
}
|
|
27497
|
+
function ensureBalEl() {
|
|
27498
|
+
if (balEl && balEl.isConnected) return balEl;
|
|
27499
|
+
balEl = el("span", { "data-nibgate-bal": "", style: "margin-left:6px;cursor:pointer;white-space:nowrap" }, depositIconHTML() + " <span data-nibgate-bal-text></span>");
|
|
27500
|
+
balEl.addEventListener("click", showGatewayWallet);
|
|
27501
|
+
if (label.parentNode) label.parentNode.insertBefore(balEl, label.nextSibling);
|
|
27502
|
+
return balEl;
|
|
27503
|
+
}
|
|
27504
|
+
async function refreshBalance() {
|
|
27505
|
+
if (stateRef?.destroyed) return;
|
|
27506
|
+
const addr = ctrl.getWalletAddress();
|
|
27507
|
+
if (!addr) return;
|
|
27508
|
+
const txt = ensureBalEl().querySelector("[data-nibgate-bal-text]");
|
|
27509
|
+
if (options.gatewayBalanceUrl) {
|
|
27510
|
+
try {
|
|
27511
|
+
const res = await fetch(options.gatewayBalanceUrl + "?address=" + encodeURIComponent(addr));
|
|
27512
|
+
const data = await res.json();
|
|
27513
|
+
if (txt) txt.textContent = data?.balance || data?.availableBalance || "\u2026";
|
|
27514
|
+
return;
|
|
27515
|
+
} catch {
|
|
27516
|
+
}
|
|
27517
|
+
}
|
|
27518
|
+
if (txt) txt.textContent = "\u2026";
|
|
27519
|
+
}
|
|
27520
|
+
if (window.ethereum) {
|
|
27521
|
+
balTimer = setInterval(refreshBalance, 3e3);
|
|
27522
|
+
setTimeout(refreshBalance, 1e3);
|
|
27523
|
+
window.ethereum.on("accountsChanged", refreshBalance);
|
|
27524
|
+
}
|
|
27764
27525
|
return { ...ctrl, element: card, destroy: () => {
|
|
27765
27526
|
cleanup();
|
|
27766
27527
|
card.remove();
|
|
27528
|
+
if (balTimer) clearInterval(balTimer);
|
|
27529
|
+
closeGatewayWallet();
|
|
27767
27530
|
} };
|
|
27768
27531
|
}
|
|
27769
27532
|
function renderDefaultRatingUI(container, resource, options = {}) {
|
|
@@ -27965,8 +27728,276 @@ ${prettyStateOverride(stateOverride)}`;
|
|
|
27965
27728
|
tabs.forEach((b) => b.addEventListener("click", () => render(b.dataset.tab)));
|
|
27966
27729
|
return { element: wrap3, destroy: () => wrap3.remove(), switchTab: render };
|
|
27967
27730
|
}
|
|
27731
|
+
var SID, theme, css;
|
|
27732
|
+
var init_default_ui = __esm({
|
|
27733
|
+
"src/browser/default-ui.js"() {
|
|
27734
|
+
init_evm_gateway();
|
|
27735
|
+
SID = "nibgate-ui-styles";
|
|
27736
|
+
theme = {
|
|
27737
|
+
bg: "var(--bg, #f4f4f0)",
|
|
27738
|
+
fg: "var(--fg, #0a0a0a)",
|
|
27739
|
+
muted: "var(--muted, #6b6862)",
|
|
27740
|
+
border: "var(--border, #cecdc3)",
|
|
27741
|
+
accent: "var(--accent, #7c9a6d)",
|
|
27742
|
+
accentSoft: "var(--accent-soft, #d8e8d3)",
|
|
27743
|
+
cardHover: "var(--card-hover, #e0ddd3)"
|
|
27744
|
+
};
|
|
27745
|
+
css = (s) => Object.entries(s).map(([k, v]) => `${k.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase())}:${v}`).join(";");
|
|
27746
|
+
}
|
|
27747
|
+
});
|
|
27748
|
+
|
|
27749
|
+
// src/browser/index.js
|
|
27750
|
+
var index_exports = {};
|
|
27751
|
+
__export(index_exports, {
|
|
27752
|
+
ACCESS_MODES: () => ACCESS_MODES,
|
|
27753
|
+
CONTENT_TYPES: () => CONTENT_TYPES,
|
|
27754
|
+
NIBGATE_CONTENT_HASH_NAMESPACE: () => NIBGATE_CONTENT_HASH_NAMESPACE,
|
|
27755
|
+
NIBGATE_CONTENT_SETTING_FIELDS: () => NIBGATE_CONTENT_SETTING_FIELDS,
|
|
27756
|
+
NIBGATE_REPUTATION_ABI: () => NIBGATE_REPUTATION_ABI,
|
|
27757
|
+
NIBGATE_REPUTATION_CHAIN_ID: () => NIBGATE_REPUTATION_CHAIN_ID,
|
|
27758
|
+
NIBGATE_REPUTATION_CHAIN_NAME: () => NIBGATE_REPUTATION_CHAIN_NAME,
|
|
27759
|
+
NIBGATE_REPUTATION_CONTRACT: () => NIBGATE_REPUTATION_CONTRACT,
|
|
27760
|
+
NIBGATE_REPUTATION_RPC_URL: () => NIBGATE_REPUTATION_RPC_URL,
|
|
27761
|
+
PAYMENT_RAILS: () => PAYMENT_RAILS,
|
|
27762
|
+
UNLOCK_MODES: () => UNLOCK_MODES,
|
|
27763
|
+
checkResourceAccess: () => checkResourceAccess,
|
|
27764
|
+
contentRatingHash: () => contentRatingHash,
|
|
27765
|
+
createCircleGatewayBrowserAdapter: () => createCircleGatewayBrowserAdapter2,
|
|
27766
|
+
createEvmGatewayUnlock: () => createEvmGatewayUnlock,
|
|
27767
|
+
createGate: () => createGate,
|
|
27768
|
+
createHostedUnlock: () => createHostedUnlock,
|
|
27769
|
+
createNibgate: () => createNibgate,
|
|
27770
|
+
createNibgateContentSettings: () => createNibgateContentSettings,
|
|
27771
|
+
createOnchainRating: () => createOnchainRating,
|
|
27772
|
+
createTransferCheckout: () => createTransferCheckout,
|
|
27773
|
+
createWalletCheckout: () => createWalletCheckout,
|
|
27774
|
+
mountRatingUI: () => mountRatingUI,
|
|
27775
|
+
nibgate: () => nibgate,
|
|
27776
|
+
normalizeAccessPolicy: () => normalizeAccessPolicy,
|
|
27777
|
+
normalizeContentType: () => normalizeContentType,
|
|
27778
|
+
normalizePaymentRail: () => normalizePaymentRail,
|
|
27779
|
+
normalizeResource: () => normalizeResource,
|
|
27780
|
+
normalizeUnlockPolicy: () => normalizeUnlockPolicy,
|
|
27781
|
+
payAndUnlockResource: () => payAndUnlockResource,
|
|
27782
|
+
payWithPaymentSignature: () => payWithPaymentSignature,
|
|
27783
|
+
payWithTransfer: () => payWithTransfer,
|
|
27784
|
+
rateContentOnchain: () => rateContentOnchain,
|
|
27785
|
+
rateResource: () => rateResource,
|
|
27786
|
+
renderDefaultGatewayWalletUI: () => renderDefaultGatewayWalletUI,
|
|
27787
|
+
renderDefaultRatingUI: () => renderDefaultRatingUI,
|
|
27788
|
+
renderDefaultUnlockUI: () => renderDefaultUnlockUI,
|
|
27789
|
+
reviewTextHash: () => reviewTextHash,
|
|
27790
|
+
settingsToAccessPolicy: () => settingsToAccessPolicy,
|
|
27791
|
+
settingsToUnlockPolicy: () => settingsToUnlockPolicy,
|
|
27792
|
+
setupResourcePage: () => setupResourcePage,
|
|
27793
|
+
trackResourcePage: () => trackResourcePage,
|
|
27794
|
+
validateResourceMetadata: () => validateResourceMetadata
|
|
27795
|
+
});
|
|
27796
|
+
init_gate();
|
|
27797
|
+
init_access();
|
|
27798
|
+
|
|
27799
|
+
// src/browser/checkout.js
|
|
27800
|
+
init_resource();
|
|
27801
|
+
init_env();
|
|
27802
|
+
init_access();
|
|
27803
|
+
function setElementText(target, message) {
|
|
27804
|
+
const win = browserWindow();
|
|
27805
|
+
if (!target || !win) return;
|
|
27806
|
+
const element = typeof target === "string" ? win.document.querySelector(target) : target;
|
|
27807
|
+
if (element) element.textContent = message || "";
|
|
27808
|
+
}
|
|
27809
|
+
function setElementDisabled(target, disabled) {
|
|
27810
|
+
const win = browserWindow();
|
|
27811
|
+
if (!target || !win) return;
|
|
27812
|
+
const element = typeof target === "string" ? win.document.querySelector(target) : target;
|
|
27813
|
+
if (element && "disabled" in element) element.disabled = Boolean(disabled);
|
|
27814
|
+
}
|
|
27815
|
+
function createWalletCheckout(resource, options = {}) {
|
|
27816
|
+
const normalized = normalizeResource(resource);
|
|
27817
|
+
const accessPath = options.accessPath || normalized.accessPath || "/api/nibgate/access";
|
|
27818
|
+
const button = options.button || null;
|
|
27819
|
+
const statusTarget = options.status || null;
|
|
27820
|
+
const status2 = typeof options.onStatus === "function" ? options.onStatus : (message) => setElementText(statusTarget, message);
|
|
27821
|
+
const checkout = options.checkout || options.createPaymentSignature || options.pay;
|
|
27822
|
+
if (typeof checkout !== "function") {
|
|
27823
|
+
throw new Error("createWalletCheckout requires checkout/createPaymentSignature/pay callback for the active wallet or Gateway adapter.");
|
|
27824
|
+
}
|
|
27825
|
+
async function unlock(extra = {}) {
|
|
27826
|
+
setElementDisabled(button, true);
|
|
27827
|
+
try {
|
|
27828
|
+
return await checkResourceAccess(normalized, {
|
|
27829
|
+
...options,
|
|
27830
|
+
...extra,
|
|
27831
|
+
accessPath,
|
|
27832
|
+
createPaymentSignature: checkout,
|
|
27833
|
+
onStatus: status2
|
|
27834
|
+
});
|
|
27835
|
+
} finally {
|
|
27836
|
+
setElementDisabled(button, false);
|
|
27837
|
+
}
|
|
27838
|
+
}
|
|
27839
|
+
function mount() {
|
|
27840
|
+
const win = browserWindow();
|
|
27841
|
+
if (!win || !button) return { unlock };
|
|
27842
|
+
const element = typeof button === "string" ? win.document.querySelector(button) : button;
|
|
27843
|
+
if (element) element.addEventListener("click", () => unlock().catch((error) => status2(error.message || "Checkout failed.")));
|
|
27844
|
+
return { unlock };
|
|
27845
|
+
}
|
|
27846
|
+
return { resource: normalized, unlock, mount };
|
|
27847
|
+
}
|
|
27848
|
+
|
|
27849
|
+
// src/browser/client.js
|
|
27850
|
+
init_resource();
|
|
27851
|
+
init_rating();
|
|
27852
|
+
init_events();
|
|
27853
|
+
init_gate();
|
|
27854
|
+
init_gate();
|
|
27855
|
+
init_access();
|
|
27856
|
+
init_evm_gateway();
|
|
27857
|
+
init_rating_ui();
|
|
27858
|
+
init_track();
|
|
27859
|
+
|
|
27860
|
+
// src/browser/transfer.js
|
|
27861
|
+
init_resource();
|
|
27862
|
+
function createTransferCheckout(resource, options = {}) {
|
|
27863
|
+
const normalized = normalizeResource({ ...resource, paymentRail: "transfer" });
|
|
27864
|
+
const sendTransfer = options.sendTransfer || options.transfer;
|
|
27865
|
+
if (typeof sendTransfer !== "function") {
|
|
27866
|
+
throw new Error("createTransferCheckout requires sendTransfer({ resource, recipient, amount, currency, network }) and a server verifyTransfer hook.");
|
|
27867
|
+
}
|
|
27868
|
+
return {
|
|
27869
|
+
resource: normalized,
|
|
27870
|
+
async pay(input = {}) {
|
|
27871
|
+
const recipient = normalized.recipient || normalized.payTo;
|
|
27872
|
+
const amount = String(normalized.price || normalized.amount || "0");
|
|
27873
|
+
const currency = normalized.currency || "USDC";
|
|
27874
|
+
const network = options.network || input.challenge?.accepts?.[0]?.network || "eip155:5042002";
|
|
27875
|
+
const result = await sendTransfer({ resource: normalized, recipient, amount, currency, network, challenge: input.challenge });
|
|
27876
|
+
const txHash = result?.txHash || result?.hash || result?.transactionHash || result?.paymentId || "";
|
|
27877
|
+
if (!txHash) throw new Error("Transfer checkout did not return a txHash.");
|
|
27878
|
+
return {
|
|
27879
|
+
paymentSignature: txHash,
|
|
27880
|
+
signature: txHash,
|
|
27881
|
+
memo: result.memo || "",
|
|
27882
|
+
metadata: {
|
|
27883
|
+
paymentProvider: "direct-transfer",
|
|
27884
|
+
paymentId: txHash,
|
|
27885
|
+
txHash,
|
|
27886
|
+
recipient,
|
|
27887
|
+
amount: Number(amount),
|
|
27888
|
+
currency,
|
|
27889
|
+
network,
|
|
27890
|
+
...result.metadata || result
|
|
27891
|
+
}
|
|
27892
|
+
};
|
|
27893
|
+
}
|
|
27894
|
+
};
|
|
27895
|
+
}
|
|
27896
|
+
async function payWithTransfer(resource, options = {}) {
|
|
27897
|
+
const checkout = options.checkout || createTransferCheckout(resource, options).pay;
|
|
27898
|
+
const result = await checkout({ resource: normalizeResource(resource), challenge: options.challenge || null });
|
|
27899
|
+
const txHash = result?.metadata?.txHash || result?.txHash || result?.paymentSignature || result?.signature || "";
|
|
27900
|
+
if (!txHash) throw new Error("Transfer checkout did not return a txHash.");
|
|
27901
|
+
return checkResourceAccess(resource, {
|
|
27902
|
+
...options,
|
|
27903
|
+
headers: {
|
|
27904
|
+
...options.headers || {},
|
|
27905
|
+
"x-nibgate-transfer-tx": txHash
|
|
27906
|
+
},
|
|
27907
|
+
payment: result.metadata || { paymentProvider: "direct-transfer", txHash, paymentId: txHash }
|
|
27908
|
+
});
|
|
27909
|
+
}
|
|
27910
|
+
|
|
27911
|
+
// src/browser/client.js
|
|
27912
|
+
function createNibgate(defaults = {}) {
|
|
27913
|
+
const defaultResource = defaults.resource ? normalizeResource(defaults.resource) : null;
|
|
27914
|
+
function resourceWithDefaults(resource = {}) {
|
|
27915
|
+
return normalizeResource({
|
|
27916
|
+
...defaultResource || {},
|
|
27917
|
+
...typeof resource === "string" ? { id: resource } : resource
|
|
27918
|
+
});
|
|
27919
|
+
}
|
|
27920
|
+
return {
|
|
27921
|
+
content(resource, extra = {}) {
|
|
27922
|
+
return emit("content_registered", payloadWithResource(resourceWithDefaults(resource), extra));
|
|
27923
|
+
},
|
|
27924
|
+
registerContent(resource, extra = {}) {
|
|
27925
|
+
return emit("content_registered", payloadWithResource(resourceWithDefaults(resource), extra));
|
|
27926
|
+
},
|
|
27927
|
+
view(resource, extra = {}) {
|
|
27928
|
+
return emit("resource_view", payloadWithResource(resourceWithDefaults(resource), extra));
|
|
27929
|
+
},
|
|
27930
|
+
track(eventName, payload = {}) {
|
|
27931
|
+
return emit(eventName || "custom", payload);
|
|
27932
|
+
},
|
|
27933
|
+
unlockStarted(resource, extra = {}) {
|
|
27934
|
+
return emit("unlock_started", payloadWithResource(resourceWithDefaults(resource), extra));
|
|
27935
|
+
},
|
|
27936
|
+
unlockCompleted(resource, payment = {}) {
|
|
27937
|
+
return emit("unlock_completed", payloadWithResource(resourceWithDefaults(resource), payment));
|
|
27938
|
+
},
|
|
27939
|
+
paymentCompleted(resource, payment = {}) {
|
|
27940
|
+
return emit("payment_completed", payloadWithResource(resourceWithDefaults(resource), payment));
|
|
27941
|
+
},
|
|
27942
|
+
rateResource(resource, rating = {}, extra = {}) {
|
|
27943
|
+
return rateResource(resourceWithDefaults(resource), rating, extra);
|
|
27944
|
+
},
|
|
27945
|
+
ratingMessage(resource, rating = {}, messageOptions = {}) {
|
|
27946
|
+
return ratingMessage(resourceWithDefaults(resource), rating, messageOptions);
|
|
27947
|
+
},
|
|
27948
|
+
gate(resource, options = {}) {
|
|
27949
|
+
return createGate(resourceWithDefaults(resource), { ...options, client: this });
|
|
27950
|
+
},
|
|
27951
|
+
trackResourcePage(resource, options = {}) {
|
|
27952
|
+
return trackResourcePage(resourceWithDefaults(resource), options);
|
|
27953
|
+
},
|
|
27954
|
+
checkResourceAccess(resource, options = {}) {
|
|
27955
|
+
return checkResourceAccess(resourceWithDefaults(resource), options);
|
|
27956
|
+
},
|
|
27957
|
+
payWithPaymentSignature(resource, options = {}) {
|
|
27958
|
+
return payWithPaymentSignature(resourceWithDefaults(resource), options);
|
|
27959
|
+
},
|
|
27960
|
+
createWalletCheckout(resource, options = {}) {
|
|
27961
|
+
return createWalletCheckout(resourceWithDefaults(resource), options);
|
|
27962
|
+
},
|
|
27963
|
+
createCircleGatewayBrowserAdapter(options = {}) {
|
|
27964
|
+
return createCircleGatewayBrowserAdapter2(options);
|
|
27965
|
+
},
|
|
27966
|
+
createTransferCheckout(resource, options = {}) {
|
|
27967
|
+
return createTransferCheckout(resourceWithDefaults(resource), options);
|
|
27968
|
+
},
|
|
27969
|
+
payWithTransfer(resource, options = {}) {
|
|
27970
|
+
return payWithTransfer(resourceWithDefaults(resource), options);
|
|
27971
|
+
},
|
|
27972
|
+
createEvmGatewayUnlock(resource, options = {}) {
|
|
27973
|
+
return createEvmGatewayUnlock(resourceWithDefaults(resource), options);
|
|
27974
|
+
},
|
|
27975
|
+
createOnchainRating(resource, options = {}) {
|
|
27976
|
+
return createOnchainRating(resourceWithDefaults(resource), options);
|
|
27977
|
+
},
|
|
27978
|
+
mountRatingUI(resource, options = {}) {
|
|
27979
|
+
return mountRatingUI(resourceWithDefaults(resource), options);
|
|
27980
|
+
},
|
|
27981
|
+
payAndUnlockResource(resource, options = {}) {
|
|
27982
|
+
return payAndUnlockResource(resourceWithDefaults(resource), options);
|
|
27983
|
+
},
|
|
27984
|
+
setupResourcePage(resource, options = {}) {
|
|
27985
|
+
return setupResourcePage(resourceWithDefaults(resource), options);
|
|
27986
|
+
},
|
|
27987
|
+
normalizeResource: resourceWithDefaults,
|
|
27988
|
+
normalizeContentType,
|
|
27989
|
+
flush: flushQueue
|
|
27990
|
+
};
|
|
27991
|
+
}
|
|
27992
|
+
var nibgate = createNibgate();
|
|
27993
|
+
setDefaultClient(nibgate);
|
|
27968
27994
|
|
|
27969
27995
|
// src/browser/index.js
|
|
27996
|
+
init_evm_gateway();
|
|
27997
|
+
init_rating_ui();
|
|
27998
|
+
init_track();
|
|
27999
|
+
init_reputation();
|
|
28000
|
+
init_default_ui();
|
|
27970
28001
|
init_resource();
|
|
27971
28002
|
|
|
27972
28003
|
// src/core/settings.js
|