@ic-pay/icpay-widget 0.1.76
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 +31 -0
- package/dist/index.d.ts +510 -0
- package/dist/index.global.js +5992 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +928 -0
- package/dist/index.js.map +1 -0
- package/dist/tailwind.css +1 -0
- package/package.json +50 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,928 @@
|
|
|
1
|
+
var Ie=Object.defineProperty;var Ue=Object.getOwnPropertyDescriptor;var s=(o,a,e,t)=>{for(var i=t>1?void 0:t?Ue(a,e):a,r=o.length-1,n;r>=0;r--)(n=o[r])&&(i=(t?n(a,e,i):n(i))||i);return t&&i&&Ie(a,e,i),i};import{css as Re}from"lit";var S=Re`
|
|
2
|
+
:host {
|
|
3
|
+
--icpay-primary: #f9fafb;
|
|
4
|
+
--icpay-secondary: #e5e7eb;
|
|
5
|
+
--icpay-accent: #9ca3af;
|
|
6
|
+
--icpay-text: #f9fafb;
|
|
7
|
+
--icpay-muted: #9ca3af;
|
|
8
|
+
--icpay-surface: #1f2937;
|
|
9
|
+
--icpay-surface-alt: #374151;
|
|
10
|
+
--icpay-border: #4b5563;
|
|
11
|
+
--icpay-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
12
|
+
display: block;
|
|
13
|
+
font-family: var(--icpay-font);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.card {
|
|
17
|
+
background: var(--icpay-surface);
|
|
18
|
+
border: 1px solid var(--icpay-border);
|
|
19
|
+
border-radius: 16px;
|
|
20
|
+
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.35);
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.section {
|
|
25
|
+
padding: 20px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.pay-button {
|
|
29
|
+
width: 100%;
|
|
30
|
+
background: linear-gradient(135deg, var(--icpay-primary) 0%, var(--icpay-secondary) 100%);
|
|
31
|
+
color: #111827;
|
|
32
|
+
border: 1px solid #d1d5db;
|
|
33
|
+
border-radius: 16px;
|
|
34
|
+
padding: 16px;
|
|
35
|
+
font-size: 16px;
|
|
36
|
+
font-weight: 600;
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
transition: all 0.3s ease;
|
|
39
|
+
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.pay-button:hover {
|
|
43
|
+
transform: translateY(-2px);
|
|
44
|
+
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
|
|
45
|
+
background: linear-gradient(135deg, #ffffff 0%, #f3f4f6 100%);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.pay-button.processing {
|
|
49
|
+
background: #6b7280;
|
|
50
|
+
color: #f9fafb;
|
|
51
|
+
border-color: #6b7280;
|
|
52
|
+
cursor: not-allowed;
|
|
53
|
+
animation: pulse 2s infinite;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@keyframes pulse {
|
|
57
|
+
0%, 100% { opacity: 1; }
|
|
58
|
+
50% { opacity: 0.7; }
|
|
59
|
+
}
|
|
60
|
+
`;function ee(o,a){if(!o||!a)return;let e=a.primaryColor||void 0,t=a.secondaryColor||void 0,i=(I,E)=>{E&&o.style.setProperty(I,E)};i("--icpay-primary",e),i("--icpay-secondary",t);let r=I=>{if(!I)return null;let E=I.replace("#",""),le=E.length===3?E.split("").map(Le=>Le+Le).join(""):E,ce=parseInt(le,16),de=ce>>16&255,Oe=ce>>8&255,Ne=ce&255;return{r:de,g:Oe,b:Ne}},g=(I=>{let E=r(I);if(!E)return 0;let le=ce=>{let de=ce/255;return de<=.03928?de/12.92:Math.pow((de+.055)/1.055,2.4)};return .2126*le(E.r)+.7152*le(E.g)+.0722*le(E.b)})(e||t)>.6,w=a.surfaceColor||(g?"#f3f4f6":"#1f2937"),H=a.surfaceAltColor||(g?"#e5e7eb":"#374151"),he=a.borderColor||(g?"#d1d5db":"#4b5563"),N=a.textColor||(g?"#111827":"#f9fafb"),J=a.accentColor||t||e||(g?"#6b7280":"#9ca3af"),ae=a.mutedTextColor||(g?"#6b7280":"#9ca3af");i("--icpay-accent",J),i("--icpay-text",N),i("--icpay-muted",ae),i("--icpay-surface",w),i("--icpay-surface-alt",H),i("--icpay-border",he)}import{Icpay as Ce}from"@ic-pay/icpay-sdk";var Ae=typeof window<"u";function fe(o,a,e){o&&(e!==void 0?console.log(`[ICPay Widget] ${a}`,e):console.log(`[ICPay Widget] ${a}`))}function c(o){if(!Ae)return{client:{},quoteUsd:async()=>({tokenAmountDecimals:"0"}),sendUsd:async()=>({transactionId:"0",status:"pending"})};fe(o.debug||!1,"Creating SDK with config:",o);let a={publishableKey:o.publishableKey};o.enableEvents!==void 0?a.enableEvents=o.enableEvents:a.enableEvents=!0,o.apiUrl&&(a.apiUrl=o.apiUrl),o.icHost&&(a.icHost=o.icHost),o.actorProvider&&(a.actorProvider=o.actorProvider),o.connectedWallet&&(a.connectedWallet=o.connectedWallet),o.debug!==void 0&&(a.debug=o.debug),fe(o.debug||!1,"Filtered SDK config:",a);try{fe(o.debug||!1,"typeof Icpay:",typeof Ce);let e=new Ce(a);if(Ae){let r=e,n=l=>{r.addEventListener(l,g=>{window.dispatchEvent(new CustomEvent(l,{detail:g?.detail??g}))})};["icpay-sdk-error","icpay-sdk-transaction-created","icpay-sdk-transaction-updated","icpay-sdk-transaction-completed","icpay-sdk-transaction-failed","icpay-sdk-method-start","icpay-sdk-method-success","icpay-sdk-method-error"].forEach(n)}async function t(r,n){return e.calculateTokenAmountFromUSD({usdAmount:r,ledgerCanisterId:n})}async function i(r,n,l){return e.sendFundsUsd({usdAmount:r,ledgerCanisterId:n,metadata:l})}return{client:e,quoteUsd:t,sendUsd:i}}catch(e){throw fe(o.debug||!1,"Error creating SDK:",e),e}}import{LitElement as Be,html as z,css as He}from"lit";import{customElement as qe,property as Ge,state as U}from"lit/decorators.js";import{IcpayError as Me}from"@ic-pay/icpay-sdk";var x={WALLET_NOT_CONNECTED:"WALLET_NOT_CONNECTED",WALLET_USER_CANCELLED:"WALLET_USER_CANCELLED",WALLET_SIGNATURE_REJECTED:"WALLET_SIGNATURE_REJECTED",INSUFFICIENT_BALANCE:"INSUFFICIENT_BALANCE",NETWORK_ERROR:"NETWORK_ERROR",API_ERROR:"API_ERROR",LEDGER_NOT_FOUND:"LEDGER_NOT_FOUND",TRANSACTION_FAILED:"TRANSACTION_FAILED",TRANSACTION_TIMEOUT:"TRANSACTION_TIMEOUT",UNKNOWN_ERROR:"UNKNOWN_ERROR"},Te={onError:o=>{console.error("[ICPay Widget] Error:",o)},onUserCancelled:()=>{console.log("[ICPay Widget] User cancelled the action")},onInsufficientBalance:o=>{console.warn("[ICPay Widget] Insufficient balance:",o.message)},onWalletError:o=>{console.warn("[ICPay Widget] Wallet error:",o.message)},onNetworkError:o=>{console.error("[ICPay Widget] Network error:",o.message)}};function k(o,a=Te){o instanceof Me?(a.onError(o),o.isUserCancelled()?a.onUserCancelled?.():o.isBalanceError()?a.onInsufficientBalance?.(o):o.isWalletError()?a.onWalletError?.(o):o.isNetworkError()&&a.onNetworkError?.(o)):(console.error("[ICPay Widget] Unknown error:",o),a.onError(new Me({code:x.UNKNOWN_ERROR,message:o instanceof Error?o.message:"An unknown error occurred",details:o})))}var Pe={[x.WALLET_NOT_CONNECTED]:"Please connect your wallet to continue",[x.WALLET_USER_CANCELLED]:"User have rejected the transfer",[x.WALLET_SIGNATURE_REJECTED]:"User have rejected the transfer",[x.INSUFFICIENT_BALANCE]:"Insufficient balance for this transaction",[x.NETWORK_ERROR]:"Network error. Please try again",[x.API_ERROR]:"Service temporarily unavailable",[x.LEDGER_NOT_FOUND]:"Selected token is not supported",[x.TRANSACTION_FAILED]:"Transaction failed. Please try again",[x.TRANSACTION_TIMEOUT]:"Transaction timed out. Please try again",[x.UNKNOWN_ERROR]:"Something went wrong. Please try again"};function W(o){return Pe[o.code]||o.message||"An error occurred"}function $(o){return!o.isUserCancelled()}function L(o){if(o.userAction)return o.userAction;switch(o.code){case x.WALLET_NOT_CONNECTED:return"Connect Wallet";case x.INSUFFICIENT_BALANCE:return"Add Funds";case x.NETWORK_ERROR:case x.API_ERROR:return"Try Again";default:return null}}function C(o){return o.isUserCancelled()?"info":o.isBalanceError()||o.isWalletError()?"warning":"error"}import{LitElement as je,html as y,css as De}from"lit";import{customElement as Fe,property as te,state as T}from"lit/decorators.js";var _e=[{key:"init",label:"Initialising icpay SDK",tooltip:"Initializing payment",status:"pending"},{key:"await",label:"Awaiting payment confirmation",tooltip:"Preparing payment",status:"pending"},{key:"transfer",label:"Transferring funds",tooltip:"Submitting payment",status:"pending"},{key:"verify",label:"Verifying payment",tooltip:"Confirming payment",status:"pending"},{key:"confirm",label:"Payment confirmed",tooltip:"Payment completed",status:"pending"}],d=class extends je{constructor(){super(...arguments);this.open=!1;this.steps=_e;this.amount=0;this.currency="";this.ledgerSymbol="";this.activeIndex=0;this.completed=!1;this.failed=!1;this.errorMessage=null;this.showSuccess=!1;this.showConfetti=!1;this.currentSteps=[];this.currentAmount=0;this.currentCurrency="";this.currentLedgerSymbol="";this.progressionTimer=null;this.onMethodStart=e=>{let t=e?.detail?.name||"",i=e?.detail?.type||"";console.log("ICPay Progress: Method start event received:",e.detail),(t==="sendFunds"||t==="sendFundsUsd"||t==="sendUsd"||t==="pay"||t==="unlock"||t==="tip"||t==="donate"||t==="order")&&(this.open=!0,this.activeIndex=0,this.completed=!1,this.failed=!1,this.errorMessage=null,this.showSuccess=!1,this.showConfetti=!1,this.currentSteps=this.currentSteps.map(r=>({...r,status:"pending"})),this.updateStepStatus(0,"loading"),e?.detail?.amount!==void 0&&(this.currentAmount=e.detail.amount,this.amount=e.detail.amount,console.log("ICPay Progress: Amount updated to:",e.detail.amount)),e?.detail?.currency&&(this.currentCurrency=e.detail.currency,this.currency=e.detail.currency,console.log("ICPay Progress: Currency updated to:",e.detail.currency)),e?.detail?.ledgerSymbol&&(this.currentLedgerSymbol=e.detail.ledgerSymbol,this.ledgerSymbol=e.detail.ledgerSymbol,console.log("ICPay Progress: Current state after method start:",{activeIndex:this.activeIndex,currentAmount:this.currentAmount,currentCurrency:this.currentCurrency,currentLedgerSymbol:this.currentLedgerSymbol})),console.log("ICPay Progress: Waiting for wallet confirmation before starting progression"),this.requestUpdate())};this.onMethodSuccess=e=>{let t=e?.detail?.name||"";(t==="sendFunds"||t==="sendFundsUsd"||t==="sendUsd"||t==="pay"||t==="unlock"||t==="tip"||t==="donate"||t==="order")&&this.dispatchEvent(new CustomEvent("icpay-progress-method-success",{detail:{methodName:t,step:this.activeIndex},bubbles:!0}))};this.onTransactionCreated=e=>{let t=e?.detail?.transactionId||e?.detail?.id;console.log("ICPay Progress: Transaction created event received:",e.detail),this.dispatchEvent(new CustomEvent("icpay-progress-transaction-created",{detail:{transactionId:t,step:this.activeIndex},bubbles:!0}))};this.onTransactionUpdated=e=>{let t=e?.detail?.status||"pending",i=e?.detail?.transactionId||e?.detail?.id;console.log("ICPay Progress: Transaction updated event received:",e.detail),this.dispatchEvent(new CustomEvent("icpay-progress-transaction-updated",{detail:{status:t,transactionId:i,step:this.activeIndex},bubbles:!0}))};this.onTransactionCompleted=e=>{let t=e?.detail?.transactionId||e?.detail?.id,i=e?.detail?.status||"completed";console.log("ICPay Progress: Transaction completed event received:",e.detail),console.log("ICPay Progress: Current state when transaction completed:",{activeIndex:this.activeIndex,completed:this.completed,failed:this.failed,showSuccess:this.showSuccess}),this.stopAutomaticProgression();for(let r=this.activeIndex;r<this.currentSteps.length;r++)this.updateStepStatus(r,"completed");this.activeIndex=this.currentSteps.length-1,this.completed=!0,this.showSuccess=!0,this.showConfetti=!0,this.dispatchEvent(new CustomEvent("icpay-progress-completed",{detail:{transactionId:t,status:i,amount:this.currentAmount||this.amount,currency:this.currentCurrency||this.currency,ledgerSymbol:this.currentLedgerSymbol||this.ledgerSymbol},bubbles:!0})),setTimeout(()=>{this.open&&this.showSuccess&&!this.failed&&(this.open=!1)},2e3),setTimeout(()=>{this.showConfetti=!1},3e3)};this.onTransactionFailed=e=>{let t=e?.detail?.message||e?.detail?.error?.message||"Transaction failed",i=e?.detail?.error?.code||e?.detail?.code||"UNKNOWN_ERROR",r=e?.detail?.transactionId||e?.detail?.id;console.log("ICPay Progress: Transaction failed event received:",e.detail),this.failed=!0,this.errorMessage=this.transformErrorMessage(t),this.showSuccess=!1,this.updateStepStatus(this.activeIndex,"error",t),this.stopAutomaticProgression(),this.open=!0,this.dispatchEvent(new CustomEvent("icpay-progress-failed",{detail:{errorMessage:t,errorCode:i,transactionId:r,step:this.activeIndex},bubbles:!0}))};this.onMethodError=e=>{let t=e?.detail?.name||"",i=e?.detail?.error?.message||e?.detail?.message||"An error occurred",r=e?.detail?.error?.code||e?.detail?.code||"METHOD_ERROR";console.log("ICPay Progress: Method error event received:",e.detail),(t?.startsWith("sendFunds")||t==="sendUsd"||t==="pay"||t==="unlock"||t==="tip"||t==="donate"||t==="order")&&(this.failed=!0,this.errorMessage=this.transformErrorMessage(i),this.showSuccess=!1,this.updateStepStatus(this.activeIndex,"error",i),this.stopAutomaticProgression(),this.open=!0,this.dispatchEvent(new CustomEvent("icpay-progress-error",{detail:{methodName:t,errorMessage:i,errorCode:r,step:this.activeIndex},bubbles:!0})))};this.onSDKError=e=>{let t=e?.detail?.message||"SDK error occurred",i=e?.detail?.code||"SDK_ERROR";console.log("ICPay Progress: SDK error event received:",e.detail),this.failed=!0,this.errorMessage=this.transformErrorMessage(t),this.showSuccess=!1,this.updateStepStatus(this.activeIndex,"error",t),this.stopAutomaticProgression(),this.open=!0,this.dispatchEvent(new CustomEvent("icpay-progress-sdk-error",{detail:{errorMessage:t,errorCode:i,step:this.activeIndex},bubbles:!0}))};this.onWalletConnected=e=>{let t=e?.detail?.walletType||"unknown";console.log("ICPay Progress: Wallet connected event received:",e.detail),this.updateStepStatus(0,"completed"),this.startAutomaticProgression(),this.dispatchEvent(new CustomEvent("icpay-progress-wallet-connected",{detail:{walletType:t,step:this.activeIndex},bubbles:!0}))};this.onWalletDisconnected=e=>{let t=e?.detail?.walletType||"unknown";console.log("ICPay Progress: Wallet disconnected event received:",e.detail),this.dispatchEvent(new CustomEvent("icpay-progress-wallet-disconnected",{detail:{walletType:t,step:this.activeIndex},bubbles:!0}))};this.onBalanceCheck=e=>{let t=e?.detail?.hasBalance||!1,i=e?.detail?.balance||0;console.log("ICPay Progress: Balance check event received:",e.detail),t||(this.failed=!0,this.errorMessage="Insufficient balance for transaction",this.updateStepStatus(this.activeIndex,"error","Insufficient balance for transaction"),this.stopAutomaticProgression(),this.dispatchEvent(new CustomEvent("icpay-progress-insufficient-balance",{detail:{balance:i,required:this.currentAmount||this.amount,step:this.activeIndex},bubbles:!0})))};this.onLedgerVerified=e=>{let t=e?.detail?.ledgerId||e?.detail?.canisterId,i=e?.detail?.symbol||"unknown";console.log("ICPay Progress: Ledger verified event received:",e.detail),i&&i!=="unknown"&&(this.currentLedgerSymbol=i,this.ledgerSymbol=i),this.dispatchEvent(new CustomEvent("icpay-progress-ledger-verified",{detail:{ledgerId:t,symbol:i,step:this.activeIndex},bubbles:!0}))};this.onWidgetPayment=e=>{let t=e?.detail?.amount,i=e?.detail?.currency,r=e?.detail?.ledgerSymbol;console.log("ICPay Progress: Widget payment event received:",e.detail),t!==void 0&&(this.currentAmount=t,this.amount=t),i&&(this.currentCurrency=i,this.currency=i),r&&(this.currentLedgerSymbol=r,this.ledgerSymbol=r),this.dispatchEvent(new CustomEvent("icpay-progress-widget-payment",{detail:{amount:t,currency:i,ledgerSymbol:r,step:this.activeIndex},bubbles:!0}))};this.onWidgetError=e=>{let t=e?.detail?.message||"Widget error occurred",i=e?.detail?.code||"WIDGET_ERROR";console.log("ICPay Progress: Widget error event received:",e.detail),this.failed=!0,this.errorMessage=this.transformErrorMessage(t),this.showSuccess=!1,this.updateStepStatus(this.activeIndex,"error",t),this.stopAutomaticProgression(),this.open=!0,this.dispatchEvent(new CustomEvent("icpay-progress-widget-error",{detail:{errorMessage:t,errorCode:i,step:this.activeIndex},bubbles:!0}))};this.onWidgetUnlock=e=>{let t=e?.detail?.amount,i=e?.detail?.currency;console.log("ICPay Progress: Widget unlock event received:",e.detail),this.dispatchEvent(new CustomEvent("icpay-progress-widget-unlock",{detail:{amount:t,currency:i,step:this.activeIndex},bubbles:!0}))};this.onWidgetTip=e=>{let t=e?.detail?.amount,i=e?.detail?.currency;console.log("ICPay Progress: Widget tip event received:",e.detail),this.dispatchEvent(new CustomEvent("icpay-progress-widget-tip",{detail:{amount:t,currency:i,step:this.activeIndex},bubbles:!0}))};this.onWidgetDonation=e=>{let t=e?.detail?.amount,i=e?.detail?.currency;console.log("ICPay Progress: Widget donation event received:",e.detail),this.dispatchEvent(new CustomEvent("icpay-progress-widget-donation",{detail:{amount:t,currency:i,step:this.activeIndex},bubbles:!0}))};this.onWidgetCoffee=e=>{let t=e?.detail?.amount,i=e?.detail?.currency;console.log("ICPay Progress: Widget coffee event received:",e.detail),this.dispatchEvent(new CustomEvent("icpay-progress-widget-coffee",{detail:{amount:t,currency:i,step:this.activeIndex},bubbles:!0}))}}connectedCallback(){super.connectedCallback();try{ee(this,this.theme)}catch{}this.currentSteps=[...this.steps],this.currentAmount=this.amount,this.currentCurrency=this.currency,this.currentLedgerSymbol=this.ledgerSymbol,this.attachSDKEventListeners()}disconnectedCallback(){super.disconnectedCallback(),this.detachSDKEventListeners(),this.stopAutomaticProgression()}updated(e){if(e.has("theme"))try{ee(this,this.theme)}catch{}}attachSDKEventListeners(){window.addEventListener("icpay-sdk-method-start",this.onMethodStart),window.addEventListener("icpay-sdk-method-success",this.onMethodSuccess),window.addEventListener("icpay-sdk-method-error",this.onMethodError),window.addEventListener("icpay-sdk-transaction-created",this.onTransactionCreated),window.addEventListener("icpay-sdk-transaction-updated",this.onTransactionUpdated),window.addEventListener("icpay-sdk-transaction-completed",this.onTransactionCompleted),window.addEventListener("icpay-sdk-transaction-failed",this.onTransactionFailed),window.addEventListener("icpay-sdk-error",this.onSDKError),window.addEventListener("icpay-sdk-wallet-connected",this.onWalletConnected),window.addEventListener("icpay-sdk-wallet-disconnected",this.onWalletDisconnected),window.addEventListener("icpay-sdk-balance-check",this.onBalanceCheck),window.addEventListener("icpay-sdk-ledger-verified",this.onLedgerVerified),window.addEventListener("icpay-pay",this.onWidgetPayment),window.addEventListener("icpay-error",this.onWidgetError),window.addEventListener("icpay-unlock",this.onWidgetUnlock),window.addEventListener("icpay-tip",this.onWidgetTip),window.addEventListener("icpay-donation",this.onWidgetDonation),window.addEventListener("icpay-coffee",this.onWidgetCoffee)}detachSDKEventListeners(){window.removeEventListener("icpay-sdk-method-start",this.onMethodStart),window.removeEventListener("icpay-sdk-method-success",this.onMethodSuccess),window.removeEventListener("icpay-sdk-method-error",this.onMethodError),window.removeEventListener("icpay-sdk-transaction-created",this.onTransactionCreated),window.removeEventListener("icpay-sdk-transaction-updated",this.onTransactionUpdated),window.removeEventListener("icpay-sdk-transaction-completed",this.onTransactionCompleted),window.removeEventListener("icpay-sdk-transaction-failed",this.onTransactionFailed),window.removeEventListener("icpay-sdk-error",this.onSDKError),window.removeEventListener("icpay-sdk-wallet-connected",this.onWalletConnected),window.removeEventListener("icpay-sdk-wallet-disconnected",this.onWalletDisconnected),window.removeEventListener("icpay-sdk-balance-check",this.onBalanceCheck),window.removeEventListener("icpay-sdk-ledger-verified",this.onLedgerVerified),window.removeEventListener("icpay-pay",this.onWidgetPayment),window.removeEventListener("icpay-error",this.onWidgetError),window.removeEventListener("icpay-unlock",this.onWidgetUnlock),window.removeEventListener("icpay-tip",this.onWidgetTip),window.removeEventListener("icpay-donation",this.onWidgetDonation),window.removeEventListener("icpay-coffee",this.onWidgetCoffee)}startAutomaticProgression(){this.progressionTimer&&clearInterval(this.progressionTimer),this.activeIndex=1,this.updateStepStatus(this.activeIndex,"loading"),console.log("ICPay Progress: Starting automatic progression from step:",this.activeIndex),this.progressionTimer=setInterval(()=>{if(this.failed||this.completed){this.stopAutomaticProgression();return}console.log("ICPay Progress: Processing step:",this.activeIndex),this.updateStepStatus(this.activeIndex,"completed"),this.activeIndex<this.currentSteps.length-1?(this.activeIndex++,this.updateStepStatus(this.activeIndex,"loading"),console.log("ICPay Progress: Auto-progressed to step:",this.activeIndex)):(this.stopAutomaticProgression(),console.log("ICPay Progress: All steps completed, waiting for transaction completion")),this.requestUpdate()},3e3)}stopAutomaticProgression(){this.progressionTimer&&(clearInterval(this.progressionTimer),this.progressionTimer=null)}updateStepStatus(e,t,i){if(e>=0&&e<this.currentSteps.length){let r=this.currentSteps[e],n=r.status;r.status=t,t==="completed"&&(r.timestamp=this.getCurrentTime()),t==="error"&&i&&(r.errorMessage=this.transformErrorMessage(i)),console.log(`ICPay Progress: Step ${e} (${r.label}) status changed from ${n} to ${t}`),this.requestUpdate()}}getCurrentTime(){return new Date().toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}progressPercent(){if(this.failed)return 0;if(this.showSuccess)return 100;let t=this.currentSteps.filter(i=>i.status==="completed").length/this.currentSteps.length*100;return Math.max(0,Math.min(100,t))}verticalPercent(){if(this.failed)return 0;if(this.showSuccess)return 100;let t=this.currentSteps.filter(i=>i.status==="completed").length/this.currentSteps.length*100;return Math.max(0,Math.min(100,t))}getStepIcon(e){switch(e.status){case"loading":return y`<div class="spinner"></div>`;case"completed":return"\u2713";case"error":return"\u2717";default:return"\u25CB"}}transformErrorMessage(e){let t=String(e||"").toLowerCase();return t.includes("user rejected")||t.includes("user cancelled")||t.includes("user canceled")||t.includes("signature rejected")?"User have rejected the transfer":e}renderConfetti(){if(!this.showConfetti)return"";let e=Array.from({length:50},(i,r)=>r),t=["#0066FF","#ef4444","#10b981","#f59e0b","#8b5cf6"];return y`
|
|
61
|
+
<div class="confetti">
|
|
62
|
+
${e.map(i=>y`
|
|
63
|
+
<div
|
|
64
|
+
class="confetti-piece"
|
|
65
|
+
style="
|
|
66
|
+
left: ${Math.random()*100}%;
|
|
67
|
+
top: ${Math.random()*100}%;
|
|
68
|
+
background-color: ${t[Math.floor(Math.random()*t.length)]};
|
|
69
|
+
animation-delay: ${Math.random()*2}s;
|
|
70
|
+
animation-duration: ${2+Math.random()*2}s;
|
|
71
|
+
"
|
|
72
|
+
></div>
|
|
73
|
+
`)}
|
|
74
|
+
</div>
|
|
75
|
+
`}renderSuccessState(){let e=this.currentAmount||this.amount,t=this.currentLedgerSymbol||this.currentCurrency||this.currency;return console.log("ICPay Progress: Rendering success state with:",{displayAmount:e,displayCurrency:t,currentAmount:this.currentAmount,amount:this.amount,currentCurrency:this.currentCurrency,currency:this.currency,currentLedgerSymbol:this.currentLedgerSymbol,ledgerSymbol:this.ledgerSymbol}),y`
|
|
76
|
+
<div class="success-container">
|
|
77
|
+
<div class="success-icon">
|
|
78
|
+
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
79
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
|
80
|
+
</svg>
|
|
81
|
+
</div>
|
|
82
|
+
<h2 class="success-title">Payment Complete!</h2>
|
|
83
|
+
<p class="success-message">Your payment of ${e} ${t} has been successfully processed.</p>
|
|
84
|
+
<div class="success-actions">
|
|
85
|
+
<button class="btn btn-primary" @click=${()=>{this.open=!1}}>Close</button>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
`}renderErrorState(){return y`
|
|
89
|
+
<div class="error-message">
|
|
90
|
+
<div class="error-icon">⚠</div>
|
|
91
|
+
<div class="error-content">
|
|
92
|
+
<h4>Transaction Failed</h4>
|
|
93
|
+
<p>${this.errorMessage}</p>
|
|
94
|
+
<div class="success-actions" style="margin-top:12px;">
|
|
95
|
+
<button class="btn btn-primary" @click=${()=>{this.open=!1}}>Close</button>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
`}renderProgressContent(){return this.showSuccess?this.renderSuccessState():this.failed?this.renderErrorState():y`
|
|
100
|
+
<div class="progress-container">
|
|
101
|
+
<div class="progress-header">
|
|
102
|
+
<h2 class="progress-title">Processing Payment</h2>
|
|
103
|
+
<p class="progress-subtitle">Please wait while we process your transaction</p>
|
|
104
|
+
</div>
|
|
105
|
+
<div class="progress-steps">
|
|
106
|
+
${this.currentSteps.map((e,t)=>y`
|
|
107
|
+
<div class="step ${t===this.activeIndex?"active":""} ${e.status==="completed"?"completed":""}">
|
|
108
|
+
<div class="step-icon">
|
|
109
|
+
${e.status==="loading"?y`<div class="loading-spinner"></div>`:""}
|
|
110
|
+
${e.status==="completed"?y`
|
|
111
|
+
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
112
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
|
113
|
+
</svg>
|
|
114
|
+
`:y`
|
|
115
|
+
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
116
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
|
|
117
|
+
</svg>
|
|
118
|
+
`}
|
|
119
|
+
</div>
|
|
120
|
+
<div class="step-content">
|
|
121
|
+
<div class="step-title">${e.label}</div>
|
|
122
|
+
<div class="step-description">${e.tooltip}</div>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
`)}
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
`}retryTransaction(){this.activeIndex=0,this.completed=!1,this.failed=!1,this.errorMessage=null,this.showSuccess=!1,this.showConfetti=!1,this.currentSteps=this.currentSteps.map(e=>({...e,status:"pending"})),this.updateStepStatus(0,"loading"),this.startAutomaticProgression(),this.requestUpdate()}closeProgress(){this.open=!1}renderStep(e,t){return y`
|
|
129
|
+
<div class="step-item ${e.status}">
|
|
130
|
+
<div class="step-icon">
|
|
131
|
+
${this.getStepIcon(e)}
|
|
132
|
+
</div>
|
|
133
|
+
<div class="step-content">
|
|
134
|
+
<div class="step-title">
|
|
135
|
+
${e.status==="completed"?"COMPLETED":e.label}
|
|
136
|
+
</div>
|
|
137
|
+
${e.status==="completed"?y`
|
|
138
|
+
<div class="step-subtitle">
|
|
139
|
+
${e.timestamp} - ${e.tooltip}
|
|
140
|
+
</div>
|
|
141
|
+
`:e.status==="error"&&e.errorMessage?y`
|
|
142
|
+
<div class="step-error">${e.errorMessage}</div>
|
|
143
|
+
`:y`
|
|
144
|
+
<div class="step-subtitle">${e.tooltip}</div>
|
|
145
|
+
`}
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
`}render(){return y`
|
|
149
|
+
${this.open?y`
|
|
150
|
+
${this.renderConfetti()}
|
|
151
|
+
<div class="modal-overlay active">
|
|
152
|
+
<div class="modal-container">
|
|
153
|
+
${this.renderProgressContent()}
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
`:null}
|
|
157
|
+
`}};d.styles=De`
|
|
158
|
+
:host {
|
|
159
|
+
display: block;
|
|
160
|
+
font-family: var(--icpay-font, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
|
|
161
|
+
color: #ffffff;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.modal-overlay {
|
|
165
|
+
position: fixed;
|
|
166
|
+
top: 0;
|
|
167
|
+
left: 0;
|
|
168
|
+
right: 0;
|
|
169
|
+
bottom: 0;
|
|
170
|
+
background: rgba(0, 0, 0, 0.85);
|
|
171
|
+
backdrop-filter: blur(10px);
|
|
172
|
+
display: flex;
|
|
173
|
+
align-items: center;
|
|
174
|
+
justify-content: center;
|
|
175
|
+
z-index: 1000;
|
|
176
|
+
opacity: 0;
|
|
177
|
+
visibility: hidden;
|
|
178
|
+
transition: opacity 0.3s ease, visibility 0.3s ease;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.modal-overlay.active {
|
|
182
|
+
opacity: 1;
|
|
183
|
+
visibility: visible;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.modal-container {
|
|
187
|
+
background: linear-gradient(180deg, #1a1a1a 0%, #0f0f0f 100%);
|
|
188
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
189
|
+
border-radius: 24px;
|
|
190
|
+
padding: 48px;
|
|
191
|
+
max-width: 480px;
|
|
192
|
+
width: 90%;
|
|
193
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
|
|
194
|
+
transform: translateY(20px);
|
|
195
|
+
transition: transform 0.3s ease;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.modal-overlay.active .modal-container {
|
|
199
|
+
transform: translateY(0);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.close-button {
|
|
203
|
+
position: absolute;
|
|
204
|
+
top: 16px;
|
|
205
|
+
right: 16px;
|
|
206
|
+
background: none;
|
|
207
|
+
border: none;
|
|
208
|
+
color: #666666;
|
|
209
|
+
cursor: pointer;
|
|
210
|
+
padding: 8px;
|
|
211
|
+
border-radius: 6px;
|
|
212
|
+
transition: all 0.2s;
|
|
213
|
+
font-size: 18px;
|
|
214
|
+
line-height: 1;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.close-button:hover {
|
|
218
|
+
background: #1a1a1a;
|
|
219
|
+
color: #ffffff;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.progress-header { text-align: center; margin-bottom: 40px; }
|
|
223
|
+
.progress-title {
|
|
224
|
+
font-size: 24px;
|
|
225
|
+
font-weight: 600;
|
|
226
|
+
margin-bottom: 8px;
|
|
227
|
+
background: linear-gradient(135deg, #ffffff 0%, #888888 100%);
|
|
228
|
+
-webkit-background-clip: text;
|
|
229
|
+
-webkit-text-fill-color: transparent;
|
|
230
|
+
background-clip: text;
|
|
231
|
+
}
|
|
232
|
+
.progress-subtitle { color: #666666; font-size: 14px; }
|
|
233
|
+
.progress-steps { margin-bottom: 40px; }
|
|
234
|
+
.step { display: flex; align-items: center; margin-bottom: 24px; opacity: 0.3; transition: opacity 0.3s ease; }
|
|
235
|
+
.step.active { opacity: 1; }
|
|
236
|
+
.step.completed { opacity: 0.7; }
|
|
237
|
+
.step-icon { width: 40px; height: 40px; border-radius: 50%; background: #1a1a1a; border: 2px solid #333333; display: flex; align-items: center; justify-content: center; margin-right: 16px; transition: all 0.3s ease; position: relative; }
|
|
238
|
+
.step.active .step-icon { background: #1a1a1a; border-color: #4a9eff; box-shadow: 0 0 0 4px rgba(74, 158, 255, 0.2); }
|
|
239
|
+
.step.completed .step-icon { background: #0d7c3d; border-color: #0d7c3d; }
|
|
240
|
+
.step-icon svg { width: 20px; height: 20px; stroke: #666666; transition: stroke 0.3s ease; }
|
|
241
|
+
.step.active .step-icon svg { stroke: #4a9eff; }
|
|
242
|
+
.step.completed .step-icon svg { stroke: #ffffff; }
|
|
243
|
+
.step-content { flex: 1; }
|
|
244
|
+
.step-title { font-weight: 500; font-size: 16px; margin-bottom: 4px; color: #999999; transition: color 0.3s ease; }
|
|
245
|
+
.step.active .step-title { color: #ffffff; }
|
|
246
|
+
.step-description { font-size: 14px; color: #666666; }
|
|
247
|
+
.loading-spinner { display: none; width: 20px; height: 20px; border: 2px solid rgba(74, 158, 255, 0.2); border-top-color: #4a9eff; border-radius: 50%; animation: spin 1s linear infinite; position: absolute; }
|
|
248
|
+
.step.active .loading-spinner { display: block; }
|
|
249
|
+
|
|
250
|
+
.error-message {
|
|
251
|
+
display: flex;
|
|
252
|
+
align-items: flex-start;
|
|
253
|
+
gap: 12px;
|
|
254
|
+
padding: 16px;
|
|
255
|
+
background: #0a0a0a;
|
|
256
|
+
border: 1px solid #dc2626;
|
|
257
|
+
border-radius: 8px;
|
|
258
|
+
margin-top: 8px;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.error-icon {
|
|
262
|
+
flex-shrink: 0;
|
|
263
|
+
width: 20px;
|
|
264
|
+
height: 20px;
|
|
265
|
+
background: #dc2626;
|
|
266
|
+
border-radius: 50%;
|
|
267
|
+
display: flex;
|
|
268
|
+
align-items: center;
|
|
269
|
+
justify-content: center;
|
|
270
|
+
color: #ffffff;
|
|
271
|
+
font-size: 12px;
|
|
272
|
+
font-weight: bold;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.error-content h4 {
|
|
276
|
+
margin: 0 0 4px 0;
|
|
277
|
+
font-size: 14px;
|
|
278
|
+
font-weight: 600;
|
|
279
|
+
color: #ffffff;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.error-content p {
|
|
283
|
+
margin: 0;
|
|
284
|
+
font-size: 12px;
|
|
285
|
+
color: #f87171;
|
|
286
|
+
line-height: 1.4;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.success-container { text-align: center; }
|
|
290
|
+
.success-icon { width: 80px; height: 80px; margin: 0 auto 24px; background: linear-gradient(135deg, #0d7c3d 0%, #0fa855 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; }
|
|
291
|
+
.success-icon svg { width: 40px; height: 40px; stroke: #ffffff; stroke-width: 3; }
|
|
292
|
+
.success-title { font-size: 28px; font-weight: 600; margin-bottom: 12px; background: linear-gradient(135deg, #0fa855 0%, #0d7c3d 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
|
|
293
|
+
.success-message { color: #999999; margin-bottom: 24px; font-size: 16px; }
|
|
294
|
+
.success-actions { display: flex; gap: 12px; justify-content: center; }
|
|
295
|
+
.btn { padding: 12px 24px; border-radius: 12px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.3s ease; text-decoration: none; display: inline-flex; align-items: center; gap: 8px; }
|
|
296
|
+
.btn-primary { background: linear-gradient(135deg, #4a9eff 0%, #3a7edf 100%); color: #ffffff; border: none; }
|
|
297
|
+
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(74, 158, 255, 0.3); }
|
|
298
|
+
.btn-secondary { background: transparent; color: #999999; border: 1px solid #333333; }
|
|
299
|
+
.btn-secondary:hover { background: rgba(255, 255, 255, 0.05); border-color: #555555; color: #ffffff; }
|
|
300
|
+
|
|
301
|
+
.confetti {
|
|
302
|
+
position: fixed;
|
|
303
|
+
top: 0;
|
|
304
|
+
left: 0;
|
|
305
|
+
width: 100%;
|
|
306
|
+
height: 100%;
|
|
307
|
+
pointer-events: none;
|
|
308
|
+
z-index: 1001;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.confetti-piece {
|
|
312
|
+
position: absolute;
|
|
313
|
+
width: 8px;
|
|
314
|
+
height: 8px;
|
|
315
|
+
background: #0066FF;
|
|
316
|
+
animation: confetti-fall 3s linear forwards;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
@keyframes spin {
|
|
320
|
+
from { transform: rotate(0deg); }
|
|
321
|
+
to { transform: rotate(360deg); }
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.spinner {
|
|
325
|
+
width: 16px;
|
|
326
|
+
height: 16px;
|
|
327
|
+
border: 2px solid transparent;
|
|
328
|
+
border-top: 2px solid #ffffff;
|
|
329
|
+
border-radius: 50%;
|
|
330
|
+
animation: spin 1s linear infinite;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
@keyframes confetti-fall {
|
|
334
|
+
0% {
|
|
335
|
+
transform: translateY(-100vh) rotate(0deg);
|
|
336
|
+
opacity: 1;
|
|
337
|
+
}
|
|
338
|
+
100% {
|
|
339
|
+
transform: translateY(100vh) rotate(720deg);
|
|
340
|
+
opacity: 0;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
`,s([te({type:Boolean})],d.prototype,"open",2),s([te({type:Array})],d.prototype,"steps",2),s([te({type:Number})],d.prototype,"amount",2),s([te({type:String})],d.prototype,"currency",2),s([te({type:String})],d.prototype,"ledgerSymbol",2),s([T()],d.prototype,"activeIndex",2),s([T()],d.prototype,"completed",2),s([T()],d.prototype,"failed",2),s([T()],d.prototype,"errorMessage",2),s([T()],d.prototype,"showSuccess",2),s([T()],d.prototype,"showConfetti",2),s([T()],d.prototype,"currentSteps",2),s([T()],d.prototype,"currentAmount",2),s([T()],d.prototype,"currentCurrency",2),s([T()],d.prototype,"currentLedgerSymbol",2),s([te({type:Object})],d.prototype,"theme",2),d=s([Fe("icpay-progress-bar")],d);import{LitElement as ze,html as pe,css as Ke}from"lit";import{customElement as Ve,property as ge}from"lit/decorators.js";var P=class extends ze{constructor(){super(...arguments);this.options=[];this.value=null;this.defaultSymbol="ICP";this.mode="buttons"}connectedCallback(){super.connectedCallback();try{ee(this,this.theme)}catch{}}updated(e){if(e.has("theme"))try{ee(this,this.theme)}catch{}}get effectiveSymbol(){if(this.value)return this.value;let e=this.options?.[0]?.symbol;return this.defaultSymbol||e||"ICP"}onSelect(e){this.value=e,this.dispatchEvent(new CustomEvent("icpay-token-change",{detail:{symbol:e},bubbles:!0,composed:!0}))}render(){let e=this.options||[];if(this.mode==="none"||e.length<=1){let i=e.length===1?e[0].symbol:this.effectiveSymbol;return this.value!==i&&queueMicrotask(()=>this.onSelect(i)),pe``}if(this.mode==="dropdown"){let i=this.effectiveSymbol;return pe`
|
|
344
|
+
<select @change=${r=>this.onSelect(r.target.value)}>
|
|
345
|
+
${e.map(r=>pe`<option value="${r.symbol}" ?selected=${i===r.symbol}>${r.label}<span class="icpay-token-selector-symbol"> (${r.symbol})</span></option>`)}
|
|
346
|
+
</select>
|
|
347
|
+
`}let t=this.effectiveSymbol;return pe`
|
|
348
|
+
<div class="icpay-token-selector">
|
|
349
|
+
<label class="label">Select Payment Method</label>
|
|
350
|
+
<div class="crypto-grid">
|
|
351
|
+
${e.map(i=>pe`
|
|
352
|
+
<div class="crypto-option ${t===i.symbol?"selected":""}" @click=${()=>this.onSelect(i.symbol)}>${i.label}<span class="icpay-token-selector-symbol"> (${i.symbol})</span></div>
|
|
353
|
+
`)}
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
`}};P.styles=Ke`
|
|
357
|
+
:host { display: block; }
|
|
358
|
+
.crypto-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 12px 0 16px; }
|
|
359
|
+
.crypto-option { background: var(--icpay-surface-alt); border: 2px solid var(--icpay-border); border-radius: 12px; padding: 12px 8px; text-align: center; cursor: pointer; color: var(--icpay-text); font-weight: 600; font-size: 12px; }
|
|
360
|
+
.crypto-option.selected { background: var(--icpay-primary); color: #111827; border-color: var(--icpay-primary); }
|
|
361
|
+
select { background: var(--icpay-surface-alt); border: 1px solid var(--icpay-border); color: var(--icpay-text); border-radius: 8px; padding: 10px; font-weight: 600; }
|
|
362
|
+
`,s([ge({type:Array})],P.prototype,"options",2),s([ge({type:String})],P.prototype,"value",2),s([ge({type:String})],P.prototype,"defaultSymbol",2),s([ge({type:String})],P.prototype,"mode",2),s([ge({type:Object})],P.prototype,"theme",2),P=s([Ve("icpay-token-selector")],P);var ye=typeof window<"u",ie=null;function q(o,a,e){o&&(e!==void 0?console.log(`[ICPay Widget] ${a}`,e):console.log(`[ICPay Widget] ${a}`))}var b=class extends Be{constructor(){super(...arguments);this.selectedSymbol="ICP";this.unlocked=!1;this.succeeded=!1;this.processing=!1;this.availableLedgers=[];this.errorMessage=null;this.errorSeverity=null;this.errorAction=null;this.walletConnected=!1;this.pendingAction=null;this.showWalletModal=!1;this.pnp=null}async tryAutoConnectPNP(){try{if(!this.config||this.config?.useOwnWallet)return;let e=localStorage.getItem("icpay:pnp");if(!e)return;let t=JSON.parse(e);if(!t?.provider||!t?.principal)return;ie||(ie=(await import("@windoge98/plug-n-play")).PNP);let i=new ie(this.config?.plugNPlay||{});this.walletConnected=!1,this.config={...this.config,connectedWallet:{owner:t.principal,principal:t.principal,connected:!1}}}catch{}}get cryptoOptions(){return this.config.cryptoOptions?this.config.cryptoOptions:this.availableLedgers}connectedCallback(){super.connectedCallback(),ye&&(q(this.config?.debug||!1,"Premium content connected",{config:this.config}),this.tryAutoConnectPNP(),this.config?.cryptoOptions&&this.config.cryptoOptions.length>0||this.loadVerifiedLedgers())}updated(e){if(e.has("config")&&this.pendingAction&&this.config?.actorProvider){let t=this.pendingAction;this.pendingAction=null,setTimeout(()=>{t==="pay"&&this.onPay()},0)}}async loadVerifiedLedgers(){if(!(!ye||!this.config?.publishableKey))try{let t=await c(this.config).client.getVerifiedLedgers();this.availableLedgers=t.map(i=>({symbol:i.symbol,label:i.name,canisterId:i.canisterId})),this.selectedSymbol||(this.selectedSymbol=this.config?.defaultSymbol||this.availableLedgers[0]?.symbol||"ICP")}catch(e){console.warn("Failed to load verified ledgers:",e),this.availableLedgers=[{symbol:"ICP",label:"ICP",canisterId:"ryjl3-tyaaa-aaaaa-aaaba-cai"}],this.selectedSymbol||(this.selectedSymbol="ICP")}}async onPay(){if(ye&&!(this.processing||this.unlocked)){q(this.config?.debug||!1,"Premium content payment started",{priceUsd:this.config.priceUsd,selectedSymbol:this.selectedSymbol,useOwnWallet:this.config.useOwnWallet}),this.errorMessage=null,this.errorSeverity=null,this.errorAction=null,this.processing=!0;try{if(this.config.useOwnWallet){if(!this.config.actorProvider){this.pendingAction="pay",this.dispatchEvent(new CustomEvent("icpay-connect-wallet",{bubbles:!0}));return}}else if(!this.walletConnected){q(this.config?.debug||!1,"Connecting to wallet via Plug N Play");try{ie||(ie=(await import("@windoge98/plug-n-play")).PNP),this.pnp=new ie(this.config?.plugNPlay||{});let n=this.pnp.getEnabledWallets();if(q(this.config?.debug||!1,"Available wallets",n),!n?.length)throw new Error("No wallets available");this.pendingAction="pay",this.showWalletModal=!0;return}catch(n){q(this.config?.debug||!1,"Wallet connection error:",n),this.errorMessage=n instanceof Error?n.message:"Wallet connection failed",this.errorSeverity="error";return}}q(this.config?.debug||!1,"Creating SDK for payment");let e=c(this.config),i=this.cryptoOptions.find(n=>n.symbol===this.selectedSymbol).canisterId||await e.client.getLedgerCanisterIdBySymbol(this.selectedSymbol);q(this.config?.debug||!1,"Payment details",{priceUsd:this.config.priceUsd,selectedSymbol:this.selectedSymbol,canisterId:i});let r=await e.sendUsd(this.config.priceUsd,i,{context:"premium-content"});q(this.config?.debug||!1,"Payment completed",{resp:r}),this.unlocked=!0,this.succeeded=!0,this.config.onSuccess&&this.config.onSuccess({id:r.transactionId,status:r.status}),this.dispatchEvent(new CustomEvent("icpay-unlock",{detail:{amount:this.config.priceUsd,tx:r},bubbles:!0}))}catch(e){k(e,{onError:t=>{this.dispatchEvent(new CustomEvent("icpay-error",{detail:t,bubbles:!0})),$(t)&&(this.errorMessage=W(t),this.errorSeverity=C(t),this.errorAction=L(t))}})}finally{this.processing=!1,this.pendingAction=null}}}select(e){this.selectedSymbol=e}getWalletId(e){return e&&(e.id||e.provider||e.key)||""}getWalletLabel(e){return e&&(e.label||e.name||e.title||e.id)||"Wallet"}getWalletIcon(e){return e&&(e.icon||e.logo||e.image)||null}async connectWithWallet(e){if(this.pnp)try{if(!e)throw new Error("No wallet ID provided");let t=await this.pnp.connect(e);if(!!!(t&&(t.connected===!0||t.principal||t.owner||this.pnp?.account)))throw new Error("Wallet connection was rejected");this.walletConnected=!0,this.config={...this.config,connectedWallet:t,actorProvider:(n,l)=>this.pnp.getActor({canisterId:n,idl:l,requiresSigning:!0,anon:!1})},this.showWalletModal=!1;let r=this.pendingAction;this.pendingAction=null,r==="pay"&&setTimeout(()=>this.onPay(),0)}catch(t){this.errorMessage=t instanceof Error?t.message:"Wallet connection failed",this.errorSeverity="error",this.showWalletModal=!1}}render(){return this.config?z`
|
|
363
|
+
<div class="card section">
|
|
364
|
+
${this.config?.progressBar?.enabled!==!1?z`<icpay-progress-bar mode="${this.config?.progressBar?.mode||"modal"}"></icpay-progress-bar>`:null}
|
|
365
|
+
<div class="image-container">
|
|
366
|
+
<div class="locked-image ${this.unlocked?"unlocked":""}" style="background-image:url('${this.config.imageUrl||""}')"></div>
|
|
367
|
+
${this.unlocked?null:z`<div class="lock-overlay">🔒</div>`}
|
|
368
|
+
</div>
|
|
369
|
+
|
|
370
|
+
<div class="pricing">
|
|
371
|
+
<div class="price">$${Number(this.config?.priceUsd??0).toFixed(2)}</div>
|
|
372
|
+
<div class="label">One-time unlock</div>
|
|
373
|
+
</div>
|
|
374
|
+
|
|
375
|
+
<div>
|
|
376
|
+
<icpay-token-selector
|
|
377
|
+
.options=${this.cryptoOptions}
|
|
378
|
+
.value=${this.selectedSymbol||""}
|
|
379
|
+
.defaultSymbol=${this.config?.defaultSymbol||"ICP"}
|
|
380
|
+
mode=${this.config?.showLedgerDropdown||"buttons"}
|
|
381
|
+
@icpay-token-change=${e=>this.select(e.detail.symbol)}
|
|
382
|
+
></icpay-token-selector>
|
|
383
|
+
</div>
|
|
384
|
+
|
|
385
|
+
<button class="pay-button ${this.processing?"processing":""}" ?disabled=${this.processing||this.unlocked||this.config?.disablePaymentButton===!0||this.succeeded&&this.config?.disableAfterSuccess===!0} @click=${()=>this.onPay()}>
|
|
386
|
+
${this.unlocked?"Unlocked":this.processing?"Processing\u2026":(this.config?.buttonLabel||"Pay ${amount} with {symbol}").replace("{amount}",`${Number(this.config?.priceUsd??0).toFixed(2)}`).replace("{symbol}",this.selectedSymbol)}
|
|
387
|
+
</button>
|
|
388
|
+
|
|
389
|
+
${this.errorMessage?z`
|
|
390
|
+
<div class="error-message ${this.errorSeverity}" style="margin-top: 12px; padding: 8px 12px; border-radius: 6px; font-size: 14px; text-align: center;">
|
|
391
|
+
${this.errorMessage}
|
|
392
|
+
${this.errorAction?z`
|
|
393
|
+
<button style="margin-left: 8px; padding: 4px 8px; background: transparent; border: 1px solid currentColor; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
|
394
|
+
${this.errorAction}
|
|
395
|
+
</button>
|
|
396
|
+
`:""}
|
|
397
|
+
</div>
|
|
398
|
+
`:""}
|
|
399
|
+
${(()=>{let e=this.pnp?.getEnabledWallets?.()||[];return this.showWalletModal&&this.pnp?z`
|
|
400
|
+
<div style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.55);z-index:9999">
|
|
401
|
+
<div class="card section" style="width:380px;border-radius:12px">
|
|
402
|
+
<div class="label" style="font-weight:700;margin-bottom:12px;text-align:center">Choose Wallet</div>
|
|
403
|
+
<div style="display:grid;grid-template-columns:1fr;gap:10px;margin-bottom:12px">
|
|
404
|
+
${e.map(t=>{let i=this.getWalletId(t),r=this.getWalletLabel(t),n=this.getWalletIcon(t);return z`
|
|
405
|
+
<button class="pay-button" style="display:flex;align-items:center;gap:10px;justify-content:center;padding:12px" @click=${()=>this.connectWithWallet(i)}>
|
|
406
|
+
${n?z`<img src="${n}" alt="${r}" style="width:20px;height:20px;border-radius:4px;object-fit:contain;background:transparent" />`:""}
|
|
407
|
+
<span>${r}</span>
|
|
408
|
+
</button>`})}
|
|
409
|
+
</div>
|
|
410
|
+
<button class="pay-button" style="background:#6b7280;color:#f9fafb" @click=${()=>{this.showWalletModal=!1}}>
|
|
411
|
+
Cancel
|
|
412
|
+
</button>
|
|
413
|
+
</div>
|
|
414
|
+
</div>
|
|
415
|
+
`:null})()}
|
|
416
|
+
</div>
|
|
417
|
+
`:z`<div class="card section">Loading...</div>`}};b.styles=[S,He`
|
|
418
|
+
.image-container {
|
|
419
|
+
position: relative;
|
|
420
|
+
border-radius: 16px;
|
|
421
|
+
overflow: hidden;
|
|
422
|
+
margin-bottom: 16px;
|
|
423
|
+
background: #111827;
|
|
424
|
+
border: 1px solid var(--icpay-border);
|
|
425
|
+
aspect-ratio: 16/10;
|
|
426
|
+
}
|
|
427
|
+
.locked-image {
|
|
428
|
+
width: 100%;
|
|
429
|
+
height: 100%;
|
|
430
|
+
background-size: cover;
|
|
431
|
+
background-position: center;
|
|
432
|
+
background-repeat: no-repeat;
|
|
433
|
+
filter: blur(8px) grayscale(1);
|
|
434
|
+
transition: all 0.6s ease;
|
|
435
|
+
min-height: 200px;
|
|
436
|
+
}
|
|
437
|
+
.locked-image.unlocked { filter: blur(0px) grayscale(1); }
|
|
438
|
+
.lock-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
|
|
439
|
+
.pricing { text-align: center; margin: 16px 0; }
|
|
440
|
+
.price { font-size: 28px; font-weight: 800; color: var(--icpay-text); }
|
|
441
|
+
.label { color: var(--icpay-muted); font-size: 14px; }
|
|
442
|
+
.crypto-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 12px 0 16px; }
|
|
443
|
+
.crypto-option { background: var(--icpay-surface-alt); border: 2px solid var(--icpay-border); border-radius: 12px; padding: 12px 8px; text-align: center; cursor: pointer; color: var(--icpay-text); font-weight: 600; font-size: 12px; }
|
|
444
|
+
.crypto-option.selected { background: var(--icpay-primary); color: #111827; border-color: var(--icpay-primary); }
|
|
445
|
+
|
|
446
|
+
.error-message {
|
|
447
|
+
border: 1px solid;
|
|
448
|
+
font-weight: 500;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.error-message.info {
|
|
452
|
+
background: rgba(59, 130, 246, 0.1);
|
|
453
|
+
border-color: rgba(59, 130, 246, 0.3);
|
|
454
|
+
color: #3b82f6;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
.error-message.warning {
|
|
458
|
+
background: rgba(245, 158, 11, 0.1);
|
|
459
|
+
border-color: rgba(245, 158, 11, 0.3);
|
|
460
|
+
color: #f59e0b;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.error-message.error {
|
|
464
|
+
background: rgba(239, 68, 68, 0.1);
|
|
465
|
+
border-color: rgba(239, 68, 68, 0.3);
|
|
466
|
+
color: #ef4444;
|
|
467
|
+
}
|
|
468
|
+
`],s([Ge({type:Object})],b.prototype,"config",2),s([U()],b.prototype,"selectedSymbol",2),s([U()],b.prototype,"unlocked",2),s([U()],b.prototype,"succeeded",2),s([U()],b.prototype,"processing",2),s([U()],b.prototype,"availableLedgers",2),s([U()],b.prototype,"errorMessage",2),s([U()],b.prototype,"errorSeverity",2),s([U()],b.prototype,"errorAction",2),s([U()],b.prototype,"walletConnected",2),s([U()],b.prototype,"pendingAction",2),s([U()],b.prototype,"showWalletModal",2),b=s([qe("icpay-premium-content")],b);import{LitElement as Ye,html as j,css as Qe}from"lit";import{customElement as Xe,property as Ze,state as A}from"lit/decorators.js";var me=typeof window<"u",re=null;function G(o,a,e){o&&(e!==void 0?console.log(`[ICPay Widget] ${a}`,e):console.log(`[ICPay Widget] ${a}`))}var u=class extends Ye{constructor(){super(...arguments);this.selectedAmount=1;this.selectedSymbol="ICP";this.total=0;this.processing=!1;this.succeeded=!1;this.availableLedgers=[];this.errorMessage=null;this.errorSeverity=null;this.errorAction=null;this.walletConnected=!1;this.pendingAction=null;this.showWalletModal=!1;this.pnp=null}async tryAutoConnectPNP(){try{if(!this.config||this.config?.useOwnWallet)return;let e=localStorage.getItem("icpay:pnp");if(!e)return;let t=JSON.parse(e);if(!t?.provider||!t?.principal)return;re||(re=(await import("@windoge98/plug-n-play")).PNP);let i=new re(this.config?.plugNPlay||{});this.walletConnected=!1,this.config={...this.config,connectedWallet:{owner:t.principal,principal:t.principal,connected:!1}}}catch{}}get amounts(){return this.config?.amountsUsd||[1,5,10]}get cryptoOptions(){return this.config.cryptoOptions?this.config.cryptoOptions:this.availableLedgers}connectedCallback(){super.connectedCallback(),me&&(G(this.config?.debug||!1,"Tip jar connected",{config:this.config}),this.config&&this.config.defaultAmountUsd&&(this.selectedAmount=this.config.defaultAmountUsd),this.tryAutoConnectPNP(),this.config?.cryptoOptions&&this.config.cryptoOptions.length>0||this.loadVerifiedLedgers(),this.config?.defaultSymbol&&(this.selectedSymbol=this.config.defaultSymbol))}updated(e){if(e.has("config")&&this.pendingAction&&this.config?.actorProvider){let t=this.pendingAction;this.pendingAction=null,setTimeout(()=>{t==="tip"&&this.tip()},0)}}async loadVerifiedLedgers(){if(!(!me||!this.config?.publishableKey))try{let t=await c(this.config).client.getVerifiedLedgers();this.availableLedgers=t.map(i=>({symbol:i.symbol,label:i.name,canisterId:i.canisterId})),this.config?.cryptoOptions&&this.config.cryptoOptions.length===1&&(this.selectedSymbol=this.config.cryptoOptions[0].symbol),!this.selectedSymbol&&this.availableLedgers.length>0&&(this.selectedSymbol=this.config?.defaultSymbol||this.availableLedgers[0].symbol)}catch(e){console.warn("Failed to load verified ledgers:",e),this.availableLedgers=[{symbol:"ICP",label:"ICP",canisterId:"ryjl3-tyaaa-aaaaa-aaaba-cai"}],this.selectedSymbol||(this.selectedSymbol="ICP")}}selectAmount(e){this.selectedAmount=e}selectSymbol(e){this.selectedSymbol=e}get fillPercentage(){return Math.min(this.total/50*100,100)}async tip(){if(me&&(G(this.config?.debug||!1,"Tip button clicked!",{config:this.config,processing:this.processing}),!this.processing)){this.errorMessage=null,this.errorSeverity=null,this.errorAction=null,this.processing=!0;try{if(this.config.useOwnWallet){if(!this.config.actorProvider){this.pendingAction="tip",this.dispatchEvent(new CustomEvent("icpay-connect-wallet",{bubbles:!0}));return}}else if(!this.walletConnected){G(this.config?.debug||!1,"Connecting to wallet via Plug N Play");try{re||(re=(await import("@windoge98/plug-n-play")).PNP),this.pnp=new re(this.config?.plugNPlay||{});let n=this.pnp.getEnabledWallets();if(G(this.config?.debug||!1,"Available wallets",n),!n?.length)throw new Error("No wallets available");this.pendingAction="tip",this.showWalletModal=!0;return}catch(n){G(this.config?.debug||!1,"Wallet connection error:",n),this.errorMessage=n instanceof Error?n.message:"Wallet connection failed",this.errorSeverity="error";return}}G(this.config?.debug||!1,"Creating SDK for payment");let e=c(this.config),i=this.cryptoOptions.find(n=>n.symbol===this.selectedSymbol).canisterId||await e.client.getLedgerCanisterIdBySymbol(this.selectedSymbol);G(this.config?.debug||!1,"Tip payment details",{amount:this.selectedAmount,selectedSymbol:this.selectedSymbol,canisterId:i});let r=await e.sendUsd(this.selectedAmount,i,{context:"tip-jar"});G(this.config?.debug||!1,"Tip payment completed",{resp:r}),this.total+=this.selectedAmount,this.succeeded=!0,this.config.onSuccess&&this.config.onSuccess({id:r.transactionId,status:r.status,total:this.total}),this.dispatchEvent(new CustomEvent("icpay-tip",{detail:{amount:this.selectedAmount,tx:r},bubbles:!0}))}catch(e){k(e,{onError:t=>{this.dispatchEvent(new CustomEvent("icpay-error",{detail:t,bubbles:!0})),$(t)&&(this.errorMessage=W(t),this.errorSeverity=C(t),this.errorAction=L(t))}})}finally{this.processing=!1,this.pendingAction=null}}}getWalletId(e){return e&&(e.id||e.provider||e.key)||""}getWalletLabel(e){return e&&(e.label||e.name||e.title||e.id)||"Wallet"}getWalletIcon(e){return e&&(e.icon||e.logo||e.image)||null}async connectWithWallet(e){if(this.pnp)try{if(!e)throw new Error("No wallet ID provided");let t=await this.pnp.connect(e);if(!!!(t&&(t.connected===!0||t.principal||t.owner||this.pnp?.account)))throw new Error("Wallet connection was rejected");this.walletConnected=!0,this.config={...this.config,connectedWallet:t,actorProvider:(n,l)=>this.pnp.getActor({canisterId:n,idl:l,requiresSigning:!0,anon:!1})},this.showWalletModal=!1;let r=this.pendingAction;this.pendingAction=null,r==="tip"&&setTimeout(()=>this.tip(),0)}catch(t){this.errorMessage=t instanceof Error?t.message:"Wallet connection failed",this.errorSeverity="error",this.showWalletModal=!1}}render(){return this.config?j`
|
|
469
|
+
<div class="card section" style="text-align:center;">
|
|
470
|
+
${this.config?.progressBar?.enabled!==!1?j`<icpay-progress-bar mode="${this.config?.progressBar?.mode||"modal"}"></icpay-progress-bar>`:null}
|
|
471
|
+
<div class="jar"><div class="fill" style="height:${this.fillPercentage}%"></div></div>
|
|
472
|
+
<div class="label">Total Tips: $${this.total}</div>
|
|
473
|
+
|
|
474
|
+
<div class="amounts">
|
|
475
|
+
${this.amounts.map(e=>j`<div class="chip ${this.selectedAmount===e?"selected":""}" @click=${()=>this.selectAmount(e)}>$${e}</div>`)}
|
|
476
|
+
</div>
|
|
477
|
+
|
|
478
|
+
${this.config?.showLedgerDropdown===!0?j`
|
|
479
|
+
<div>
|
|
480
|
+
<icpay-token-selector
|
|
481
|
+
.options=${this.cryptoOptions}
|
|
482
|
+
.value=${this.selectedSymbol||""}
|
|
483
|
+
.defaultSymbol=${this.config?.defaultSymbol||"ICP"}
|
|
484
|
+
mode=${this.config?.showLedgerDropdown||"buttons"}
|
|
485
|
+
@icpay-token-change=${e=>this.selectSymbol(e.detail.symbol)}
|
|
486
|
+
></icpay-token-selector>
|
|
487
|
+
</div>
|
|
488
|
+
`:null}
|
|
489
|
+
|
|
490
|
+
<button class="pay-button ${this.processing?"processing":""}"
|
|
491
|
+
?disabled=${this.processing||this.config?.disablePaymentButton===!0||this.succeeded&&this.config?.disableAfterSuccess===!0}
|
|
492
|
+
@click=${()=>this.tip()}>
|
|
493
|
+
${this.succeeded&&this.config?.disableAfterSuccess?"Paid":this.processing?"Processing\u2026":this.config?.buttonLabel?this.config.buttonLabel.replace("{amount}",String(this.selectedAmount)).replace("{symbol}",this.selectedSymbol):`Tip $${this.selectedAmount} with ${this.selectedSymbol}`}
|
|
494
|
+
</button>
|
|
495
|
+
|
|
496
|
+
${this.errorMessage?j`
|
|
497
|
+
<div class="error-message ${this.errorSeverity}" style="margin-top: 12px; padding: 8px 12px; border-radius: 6px; font-size: 14px; text-align: center;">
|
|
498
|
+
${this.errorMessage}
|
|
499
|
+
${this.errorAction?j`
|
|
500
|
+
<button style="margin-left: 8px; padding: 4px 8px; background: transparent; border: 1px solid currentColor; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
|
501
|
+
${this.errorAction}
|
|
502
|
+
</button>
|
|
503
|
+
`:""}
|
|
504
|
+
</div>
|
|
505
|
+
`:""}
|
|
506
|
+
${(()=>{let e=this.pnp?.getEnabledWallets?.()||[];return this.showWalletModal&&this.pnp?j`
|
|
507
|
+
<div style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.55);z-index:9999">
|
|
508
|
+
<div class="card section" style="width:380px;border-radius:12px">
|
|
509
|
+
<div class="label" style="font-weight:700;margin-bottom:12px;text-align:center">Choose Wallet</div>
|
|
510
|
+
<div style="display:grid;grid-template-columns:1fr;gap:10px;margin-bottom:12px">
|
|
511
|
+
${e.map(t=>{let i=this.getWalletId(t),r=this.getWalletLabel(t),n=this.getWalletIcon(t);return j`
|
|
512
|
+
<button class="pay-button" style="display:flex;align-items:center;gap:10px;justify-content:center;padding:12px" @click=${()=>this.connectWithWallet(i)}>
|
|
513
|
+
${n?j`<img src="${n}" alt="${r}" style="width:20px;height:20px;border-radius:4px;object-fit:contain;background:transparent" />`:""}
|
|
514
|
+
<span>${r}</span>
|
|
515
|
+
</button>`})}
|
|
516
|
+
</div>
|
|
517
|
+
<button class="pay-button" style="background:#6b7280;color:#f9fafb" @click=${()=>{this.showWalletModal=!1}}>
|
|
518
|
+
Cancel
|
|
519
|
+
</button>
|
|
520
|
+
</div>
|
|
521
|
+
</div>
|
|
522
|
+
`:null})()}
|
|
523
|
+
</div>
|
|
524
|
+
`:j`<div class="card section">Loading...</div>`}};u.styles=[S,Qe`
|
|
525
|
+
.jar { width: 120px; height: 160px; margin: 0 auto 12px; position: relative; background: linear-gradient(135deg, #374151 0%, #4b5563 100%); border-radius: 0 0 60px 60px; border: 3px solid #6b7280; border-top: 8px solid #6b7280; overflow: hidden; }
|
|
526
|
+
.fill { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(135deg, #d1d5db 0%, #9ca3af 100%); transition: height 0.8s ease; height: 0%; }
|
|
527
|
+
.amounts { display: grid; grid-template-columns: repeat(3,1fr); gap: 8px; margin: 12px 0; }
|
|
528
|
+
.chip { background: var(--icpay-surface-alt); border: 2px solid var(--icpay-border); border-radius: 12px; padding: 12px; text-align: center; cursor: pointer; color: var(--icpay-text); font-weight: 600; }
|
|
529
|
+
.chip.selected { background: var(--icpay-primary); color: #111827; border-color: var(--icpay-primary); }
|
|
530
|
+
.crypto-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 12px 0 16px; }
|
|
531
|
+
.crypto-option { background: var(--icpay-surface-alt); border: 2px solid var(--icpay-border); border-radius: 12px; padding: 12px 8px; text-align: center; cursor: pointer; color: var(--icpay-text); font-weight: 600; font-size: 12px; }
|
|
532
|
+
.crypto-option.selected { background: var(--icpay-primary); color: #111827; border-color: var(--icpay-primary); }
|
|
533
|
+
|
|
534
|
+
.error-message {
|
|
535
|
+
border: 1px solid;
|
|
536
|
+
font-weight: 500;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
.error-message.info {
|
|
540
|
+
background: rgba(59, 130, 246, 0.1);
|
|
541
|
+
border-color: rgba(59, 130, 246, 0.3);
|
|
542
|
+
color: #3b82f6;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.error-message.warning {
|
|
546
|
+
background: rgba(245, 158, 11, 0.1);
|
|
547
|
+
border-color: rgba(245, 158, 11, 0.3);
|
|
548
|
+
color: #f59e0b;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
.error-message.error {
|
|
552
|
+
background: rgba(239, 68, 68, 0.1);
|
|
553
|
+
border-color: rgba(239, 68, 68, 0.3);
|
|
554
|
+
color: #ef4444;
|
|
555
|
+
}
|
|
556
|
+
`],s([Ze({type:Object})],u.prototype,"config",2),s([A()],u.prototype,"selectedAmount",2),s([A()],u.prototype,"selectedSymbol",2),s([A()],u.prototype,"total",2),s([A()],u.prototype,"processing",2),s([A()],u.prototype,"succeeded",2),s([A()],u.prototype,"availableLedgers",2),s([A()],u.prototype,"errorMessage",2),s([A()],u.prototype,"errorSeverity",2),s([A()],u.prototype,"errorAction",2),s([A()],u.prototype,"walletConnected",2),s([A()],u.prototype,"pendingAction",2),s([A()],u.prototype,"showWalletModal",2),u=s([Xe("icpay-tip-jar")],u);import{LitElement as Je,html as Y,css as et}from"lit";import{customElement as tt,property as be,state as R}from"lit/decorators.js";var ve=typeof window<"u",ne=null;function Q(o,a,e){o&&(e!==void 0?console.log(`[ICPay Widget] ${a}`,e):console.log(`[ICPay Widget] ${a}`))}var p=class extends Je{constructor(){super(...arguments);this.title="Article Title";this.preview="";this.lockedContent="";this.selectedSymbol="ICP";this.unlocked=!1;this.succeeded=!1;this.processing=!1;this.availableLedgers=[];this.errorMessage=null;this.errorSeverity=null;this.errorAction=null;this.walletConnected=!1;this.pendingAction=null;this.showWalletModal=!1;this.pnp=null}async tryAutoConnectPNP(){try{if(!this.config||this.config?.useOwnWallet)return;let e=localStorage.getItem("icpay:pnp");if(!e)return;let t=JSON.parse(e);if(!t?.provider||!t?.principal)return;ne||(ne=(await import("@windoge98/plug-n-play")).PNP);let i=new ne(this.config?.plugNPlay||{});this.walletConnected=!1,this.config={...this.config,connectedWallet:{owner:t.principal,principal:t.principal,connected:!1}}}catch{}}get cryptoOptions(){return this.config.cryptoOptions?this.config.cryptoOptions:this.availableLedgers}connectedCallback(){super.connectedCallback(),ve&&(Q(this.config?.debug||!1,"Article paywall connected",{config:this.config}),this.config&&(typeof this.config.title=="string"&&(this.title=this.config.title),typeof this.config.preview=="string"&&(this.preview=this.config.preview),typeof this.config.lockedContent=="string"&&(this.lockedContent=this.config.lockedContent)),this.tryAutoConnectPNP(),this.config?.cryptoOptions&&this.config.cryptoOptions.length>0||this.loadVerifiedLedgers())}updated(e){if(e.has("config")&&this.config&&(typeof this.config.title=="string"&&(this.title=this.config.title),typeof this.config.preview=="string"&&(this.preview=this.config.preview),typeof this.config.lockedContent=="string"&&(this.lockedContent=this.config.lockedContent)),e.has("config")&&this.pendingAction&&this.config?.actorProvider){let t=this.pendingAction;this.pendingAction=null,setTimeout(()=>{t==="unlock"&&this.unlock()},0)}}async loadVerifiedLedgers(){if(!(!ve||!this.config?.publishableKey))try{let t=await c(this.config).client.getVerifiedLedgers();this.availableLedgers=t.map(i=>({symbol:i.symbol,label:i.name,canisterId:i.canisterId})),this.selectedSymbol||(this.selectedSymbol=this.config?.defaultSymbol||this.availableLedgers[0]?.symbol||"ICP")}catch(e){console.warn("Failed to load verified ledgers:",e),this.availableLedgers=[{symbol:"ICP",label:"ICP",canisterId:"ryjl3-tyaaa-aaaaa-aaaba-cai"}],this.selectedSymbol||(this.selectedSymbol="ICP")}}selectSymbol(e){this.selectedSymbol=e}async unlock(){if(ve&&!(this.processing||this.unlocked)){Q(this.config?.debug||!1,"Article paywall unlock started",{priceUsd:this.config.priceUsd,selectedSymbol:this.selectedSymbol,useOwnWallet:this.config.useOwnWallet}),this.errorMessage=null,this.errorSeverity=null,this.errorAction=null,this.processing=!0;try{if(this.config.useOwnWallet){if(!this.config.actorProvider){this.pendingAction="unlock",this.dispatchEvent(new CustomEvent("icpay-connect-wallet",{bubbles:!0}));return}}else if(!this.walletConnected){Q(this.config?.debug||!1,"Connecting to wallet via Plug N Play");try{ne||(ne=(await import("@windoge98/plug-n-play")).PNP),this.pnp=new ne(this.config?.plugNPlay||{});let n=this.pnp.getEnabledWallets();if(Q(this.config?.debug||!1,"Available wallets",n),!n?.length)throw new Error("No wallets available");this.pendingAction="unlock",this.showWalletModal=!0;return}catch(n){Q(this.config?.debug||!1,"Wallet connection error:",n),this.errorMessage=n instanceof Error?n.message:"Wallet connection failed",this.errorSeverity="error";return}}Q(this.config?.debug||!1,"Creating SDK for payment");let e=c(this.config),i=this.cryptoOptions.find(n=>n.symbol===this.selectedSymbol).canisterId||await e.client.getLedgerCanisterIdBySymbol(this.selectedSymbol);Q(this.config?.debug||!1,"Article payment details",{priceUsd:this.config.priceUsd,selectedSymbol:this.selectedSymbol,canisterId:i});let r=await e.sendUsd(this.config.priceUsd,i,{context:"article"});Q(this.config?.debug||!1,"Article payment completed",{resp:r}),this.unlocked=!0,this.succeeded=!0,this.config.onSuccess&&this.config.onSuccess({id:r.transactionId,status:r.status}),this.dispatchEvent(new CustomEvent("icpay-unlock",{detail:{amount:this.config.priceUsd,tx:r},bubbles:!0}))}catch(e){k(e,{onError:t=>{this.dispatchEvent(new CustomEvent("icpay-error",{detail:t,bubbles:!0})),$(t)&&(this.errorMessage=W(t),this.errorSeverity=C(t),this.errorAction=L(t))}})}finally{this.processing=!1,this.pendingAction=null}}}getWalletId(e){return e&&(e.id||e.provider||e.key)||""}getWalletLabel(e){return e&&(e.label||e.name||e.title||e.id)||"Wallet"}getWalletIcon(e){return e&&(e.icon||e.logo||e.image)||null}async connectWithWallet(e){if(this.pnp)try{if(!e)throw new Error("No wallet ID provided");let t=await this.pnp.connect(e);if(!!!(t&&(t.connected===!0||t.principal||t.owner||this.pnp?.account)))throw new Error("Wallet connection was rejected");this.walletConnected=!0,this.config={...this.config,connectedWallet:t,actorProvider:(n,l)=>this.pnp.getActor({canisterId:n,idl:l,requiresSigning:!0,anon:!1})},this.showWalletModal=!1;let r=this.pendingAction;this.pendingAction=null,r==="unlock"&&setTimeout(()=>this.unlock(),0)}catch(t){this.errorMessage=t instanceof Error?t.message:"Wallet connection failed",this.errorSeverity="error",this.showWalletModal=!1}}render(){return this.config?Y`
|
|
557
|
+
<div class="card section">
|
|
558
|
+
${this.config?.progressBar?.enabled!==!1?Y`<icpay-progress-bar mode="${this.config?.progressBar?.mode||"modal"}"></icpay-progress-bar>`:null}
|
|
559
|
+
<div class="container">
|
|
560
|
+
<div class="title">${this.title}</div>
|
|
561
|
+
<div class="preview">${this.preview}</div>
|
|
562
|
+
<div class="${this.unlocked?"unlocked":"locked"}">${this.lockedContent}</div>
|
|
563
|
+
</div>
|
|
564
|
+
<div class="pricing" style="text-align:center;">
|
|
565
|
+
<div class="price">$${Number(this.config?.priceUsd??0).toFixed(2)}</div>
|
|
566
|
+
<div class="label">Continue reading</div>
|
|
567
|
+
</div>
|
|
568
|
+
<div>
|
|
569
|
+
<icpay-token-selector
|
|
570
|
+
.options=${this.cryptoOptions}
|
|
571
|
+
.value=${this.selectedSymbol||""}
|
|
572
|
+
.defaultSymbol=${this.config?.defaultSymbol||"ICP"}
|
|
573
|
+
mode=${this.config?.showLedgerDropdown||"buttons"}
|
|
574
|
+
@icpay-token-change=${e=>this.selectSymbol(e.detail.symbol)}
|
|
575
|
+
></icpay-token-selector>
|
|
576
|
+
</div>
|
|
577
|
+
<button class="pay-button ${this.processing?"processing":""}" ?disabled=${this.processing||this.unlocked||this.config?.disablePaymentButton===!0||this.succeeded&&this.config?.disableAfterSuccess===!0} @click=${()=>this.unlock()}>
|
|
578
|
+
${this.unlocked?"Unlocked":this.processing?"Processing\u2026":(this.config?.buttonLabel||"Pay ${amount} with {symbol}").replace("{amount}",`${Number(this.config?.priceUsd??0).toFixed(2)}`).replace("{symbol}",this.selectedSymbol)}
|
|
579
|
+
</button>
|
|
580
|
+
|
|
581
|
+
${this.errorMessage?Y`
|
|
582
|
+
<div class="error-message ${this.errorSeverity}" style="margin-top: 12px; padding: 8px 12px; border-radius: 6px; font-size: 14px; text-align: center;">
|
|
583
|
+
${this.errorMessage}
|
|
584
|
+
${this.errorAction?Y`
|
|
585
|
+
<button style="margin-left: 8px; padding: 4px 8px; background: transparent; border: 1px solid currentColor; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
|
586
|
+
${this.errorAction}
|
|
587
|
+
</button>
|
|
588
|
+
`:""}
|
|
589
|
+
</div>
|
|
590
|
+
`:""}
|
|
591
|
+
${(()=>{let e=this.pnp?.getEnabledWallets?.()||[];return this.showWalletModal&&this.pnp?Y`
|
|
592
|
+
<div style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.55);z-index:9999">
|
|
593
|
+
<div class="card section" style="width:380px;border-radius:12px">
|
|
594
|
+
<div class="label" style="font-weight:700;margin-bottom:12px;text-align:center">Choose Wallet</div>
|
|
595
|
+
<div style="display:grid;grid-template-columns:1fr;gap:10px;margin-bottom:12px">
|
|
596
|
+
${e.map(t=>{let i=this.getWalletId(t),r=this.getWalletLabel(t),n=this.getWalletIcon(t);return Y`
|
|
597
|
+
<button class="pay-button" style="display:flex;align-items:center;gap:10px;justify-content:center;padding:12px" @click=${()=>this.connectWithWallet(i)}>
|
|
598
|
+
${n?Y`<img src="${n}" alt="${r}" style="width:20px;height:20px;border-radius:4px;object-fit:contain;background:transparent" />`:""}
|
|
599
|
+
<span>${r}</span>
|
|
600
|
+
</button>`})}
|
|
601
|
+
</div>
|
|
602
|
+
<button class="pay-button" style="background:#6b7280;color:#f9fafb" @click=${()=>{this.showWalletModal=!1}}>
|
|
603
|
+
Cancel
|
|
604
|
+
</button>
|
|
605
|
+
</div>
|
|
606
|
+
</div>
|
|
607
|
+
`:null})()}
|
|
608
|
+
</div>
|
|
609
|
+
`:Y`<div class="card section">Loading...</div>`}};p.styles=[S,et`
|
|
610
|
+
.container { background: var(--icpay-surface-alt); border: 1px solid var(--icpay-border); border-radius: 16px; padding: 16px; margin-bottom: 16px; }
|
|
611
|
+
.title { color: var(--icpay-text); font-weight: 700; margin-bottom: 8px; }
|
|
612
|
+
.preview { color: var(--icpay-muted); margin-bottom: 12px; line-height: 1.6; }
|
|
613
|
+
.locked { filter: blur(3px); color: #6b7280; margin-bottom: 12px; }
|
|
614
|
+
.unlocked { filter: blur(0); color: var(--icpay-text); }
|
|
615
|
+
.crypto-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 12px 0 16px; }
|
|
616
|
+
.crypto-option { background: var(--icpay-surface-alt); border: 2px solid var(--icpay-border); border-radius: 12px; padding: 12px 8px; text-align: center; cursor: pointer; color: var(--icpay-text); font-weight: 600; font-size: 12px; }
|
|
617
|
+
.crypto-option.selected { background: var(--icpay-primary); color: #111827; border-color: var(--icpay-primary); }
|
|
618
|
+
|
|
619
|
+
.error-message {
|
|
620
|
+
border: 1px solid;
|
|
621
|
+
font-weight: 500;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
.error-message.info {
|
|
625
|
+
background: rgba(59, 130, 246, 0.1);
|
|
626
|
+
border-color: rgba(59, 130, 246, 0.3);
|
|
627
|
+
color: #3b82f6;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
.error-message.warning {
|
|
631
|
+
background: rgba(245, 158, 11, 0.1);
|
|
632
|
+
border-color: rgba(245, 158, 11, 0.3);
|
|
633
|
+
color: #f59e0b;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
.error-message.error {
|
|
637
|
+
background: rgba(239, 68, 68, 0.1);
|
|
638
|
+
border-color: rgba(239, 68, 68, 0.3);
|
|
639
|
+
color: #ef4444;
|
|
640
|
+
}
|
|
641
|
+
`],s([be({type:Object})],p.prototype,"config",2),s([be({type:String})],p.prototype,"title",2),s([be({type:String})],p.prototype,"preview",2),s([be({type:String})],p.prototype,"lockedContent",2),s([R()],p.prototype,"selectedSymbol",2),s([R()],p.prototype,"unlocked",2),s([R()],p.prototype,"succeeded",2),s([R()],p.prototype,"processing",2),s([R()],p.prototype,"availableLedgers",2),s([R()],p.prototype,"errorMessage",2),s([R()],p.prototype,"errorSeverity",2),s([R()],p.prototype,"errorAction",2),s([R()],p.prototype,"walletConnected",2),s([R()],p.prototype,"pendingAction",2),s([R()],p.prototype,"showWalletModal",2),p=s([tt("icpay-article-paywall")],p);import{LitElement as it,html as K,css as st}from"lit";import{customElement as rt,property as nt,state as D}from"lit/decorators.js";var xe=typeof window<"u",we=null;function X(o,a,e){o&&(e!==void 0?console.log(`[ICPay Widget] ${a}`,e):console.log(`[ICPay Widget] ${a}`))}var m=class extends it{constructor(){super(...arguments);this.selectedIndex=0;this.selectedSymbol="ICP";this.processing=!1;this.availableLedgers=[];this.errorMessage=null;this.errorSeverity=null;this.errorAction=null;this.walletConnected=!1;this.pendingAction=null;this.showWalletModal=!1;this.pnp=null}get cryptoOptions(){return this.config.cryptoOptions?this.config.cryptoOptions:this.availableLedgers}connectedCallback(){super.connectedCallback(),xe&&(X(this.config?.debug||!1,"Coffee shop connected",{config:this.config}),this.config&&typeof this.config.defaultItemIndex=="number"&&(this.selectedIndex=this.config.defaultItemIndex),this.config?.cryptoOptions&&this.config.cryptoOptions.length>0||this.loadVerifiedLedgers())}updated(e){if(e.has("config")&&this.pendingAction&&this.config?.actorProvider){let t=this.pendingAction;this.pendingAction=null,setTimeout(()=>{t==="order"&&this.order()},0)}}async loadVerifiedLedgers(){if(!(!xe||!this.config?.publishableKey))try{let t=await c(this.config).client.getVerifiedLedgers();this.availableLedgers=t.map(i=>({symbol:i.symbol,label:i.name,canisterId:i.canisterId})),this.availableLedgers.length>0&&!this.selectedSymbol&&(this.selectedSymbol=this.availableLedgers[0].symbol)}catch(e){console.warn("Failed to load verified ledgers:",e),this.availableLedgers=[{symbol:"ICP",label:"ICP",canisterId:"ryjl3-tyaaa-aaaaa-aaaba-cai"}],this.selectedSymbol||(this.selectedSymbol="ICP")}}selectItem(e){this.selectedIndex=e}selectSymbol(e){this.selectedSymbol=e}get selectedItem(){return this.config?.items?.[this.selectedIndex]||{name:"Loading...",priceUsd:0}}async order(){if(xe&&!this.processing){X(this.config?.debug||!1,"Coffee order started",{selectedItem:this.selectedItem,selectedSymbol:this.selectedSymbol,useOwnWallet:this.config.useOwnWallet}),this.errorMessage=null,this.errorSeverity=null,this.errorAction=null,this.processing=!0;try{if(this.config.useOwnWallet){if(!this.config.actorProvider){this.pendingAction="order",this.dispatchEvent(new CustomEvent("icpay-connect-wallet",{bubbles:!0}));return}}else if(!this.walletConnected){X(this.config?.debug||!1,"Connecting to wallet via Plug N Play");try{we||(we=(await import("@windoge98/plug-n-play")).PNP),this.pnp=new we(this.config?.plugNPlay||{});let n=this.pnp.getEnabledWallets();if(X(this.config?.debug||!1,"Available wallets",n),!n?.length)throw new Error("No wallets available");this.pendingAction="order",this.showWalletModal=!0;return}catch(n){X(this.config?.debug||!1,"Wallet connection error:",n),this.errorMessage=n instanceof Error?n.message:"Wallet connection failed",this.errorSeverity="error";return}}X(this.config?.debug||!1,"Creating SDK for payment");let e=c(this.config),i=this.cryptoOptions.find(n=>n.symbol===this.selectedSymbol).canisterId||await e.client.getLedgerCanisterIdBySymbol(this.selectedSymbol);X(this.config?.debug||!1,"Coffee order payment details",{item:this.selectedItem.name,priceUsd:this.selectedItem.priceUsd,selectedSymbol:this.selectedSymbol,canisterId:i});let r=await e.sendUsd(this.selectedItem.priceUsd,i,{context:"coffee",item:this.selectedItem.name});X(this.config?.debug||!1,"Coffee order payment completed",{resp:r}),this.config.onSuccess&&this.config.onSuccess({id:r.transactionId,status:r.status,item:this.selectedItem.name}),this.dispatchEvent(new CustomEvent("icpay-coffee",{detail:{item:this.selectedItem,tx:r},bubbles:!0}))}catch(e){k(e,{onError:t=>{this.dispatchEvent(new CustomEvent("icpay-error",{detail:t,bubbles:!0})),$(t)&&(this.errorMessage=W(t),this.errorSeverity=C(t),this.errorAction=L(t))}})}finally{this.processing=!1}}}getWalletId(e){return e&&(e.id||e.provider||e.key)||""}getWalletLabel(e){return e&&(e.label||e.name||e.title||e.id)||"Wallet"}getWalletIcon(e){return e&&(e.icon||e.logo||e.image)||null}async connectWithWallet(e){if(this.pnp)try{if(!e)throw new Error("No wallet ID provided");let t=await this.pnp.connect(e);if(!!!(t&&(t.connected===!0||t.principal||t.owner||this.pnp?.account)))throw new Error("Wallet connection was rejected");this.walletConnected=!0,this.config={...this.config,connectedWallet:t,actorProvider:(n,l)=>this.pnp.getActor({canisterId:n,idl:l,requiresSigning:!0,anon:!1})},this.showWalletModal=!1;let r=this.pendingAction;this.pendingAction=null,r==="order"&&setTimeout(()=>this.order(),0)}catch(t){this.errorMessage=t instanceof Error?t.message:"Wallet connection failed",this.errorSeverity="error",this.showWalletModal=!1}}render(){return this.config?K`
|
|
642
|
+
<div class="card section">
|
|
643
|
+
${this.config?.progressBar?.enabled!==!1?K`<icpay-progress-bar mode="${this.config?.progressBar?.mode||"modal"}"></icpay-progress-bar>`:null}
|
|
644
|
+
<div class="menu">
|
|
645
|
+
${this.config.items.map((e,t)=>K`
|
|
646
|
+
<div class="item ${this.selectedIndex===t?"selected":""}" @click=${()=>this.selectItem(t)}>
|
|
647
|
+
<span>${e.name}</span>
|
|
648
|
+
<span>$${Number(e?.priceUsd??0).toFixed(2)}</span>
|
|
649
|
+
</div>
|
|
650
|
+
`)}
|
|
651
|
+
</div>
|
|
652
|
+
|
|
653
|
+
<div class="total">Order Total: $${Number(this.selectedItem?.priceUsd??0).toFixed(2)}</div>
|
|
654
|
+
|
|
655
|
+
<div>
|
|
656
|
+
<icpay-token-selector
|
|
657
|
+
.options=${this.cryptoOptions}
|
|
658
|
+
.value=${this.selectedSymbol||""}
|
|
659
|
+
.defaultSymbol=${this.config?.defaultSymbol||"ICP"}
|
|
660
|
+
mode=${this.config?.showLedgerDropdown||"buttons"}
|
|
661
|
+
@icpay-token-change=${e=>this.selectSymbol(e.detail.symbol)}
|
|
662
|
+
></icpay-token-selector>
|
|
663
|
+
</div>
|
|
664
|
+
|
|
665
|
+
<button class="pay-button ${this.processing?"processing":""}" ?disabled=${this.processing} @click=${()=>this.order()}>
|
|
666
|
+
${this.processing?"Processing\u2026":`Order ${this.selectedItem.name}`}
|
|
667
|
+
</button>
|
|
668
|
+
|
|
669
|
+
${this.errorMessage?K`
|
|
670
|
+
<div class="error-message ${this.errorSeverity}" style="margin-top: 12px; padding: 8px 12px; border-radius: 6px; font-size: 14px; text-align: center;">
|
|
671
|
+
${this.errorMessage}
|
|
672
|
+
${this.errorAction?K`
|
|
673
|
+
<button style="margin-left: 8px; padding: 4px 8px; background: transparent; border: 1px solid currentColor; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
|
674
|
+
${this.errorAction}
|
|
675
|
+
</button>
|
|
676
|
+
`:""}
|
|
677
|
+
</div>
|
|
678
|
+
`:""}
|
|
679
|
+
${(()=>{let e=this.pnp?.getEnabledWallets?.()||[];return this.showWalletModal&&this.pnp?K`
|
|
680
|
+
<div style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.55);z-index:9999">
|
|
681
|
+
<div class="card section" style="width:380px;border-radius:12px">
|
|
682
|
+
<div class="label" style="font-weight:700;margin-bottom:12px;text-align:center">Choose Wallet</div>
|
|
683
|
+
<div style="display:grid;grid-template-columns:1fr;gap:10px;margin-bottom:12px">
|
|
684
|
+
${e.map(t=>{let i=this.getWalletId(t),r=this.getWalletLabel(t),n=this.getWalletIcon(t);return K`
|
|
685
|
+
<button class="pay-button" style="display:flex;align-items:center;gap:10px;justify-content:center;padding:12px" @click=${()=>this.connectWithWallet(i)}>
|
|
686
|
+
${n?K`<img src="${n}" alt="${r}" style="width:20px;height:20px;border-radius:4px;object-fit:contain;background:transparent" />`:""}
|
|
687
|
+
<span>${r}</span>
|
|
688
|
+
</button>`})}
|
|
689
|
+
</div>
|
|
690
|
+
<button class="pay-button" style="background:#6b7280;color:#f9fafb" @click=${()=>{this.showWalletModal=!1}}>
|
|
691
|
+
Cancel
|
|
692
|
+
</button>
|
|
693
|
+
</div>
|
|
694
|
+
</div>
|
|
695
|
+
`:null})()}
|
|
696
|
+
</div>
|
|
697
|
+
`:K`<div class="card section">Loading...</div>`}};m.styles=[S,st`
|
|
698
|
+
.menu { display: grid; gap: 8px; margin-bottom: 12px; }
|
|
699
|
+
.item { background: var(--icpay-surface-alt); border: 2px solid var(--icpay-border); border-radius: 12px; padding: 16px; display:flex; justify-content: space-between; align-items:center; cursor: pointer; color: var(--icpay-text); font-weight: 600; }
|
|
700
|
+
.item.selected { background: var(--icpay-primary); color: #111827; border-color: var(--icpay-primary); }
|
|
701
|
+
.total { background: var(--icpay-surface-alt); border: 1px solid var(--icpay-border); border-radius: 12px; padding: 12px; text-align: center; margin-bottom: 12px; color: var(--icpay-text); }
|
|
702
|
+
.crypto-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 12px 0 16px; }
|
|
703
|
+
.crypto-option { background: var(--icpay-surface-alt); border: 2px solid var(--icpay-border); border-radius: 12px; padding: 12px 8px; text-align: center; cursor: pointer; color: var(--icpay-text); font-weight: 600; font-size: 12px; }
|
|
704
|
+
.crypto-option.selected { background: var(--icpay-primary); color: #111827; border-color: var(--icpay-primary); }
|
|
705
|
+
|
|
706
|
+
.error-message {
|
|
707
|
+
border: 1px solid;
|
|
708
|
+
font-weight: 500;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
.error-message.info {
|
|
712
|
+
background: rgba(59, 130, 246, 0.1);
|
|
713
|
+
border-color: rgba(59, 130, 246, 0.3);
|
|
714
|
+
color: #3b82f6;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
.error-message.warning {
|
|
718
|
+
background: rgba(245, 158, 11, 0.1);
|
|
719
|
+
border-color: rgba(245, 158, 11, 0.3);
|
|
720
|
+
color: #f59e0b;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.error-message.error {
|
|
724
|
+
background: rgba(239, 68, 68, 0.1);
|
|
725
|
+
border-color: rgba(239, 68, 68, 0.3);
|
|
726
|
+
color: #ef4444;
|
|
727
|
+
}
|
|
728
|
+
`],s([nt({type:Object})],m.prototype,"config",2),s([D()],m.prototype,"selectedIndex",2),s([D()],m.prototype,"selectedSymbol",2),s([D()],m.prototype,"processing",2),s([D()],m.prototype,"availableLedgers",2),s([D()],m.prototype,"errorMessage",2),s([D()],m.prototype,"errorSeverity",2),s([D()],m.prototype,"errorAction",2),s([D()],m.prototype,"walletConnected",2),s([D()],m.prototype,"pendingAction",2),s([D()],m.prototype,"showWalletModal",2),m=s([rt("icpay-coffee-shop")],m);import{LitElement as ot,html as V,css as at}from"lit";import{customElement as lt,property as ct,state as M}from"lit/decorators.js";var Ee=typeof window<"u",oe=null;function Z(o,a,e){o&&(e!==void 0?console.log(`[ICPay Widget] ${a}`,e):console.log(`[ICPay Widget] ${a}`))}var h=class extends ot{constructor(){super(...arguments);this.selectedAmount=10;this.selectedSymbol="ICP";this.raised=0;this.processing=!1;this.succeeded=!1;this.availableLedgers=[];this.errorMessage=null;this.errorSeverity=null;this.errorAction=null;this.walletConnected=!1;this.pendingAction=null;this.showWalletModal=!1;this.pnp=null}async tryAutoConnectPNP(){try{if(!this.config||this.config?.useOwnWallet)return;let e=localStorage.getItem("icpay:pnp");if(!e)return;let t=JSON.parse(e);if(!t?.provider||!t?.principal)return;oe||(oe=(await import("@windoge98/plug-n-play")).PNP);let i=new oe(this.config?.plugNPlay||{});this.walletConnected=!1,this.config={...this.config,connectedWallet:{owner:t.principal,principal:t.principal,connected:!1}}}catch{}}get amounts(){return this.config?.amountsUsd||[10,25,50,100,250,500]}get cryptoOptions(){return this.config.cryptoOptions?this.config.cryptoOptions:this.availableLedgers}connectedCallback(){super.connectedCallback(),Ee&&(Z(this.config?.debug||!1,"Donation thermometer connected",{config:this.config}),this.config&&typeof this.config.defaultAmountUsd=="number"&&(this.selectedAmount=this.config.defaultAmountUsd),this.tryAutoConnectPNP(),this.config?.cryptoOptions&&this.config.cryptoOptions.length>0||this.loadVerifiedLedgers())}updated(e){if(e.has("config")&&this.pendingAction&&this.config?.actorProvider){let t=this.pendingAction;this.pendingAction=null,setTimeout(()=>{t==="donate"&&this.donate()},0)}}async loadVerifiedLedgers(){if(!(!Ee||!this.config?.publishableKey))try{let t=await c(this.config).client.getVerifiedLedgers();this.availableLedgers=t.map(i=>({symbol:i.symbol,label:i.name,canisterId:i.canisterId})),this.availableLedgers.length>0&&!this.selectedSymbol&&(this.selectedSymbol=this.availableLedgers[0].symbol)}catch(e){console.warn("Failed to load verified ledgers:",e),this.availableLedgers=[{symbol:"ICP",label:"ICP",canisterId:"ryjl3-tyaaa-aaaaa-aaaba-cai"}],this.selectedSymbol||(this.selectedSymbol="ICP")}}selectAmount(e){this.selectedAmount=e}selectSymbol(e){this.selectedSymbol=e}get fillPercentage(){let e=Number(this.config?.goalUsd??1e3),t=e>0?e:1e3;return Math.min(this.raised/t*100,100)}async donate(){if(Ee&&!this.processing){Z(this.config?.debug||!1,"Donation started",{amount:this.selectedAmount,selectedSymbol:this.selectedSymbol,useOwnWallet:this.config.useOwnWallet}),this.errorMessage=null,this.errorSeverity=null,this.errorAction=null,this.processing=!0;try{if(this.config.useOwnWallet){if(!this.config.actorProvider){this.pendingAction="donate",this.dispatchEvent(new CustomEvent("icpay-connect-wallet",{bubbles:!0}));return}}else if(!this.walletConnected){Z(this.config?.debug||!1,"Connecting to wallet via Plug N Play");try{oe||(oe=(await import("@windoge98/plug-n-play")).PNP),this.pnp=new oe(this.config?.plugNPlay||{});let n=this.pnp.getEnabledWallets();if(Z(this.config?.debug||!1,"Available wallets",n),!n?.length)throw new Error("No wallets available");this.pendingAction="donate",this.showWalletModal=!0;return}catch(n){Z(this.config?.debug||!1,"Wallet connection error:",n),this.errorMessage=n instanceof Error?n.message:"Wallet connection failed",this.errorSeverity="error";return}}Z(this.config?.debug||!1,"Creating SDK for payment");let e=c(this.config),i=this.cryptoOptions.find(n=>n.symbol===this.selectedSymbol).canisterId||await e.client.getLedgerCanisterIdBySymbol(this.selectedSymbol);Z(this.config?.debug||!1,"Donation payment details",{amount:this.selectedAmount,selectedSymbol:this.selectedSymbol,canisterId:i});let r=await e.sendUsd(this.selectedAmount,i,{context:"donation"});Z(this.config?.debug||!1,"Donation payment completed",{resp:r}),this.raised+=this.selectedAmount,this.succeeded=!0,this.config.onSuccess&&this.config.onSuccess({id:r.transactionId,status:r.status,raised:this.raised}),this.dispatchEvent(new CustomEvent("icpay-donation",{detail:{amount:this.selectedAmount,tx:r},bubbles:!0}))}catch(e){k(e,{onError:t=>{this.dispatchEvent(new CustomEvent("icpay-error",{detail:t,bubbles:!0})),$(t)&&(this.errorMessage=W(t),this.errorSeverity=C(t),this.errorAction=L(t))}})}finally{this.processing=!1,this.pendingAction=null}}}getWalletId(e){return e&&(e.id||e.provider||e.key)||""}getWalletLabel(e){return e&&(e.label||e.name||e.title||e.id)||"Wallet"}getWalletIcon(e){return e&&(e.icon||e.logo||e.image)||null}async connectWithWallet(e){if(this.pnp)try{if(!e)throw new Error("No wallet ID provided");let t=await this.pnp.connect(e);if(!!!(t&&(t.connected===!0||t.principal||t.owner||this.pnp?.account)))throw new Error("Wallet connection was rejected");this.walletConnected=!0,this.config={...this.config,connectedWallet:t,actorProvider:(n,l)=>this.pnp.getActor({canisterId:n,idl:l,requiresSigning:!0,anon:!1})},this.showWalletModal=!1;let r=this.pendingAction;this.pendingAction=null,r==="donate"&&setTimeout(()=>this.donate(),0)}catch(t){this.errorMessage=t instanceof Error?t.message:"Wallet connection failed",this.errorSeverity="error",this.showWalletModal=!1}}render(){return this.config?V`
|
|
729
|
+
<div class="card section" style="text-align:center;">
|
|
730
|
+
${this.config?.progressBar?.enabled!==!1?V`<icpay-progress-bar mode="${this.config?.progressBar?.mode||"modal"}"></icpay-progress-bar>`:null}
|
|
731
|
+
<div class="thermo"><div class="fill" style="height:${this.fillPercentage}%"></div></div>
|
|
732
|
+
<div class="total">$${Number(this.raised).toFixed(0)} / $${Number(this.config?.goalUsd??0).toFixed(2)}</div>
|
|
733
|
+
|
|
734
|
+
<div class="amounts">
|
|
735
|
+
${this.amounts.map(e=>V`<div class="chip ${this.selectedAmount===e?"selected":""}" @click=${()=>this.selectAmount(e)}>$${e}</div>`)}
|
|
736
|
+
</div>
|
|
737
|
+
|
|
738
|
+
<div>
|
|
739
|
+
<icpay-token-selector
|
|
740
|
+
.options=${this.cryptoOptions}
|
|
741
|
+
.value=${this.selectedSymbol||""}
|
|
742
|
+
.defaultSymbol=${this.config?.defaultSymbol||"ICP"}
|
|
743
|
+
mode=${this.config?.showLedgerDropdown||"buttons"}
|
|
744
|
+
@icpay-token-change=${e=>this.selectSymbol(e.detail.symbol)}
|
|
745
|
+
></icpay-token-selector>
|
|
746
|
+
</div>
|
|
747
|
+
|
|
748
|
+
<button class="pay-button ${this.processing?"processing":""}"
|
|
749
|
+
?disabled=${this.processing||this.config?.disablePaymentButton===!0||this.succeeded&&this.config?.disableAfterSuccess===!0}
|
|
750
|
+
@click=${()=>this.donate()}>
|
|
751
|
+
${this.succeeded&&this.config?.disableAfterSuccess?"Donated":this.processing?"Processing\u2026":(this.config?.buttonLabel||"Donate {amount} with {symbol}").replace("{amount}",`${this.selectedAmount}`).replace("{symbol}",this.selectedSymbol)}
|
|
752
|
+
</button>
|
|
753
|
+
|
|
754
|
+
${this.errorMessage?V`
|
|
755
|
+
<div class="error-message ${this.errorSeverity}" style="margin-top: 12px; padding: 8px 12px; border-radius: 6px; font-size: 14px; text-align: center;">
|
|
756
|
+
${this.errorMessage}
|
|
757
|
+
${this.errorAction?V`
|
|
758
|
+
<button style="margin-left: 8px; padding: 4px 8px; background: transparent; border: 1px solid currentColor; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
|
759
|
+
${this.errorAction}
|
|
760
|
+
</button>
|
|
761
|
+
`:""}
|
|
762
|
+
</div>
|
|
763
|
+
`:""}
|
|
764
|
+
${(()=>{let e=this.pnp?.getEnabledWallets?.()||[];return this.showWalletModal&&this.pnp?V`
|
|
765
|
+
<div style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.55);z-index:9999">
|
|
766
|
+
<div class="card section" style="width:380px;border-radius:12px">
|
|
767
|
+
<div class="label" style="font-weight:700;margin-bottom:12px;text-align:center">Choose Wallet</div>
|
|
768
|
+
<div style="display:grid;grid-template-columns:1fr;gap:10px;margin-bottom:12px">
|
|
769
|
+
${e.map(t=>{let i=this.getWalletId(t),r=this.getWalletLabel(t),n=this.getWalletIcon(t);return V`
|
|
770
|
+
<button class="pay-button" style="display:flex;align-items:center;gap:10px;justify-content:center;padding:12px" @click=${()=>this.connectWithWallet(i)}>
|
|
771
|
+
${n?V`<img src="${n}" alt="${r}" style="width:20px;height:20px;border-radius:4px;object-fit:contain;background:transparent" />`:""}
|
|
772
|
+
<span>${r}</span>
|
|
773
|
+
</button>`})}
|
|
774
|
+
</div>
|
|
775
|
+
<button class="pay-button" style="background:#6b7280;color:#f9fafb" @click=${()=>{this.showWalletModal=!1}}>
|
|
776
|
+
Cancel
|
|
777
|
+
</button>
|
|
778
|
+
</div>
|
|
779
|
+
</div>
|
|
780
|
+
`:null})()}
|
|
781
|
+
</div>
|
|
782
|
+
`:V`<div class="card section">Loading...</div>`}};h.styles=[S,at`
|
|
783
|
+
.thermo { width: 60px; height: 200px; background: var(--icpay-surface-alt); border: 3px solid #6b7280; border-radius: 30px; margin: 0 auto 12px; position: relative; overflow: hidden; }
|
|
784
|
+
.fill { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(135deg, #d1d5db 0%, #9ca3af 100%); transition: height 0.8s ease; height: 0%; border-radius: 0 0 27px 27px; }
|
|
785
|
+
.amounts { display: grid; grid-template-columns: repeat(3,1fr); gap: 8px; margin: 12px 0; }
|
|
786
|
+
.chip { background: var(--icpay-surface-alt); border: 2px solid var(--icpay-border); border-radius: 12px; padding: 12px; text-align: center; cursor: pointer; color: var(--icpay-text); font-weight: 600; }
|
|
787
|
+
.chip.selected { background: var(--icpay-primary); color: #111827; border-color: var(--icpay-primary); }
|
|
788
|
+
.crypto-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 12px 0 16px; }
|
|
789
|
+
.crypto-option { background: var(--icpay-surface-alt); border: 2px solid var(--icpay-border); border-radius: 12px; padding: 12px 8px; text-align: center; cursor: pointer; color: var(--icpay-text); font-weight: 600; font-size: 12px; }
|
|
790
|
+
.crypto-option.selected { background: var(--icpay-primary); color: #111827; border-color: var(--icpay-primary); }
|
|
791
|
+
|
|
792
|
+
.error-message {
|
|
793
|
+
border: 1px solid;
|
|
794
|
+
font-weight: 500;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
.error-message.info {
|
|
798
|
+
background: rgba(59, 130, 246, 0.1);
|
|
799
|
+
border-color: rgba(59, 130, 246, 0.3);
|
|
800
|
+
color: #3b82f6;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
.error-message.warning {
|
|
804
|
+
background: rgba(245, 158, 11, 0.1);
|
|
805
|
+
border-color: rgba(245, 158, 11, 0.3);
|
|
806
|
+
color: #f59e0b;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
.error-message.error {
|
|
810
|
+
background: rgba(239, 68, 68, 0.1);
|
|
811
|
+
border-color: rgba(239, 68, 68, 0.3);
|
|
812
|
+
color: #ef4444;
|
|
813
|
+
}
|
|
814
|
+
`],s([ct({type:Object})],h.prototype,"config",2),s([M()],h.prototype,"selectedAmount",2),s([M()],h.prototype,"selectedSymbol",2),s([M()],h.prototype,"raised",2),s([M()],h.prototype,"processing",2),s([M()],h.prototype,"succeeded",2),s([M()],h.prototype,"availableLedgers",2),s([M()],h.prototype,"errorMessage",2),s([M()],h.prototype,"errorSeverity",2),s([M()],h.prototype,"errorAction",2),s([M()],h.prototype,"walletConnected",2),s([M()],h.prototype,"pendingAction",2),s([M()],h.prototype,"showWalletModal",2),h=s([lt("icpay-donation-thermometer")],h);import{LitElement as dt,html as B,css as pt}from"lit";import{customElement as gt,property as ut,state as F}from"lit/decorators.js";var Se=typeof window<"u",ke=null;function ue(o,a,e){o&&(e!==void 0?console.log(`[ICPay Widget] ${a}`,e):console.log(`[ICPay Widget] ${a}`))}var v=class extends dt{constructor(){super(...arguments);this.selectedSymbol=null;this.processing=!1;this.succeeded=!1;this.availableLedgers=[];this.errorMessage=null;this.errorSeverity=null;this.errorAction=null;this.walletConnected=!1;this.pendingAction=null;this.showWalletModal=!1;this.pnp=null}get cryptoOptions(){return this.config?.cryptoOptions?.length?this.config.cryptoOptions:this.availableLedgers}connectedCallback(){super.connectedCallback(),Se&&(ue(this.config?.debug||!1,"Pay button connected",{config:this.config}),this.config?.cryptoOptions&&this.config.cryptoOptions.length>0||this.loadVerifiedLedgers(),this.config?.defaultSymbol&&(this.selectedSymbol=this.config.defaultSymbol))}updated(e){if(e.has("config")&&this.pendingAction&&this.config?.actorProvider){let t=this.pendingAction;this.pendingAction=null,setTimeout(()=>{t==="pay"&&this.pay()},0)}}async loadVerifiedLedgers(){if(!(!Se||!this.config?.publishableKey))try{let t=await c(this.config).client.getVerifiedLedgers();this.availableLedgers=t.map(i=>({symbol:i.symbol,label:i.name,canisterId:i.canisterId})),this.selectedSymbol||(this.selectedSymbol=this.config?.defaultSymbol||(this.availableLedgers[0]?.symbol??"ICP"))}catch(e){this.dispatchEvent(new CustomEvent("icpay-error",{detail:{message:"Failed to load verified ledgers",cause:e},bubbles:!0})),this.availableLedgers=[{symbol:"ICP",label:"ICP",canisterId:"ryjl3-tyaaa-aaaaa-aaaba-cai"}],this.selectedSymbol||(this.selectedSymbol=this.config?.defaultSymbol||"ICP")}}selectSymbol(e){this.selectedSymbol=e}async ensureWallet(){if(this.config.useOwnWallet)return this.config.actorProvider?!0:(this.pendingAction="pay",this.dispatchEvent(new CustomEvent("icpay-connect-wallet",{bubbles:!0})),!1);if(this.walletConnected)return!0;try{ke||(ke=(await import("@windoge98/plug-n-play")).PNP),this.pnp=new ke(this.config?.plugNPlay||{});let e=this.pnp.getEnabledWallets();if(ue(this.config?.debug||!1,"Available wallets",e),!e?.length)throw new Error("No wallets available");return this.pendingAction="pay",this.showWalletModal=!0,!1}catch(e){return this.errorMessage=e instanceof Error?e.message:"Wallet connection failed",this.errorSeverity="error",!1}}getWalletId(e){return e&&(e.id||e.provider||e.key)||""}getWalletLabel(e){return e&&(e.label||e.name||e.title||e.id)||"Wallet"}getWalletIcon(e){return e&&(e.icon||e.logo||e.image)||null}async connectWithWallet(e){if(this.pnp)try{if(ue(this.config?.debug||!1,"Connecting to wallet",{walletId:e}),!e)throw new Error("No wallet ID provided");let t=await this.pnp.connect(e);if(ue(this.config?.debug||!1,"Wallet connect result",t),!!!(t&&(t.connected===!0||t.principal||t.owner||this.pnp?.account)))throw new Error("Wallet connection was rejected");this.walletConnected=!0,this.config={...this.config,connectedWallet:t,actorProvider:(n,l)=>this.pnp.getActor({canisterId:n,idl:l,requiresSigning:!0,anon:!1})},this.showWalletModal=!1;let r=this.pendingAction;this.pendingAction=null,r==="pay"&&setTimeout(()=>this.pay(),0)}catch(t){ue(this.config?.debug||!1,"Wallet connection error",t),this.errorMessage=t instanceof Error?t.message:"Wallet connection failed",this.errorSeverity="error",this.showWalletModal=!1}}renderWalletModal(){if(!this.showWalletModal||!this.pnp)return null;let e=this.pnp.getEnabledWallets()||[];return B`
|
|
815
|
+
<div style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.55);z-index:9999">
|
|
816
|
+
<div class="card" style="width:380px;padding:16px;border-radius:12px">
|
|
817
|
+
<div class="label" style="font-weight:700;margin-bottom:12px;text-align:center">Choose Wallet</div>
|
|
818
|
+
<div style="display:grid;grid-template-columns:1fr;gap:10px;margin-bottom:12px">
|
|
819
|
+
${e.map(t=>{let i=this.getWalletId(t),r=this.getWalletLabel(t),n=this.getWalletIcon(t);return B`
|
|
820
|
+
<button class="pay-button" style="display:flex;align-items:center;gap:10px;justify-content:center;padding:12px" @click=${()=>this.connectWithWallet(i)}>
|
|
821
|
+
${n?B`<img src="${n}" alt="${r}" style="width:20px;height:20px;border-radius:4px;object-fit:contain;background:transparent" />`:""}
|
|
822
|
+
<span>${r}</span>
|
|
823
|
+
</button>`})}
|
|
824
|
+
</div>
|
|
825
|
+
<button class="pay-button" style="background:#6b7280;color:#f9fafb" @click=${()=>{this.showWalletModal=!1}}>
|
|
826
|
+
Cancel
|
|
827
|
+
</button>
|
|
828
|
+
</div>
|
|
829
|
+
</div>
|
|
830
|
+
`}async pay(){if(!(!Se||this.processing)){this.errorMessage=null,this.errorSeverity=null,this.errorAction=null,this.processing=!0;try{if(!await this.ensureWallet())return;let t=c(this.config),i=this.selectedSymbol||"ICP",n=this.cryptoOptions.find(H=>H.symbol===i)?.canisterId||await t.client.getLedgerCanisterIdBySymbol(i),l=Number(this.config?.amountUsd??0),g={context:"pay-button"},w=await t.sendUsd(l,n,g);this.config.onSuccess&&this.config.onSuccess({id:w.transactionId,status:w.status}),this.succeeded=!0,this.dispatchEvent(new CustomEvent("icpay-pay",{detail:{amount:l,tx:w},bubbles:!0}))}catch(e){k(e,{onError:t=>{this.dispatchEvent(new CustomEvent("icpay-error",{detail:t,bubbles:!0})),$(t)&&(this.errorMessage=W(t),this.errorSeverity=C(t),this.errorAction=L(t))}})}finally{this.processing=!1,this.pendingAction=null}}}render(){if(!this.config)return B`<div class="card section">Loading...</div>`;let e=this.config?.showLedgerDropdown===!0,i=(this.cryptoOptions?.length||0)>1,r=this.config?.showLedgerDropdown,n=r==="dropdown"?"dropdown":r==="none"?"none":"buttons",l=n!=="none"&&(i||n==="dropdown"),g=n==="dropdown"?"dropdown":i?"buttons":"none",w=this.selectedSymbol||this.config?.defaultSymbol||"ICP",H=typeof this.config?.amountUsd=="number"?`${Number(this.config.amountUsd).toFixed(2)}`:"",N=(this.config?.buttonLabel||(typeof this.config?.amountUsd=="number"?"Pay ${amount} with {symbol}":"Pay with {symbol}")).replace("{amount}",H||"$0.00").replace("{symbol}",w),ae=this.config?.progressBar?.enabled!==!1;return B`
|
|
831
|
+
<div class="card section">
|
|
832
|
+
${ae?B`
|
|
833
|
+
<icpay-progress-bar></icpay-progress-bar>
|
|
834
|
+
`:null}
|
|
835
|
+
|
|
836
|
+
<div class="row ${l?"":"single"}">
|
|
837
|
+
${l?B`
|
|
838
|
+
<icpay-token-selector
|
|
839
|
+
.options=${this.cryptoOptions}
|
|
840
|
+
.value=${this.selectedSymbol||""}
|
|
841
|
+
.defaultSymbol=${this.config?.defaultSymbol||"ICP"}
|
|
842
|
+
mode=${g}
|
|
843
|
+
@icpay-token-change=${I=>this.selectSymbol(I.detail.symbol)}
|
|
844
|
+
></icpay-token-selector>
|
|
845
|
+
`:null}
|
|
846
|
+
<button class="pay-button ${this.processing?"processing":""}"
|
|
847
|
+
?disabled=${this.processing||this.config?.disablePaymentButton===!0||this.succeeded&&this.config?.disableAfterSuccess===!0}
|
|
848
|
+
@click=${()=>this.pay()}>
|
|
849
|
+
${this.succeeded&&this.config?.disableAfterSuccess?"Paid":this.processing?"Processing\u2026":N}
|
|
850
|
+
</button>
|
|
851
|
+
</div>
|
|
852
|
+
|
|
853
|
+
${this.errorMessage?B`
|
|
854
|
+
<div class="error-message ${this.errorSeverity}" style="margin-top: 12px; padding: 8px 12px; border-radius: 6px; font-size: 14px; text-align: center;">
|
|
855
|
+
${this.errorMessage}
|
|
856
|
+
${this.errorAction?B`<button style="margin-left: 8px; padding: 4px 8px; background: transparent; border: 1px solid currentColor; border-radius: 4px; font-size: 12px; cursor: pointer;">${this.errorAction}</button>`:""}
|
|
857
|
+
</div>
|
|
858
|
+
`:""}
|
|
859
|
+
${this.renderWalletModal()}
|
|
860
|
+
</div>
|
|
861
|
+
`}};v.styles=[S,pt`
|
|
862
|
+
.row { display: grid; grid-template-columns: 1fr auto; gap: 8px; align-items: center; }
|
|
863
|
+
.row.single { grid-template-columns: 1fr; }
|
|
864
|
+
select { background: var(--icpay-surface-alt); border: 1px solid var(--icpay-border); color: var(--icpay-text); border-radius: 8px; padding: 10px; font-weight: 600; }
|
|
865
|
+
.error-message { border: 1px solid; font-weight: 500; }
|
|
866
|
+
.error-message.info { background: rgba(59,130,246,0.1); border-color: rgba(59,130,246,0.3); color: #3b82f6; }
|
|
867
|
+
.error-message.warning { background: rgba(245,158,11,0.1); border-color: rgba(245,158,11,0.3); color: #f59e0b; }
|
|
868
|
+
.error-message.error { background: rgba(239,68,68,0.1); border-color: rgba(239,68,68,0.3); color: #ef4444; }
|
|
869
|
+
`],s([ut({type:Object})],v.prototype,"config",2),s([F()],v.prototype,"selectedSymbol",2),s([F()],v.prototype,"processing",2),s([F()],v.prototype,"succeeded",2),s([F()],v.prototype,"availableLedgers",2),s([F()],v.prototype,"errorMessage",2),s([F()],v.prototype,"errorSeverity",2),s([F()],v.prototype,"errorAction",2),s([F()],v.prototype,"walletConnected",2),s([F()],v.prototype,"pendingAction",2),s([F()],v.prototype,"showWalletModal",2),v=s([gt("icpay-pay-button")],v);import{LitElement as ht,html as _,css as ft}from"lit";import{customElement as bt,property as yt,state as O}from"lit/decorators.js";var We=typeof window<"u",$e=null;function mt(o,a,e){o&&(e!==void 0?console.log(`[ICPay Widget] ${a}`,e):console.log(`[ICPay Widget] ${a}`))}var f=class extends ht{constructor(){super(...arguments);this.amountUsd=0;this.hasUserAmount=!1;this.selectedSymbol=null;this.processing=!1;this.succeeded=!1;this.availableLedgers=[];this.errorMessage=null;this.errorSeverity=null;this.errorAction=null;this.walletConnected=!1;this.pendingAction=null;this.showWalletModal=!1;this.pnp=null}get cryptoOptions(){return this.config?.cryptoOptions?.length?this.config.cryptoOptions:this.availableLedgers}connectedCallback(){super.connectedCallback(),We&&(mt(this.config?.debug||!1,"Amount input connected",{config:this.config}),this.amountUsd=Number(this.config?.defaultAmountUsd??0),this.hasUserAmount=!1,this.config?.cryptoOptions&&this.config.cryptoOptions.length>0||this.loadVerifiedLedgers(),this.config?.defaultSymbol&&(this.selectedSymbol=this.config.defaultSymbol))}updated(e){if(e.has("config")&&(!this.hasUserAmount&&typeof this.config?.defaultAmountUsd=="number"&&(this.amountUsd===0||this.amountUsd==null||Number.isNaN(this.amountUsd))&&(this.amountUsd=Number(this.config.defaultAmountUsd)),!this.selectedSymbol&&this.config?.defaultSymbol&&(this.selectedSymbol=this.config.defaultSymbol),!(this.config?.cryptoOptions&&this.config.cryptoOptions.length>0)&&this.availableLedgers.length===0&&this.loadVerifiedLedgers(),this.pendingAction&&this.config?.actorProvider)){let t=this.pendingAction;this.pendingAction=null,setTimeout(()=>{t==="pay"&&this.pay()},0)}}async loadVerifiedLedgers(){if(!(!We||!this.config?.publishableKey))try{let t=await c(this.config).client.getVerifiedLedgers();this.availableLedgers=t.map(i=>({symbol:i.symbol,label:i.name,canisterId:i.canisterId})),this.selectedSymbol||(this.selectedSymbol=this.config?.defaultSymbol||(this.availableLedgers[0]?.symbol??"ICP"))}catch(e){this.dispatchEvent(new CustomEvent("icpay-error",{detail:{message:"Failed to load verified ledgers",cause:e},bubbles:!0})),this.availableLedgers=[{symbol:"ICP",label:"ICP",canisterId:"ryjl3-tyaaa-aaaaa-aaaba-cai"}],this.selectedSymbol||(this.selectedSymbol=this.config?.defaultSymbol||"ICP")}}onInputChange(e){let t=Number(this.config?.stepUsd??.5),i=Math.max(0,Number(e.target.value||0)),r=Math.round(i/t)*t;this.amountUsd=Number(r.toFixed(2)),this.hasUserAmount=!0}selectSymbol(e){this.selectedSymbol=e}isValidAmount(){let e=Number(this.config?.minUsd??.5),t=this.config?.maxUsd!==void 0?Number(this.config.maxUsd):1/0;return this.amountUsd>=e&&this.amountUsd<=t}async ensureWallet(){if(this.config.useOwnWallet)return this.config.actorProvider?!0:(this.pendingAction="pay",this.dispatchEvent(new CustomEvent("icpay-connect-wallet",{bubbles:!0})),!1);if(this.walletConnected)return!0;try{if($e||($e=(await import("@windoge98/plug-n-play")).PNP),this.pnp=new $e(this.config?.plugNPlay||{}),!this.pnp.getEnabledWallets()?.length)throw new Error("No wallets available");return this.pendingAction="pay",this.showWalletModal=!0,!1}catch(e){return this.errorMessage=e instanceof Error?e.message:"Wallet connection failed",this.errorSeverity="error",!1}}getWalletId(e){return e&&(e.id||e.provider||e.key)||""}getWalletLabel(e){return e&&(e.label||e.name||e.title||e.id)||"Wallet"}getWalletIcon(e){return e&&(e.icon||e.logo||e.image)||null}async connectWithWallet(e){if(this.pnp)try{if(!e)throw new Error("No wallet ID provided");let t=await this.pnp.connect(e);if(!!!(t&&(t.connected===!0||t.principal||t.owner||this.pnp?.account)))throw new Error("Wallet connection was rejected");this.walletConnected=!0,this.config={...this.config,connectedWallet:t,actorProvider:(n,l)=>this.pnp.getActor({canisterId:n,idl:l,requiresSigning:!0,anon:!1})},this.showWalletModal=!1;let r=this.pendingAction;this.pendingAction=null,r==="pay"&&setTimeout(()=>this.pay(),0)}catch(t){this.errorMessage=t instanceof Error?t.message:"Wallet connection failed",this.errorSeverity="error",this.showWalletModal=!1}}async pay(){if(!(!We||this.processing)){if(this.errorMessage=null,this.errorSeverity=null,this.errorAction=null,!this.isValidAmount()){this.errorMessage="Please enter a valid amount",this.errorSeverity="warning";return}this.processing=!0;try{if(!await this.ensureWallet())return;let t=c(this.config),i=this.selectedSymbol||"ICP",n=this.cryptoOptions.find(H=>H.symbol===i)?.canisterId||await t.client.getLedgerCanisterIdBySymbol(i),l=Number(this.amountUsd),g={context:"amount-input"},w=await t.sendUsd(l,n,g);this.config.onSuccess&&this.config.onSuccess({id:w.transactionId,status:w.status,amountUsd:l}),this.succeeded=!0,this.dispatchEvent(new CustomEvent("icpay-amount-pay",{detail:{amount:l,tx:w},bubbles:!0}))}catch(e){k(e,{onError:t=>{this.dispatchEvent(new CustomEvent("icpay-error",{detail:t,bubbles:!0})),$(t)&&(this.errorMessage=W(t),this.errorSeverity=C(t),this.errorAction=L(t))}})}finally{this.processing=!1,this.pendingAction=null}}}render(){if(!this.config)return _`<div class="card section">Loading...</div>`;let e=this.config?.placeholder||"Enter amount in USD",i=(this.config?.buttonLabel||"Pay ${amount} with {symbol}").replace("{amount}",this.amountUsd?`${Number(this.amountUsd).toFixed(2)}`:"$0.00").replace("{symbol}",this.selectedSymbol||this.config?.defaultSymbol||"ICP"),r=this.config?.showLedgerDropdown===!0,n=this.cryptoOptions.find(N=>N.symbol===(this.selectedSymbol||""))?.label||this.cryptoOptions[0]?.label||this.config?.defaultSymbol||"ICP",l=this.config?.progressBar?.mode||"modal",g=this.config?.showLedgerDropdown,w=g==="buttons"?"buttons":g==="none"?"none":"dropdown",he=this.config?.progressBar?.enabled!==!1&&(l==="modal"?!0:this.processing);return _`
|
|
870
|
+
<div class="card section">
|
|
871
|
+
${he?_`<icpay-progress-bar mode="${l}"></icpay-progress-bar>`:null}
|
|
872
|
+
|
|
873
|
+
<div class="row">
|
|
874
|
+
<input type="number" min="0" step="${Number(this.config?.stepUsd??.5)}" .value=${String(this.amountUsd||"")} placeholder="${e}" @input=${N=>this.onInputChange(N)} />
|
|
875
|
+
${w!=="none"?_`
|
|
876
|
+
<icpay-token-selector
|
|
877
|
+
.options=${this.cryptoOptions}
|
|
878
|
+
.value=${this.selectedSymbol||""}
|
|
879
|
+
.defaultSymbol=${this.config?.defaultSymbol||"ICP"}
|
|
880
|
+
mode=${w}
|
|
881
|
+
@icpay-token-change=${N=>this.selectSymbol(N.detail.symbol)}
|
|
882
|
+
></icpay-token-selector>
|
|
883
|
+
`:_`
|
|
884
|
+
<div class="label" style="padding: 10px;">${n}</div>
|
|
885
|
+
`}
|
|
886
|
+
<button class="pay-button ${this.processing?"processing":""}"
|
|
887
|
+
?disabled=${this.processing||this.config?.disablePaymentButton===!0||this.succeeded&&this.config?.disableAfterSuccess===!0}
|
|
888
|
+
@click=${()=>this.pay()}>
|
|
889
|
+
${this.succeeded&&this.config?.disableAfterSuccess?"Paid":this.processing?"Processing\u2026":i}
|
|
890
|
+
</button>
|
|
891
|
+
</div>
|
|
892
|
+
<div class="hint">Default: ${this.config?.defaultSymbol||"ICP"}. Min: $${Number(this.config?.minUsd??.5).toFixed(2)}${this.config?.maxUsd?`, Max: $${Number(this.config.maxUsd).toFixed(2)}`:""}</div>
|
|
893
|
+
|
|
894
|
+
${this.errorMessage?_`
|
|
895
|
+
<div class="error-message ${this.errorSeverity}" style="margin-top: 12px; padding: 8px 12px; border-radius: 6px; font-size: 14px; text-align: center;">
|
|
896
|
+
${this.errorMessage}
|
|
897
|
+
${this.errorAction?_`<button style="margin-left: 8px; padding: 4px 8px; background: transparent; border: 1px solid currentColor; border-radius: 4px; font-size: 12px; cursor: pointer;">${this.errorAction}</button>`:""}
|
|
898
|
+
</div>
|
|
899
|
+
`:""}
|
|
900
|
+
${(()=>{let N=this.pnp?.getEnabledWallets?.()||[];return this.showWalletModal&&this.pnp?_`
|
|
901
|
+
<div style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.55);z-index:9999">
|
|
902
|
+
<div class="card" style="width:380px;padding:16px;border-radius:12px">
|
|
903
|
+
<div class="label" style="font-weight:700;margin-bottom:12px;text-align:center">Choose Wallet</div>
|
|
904
|
+
<div style="display:grid;grid-template-columns:1fr;gap:10px;margin-bottom:12px">
|
|
905
|
+
${N.map(J=>{let ae=this.getWalletId(J),I=this.getWalletLabel(J),E=this.getWalletIcon(J);return _`
|
|
906
|
+
<button class="pay-button" style="display:flex;align-items:center;gap:10px;justify-content:center;padding:12px" @click=${()=>this.connectWithWallet(ae)}>
|
|
907
|
+
${E?_`<img src="${E}" alt="${I}" style="width:20px;height:20px;border-radius:4px;object-fit:contain;background:transparent" />`:""}
|
|
908
|
+
<span>${I}</span>
|
|
909
|
+
</button>`})}
|
|
910
|
+
</div>
|
|
911
|
+
<button class="pay-button" style="background:#6b7280;color:#f9fafb" @click=${()=>{this.showWalletModal=!1}}>
|
|
912
|
+
Cancel
|
|
913
|
+
</button>
|
|
914
|
+
</div>
|
|
915
|
+
</div>
|
|
916
|
+
`:null})()}
|
|
917
|
+
</div>
|
|
918
|
+
`}};f.styles=[S,ft`
|
|
919
|
+
.row { display: grid; grid-template-columns: 1fr auto auto; gap: 8px; align-items: center; }
|
|
920
|
+
input[type="number"] { background: var(--icpay-surface-alt); border: 1px solid var(--icpay-border); color: var(--icpay-text); border-radius: 8px; padding: 10px; font-weight: 600; }
|
|
921
|
+
select { background: var(--icpay-surface-alt); border: 1px solid var(--icpay-border); color: var(--icpay-text); border-radius: 8px; padding: 10px; font-weight: 600; }
|
|
922
|
+
.error-message { border: 1px solid; font-weight: 500; }
|
|
923
|
+
.error-message.info { background: rgba(59,130,246,0.1); border-color: rgba(59,130,246,0.3); color: #3b82f6; }
|
|
924
|
+
.error-message.warning { background: rgba(245,158,11,0.1); border-color: rgba(245,158,11,0.3); color: #f59e0b; }
|
|
925
|
+
.error-message.error { background: rgba(239,68,68,0.1); border-color: rgba(239,68,68,0.3); color: #ef4444; }
|
|
926
|
+
.hint { font-size: 12px; color: var(--icpay-muted); margin-top: 6px; }
|
|
927
|
+
`],s([yt({type:Object})],f.prototype,"config",2),s([O()],f.prototype,"amountUsd",2),s([O()],f.prototype,"hasUserAmount",2),s([O()],f.prototype,"selectedSymbol",2),s([O()],f.prototype,"processing",2),s([O()],f.prototype,"succeeded",2),s([O()],f.prototype,"availableLedgers",2),s([O()],f.prototype,"errorMessage",2),s([O()],f.prototype,"errorSeverity",2),s([O()],f.prototype,"errorAction",2),s([O()],f.prototype,"walletConnected",2),s([O()],f.prototype,"pendingAction",2),s([O()],f.prototype,"showWalletModal",2),f=s([bt("icpay-amount-input")],f);export{f as ICPayAmountInput,p as ICPayArticlePaywall,m as ICPayCoffeeShop,h as ICPayDonationThermometer,v as ICPayPayButton,b as ICPayPremiumContent,u as ICPayTipJar,ee as applyThemeVars,S as baseStyles,c as createSdk};
|
|
928
|
+
//# sourceMappingURL=index.js.map
|