@nibgate/sdk 0.2.0 → 0.2.2
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/SKILL.md +215 -18
- package/dist/nibgate.js +352 -362
- package/dist/nibgate.js.map +4 -4
- package/dist/nibgate.min.js +2 -2
- package/dist/nibgate.min.js.map +4 -4
- package/package.json +6 -3
- package/src/browser/access.js +168 -0
- package/src/browser/checkout.js +53 -0
- package/src/browser/client.js +97 -0
- package/src/browser/evm-gateway.js +180 -0
- package/src/browser/gate.js +63 -0
- package/src/browser/index.js +9 -770
- package/src/browser/rating-ui.js +161 -0
- package/src/browser/track.js +45 -0
- package/src/server/access.js +22 -32
- package/src/server/admin-page.html +168 -0
- package/src/server/admin.js +18 -180
- package/src/server/gateway.js +8 -3
- package/src/server/webhooks.js +2 -2
- package/src/server/runtime.js +0 -39
package/dist/nibgate.js
CHANGED
|
@@ -142,7 +142,6 @@ var Nibgate = (() => {
|
|
|
142
142
|
createOnchainRating: () => createOnchainRating,
|
|
143
143
|
createTransferCheckout: () => createTransferCheckout,
|
|
144
144
|
createWalletCheckout: () => createWalletCheckout,
|
|
145
|
-
gate: () => gate,
|
|
146
145
|
mountRatingUI: () => mountRatingUI,
|
|
147
146
|
nibgate: () => nibgate,
|
|
148
147
|
normalizeAccessPolicy: () => normalizeAccessPolicy,
|
|
@@ -293,31 +292,6 @@ var Nibgate = (() => {
|
|
|
293
292
|
};
|
|
294
293
|
}
|
|
295
294
|
|
|
296
|
-
// src/core/rating.js
|
|
297
|
-
function normalizeRating(input = {}) {
|
|
298
|
-
const value = typeof input === "number" ? input : input.rating ?? input.stars ?? input.ratingValue ?? input.score;
|
|
299
|
-
const numeric = Number.parseFloat(value);
|
|
300
|
-
const ratingValue = Number.isFinite(numeric) ? Math.max(1, Math.min(50, numeric <= 5 ? Math.round(numeric * 10) : Math.round(numeric))) : null;
|
|
301
|
-
return {
|
|
302
|
-
...input,
|
|
303
|
-
rating: ratingValue ? ratingValue / 10 : void 0,
|
|
304
|
-
ratingValue: ratingValue || void 0
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
function ratingMessage(resource, rating = {}, options = {}) {
|
|
308
|
-
const normalized = normalizeResource(resource);
|
|
309
|
-
const normalizedRating = normalizeRating(rating);
|
|
310
|
-
const value = normalizedRating.ratingValue || 0;
|
|
311
|
-
return [
|
|
312
|
-
"Nibgate content rating",
|
|
313
|
-
`site:${options.siteDomain || options.domain || normalized.siteDomain || normalized.domain || ""}`,
|
|
314
|
-
`content:${normalized.externalId || normalized.id}`,
|
|
315
|
-
`url:${normalized.url || options.url || ""}`,
|
|
316
|
-
`rating:${value}`,
|
|
317
|
-
"I confirm this rating is tied to my unlock/payment proof."
|
|
318
|
-
].join("\n");
|
|
319
|
-
}
|
|
320
|
-
|
|
321
295
|
// src/browser/env.js
|
|
322
296
|
function browserWindow() {
|
|
323
297
|
return typeof window === "undefined" ? null : window;
|
|
@@ -435,241 +409,14 @@ var Nibgate = (() => {
|
|
|
435
409
|
}
|
|
436
410
|
}
|
|
437
411
|
|
|
438
|
-
// src/browser/
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
var RATE_CONTENT_SELECTOR = "0xc62fad09";
|
|
443
|
-
var ZERO_HASH = `0x${"0".repeat(64)}`;
|
|
444
|
-
var NIBGATE_CONTENT_HASH_NAMESPACE = "nibgate:content:v1";
|
|
445
|
-
var NIBGATE_REPUTATION_CHAIN_ID = 5042002;
|
|
446
|
-
var NIBGATE_REPUTATION_CHAIN_NAME = "Arc Testnet";
|
|
447
|
-
var NIBGATE_REPUTATION_RPC_URL = "https://rpc.testnet.arc.network";
|
|
448
|
-
var NIBGATE_REPUTATION_CONTRACT = "0x9f27fd62e75f86a3c7addfdba443aab1f930e281";
|
|
449
|
-
var NIBGATE_REPUTATION_ABI = [
|
|
450
|
-
{
|
|
451
|
-
type: "function",
|
|
452
|
-
name: "rateContent",
|
|
453
|
-
stateMutability: "nonpayable",
|
|
454
|
-
inputs: [
|
|
455
|
-
{ name: "contentId", type: "bytes32" },
|
|
456
|
-
{ name: "rating", type: "uint8" },
|
|
457
|
-
{ name: "reviewHash", type: "bytes32" },
|
|
458
|
-
{ name: "unlockRef", type: "string" }
|
|
459
|
-
],
|
|
460
|
-
outputs: []
|
|
461
|
-
}
|
|
462
|
-
];
|
|
463
|
-
function stripHex(value = "") {
|
|
464
|
-
return String(value || "").replace(/^0x/i, "").toLowerCase();
|
|
465
|
-
}
|
|
466
|
-
function wordRight(hex = "") {
|
|
467
|
-
const clean = stripHex(hex);
|
|
468
|
-
if (clean.length > 64) throw new Error("ABI word is too long.");
|
|
469
|
-
return clean.padEnd(64, "0");
|
|
470
|
-
}
|
|
471
|
-
function numberWord(value = 0) {
|
|
472
|
-
return Number(value || 0).toString(16).padStart(64, "0");
|
|
473
|
-
}
|
|
474
|
-
function utf8Hex(value = "") {
|
|
475
|
-
return Array.from(new TextEncoder().encode(String(value || ""))).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
476
|
-
}
|
|
477
|
-
function encodeString(value = "") {
|
|
478
|
-
const hex = utf8Hex(value);
|
|
479
|
-
const byteLength = hex.length / 2;
|
|
480
|
-
const paddedLength = Math.ceil(byteLength / 32) * 64;
|
|
481
|
-
return numberWord(byteLength) + hex.padEnd(paddedLength, "0");
|
|
482
|
-
}
|
|
483
|
-
function encodeRateContent({ contentId, ratingValue, reviewHash, unlockRef }) {
|
|
484
|
-
return RATE_CONTENT_SELECTOR + wordRight(contentId) + numberWord(ratingValue) + wordRight(reviewHash || ZERO_HASH) + numberWord(128) + encodeString(unlockRef || "");
|
|
485
|
-
}
|
|
486
|
-
function contentRatingHash(_resource, options = {}) {
|
|
487
|
-
const contentId = options.contentId || options.contentHash;
|
|
488
|
-
if (!contentId) {
|
|
489
|
-
throw new Error("contentId/contentHash is required. Use the Nibgate backend prepare endpoint or pass a known content hash.");
|
|
490
|
-
}
|
|
491
|
-
return contentId;
|
|
492
|
-
}
|
|
493
|
-
function reviewTextHash(review = "") {
|
|
494
|
-
if (!review) return ZERO_HASH;
|
|
495
|
-
throw new Error("Text review hashing is not available in direct-browser mode. Pass reviewHash from your app/backend.");
|
|
496
|
-
}
|
|
497
|
-
async function prepareOnchainRating(resource, options = {}) {
|
|
498
|
-
if (options.contentId || options.contentHash) return { contentId: options.contentId || options.contentHash };
|
|
499
|
-
const prepareUrl = options.prepareUrl || options.indexUrl?.replace(/\/index$/, "/prepare");
|
|
500
|
-
if (!prepareUrl) throw new Error("contentId/contentHash or prepareUrl is required for onchain rating.");
|
|
501
|
-
const response = await fetch(prepareUrl, {
|
|
502
|
-
method: "POST",
|
|
503
|
-
headers: { "content-type": "application/json", ...options.indexHeaders || {} },
|
|
504
|
-
body: JSON.stringify({
|
|
505
|
-
siteId: options.siteId,
|
|
506
|
-
token: options.token,
|
|
507
|
-
resource,
|
|
508
|
-
url: resource.url,
|
|
509
|
-
path: resource.path
|
|
510
|
-
})
|
|
511
|
-
});
|
|
512
|
-
const payload = await response.json().catch(() => ({}));
|
|
513
|
-
if (!response.ok || !payload.contentHash) throw new Error(payload.error || "Could not prepare Nibgate onchain rating.");
|
|
514
|
-
return payload;
|
|
515
|
-
}
|
|
516
|
-
async function rateContentOnchain(resource, options = {}) {
|
|
517
|
-
const normalized = normalizeResource(resource);
|
|
518
|
-
const rating = normalizeRating(options.rating ?? options.stars ?? options);
|
|
519
|
-
if (!rating.ratingValue) throw new Error("Rating must be between 0.1 and 5 stars.");
|
|
520
|
-
const provider = options.provider || globalThis?.ethereum;
|
|
521
|
-
if (!provider?.request) throw new Error("Connect an EVM wallet to rate this content onchain.");
|
|
522
|
-
const contractAddress = options.contractAddress || options.reputationContract || NIBGATE_REPUTATION_CONTRACT;
|
|
523
|
-
if (!contractAddress) throw new Error("Nibgate reputation contract address is not configured.");
|
|
524
|
-
const accounts = await provider.request({ method: "eth_requestAccounts" });
|
|
525
|
-
const walletAddress = Array.isArray(accounts) ? accounts[0] || "" : "";
|
|
526
|
-
if (!walletAddress) throw new Error("No wallet account selected.");
|
|
527
|
-
const prepared = await prepareOnchainRating(normalized, options);
|
|
528
|
-
const contentId = prepared.contentHash || prepared.contentId || contentRatingHash(normalized, options);
|
|
529
|
-
const reviewHash = options.reviewHash || ZERO_HASH;
|
|
530
|
-
const unlockRef = String(options.unlockRef || options.paymentId || options.txHash || "");
|
|
531
|
-
const data = encodeRateContent({ contentId, ratingValue: rating.ratingValue, reviewHash, unlockRef });
|
|
532
|
-
const txHash = await provider.request({
|
|
533
|
-
method: "eth_sendTransaction",
|
|
534
|
-
params: [{
|
|
535
|
-
from: walletAddress,
|
|
536
|
-
to: contractAddress,
|
|
537
|
-
data
|
|
538
|
-
}]
|
|
539
|
-
});
|
|
540
|
-
const payload = payloadWithResource(normalized, {
|
|
541
|
-
rating: rating.rating,
|
|
542
|
-
ratingValue: rating.ratingValue,
|
|
543
|
-
walletAddress,
|
|
544
|
-
txHash,
|
|
545
|
-
contentHash: contentId,
|
|
546
|
-
reviewHash,
|
|
547
|
-
proofType: "onchain_pending",
|
|
548
|
-
proof: unlockRef,
|
|
549
|
-
paymentId: options.paymentId,
|
|
550
|
-
actor: options.actor || "human"
|
|
551
|
-
});
|
|
552
|
-
emit("content_rating", payload);
|
|
553
|
-
if (options.indexUrl) {
|
|
554
|
-
await fetch(options.indexUrl, {
|
|
555
|
-
method: "POST",
|
|
556
|
-
headers: { "content-type": "application/json", ...options.indexHeaders || {} },
|
|
557
|
-
body: JSON.stringify({
|
|
558
|
-
siteId: options.siteId,
|
|
559
|
-
token: options.token,
|
|
560
|
-
txHash,
|
|
561
|
-
resource: normalized,
|
|
562
|
-
url: normalized.url,
|
|
563
|
-
path: normalized.path,
|
|
564
|
-
actor: options.actor || "human"
|
|
565
|
-
})
|
|
566
|
-
}).catch(() => null);
|
|
567
|
-
}
|
|
568
|
-
return { txHash, walletAddress, contentId, ratingValue: rating.ratingValue, reviewHash };
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// src/browser/transfer.js
|
|
572
|
-
function createTransferCheckout(resource, options = {}) {
|
|
573
|
-
const normalized = normalizeResource({ ...resource, paymentRail: "transfer" });
|
|
574
|
-
const sendTransfer = options.sendTransfer || options.transfer;
|
|
575
|
-
if (typeof sendTransfer !== "function") {
|
|
576
|
-
throw new Error("createTransferCheckout requires sendTransfer({ resource, recipient, amount, currency, network }) and a server verifyTransfer hook.");
|
|
577
|
-
}
|
|
578
|
-
return {
|
|
579
|
-
resource: normalized,
|
|
580
|
-
async pay(input = {}) {
|
|
581
|
-
const recipient = normalized.recipient || normalized.payTo;
|
|
582
|
-
const amount = String(normalized.price || normalized.amount || "0");
|
|
583
|
-
const currency = normalized.currency || "USDC";
|
|
584
|
-
const network = options.network || input.challenge?.accepts?.[0]?.network || "eip155:5042002";
|
|
585
|
-
const result = await sendTransfer({ resource: normalized, recipient, amount, currency, network, challenge: input.challenge });
|
|
586
|
-
const txHash = result?.txHash || result?.hash || result?.transactionHash || result?.paymentId || "";
|
|
587
|
-
if (!txHash) throw new Error("Transfer checkout did not return a txHash.");
|
|
588
|
-
return {
|
|
589
|
-
paymentSignature: txHash,
|
|
590
|
-
signature: txHash,
|
|
591
|
-
memo: result.memo || "",
|
|
592
|
-
metadata: {
|
|
593
|
-
paymentProvider: "direct-transfer",
|
|
594
|
-
paymentId: txHash,
|
|
595
|
-
txHash,
|
|
596
|
-
recipient,
|
|
597
|
-
amount: Number(amount),
|
|
598
|
-
currency,
|
|
599
|
-
network,
|
|
600
|
-
...result.metadata || result
|
|
601
|
-
}
|
|
602
|
-
};
|
|
603
|
-
}
|
|
604
|
-
};
|
|
605
|
-
}
|
|
606
|
-
async function payWithTransfer(resource, options = {}) {
|
|
607
|
-
const checkout = options.checkout || createTransferCheckout(resource, options).pay;
|
|
608
|
-
const result = await checkout({ resource: normalizeResource(resource), challenge: options.challenge || null });
|
|
609
|
-
const txHash = result?.metadata?.txHash || result?.txHash || result?.paymentSignature || result?.signature || "";
|
|
610
|
-
if (!txHash) throw new Error("Transfer checkout did not return a txHash.");
|
|
611
|
-
return checkResourceAccess(resource, {
|
|
612
|
-
...options,
|
|
613
|
-
headers: {
|
|
614
|
-
...options.headers || {},
|
|
615
|
-
"x-nibgate-transfer-tx": txHash
|
|
616
|
-
},
|
|
617
|
-
payment: result.metadata || { paymentProvider: "direct-transfer", txHash, paymentId: txHash }
|
|
618
|
-
});
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
// src/core/settings.js
|
|
622
|
-
var NIBGATE_CONTENT_SETTING_FIELDS = [
|
|
623
|
-
{ name: "publishToNibgate", label: "Publish to Nibgate discovery", type: "boolean", defaultValue: true },
|
|
624
|
-
{ name: "type", label: "Content type", type: "select", options: CONTENT_TYPES, defaultValue: "article" },
|
|
625
|
-
{ name: "humanAccess", label: "Human access", type: "select", options: ACCESS_MODES, defaultValue: "paid" },
|
|
626
|
-
{ name: "agentAccess", label: "Agent access", type: "select", options: ACCESS_MODES, defaultValue: "paid" },
|
|
627
|
-
{ name: "unlockMode", label: "Unlock mode", type: "select", options: UNLOCK_MODES, defaultValue: "one_time" },
|
|
628
|
-
{ name: "paymentRail", label: "Payment rail", type: "select", options: PAYMENT_RAILS, defaultValue: "gateway" },
|
|
629
|
-
{ name: "price", label: "Price", type: "text", defaultValue: "0.005" },
|
|
630
|
-
{ name: "currency", label: "Currency", type: "text", defaultValue: "USDC" },
|
|
631
|
-
{ name: "recipient", label: "Recipient wallet", type: "wallet", defaultValue: "" },
|
|
632
|
-
{ name: "ratingsEnabled", label: "Enable ratings", type: "boolean", defaultValue: true },
|
|
633
|
-
{ name: "license", label: "License / terms", type: "textarea", defaultValue: "" }
|
|
634
|
-
];
|
|
635
|
-
function createNibgateContentSettings(input = {}) {
|
|
636
|
-
const access = normalizeAccessPolicy(input.access || {
|
|
637
|
-
humans: input.humanAccess,
|
|
638
|
-
agents: input.agentAccess
|
|
639
|
-
});
|
|
640
|
-
const unlock = normalizeUnlockPolicy(input.unlock || input.unlockMode || "one_time");
|
|
641
|
-
return {
|
|
642
|
-
publishToNibgate: input.publishToNibgate ?? input.publishedToNibgate ?? true,
|
|
643
|
-
type: normalizeContentType(input.type || input.contentType || "article"),
|
|
644
|
-
humanAccess: access.humans,
|
|
645
|
-
agentAccess: access.agents,
|
|
646
|
-
unlockMode: unlock.mode,
|
|
647
|
-
paymentRail: normalizePaymentRail(input.paymentRail || input.paymentMode || input.rail),
|
|
648
|
-
price: String(input.price ?? input.amount ?? "0.005"),
|
|
649
|
-
currency: input.currency || "USDC",
|
|
650
|
-
recipient: input.recipient || input.payTo || input.receiverAddress || input.creatorWallet || "",
|
|
651
|
-
ratingsEnabled: input.ratingsEnabled ?? input.enableRatings ?? input.reputation?.ratingsEnabled ?? true,
|
|
652
|
-
license: input.license || input.terms || ""
|
|
653
|
-
};
|
|
654
|
-
}
|
|
655
|
-
function settingsToAccessPolicy(settings = {}) {
|
|
656
|
-
return normalizeAccessPolicy({
|
|
657
|
-
humans: settings.humanAccess,
|
|
658
|
-
agents: settings.agentAccess
|
|
659
|
-
});
|
|
660
|
-
}
|
|
661
|
-
function settingsToUnlockPolicy(settings = {}) {
|
|
662
|
-
return normalizeUnlockPolicy(settings.unlockMode || settings.unlock || "one_time");
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
// src/browser/index.js
|
|
666
|
-
async function createCircleGatewayBrowserAdapter2(options = {}) {
|
|
667
|
-
const gateway = await Promise.resolve().then(() => (init_gateway(), gateway_exports));
|
|
668
|
-
return gateway.createCircleGatewayBrowserAdapter(options);
|
|
412
|
+
// src/browser/gate.js
|
|
413
|
+
var defaultClient = null;
|
|
414
|
+
function setDefaultClient(client) {
|
|
415
|
+
defaultClient = client;
|
|
669
416
|
}
|
|
670
417
|
function createGate(resource, options = {}) {
|
|
671
418
|
const normalized = normalizeResource(resource);
|
|
672
|
-
const client = options.client ||
|
|
419
|
+
const client = options.client || defaultClient;
|
|
673
420
|
return {
|
|
674
421
|
resource: normalized,
|
|
675
422
|
content(extra = {}) {
|
|
@@ -713,18 +460,11 @@ var Nibgate = (() => {
|
|
|
713
460
|
}
|
|
714
461
|
};
|
|
715
462
|
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
...normalizedRating,
|
|
722
|
-
ratingMessage: extra.ratingMessage || rating.message || rating.ratingMessage || ratingMessage(normalized, normalizedRating, extra),
|
|
723
|
-
ratingSignature: extra.ratingSignature || rating.signature || rating.ratingSignature || void 0,
|
|
724
|
-
resource: normalized
|
|
725
|
-
};
|
|
726
|
-
return emit("content_rating", payload);
|
|
727
|
-
}
|
|
463
|
+
|
|
464
|
+
// src/browser/access.js
|
|
465
|
+
init_json();
|
|
466
|
+
|
|
467
|
+
// src/browser/track.js
|
|
728
468
|
function trackResourcePage(resource, options = {}) {
|
|
729
469
|
const item = createGate(resource, options.gateOptions || {});
|
|
730
470
|
const validation = validateResourceMetadata(item.resource, options.validation || {});
|
|
@@ -740,6 +480,29 @@ var Nibgate = (() => {
|
|
|
740
480
|
});
|
|
741
481
|
return item;
|
|
742
482
|
}
|
|
483
|
+
function setupResourcePage(resource, options = {}) {
|
|
484
|
+
const item = trackResourcePage(resource, options);
|
|
485
|
+
const win = browserWindow();
|
|
486
|
+
if (!win) return item;
|
|
487
|
+
const button = typeof options.button === "string" ? win.document.querySelector(options.button) : options.button;
|
|
488
|
+
const statusElement = typeof options.status === "string" ? win.document.querySelector(options.status) : options.status;
|
|
489
|
+
const setStatus = options.onStatus || ((message) => {
|
|
490
|
+
if (statusElement) statusElement.textContent = message || "";
|
|
491
|
+
});
|
|
492
|
+
if (button) {
|
|
493
|
+
button.addEventListener("click", async () => {
|
|
494
|
+
button.disabled = true;
|
|
495
|
+
try {
|
|
496
|
+
await checkResourceAccess(resource, { ...options, onStatus: setStatus });
|
|
497
|
+
} finally {
|
|
498
|
+
button.disabled = false;
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
return item;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// src/browser/access.js
|
|
743
506
|
async function checkResourceAccess(resource, options = {}) {
|
|
744
507
|
const item = createGate(resource, options.gateOptions || {});
|
|
745
508
|
const accessPath = options.accessPath || item.resource.accessPath || "/api/nibgate/access";
|
|
@@ -761,12 +524,11 @@ var Nibgate = (() => {
|
|
|
761
524
|
item.track("payment_challenge_returned", { source: options.source, challenge: payload, resource: item.resource });
|
|
762
525
|
status(options.challengeMessage || "Payment challenge returned. Continue with checkout.");
|
|
763
526
|
if (typeof options.createPaymentSignature === "function" || typeof options.checkout === "function") {
|
|
764
|
-
|
|
527
|
+
return payWithPaymentSignature(resource, {
|
|
765
528
|
...options,
|
|
766
529
|
challenge: payload,
|
|
767
530
|
paymentRequiredHeader: response.headers.get("PAYMENT-REQUIRED") || response.headers.get("payment-required") || ""
|
|
768
531
|
});
|
|
769
|
-
return paymentResult;
|
|
770
532
|
}
|
|
771
533
|
if (options.autoPay && options.payPath) {
|
|
772
534
|
const paymentResult = await payAndUnlockResource(resource, options);
|
|
@@ -856,6 +618,42 @@ var Nibgate = (() => {
|
|
|
856
618
|
status(options.paymentSuccessMessage || "Payment verified. Content unlocked.");
|
|
857
619
|
return { ok: true, status: response.status, payload, payment, resource: item.resource, response };
|
|
858
620
|
}
|
|
621
|
+
async function payAndUnlockResource(resource, options = {}) {
|
|
622
|
+
const item = createGate(resource, options.gateOptions || {});
|
|
623
|
+
const payPath = options.payPath || item.resource.payPath || "/api/nibgate/pay";
|
|
624
|
+
const status = typeof options.onStatus === "function" ? options.onStatus : () => {
|
|
625
|
+
};
|
|
626
|
+
status(options.paymentMessage || "Starting payment...");
|
|
627
|
+
item.unlockStarted({ source: options.source, paymentProvider: options.paymentProvider || "circle-gateway" });
|
|
628
|
+
const response = await fetch(payPath, {
|
|
629
|
+
method: options.payMethod || "POST",
|
|
630
|
+
headers: {
|
|
631
|
+
accept: "application/json",
|
|
632
|
+
"content-type": "application/json",
|
|
633
|
+
...options.payHeaders || {}
|
|
634
|
+
},
|
|
635
|
+
body: JSON.stringify({ resource: item.resource, ...options.payPayload || {} })
|
|
636
|
+
});
|
|
637
|
+
const payload = await response.json().catch(() => ({}));
|
|
638
|
+
if (!response.ok || !payload.ok) {
|
|
639
|
+
item.track("payment_failed", { source: options.source, status: response.status, error: payload.error || "Payment failed", detail: payload.detail || "" });
|
|
640
|
+
status(payload.detail || payload.error || options.paymentErrorMessage || "Payment failed.");
|
|
641
|
+
return { ok: false, status: response.status, payload, resource: item.resource, response };
|
|
642
|
+
}
|
|
643
|
+
const payment = payload.payment || {
|
|
644
|
+
paymentProvider: options.paymentProvider || "circle-gateway",
|
|
645
|
+
paymentId: payload.paymentId || `nibgate_payment_${Date.now()}`,
|
|
646
|
+
amount: Number(item.resource.price || 0),
|
|
647
|
+
revenue: Number(item.resource.price || 0),
|
|
648
|
+
currency: item.resource.currency || "USDC"
|
|
649
|
+
};
|
|
650
|
+
storePaymentProof(item.resource, payload.unlockProof);
|
|
651
|
+
item.markUnlocked(payment);
|
|
652
|
+
status(options.paymentSuccessMessage || "Payment verified. Content unlocked.");
|
|
653
|
+
return { ok: true, status: response.status, payload, payment, resource: item.resource, response };
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// src/browser/checkout.js
|
|
859
657
|
function setElementText(target, message) {
|
|
860
658
|
const win = browserWindow();
|
|
861
659
|
if (!target || !win) return;
|
|
@@ -899,12 +697,40 @@ var Nibgate = (() => {
|
|
|
899
697
|
if (element) element.addEventListener("click", () => unlock().catch((error) => status(error.message || "Checkout failed.")));
|
|
900
698
|
return { unlock };
|
|
901
699
|
}
|
|
700
|
+
return { resource: normalized, unlock, mount };
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// src/core/rating.js
|
|
704
|
+
function normalizeRating(input = {}) {
|
|
705
|
+
const value = typeof input === "number" ? input : input.rating ?? input.stars ?? input.ratingValue ?? input.score;
|
|
706
|
+
const numeric = Number.parseFloat(value);
|
|
707
|
+
const ratingValue = Number.isFinite(numeric) ? Math.max(1, Math.min(50, numeric <= 5 ? Math.round(numeric * 10) : Math.round(numeric))) : null;
|
|
902
708
|
return {
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
709
|
+
...input,
|
|
710
|
+
rating: ratingValue ? ratingValue / 10 : void 0,
|
|
711
|
+
ratingValue: ratingValue || void 0
|
|
906
712
|
};
|
|
907
713
|
}
|
|
714
|
+
function ratingMessage(resource, rating = {}, options = {}) {
|
|
715
|
+
const normalized = normalizeResource(resource);
|
|
716
|
+
const normalizedRating = normalizeRating(rating);
|
|
717
|
+
const value = normalizedRating.ratingValue || 0;
|
|
718
|
+
return [
|
|
719
|
+
"Nibgate content rating",
|
|
720
|
+
`site:${options.siteDomain || options.domain || normalized.siteDomain || normalized.domain || ""}`,
|
|
721
|
+
`content:${normalized.externalId || normalized.id}`,
|
|
722
|
+
`url:${normalized.url || options.url || ""}`,
|
|
723
|
+
`rating:${value}`,
|
|
724
|
+
"I confirm this rating is tied to my unlock/payment proof."
|
|
725
|
+
].join("\n");
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// src/browser/evm-gateway.js
|
|
729
|
+
init_json();
|
|
730
|
+
async function createCircleGatewayBrowserAdapter2(options = {}) {
|
|
731
|
+
const gateway = await Promise.resolve().then(() => (init_gateway(), gateway_exports));
|
|
732
|
+
return gateway.createCircleGatewayBrowserAdapter(options);
|
|
733
|
+
}
|
|
908
734
|
function createEvmGatewayUnlock(resource, options = {}) {
|
|
909
735
|
const item = createGate(resource, options.gateOptions || {});
|
|
910
736
|
const win = browserWindow();
|
|
@@ -976,10 +802,7 @@ var Nibgate = (() => {
|
|
|
976
802
|
const evm = provider();
|
|
977
803
|
if (evm?.request && walletAddress) {
|
|
978
804
|
try {
|
|
979
|
-
await evm.request({
|
|
980
|
-
method: "wallet_revokePermissions",
|
|
981
|
-
params: [{ eth_accounts: {} }]
|
|
982
|
-
});
|
|
805
|
+
await evm.request({ method: "wallet_revokePermissions", params: [{ eth_accounts: {} }] });
|
|
983
806
|
} catch (_error) {
|
|
984
807
|
}
|
|
985
808
|
}
|
|
@@ -999,10 +822,7 @@ var Nibgate = (() => {
|
|
|
999
822
|
network,
|
|
1000
823
|
signer: {
|
|
1001
824
|
address: walletAddress,
|
|
1002
|
-
signTypedData: (typedData) => evm.request({
|
|
1003
|
-
method: "eth_signTypedData_v4",
|
|
1004
|
-
params: [walletAddress, stringifyJson(typedData)]
|
|
1005
|
-
})
|
|
825
|
+
signTypedData: (typedData) => evm.request({ method: "eth_signTypedData_v4", params: [walletAddress, stringifyJson(typedData)] })
|
|
1006
826
|
},
|
|
1007
827
|
clientModule: options.circleClientModule,
|
|
1008
828
|
clientModuleUrl: options.circleClientModuleUrl
|
|
@@ -1054,18 +874,162 @@ var Nibgate = (() => {
|
|
|
1054
874
|
renderWallet();
|
|
1055
875
|
setUnlocked(false);
|
|
1056
876
|
}
|
|
1057
|
-
function mount() {
|
|
1058
|
-
connectButton?.addEventListener?.("click", () => connect().catch((error) => setStatus(error?.message || "Could not connect wallet.")));
|
|
1059
|
-
disconnectButton?.addEventListener?.("click", () => disconnect().catch((error) => setStatus(error?.message || "Could not disconnect wallet.")));
|
|
1060
|
-
unlockButton?.addEventListener?.("click", () => unlock());
|
|
1061
|
-
clearButton?.addEventListener?.("click", clear);
|
|
1062
|
-
hydrate();
|
|
1063
|
-
trackResourcePage(item.resource, { source });
|
|
1064
|
-
return controller;
|
|
877
|
+
function mount() {
|
|
878
|
+
connectButton?.addEventListener?.("click", () => connect().catch((error) => setStatus(error?.message || "Could not connect wallet.")));
|
|
879
|
+
disconnectButton?.addEventListener?.("click", () => disconnect().catch((error) => setStatus(error?.message || "Could not disconnect wallet.")));
|
|
880
|
+
unlockButton?.addEventListener?.("click", () => unlock());
|
|
881
|
+
clearButton?.addEventListener?.("click", clear);
|
|
882
|
+
hydrate();
|
|
883
|
+
trackResourcePage(item.resource, { source });
|
|
884
|
+
return controller;
|
|
885
|
+
}
|
|
886
|
+
const controller = { resource: item.resource, connect, disconnect, unlock, clear, hydrate, mount, getWalletAddress: () => walletAddress };
|
|
887
|
+
if (options.autoMount !== false) mount();
|
|
888
|
+
return controller;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// src/browser/reputation.js
|
|
892
|
+
var RATE_CONTENT_SELECTOR = "0xc62fad09";
|
|
893
|
+
var ZERO_HASH = `0x${"0".repeat(64)}`;
|
|
894
|
+
var NIBGATE_CONTENT_HASH_NAMESPACE = "nibgate:content:v1";
|
|
895
|
+
var NIBGATE_REPUTATION_CHAIN_ID = 5042002;
|
|
896
|
+
var NIBGATE_REPUTATION_CHAIN_NAME = "Arc Testnet";
|
|
897
|
+
var NIBGATE_REPUTATION_RPC_URL = "https://rpc.testnet.arc.network";
|
|
898
|
+
var NIBGATE_REPUTATION_CONTRACT = "0x9f27fd62e75f86a3c7addfdba443aab1f930e281";
|
|
899
|
+
var NIBGATE_REPUTATION_ABI = [
|
|
900
|
+
{
|
|
901
|
+
type: "function",
|
|
902
|
+
name: "rateContent",
|
|
903
|
+
stateMutability: "nonpayable",
|
|
904
|
+
inputs: [
|
|
905
|
+
{ name: "contentId", type: "bytes32" },
|
|
906
|
+
{ name: "rating", type: "uint8" },
|
|
907
|
+
{ name: "reviewHash", type: "bytes32" },
|
|
908
|
+
{ name: "unlockRef", type: "string" }
|
|
909
|
+
],
|
|
910
|
+
outputs: []
|
|
911
|
+
}
|
|
912
|
+
];
|
|
913
|
+
function stripHex(value = "") {
|
|
914
|
+
return String(value || "").replace(/^0x/i, "").toLowerCase();
|
|
915
|
+
}
|
|
916
|
+
function wordRight(hex = "") {
|
|
917
|
+
const clean = stripHex(hex);
|
|
918
|
+
if (clean.length > 64) throw new Error("ABI word is too long.");
|
|
919
|
+
return clean.padEnd(64, "0");
|
|
920
|
+
}
|
|
921
|
+
function numberWord(value = 0) {
|
|
922
|
+
return Number(value || 0).toString(16).padStart(64, "0");
|
|
923
|
+
}
|
|
924
|
+
function utf8Hex(value = "") {
|
|
925
|
+
return Array.from(new TextEncoder().encode(String(value || ""))).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
926
|
+
}
|
|
927
|
+
function encodeString(value = "") {
|
|
928
|
+
const hex = utf8Hex(value);
|
|
929
|
+
const byteLength = hex.length / 2;
|
|
930
|
+
const paddedLength = Math.ceil(byteLength / 32) * 64;
|
|
931
|
+
return numberWord(byteLength) + hex.padEnd(paddedLength, "0");
|
|
932
|
+
}
|
|
933
|
+
function encodeRateContent({ contentId, ratingValue, reviewHash, unlockRef }) {
|
|
934
|
+
return RATE_CONTENT_SELECTOR + wordRight(contentId) + numberWord(ratingValue) + wordRight(reviewHash || ZERO_HASH) + numberWord(128) + encodeString(unlockRef || "");
|
|
935
|
+
}
|
|
936
|
+
function contentRatingHash(_resource, options = {}) {
|
|
937
|
+
const contentId = options.contentId || options.contentHash;
|
|
938
|
+
if (!contentId) {
|
|
939
|
+
throw new Error("contentId/contentHash is required. Use the Nibgate backend prepare endpoint or pass a known content hash.");
|
|
940
|
+
}
|
|
941
|
+
return contentId;
|
|
942
|
+
}
|
|
943
|
+
function reviewTextHash(review = "") {
|
|
944
|
+
if (!review) return ZERO_HASH;
|
|
945
|
+
throw new Error("Text review hashing is not available in direct-browser mode. Pass reviewHash from your app/backend.");
|
|
946
|
+
}
|
|
947
|
+
async function prepareOnchainRating(resource, options = {}) {
|
|
948
|
+
if (options.contentId || options.contentHash) return { contentId: options.contentId || options.contentHash };
|
|
949
|
+
const prepareUrl = options.prepareUrl || options.indexUrl?.replace(/\/index$/, "/prepare");
|
|
950
|
+
if (!prepareUrl) throw new Error("contentId/contentHash or prepareUrl is required for onchain rating.");
|
|
951
|
+
const response = await fetch(prepareUrl, {
|
|
952
|
+
method: "POST",
|
|
953
|
+
headers: { "content-type": "application/json", ...options.indexHeaders || {} },
|
|
954
|
+
body: JSON.stringify({
|
|
955
|
+
siteId: options.siteId,
|
|
956
|
+
token: options.token,
|
|
957
|
+
resource,
|
|
958
|
+
url: resource.url,
|
|
959
|
+
path: resource.path
|
|
960
|
+
})
|
|
961
|
+
});
|
|
962
|
+
const payload = await response.json().catch(() => ({}));
|
|
963
|
+
if (!response.ok || !payload.contentHash) throw new Error(payload.error || "Could not prepare Nibgate onchain rating.");
|
|
964
|
+
return payload;
|
|
965
|
+
}
|
|
966
|
+
async function rateContentOnchain(resource, options = {}) {
|
|
967
|
+
const normalized = normalizeResource(resource);
|
|
968
|
+
const rating = normalizeRating(options.rating ?? options.stars ?? options);
|
|
969
|
+
if (!rating.ratingValue) throw new Error("Rating must be between 0.1 and 5 stars.");
|
|
970
|
+
const provider = options.provider || globalThis?.ethereum;
|
|
971
|
+
if (!provider?.request) throw new Error("Connect an EVM wallet to rate this content onchain.");
|
|
972
|
+
const contractAddress = options.contractAddress || options.reputationContract || NIBGATE_REPUTATION_CONTRACT;
|
|
973
|
+
if (!contractAddress) throw new Error("Nibgate reputation contract address is not configured.");
|
|
974
|
+
const accounts = await provider.request({ method: "eth_requestAccounts" });
|
|
975
|
+
const walletAddress = Array.isArray(accounts) ? accounts[0] || "" : "";
|
|
976
|
+
if (!walletAddress) throw new Error("No wallet account selected.");
|
|
977
|
+
const prepared = await prepareOnchainRating(normalized, options);
|
|
978
|
+
const contentId = prepared.contentHash || prepared.contentId || contentRatingHash(normalized, options);
|
|
979
|
+
const reviewHash = options.reviewHash || ZERO_HASH;
|
|
980
|
+
const unlockRef = String(options.unlockRef || options.paymentId || options.txHash || "");
|
|
981
|
+
const data = encodeRateContent({ contentId, ratingValue: rating.ratingValue, reviewHash, unlockRef });
|
|
982
|
+
const txHash = await provider.request({
|
|
983
|
+
method: "eth_sendTransaction",
|
|
984
|
+
params: [{
|
|
985
|
+
from: walletAddress,
|
|
986
|
+
to: contractAddress,
|
|
987
|
+
data
|
|
988
|
+
}]
|
|
989
|
+
});
|
|
990
|
+
const payload = payloadWithResource(normalized, {
|
|
991
|
+
rating: rating.rating,
|
|
992
|
+
ratingValue: rating.ratingValue,
|
|
993
|
+
walletAddress,
|
|
994
|
+
txHash,
|
|
995
|
+
contentHash: contentId,
|
|
996
|
+
reviewHash,
|
|
997
|
+
proofType: "onchain_pending",
|
|
998
|
+
proof: unlockRef,
|
|
999
|
+
paymentId: options.paymentId,
|
|
1000
|
+
actor: options.actor || "human"
|
|
1001
|
+
});
|
|
1002
|
+
emit("content_rating", payload);
|
|
1003
|
+
if (options.indexUrl) {
|
|
1004
|
+
await fetch(options.indexUrl, {
|
|
1005
|
+
method: "POST",
|
|
1006
|
+
headers: { "content-type": "application/json", ...options.indexHeaders || {} },
|
|
1007
|
+
body: JSON.stringify({
|
|
1008
|
+
siteId: options.siteId,
|
|
1009
|
+
token: options.token,
|
|
1010
|
+
txHash,
|
|
1011
|
+
resource: normalized,
|
|
1012
|
+
url: normalized.url,
|
|
1013
|
+
path: normalized.path,
|
|
1014
|
+
actor: options.actor || "human"
|
|
1015
|
+
})
|
|
1016
|
+
}).catch(() => null);
|
|
1065
1017
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1018
|
+
return { txHash, walletAddress, contentId, ratingValue: rating.ratingValue, reviewHash };
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
// src/browser/rating-ui.js
|
|
1022
|
+
function rateResource(resource, rating = {}, extra = {}) {
|
|
1023
|
+
const normalized = normalizeResource(resource);
|
|
1024
|
+
const normalizedRating = normalizeRating(rating);
|
|
1025
|
+
const payload = {
|
|
1026
|
+
...extra,
|
|
1027
|
+
...normalizedRating,
|
|
1028
|
+
ratingMessage: extra.ratingMessage || rating.message || rating.ratingMessage || ratingMessage(normalized, normalizedRating, extra),
|
|
1029
|
+
ratingSignature: extra.ratingSignature || rating.signature || rating.ratingSignature || void 0,
|
|
1030
|
+
resource: normalized
|
|
1031
|
+
};
|
|
1032
|
+
return emit("content_rating", payload);
|
|
1069
1033
|
}
|
|
1070
1034
|
function createOnchainRating(resource, options = {}) {
|
|
1071
1035
|
const item = createGate(resource, options.gateOptions || {});
|
|
@@ -1111,14 +1075,7 @@ var Nibgate = (() => {
|
|
|
1111
1075
|
const paymentId = input.paymentId || options.paymentId || (typeof options.getPaymentId === "function" ? options.getPaymentId() : payment?.paymentId);
|
|
1112
1076
|
const unlockRef = input.unlockRef || options.unlockRef || (typeof options.getUnlockRef === "function" ? options.getUnlockRef() : null) || paymentId || payment?.txHash || payment?.transactionHash || "";
|
|
1113
1077
|
setStatus(options.pendingMessage || "Send the onchain rating transaction...");
|
|
1114
|
-
const result = await rateContentOnchain(item.resource, {
|
|
1115
|
-
...options,
|
|
1116
|
-
...input,
|
|
1117
|
-
rating,
|
|
1118
|
-
paymentId,
|
|
1119
|
-
unlockRef,
|
|
1120
|
-
source
|
|
1121
|
-
});
|
|
1078
|
+
const result = await rateContentOnchain(item.resource, { ...options, ...input, rating, paymentId, unlockRef, source });
|
|
1122
1079
|
setStatus(options.successMessage || "Rating sent to Nibgate reputation.");
|
|
1123
1080
|
if (typeof options.onRated === "function") options.onRated(result);
|
|
1124
1081
|
return result;
|
|
@@ -1169,7 +1126,7 @@ var Nibgate = (() => {
|
|
|
1169
1126
|
btn.addEventListener("click", () => {
|
|
1170
1127
|
selectedRating = value;
|
|
1171
1128
|
starButtons.forEach((b, i) => b.style.color = i < value ? "#f5b342" : "#ccc");
|
|
1172
|
-
|
|
1129
|
+
rateResource(item.resource, { rating: value }).catch(() => {
|
|
1173
1130
|
});
|
|
1174
1131
|
});
|
|
1175
1132
|
container.appendChild(btn);
|
|
@@ -1187,71 +1144,60 @@ var Nibgate = (() => {
|
|
|
1187
1144
|
selectedRating = value;
|
|
1188
1145
|
starButtons.forEach((b, i) => b.style.color = i < value ? "#f5b342" : "#ccc");
|
|
1189
1146
|
}
|
|
1147
|
+
return { resource: item.resource, container, setRating, rate };
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
// src/browser/transfer.js
|
|
1151
|
+
function createTransferCheckout(resource, options = {}) {
|
|
1152
|
+
const normalized = normalizeResource({ ...resource, paymentRail: "transfer" });
|
|
1153
|
+
const sendTransfer = options.sendTransfer || options.transfer;
|
|
1154
|
+
if (typeof sendTransfer !== "function") {
|
|
1155
|
+
throw new Error("createTransferCheckout requires sendTransfer({ resource, recipient, amount, currency, network }) and a server verifyTransfer hook.");
|
|
1156
|
+
}
|
|
1190
1157
|
return {
|
|
1191
|
-
resource:
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1158
|
+
resource: normalized,
|
|
1159
|
+
async pay(input = {}) {
|
|
1160
|
+
const recipient = normalized.recipient || normalized.payTo;
|
|
1161
|
+
const amount = String(normalized.price || normalized.amount || "0");
|
|
1162
|
+
const currency = normalized.currency || "USDC";
|
|
1163
|
+
const network = options.network || input.challenge?.accepts?.[0]?.network || "eip155:5042002";
|
|
1164
|
+
const result = await sendTransfer({ resource: normalized, recipient, amount, currency, network, challenge: input.challenge });
|
|
1165
|
+
const txHash = result?.txHash || result?.hash || result?.transactionHash || result?.paymentId || "";
|
|
1166
|
+
if (!txHash) throw new Error("Transfer checkout did not return a txHash.");
|
|
1167
|
+
return {
|
|
1168
|
+
paymentSignature: txHash,
|
|
1169
|
+
signature: txHash,
|
|
1170
|
+
memo: result.memo || "",
|
|
1171
|
+
metadata: {
|
|
1172
|
+
paymentProvider: "direct-transfer",
|
|
1173
|
+
paymentId: txHash,
|
|
1174
|
+
txHash,
|
|
1175
|
+
recipient,
|
|
1176
|
+
amount: Number(amount),
|
|
1177
|
+
currency,
|
|
1178
|
+
network,
|
|
1179
|
+
...result.metadata || result
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1195
1183
|
};
|
|
1196
1184
|
}
|
|
1197
|
-
async function
|
|
1198
|
-
const
|
|
1199
|
-
const
|
|
1200
|
-
const
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
const response = await fetch(payPath, {
|
|
1205
|
-
method: options.payMethod || "POST",
|
|
1185
|
+
async function payWithTransfer(resource, options = {}) {
|
|
1186
|
+
const checkout = options.checkout || createTransferCheckout(resource, options).pay;
|
|
1187
|
+
const result = await checkout({ resource: normalizeResource(resource), challenge: options.challenge || null });
|
|
1188
|
+
const txHash = result?.metadata?.txHash || result?.txHash || result?.paymentSignature || result?.signature || "";
|
|
1189
|
+
if (!txHash) throw new Error("Transfer checkout did not return a txHash.");
|
|
1190
|
+
return checkResourceAccess(resource, {
|
|
1191
|
+
...options,
|
|
1206
1192
|
headers: {
|
|
1207
|
-
|
|
1208
|
-
"
|
|
1209
|
-
...options.payHeaders || {}
|
|
1193
|
+
...options.headers || {},
|
|
1194
|
+
"x-nibgate-transfer-tx": txHash
|
|
1210
1195
|
},
|
|
1211
|
-
|
|
1212
|
-
resource: item.resource,
|
|
1213
|
-
...options.payPayload || {}
|
|
1214
|
-
})
|
|
1215
|
-
});
|
|
1216
|
-
const payload = await response.json().catch(() => ({}));
|
|
1217
|
-
if (!response.ok || !payload.success) {
|
|
1218
|
-
item.track("payment_failed", { source: options.source, status: response.status, error: payload.error || "Payment failed", detail: payload.detail || "" });
|
|
1219
|
-
status(payload.detail || payload.error || options.paymentErrorMessage || "Payment failed.");
|
|
1220
|
-
return { ok: false, status: response.status, payload, resource: item.resource, response };
|
|
1221
|
-
}
|
|
1222
|
-
const payment = payload.payment || {
|
|
1223
|
-
paymentProvider: options.paymentProvider || "circle-gateway",
|
|
1224
|
-
paymentId: payload.paymentId || `nibgate_payment_${Date.now()}`,
|
|
1225
|
-
amount: Number(item.resource.price || 0),
|
|
1226
|
-
revenue: Number(item.resource.price || 0),
|
|
1227
|
-
currency: item.resource.currency || "USDC"
|
|
1228
|
-
};
|
|
1229
|
-
storePaymentProof(item.resource, payload.unlockProof);
|
|
1230
|
-
item.markUnlocked(payment);
|
|
1231
|
-
status(options.paymentSuccessMessage || "Payment verified. Content unlocked.");
|
|
1232
|
-
return { ok: true, status: response.status, payload, payment, resource: item.resource, response };
|
|
1233
|
-
}
|
|
1234
|
-
function setupResourcePage(resource, options = {}) {
|
|
1235
|
-
const item = trackResourcePage(resource, options);
|
|
1236
|
-
const win = browserWindow();
|
|
1237
|
-
if (!win) return item;
|
|
1238
|
-
const button = typeof options.button === "string" ? win.document.querySelector(options.button) : options.button;
|
|
1239
|
-
const statusElement = typeof options.status === "string" ? win.document.querySelector(options.status) : options.status;
|
|
1240
|
-
const setStatus = options.onStatus || ((message) => {
|
|
1241
|
-
if (statusElement) statusElement.textContent = message || "";
|
|
1196
|
+
payment: result.metadata || { paymentProvider: "direct-transfer", txHash, paymentId: txHash }
|
|
1242
1197
|
});
|
|
1243
|
-
if (button) {
|
|
1244
|
-
button.addEventListener("click", async () => {
|
|
1245
|
-
button.disabled = true;
|
|
1246
|
-
try {
|
|
1247
|
-
await checkResourceAccess(resource, { ...options, onStatus: setStatus });
|
|
1248
|
-
} finally {
|
|
1249
|
-
button.disabled = false;
|
|
1250
|
-
}
|
|
1251
|
-
});
|
|
1252
|
-
}
|
|
1253
|
-
return item;
|
|
1254
1198
|
}
|
|
1199
|
+
|
|
1200
|
+
// src/browser/client.js
|
|
1255
1201
|
function createNibgate(defaults = {}) {
|
|
1256
1202
|
const defaultResource = defaults.resource ? normalizeResource(defaults.resource) : null;
|
|
1257
1203
|
function resourceWithDefaults(resource = {}) {
|
|
@@ -1333,7 +1279,51 @@ var Nibgate = (() => {
|
|
|
1333
1279
|
};
|
|
1334
1280
|
}
|
|
1335
1281
|
var nibgate = createNibgate();
|
|
1336
|
-
|
|
1282
|
+
setDefaultClient(nibgate);
|
|
1283
|
+
|
|
1284
|
+
// src/core/settings.js
|
|
1285
|
+
var NIBGATE_CONTENT_SETTING_FIELDS = [
|
|
1286
|
+
{ name: "publishToNibgate", label: "Publish to Nibgate discovery", type: "boolean", defaultValue: true },
|
|
1287
|
+
{ name: "type", label: "Content type", type: "select", options: CONTENT_TYPES, defaultValue: "article" },
|
|
1288
|
+
{ name: "humanAccess", label: "Human access", type: "select", options: ACCESS_MODES, defaultValue: "paid" },
|
|
1289
|
+
{ name: "agentAccess", label: "Agent access", type: "select", options: ACCESS_MODES, defaultValue: "paid" },
|
|
1290
|
+
{ name: "unlockMode", label: "Unlock mode", type: "select", options: UNLOCK_MODES, defaultValue: "one_time" },
|
|
1291
|
+
{ name: "paymentRail", label: "Payment rail", type: "select", options: PAYMENT_RAILS, defaultValue: "gateway" },
|
|
1292
|
+
{ name: "price", label: "Price", type: "text", defaultValue: "0.005" },
|
|
1293
|
+
{ name: "currency", label: "Currency", type: "text", defaultValue: "USDC" },
|
|
1294
|
+
{ name: "recipient", label: "Recipient wallet", type: "wallet", defaultValue: "" },
|
|
1295
|
+
{ name: "ratingsEnabled", label: "Enable ratings", type: "boolean", defaultValue: true },
|
|
1296
|
+
{ name: "license", label: "License / terms", type: "textarea", defaultValue: "" }
|
|
1297
|
+
];
|
|
1298
|
+
function createNibgateContentSettings(input = {}) {
|
|
1299
|
+
const access = normalizeAccessPolicy(input.access || {
|
|
1300
|
+
humans: input.humanAccess,
|
|
1301
|
+
agents: input.agentAccess
|
|
1302
|
+
});
|
|
1303
|
+
const unlock = normalizeUnlockPolicy(input.unlock || input.unlockMode || "one_time");
|
|
1304
|
+
return {
|
|
1305
|
+
publishToNibgate: input.publishToNibgate ?? input.publishedToNibgate ?? true,
|
|
1306
|
+
type: normalizeContentType(input.type || input.contentType || "article"),
|
|
1307
|
+
humanAccess: access.humans,
|
|
1308
|
+
agentAccess: access.agents,
|
|
1309
|
+
unlockMode: unlock.mode,
|
|
1310
|
+
paymentRail: normalizePaymentRail(input.paymentRail || input.paymentMode || input.rail),
|
|
1311
|
+
price: String(input.price ?? input.amount ?? "0.005"),
|
|
1312
|
+
currency: input.currency || "USDC",
|
|
1313
|
+
recipient: input.recipient || input.payTo || input.receiverAddress || input.creatorWallet || "",
|
|
1314
|
+
ratingsEnabled: input.ratingsEnabled ?? input.enableRatings ?? input.reputation?.ratingsEnabled ?? true,
|
|
1315
|
+
license: input.license || input.terms || ""
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
function settingsToAccessPolicy(settings = {}) {
|
|
1319
|
+
return normalizeAccessPolicy({
|
|
1320
|
+
humans: settings.humanAccess,
|
|
1321
|
+
agents: settings.agentAccess
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
function settingsToUnlockPolicy(settings = {}) {
|
|
1325
|
+
return normalizeUnlockPolicy(settings.unlockMode || settings.unlock || "one_time");
|
|
1326
|
+
}
|
|
1337
1327
|
return __toCommonJS(index_exports);
|
|
1338
1328
|
})();
|
|
1339
1329
|
//# sourceMappingURL=nibgate.js.map
|