From cadf0427e71cdae7d87981a551d4477c1ad9f7f5 Mon Sep 17 00:00:00 2001 From: DeveloperAmrit Date: Sun, 7 Jun 2026 18:16:24 +0530 Subject: [PATCH 1/6] feat: Add example website --- stablepay-sdk/dist/esm/index.js | 2 +- stablepay-sdk/dist/umd/index.js | 2 +- stablepay-sdk/dist/umd/index.js.map | 2 +- stablepay-sdk/example/.gitignore | 24 + stablepay-sdk/example/README.md | 16 + stablepay-sdk/example/eslint.config.js | 21 + stablepay-sdk/example/index.html | 13 + stablepay-sdk/example/package-lock.json | 2835 ++++++++++++++++++++ stablepay-sdk/example/package.json | 30 + stablepay-sdk/example/public/favicon.svg | 1 + stablepay-sdk/example/public/icons.svg | 24 + stablepay-sdk/example/src/App.css | 91 + stablepay-sdk/example/src/App.jsx | 68 + stablepay-sdk/example/src/assets/hero.png | Bin 0 -> 13057 bytes stablepay-sdk/example/src/assets/react.svg | 1 + stablepay-sdk/example/src/assets/vite.svg | 1 + stablepay-sdk/example/src/index.css | 9 + stablepay-sdk/example/src/main.jsx | 11 + stablepay-sdk/example/vite.config.js | 7 + stablepay-sdk/examples/index.txt | 1 - 20 files changed, 3155 insertions(+), 4 deletions(-) create mode 100644 stablepay-sdk/example/.gitignore create mode 100644 stablepay-sdk/example/README.md create mode 100644 stablepay-sdk/example/eslint.config.js create mode 100644 stablepay-sdk/example/index.html create mode 100644 stablepay-sdk/example/package-lock.json create mode 100644 stablepay-sdk/example/package.json create mode 100644 stablepay-sdk/example/public/favicon.svg create mode 100644 stablepay-sdk/example/public/icons.svg create mode 100644 stablepay-sdk/example/src/App.css create mode 100644 stablepay-sdk/example/src/App.jsx create mode 100644 stablepay-sdk/example/src/assets/hero.png create mode 100644 stablepay-sdk/example/src/assets/react.svg create mode 100644 stablepay-sdk/example/src/assets/vite.svg create mode 100644 stablepay-sdk/example/src/index.css create mode 100644 stablepay-sdk/example/src/main.jsx create mode 100644 stablepay-sdk/example/vite.config.js delete mode 100644 stablepay-sdk/examples/index.txt diff --git a/stablepay-sdk/dist/esm/index.js b/stablepay-sdk/dist/esm/index.js index 907d446..116101c 100644 --- a/stablepay-sdk/dist/esm/index.js +++ b/stablepay-sdk/dist/esm/index.js @@ -1 +1 @@ -import{getWeb3 as e,getDjedContract as t,getCoinContracts as n,getDecimals as r,getOracleAddress as a,getOracleContract as o,tradeDataPriceBuySc as i,buyScTx as s}from"djed-sdk";import c,{useContext as l,createContext as d,useState as m,useEffect as u,useRef as h,useCallback as w}from"react";import{defineChain as k,createWalletClient as g,custom as C,createPublicClient as p,http as b,parseEther as f,parseUnits as v,encodeFunctionData as E}from"viem";import{sepolia as y}from"viem/chains";const _={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class N{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e(this.networkUri),this.djedContract=t(this.web3,this.djedAddress);try{const{stableCoin:e,reserveCoin:t}=await n(this.djedContract,this.web3),{scDecimals:i,rcDecimals:s}=await r(e,t);this.stableCoin=e,this.reserveCoin=t,this.scDecimals=i,this.rcDecimals=s,this.oracleContract=await a(this.djedContract).then((e=>o(this.web3,e,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){if(console.error("[Transaction] Error fetching contract details:",e),e.message&&e.message.includes("execution reverted")){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){if(console.error("[Transaction] Error initializing transaction:",e),e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(e){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof e)throw new Error("Amount must be a string");try{return(await i(this.djedContract,this.scDecimals,e)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(e,t,n){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await s(this.djedContract,e,t,n,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var T="main_stablePayButton__UA7HC",S="main_logo__ITyEy",A="main_buttonText__N-ewy";const D=({onClick:e,size:t="medium"})=>{const n={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},a=n[t]||n.medium,o=r[t]||r.medium;return c.createElement("button",{className:T,onClick:e,style:a},c.createElement("div",{className:S,style:o}),c.createElement("span",{className:A},"Pay with StablePay"))};var x={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",infoSection:"PricingCard_infoSection__gyjMQ",infoIcon:"PricingCard_infoIcon__rraxD",infoText:"PricingCard_infoText__l4b7A",walletButton:"PricingCard_walletButton__llw4v",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",networkError:"PricingCard_networkError__zR-36",errorText:"PricingCard_errorText__qZRJt","message-box":"PricingCard_message-box__vkUKy",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",loadingContainer:"PricingCard_loadingContainer__6nOVa",spinner:"PricingCard_spinner__9ucQv",spin:"PricingCard_spin__24tni"};const P=({children:e,onClose:t,size:n="medium"})=>c.createElement("div",{className:x.dialogOverlay},c.createElement("div",{className:`${x.pricingCard} ${x[n]}`},c.createElement("button",{className:x.dialogClose,onClick:t},"×"),c.createElement("div",{className:x.pricingCardHeader},c.createElement("div",{className:x.allianceLogo}),c.createElement("h2",{className:x.stablepayTitle},"StablePay")),c.createElement("div",{className:x.pricingCardBody},e)));class I{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const B=d(),M=({children:e,networkSelector:t})=>{const[n]=m((()=>new I(t))),[r,a]=m(null),[o,i]=m(null),[s,l]=m(null),d=()=>{i(null),l(null)};return u((()=>{a(t.selectedNetwork)}),[t.selectedNetwork]),c.createElement(B.Provider,{value:{networkSelector:t,tokenSelector:n,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:l,selectNetwork:e=>!!t.selectNetwork(e)&&(a(e),d(),!0),selectToken:e=>{if(n.selectToken(e)){const e=n.getSelectedToken();return i(e),!0}return!1},resetSelections:()=>{t.selectNetwork(null),a(null),d()}}},e)},$=()=>{const e=l(B);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},j=()=>{const{networkSelector:e,selectedNetwork:t,selectNetwork:n}=$();return c.createElement("div",{className:x.selectField},c.createElement("label",{htmlFor:"network-select"},"Select Network"),c.createElement("select",{id:"network-select",onChange:e=>{n(e.target.value)},value:t||""},c.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>c.createElement("option",{key:e,value:e},e)))))},U=()=>{const{networkSelector:e,tokenSelector:t,selectedNetwork:n,selectedToken:r,selectToken:a,setTransactionDetails:o}=$(),[i,s]=m(!1),[l,d]=m(null),u=n?t.getAvailableTokens():[];return c.createElement("div",{className:x.selectField},c.createElement("label",{htmlFor:"token-select"},"Select Token"),c.createElement("select",{id:"token-select",onChange:async r=>{const i=r.target.value;d(null),s(!0);try{if(a(i)){const r=e.getSelectedNetworkConfig(),a=new N(r.uri,r.djedAddress);await a.init();const s=e.getTokenAmount(i),c=a.getBlockchainDetails();let l=null;"native"===i&&(l=await a.handleTradeDataBuySc(String(s))),o({network:n,token:i,tokenSymbol:t.getSelectedToken().symbol,amount:s,receivingAddress:e.getReceivingAddress(),djedContractAddress:r.djedAddress,isDirectTransfer:t.getSelectedToken().isDirectTransfer||!1,isNativeToken:t.getSelectedToken().isNative||!1,tradeAmount:l?l.amount:null,...c})}}catch(e){console.error("Error fetching transaction details:",e),d("Failed to fetch transaction details. Please try again.")}finally{s(!1)}},value:r?r.key:"",disabled:!n||i},c.createElement("option",{value:"",disabled:!0},n?i?"Loading...":"Select a token":"Please select a network first"),u.map((e=>c.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),l&&c.createElement("div",{className:x.error},l))};k({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const F=k({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),R=k({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),L=d(null),z=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${y.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:y.rpcUrls.default.http,blockExplorerUrls:y.blockExplorers?.default?.url?[y.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${R.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${F.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},W=({children:e})=>{const{selectedNetwork:t}=$(),[n,r]=m(null),[a,o]=m(null),[i,s]=m(null),[l,d]=m(null),[k,f]=m(null),[v,E]=m(null),[_,N]=m(!1),T=t?(e=>{switch(e){case"sepolia":return y;case"ethereum-classic":return R;case"milkomeda-mainnet":return F;default:return null}})(t):null,S=T?T.id:null,A=h(null),D=h(null),x=w((()=>{r(null),o(null),s(null),d(null),f(null),E(null)}),[]),P=w((async e=>{const n=parseInt(e,16);if(d(n),T&&n===S){if(E(null),window.ethereum&&T){const e=g({chain:T,transport:C(window.ethereum)});r(e)}}else if(T&&n!==S){E(`Wrong network detected. Please switch to ${T?.name||t||"selected network"}`)}}),[T,S,t]);D.current=P;const I=w((async e=>{if(0===e.length){if(x(),window.ethereum){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(s(e[0]),T)try{const t=p({chain:T,transport:b()});o(t);const n=await t.getBalance({address:e[0]});f(parseFloat(n)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}}),[T,x]);A.current=I;const B=w((()=>{if(x(),window.ethereum){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[x]),M=w((()=>{T&&o(p({chain:T,transport:b()}))}),[T]),j=w((async()=>{if(!window.ethereum)return E("Please install MetaMask or another Web3 wallet"),!1;if(!t||!T)return E("Please select a network first"),!1;N(!0),E(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const n=await window.ethereum.request({method:"eth_chainId"});parseInt(n,16)!==S&&await z(t);const a=g({chain:T,transport:C(window.ethereum)});r(a),s(e[0]),d(S);const i=p({chain:T,transport:b()});o(i);try{const t=await i.getBalance({address:e[0]});f(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}return A.current=I,D.current=P,window.ethereum.on("accountsChanged",I),window.ethereum.on("chainChanged",P),!0}catch(e){return console.error("Error connecting wallet:",e),E(e.message),!1}finally{N(!1)}}),[t,T,S,I,P]),U=w((async()=>{if(!(window.ethereum&&t&&T&&i)){return E("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==S){E(null),await z(t);const e=500;await new Promise((t=>setTimeout(t,e)));const n=await window.ethereum.request({method:"eth_chainId"}),r=parseInt(n,16);if(r!==S)throw new Error(`Failed to switch network. MetaMask is still on chain ${r}, expected ${S}`)}const n=g({chain:T,transport:C(window.ethereum)});return r(n),d(S),E(null),n}catch(e){return E(e.message),null}}),[t,T,S,i]),W=h(t);return u((()=>{if(null!==W.current&&W.current!==t&&i&&(x(),window.ethereum)){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}W.current=t}),[t,i,x]),u((()=>{M()}),[M]),c.createElement(L.Provider,{value:{walletClient:n,publicClient:a,account:i,chainId:l,balance:k,error:v,isConnecting:_,connectWallet:j,disconnectWallet:B,ensureCorrectNetwork:U,expectedChainId:S}},e)},O=({onTransactionComplete:e})=>{const{networkSelector:t,selectedNetwork:n,selectedToken:r,transactionDetails:a,setTransactionDetails:o}=$(),{connectWallet:i,account:s,walletClient:d,publicClient:h,isConnecting:w,ensureCorrectNetwork:k,expectedChainId:g}=(()=>{const e=l(L);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[C,p]=m(null),[b,y]=m(null),[_,T]=m(null),[S,A]=m(""),[D,P]=m(null),[I,B]=m(null),[M,j]=m(!1);if(u((()=>{T(null),y(null),A(""),B(null),P(null)}),[n,r]),u((()=>{(async()=>{if(n&&r)try{const e=t.getSelectedNetworkConfig(),a=t.getReceivingAddress(),i=t.getTokenAmount(r.key),s=new N(e.uri,e.djedAddress);await s.init(),p(s);let c=null;if("native"===r.key)try{c=await s.handleTradeDataBuySc(String(i)),y(c)}catch(e){console.error("Error fetching trade data:",e)}o({network:n,token:r.key,tokenSymbol:r.symbol,amount:i||"0",receivingAddress:a,djedContractAddress:e.djedAddress,isDirectTransfer:r.isDirectTransfer||!1,isNativeToken:r.isNative||!1,tradeAmount:c?c.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[n,r,t,o]),!a)return c.createElement("div",{className:x.loading},"Initializing transaction...");const U=()=>{if(!D||!n)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[n]?`${e[n]}${D}`:null};return c.createElement("div",{className:x.transactionReview},c.createElement("div",{className:x.transactionInfo},c.createElement("span",{className:x.transactionLabel},"Network:"),c.createElement("span",{className:x.transactionValue},a.network)),c.createElement("div",{className:x.transactionInfo},c.createElement("span",{className:x.transactionLabel},"You Pay:"),c.createElement("span",{className:x.transactionValue},"stablecoin"===r.key?`${a.amount} ${a.tokenSymbol}`:`${b||"Calculating..."} ${a.tokenSymbol}`)),c.createElement("button",{className:x.walletButton,onClick:async()=>{await i()},disabled:w},w?"Connecting...":"Connect Wallet"),s&&!_&&c.createElement("button",{className:x.walletButton,onClick:async()=>{if(s&&a&&C)try{T(null),B(null),A("⏳ Preparing transaction...");const e=a.receivingAddress;let n;if("native"===r.key){const t="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=f(String(b||"0"));n=await C.buyStablecoins(s,e,r,t),n={...n,value:r,account:s}}else{const r=t.getSelectedNetworkConfig(),o=r?.tokens?.stablecoin?.address;if(!o)throw new Error("Stablecoin address not found in network configuration");const i=a.amount?v(String(a.amount),a.stableCoinDecimals):"0";n={to:o,value:0n,data:E({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:s}}T(n),A("✅ Transaction ready! Click 'Send Transaction' to proceed.")}catch(e){B(e),A("❌ Transaction preparation failed.")}else A("❌ Wallet not connected or transaction details missing")}},"Prepare Transaction"),s&&_&&c.createElement("button",{className:x.walletButton,onClick:async()=>{B(null);try{if(!s||!_)return void A("❌ Wallet account or transaction data is missing");if(!n)return void A("❌ Network not selected");const o=t.getSelectedNetworkConfig();if(!o)return void A("❌ Network configuration not found");A("⏳ Verifying network...");const i=await k();if(!i)return void A("❌ Failed to switch to correct network. Please approve the network switch in MetaMask and try again.");if(!window.ethereum)return void A("❌ MetaMask not available");const c=await window.ethereum.request({method:"eth_chainId"}),l=parseInt(c,16);if(l!==o.chainId){const e=`Network mismatch. MetaMask is on chain ${l}, but ${n} requires chain ${o.chainId}. Please switch networks in MetaMask.`;return A(`❌ ${e}`),void B(new Error(e))}if(i.chain.id!==o.chainId){const e=`Wallet client chain mismatch. Wallet client is on chain ${i.chain.id}, but expected ${o.chainId}.`;return A(`❌ ${e}`),void B(new Error(e))}A("⏳ Sending transaction...");const d=await i.sendTransaction({..._,account:s});P(d),A("✅ Transaction sent!"),e&&e({txHash:d,network:n,token:r?.key,tokenSymbol:r?.symbol,amount:a?.amount,receivingAddress:a?.receivingAddress})}catch(e){B(e),A("❌ Transaction failed."),console.error("Transaction error:",e)}},disabled:null!==D},"Send Transaction"),S&&c.createElement("div",{className:"message-box"},S,I&&c.createElement("button",{onClick:()=>j(!M),className:x.detailsButton},M?"Hide Details":"Show Details")),M&&I&&c.createElement("div",{className:x.errorDetails},c.createElement("pre",null,I.message)),D&&c.createElement("div",{className:x.transactionLink},"✅ Transaction Hash:"," ",U()?c.createElement("a",{href:U(),target:"_blank",rel:"noopener noreferrer",className:x.explorerLink,style:{color:"#007bff",textDecoration:"underline",fontWeight:"bold",cursor:"pointer",wordBreak:"break-word"}},D.slice(0,6),"...",D.slice(-6)):c.createElement("span",{style:{wordBreak:"break-word"}},D)))},q=({onClose:e,buttonSize:t,onTransactionComplete:n})=>{const{resetSelections:r}=$();return c.createElement(P,{onClose:()=>{r(),e()},size:t},c.createElement(j,null),c.createElement(U,null),c.createElement(O,{onTransactionComplete:n}))},H=({onClose:e,buttonSize:t,networkSelector:n,onTransactionComplete:r})=>c.createElement(M,{networkSelector:n},c.createElement(W,null,c.createElement(q,{onClose:e,buttonSize:t,onTransactionComplete:r}))),V={NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(_).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:N,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!_[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:t="medium",onTransactionComplete:n,onSuccess:r})=>{const[a,o]=m(!1),i=n||r;return c.createElement("div",{className:x.widgetContainer},!a&&c.createElement(D,{onClick:()=>{o(!0)},size:t}),a&&c.createElement(H,{onClose:()=>{o(!1)},buttonSize:t,networkSelector:e,onTransactionComplete:i}))},PayButton:D,Dialog:P,NetworkDropdown:j};export{V as default}; +import{getWeb3 as e,getDjedContract as t,getCoinContracts as n,getDecimals as r,getOracleAddress as a,getOracleContract as o,tradeDataPriceBuySc as i,buyScTx as s}from"djed-sdk";import c,{useContext as l,createContext as d,useState as m,useEffect as u,useRef as h,useCallback as w}from"react";import{defineChain as k,createWalletClient as g,custom as C,createPublicClient as p,http as b,parseEther as f,parseUnits as v,encodeFunctionData as E}from"viem";import{sepolia as y}from"viem/chains";const _={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class N{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e(this.networkUri),this.djedContract=t(this.web3,this.djedAddress);try{const{stableCoin:e,reserveCoin:t}=await n(this.djedContract,this.web3),{scDecimals:i,rcDecimals:s}=await r(e,t);this.stableCoin=e,this.reserveCoin=t,this.scDecimals=i,this.rcDecimals=s,this.oracleContract=await a(this.djedContract).then((e=>o(this.web3,e,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){if(console.error("[Transaction] Error fetching contract details:",e),e.message&&e.message.includes("execution reverted")){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){if(console.error("[Transaction] Error initializing transaction:",e),e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(e){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof e)throw new Error("Amount must be a string");try{return(await i(this.djedContract,this.scDecimals,e)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(e,t,n){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await s(this.djedContract,e,t,n,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var T="main_stablePayButton__UA7HC",S="main_logo__ITyEy",A="main_buttonText__N-ewy";const D=({onClick:e,size:t="medium"})=>{const n={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},a=n[t]||n.medium,o=r[t]||r.medium;return c.createElement("button",{className:T,onClick:e,style:a},c.createElement("div",{className:S,style:o}),c.createElement("span",{className:A},"Pay with StablePay"))};var x={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",infoSection:"PricingCard_infoSection__gyjMQ",infoIcon:"PricingCard_infoIcon__rraxD",infoText:"PricingCard_infoText__l4b7A",walletButton:"PricingCard_walletButton__llw4v",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",networkError:"PricingCard_networkError__zR-36",errorText:"PricingCard_errorText__qZRJt","message-box":"PricingCard_message-box__vkUKy",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",loadingContainer:"PricingCard_loadingContainer__6nOVa",spinner:"PricingCard_spinner__9ucQv",spin:"PricingCard_spin__24tni"};const P=({children:e,onClose:t,size:n="medium"})=>c.createElement("div",{className:x.dialogOverlay},c.createElement("div",{className:`${x.pricingCard} ${x[n]}`},c.createElement("button",{className:x.dialogClose,onClick:t},"×"),c.createElement("div",{className:x.pricingCardHeader},c.createElement("div",{className:x.allianceLogo}),c.createElement("h2",{className:x.stablepayTitle},"StablePay")),c.createElement("div",{className:x.pricingCardBody},e)));class I{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const B=d(),M=({children:e,networkSelector:t})=>{const[n]=m((()=>new I(t))),[r,a]=m(null),[o,i]=m(null),[s,l]=m(null),d=()=>{i(null),l(null)};return u((()=>{a(t.selectedNetwork)}),[t.selectedNetwork]),c.createElement(B.Provider,{value:{networkSelector:t,tokenSelector:n,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:l,selectNetwork:e=>!!t.selectNetwork(e)&&(a(e),d(),!0),selectToken:e=>{if(n.selectToken(e)){const e=n.getSelectedToken();return i(e),!0}return!1},resetSelections:()=>{t.selectNetwork(null),a(null),d()}}},e)},$=()=>{const e=l(B);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},j=()=>{const{networkSelector:e,selectedNetwork:t,selectNetwork:n}=$();return c.createElement("div",{className:x.selectField},c.createElement("label",{htmlFor:"network-select"},"Select Network"),c.createElement("select",{id:"network-select",onChange:e=>{n(e.target.value)},value:t||""},c.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>c.createElement("option",{key:e,value:e},e)))))},U=()=>{const{networkSelector:e,tokenSelector:t,selectedNetwork:n,selectedToken:r,selectToken:a,setTransactionDetails:o}=$(),[i,s]=m(!1),[l,d]=m(null),u=n?t.getAvailableTokens():[];return c.createElement("div",{className:x.selectField},c.createElement("label",{htmlFor:"token-select"},"Select Token"),c.createElement("select",{id:"token-select",onChange:async r=>{const i=r.target.value;d(null),s(!0);try{if(a(i)){const r=e.getSelectedNetworkConfig(),a=new N(r.uri,r.djedAddress);await a.init();const s=e.getTokenAmount(i),c=a.getBlockchainDetails();let l=null;"native"===i&&(l=await a.handleTradeDataBuySc(String(s))),o({network:n,token:i,tokenSymbol:t.getSelectedToken().symbol,amount:s,receivingAddress:e.getReceivingAddress(),djedContractAddress:r.djedAddress,isDirectTransfer:t.getSelectedToken().isDirectTransfer||!1,isNativeToken:t.getSelectedToken().isNative||!1,tradeAmount:l?l.amount:null,...c})}}catch(e){console.error("Error fetching transaction details:",e),d("Failed to fetch transaction details. Please try again.")}finally{s(!1)}},value:r?r.key:"",disabled:!n||i},c.createElement("option",{value:"",disabled:!0},n?i?"Loading...":"Select a token":"Please select a network first"),u.map((e=>c.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),l&&c.createElement("div",{className:x.error},l))};k({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const F=k({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),R=k({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),L=d(null),z=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${y.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:y.rpcUrls.default.http,blockExplorerUrls:y.blockExplorers?.default?.url?[y.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${R.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${F.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},W=({children:e})=>{const{selectedNetwork:t}=$(),[n,r]=m(null),[a,o]=m(null),[i,s]=m(null),[l,d]=m(null),[k,f]=m(null),[v,E]=m(null),[_,N]=m(!1),T=t?(e=>{switch(e){case"sepolia":return y;case"ethereum-classic":return R;case"milkomeda-mainnet":return F;default:return null}})(t):null,S=T?T.id:null,A=h(null),D=h(null),x=w((()=>{r(null),o(null),s(null),d(null),f(null),E(null)}),[]),P=w((async e=>{const n=parseInt(e,16);if(d(n),T&&n===S){if(E(null),window.ethereum&&T){const e=g({chain:T,transport:C(window.ethereum)});r(e)}}else if(T&&n!==S){E(`Wrong network detected. Please switch to ${T?.name||t||"selected network"}`)}}),[T,S,t]);D.current=P;const I=w((async e=>{if(0===e.length){if(x(),window.ethereum){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(s(e[0]),T)try{const t=p({chain:T,transport:b()});o(t);const n=await t.getBalance({address:e[0]});f(parseFloat(n)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}}),[T,x]);A.current=I;const B=w((()=>{if(x(),window.ethereum){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[x]),M=w((()=>{T&&o(p({chain:T,transport:b()}))}),[T]),j=w((async()=>{if(!window.ethereum)return E("Please install MetaMask or another Web3 wallet"),!1;if(!t||!T)return E("Please select a network first"),!1;N(!0),E(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const n=await window.ethereum.request({method:"eth_chainId"});parseInt(n,16)!==S&&await z(t);const a=g({chain:T,transport:C(window.ethereum)});r(a),s(e[0]),d(S);const i=p({chain:T,transport:b()});o(i);try{const t=await i.getBalance({address:e[0]});f(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}return A.current=I,D.current=P,window.ethereum.on("accountsChanged",I),window.ethereum.on("chainChanged",P),!0}catch(e){return console.error("Error connecting wallet:",e),E(e.message),!1}finally{N(!1)}}),[t,T,S,I,P]),U=w((async()=>{if(!(window.ethereum&&t&&T&&i)){return E("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==S){E(null),await z(t);const e=500;await new Promise((t=>setTimeout(t,e)));const n=await window.ethereum.request({method:"eth_chainId"}),r=parseInt(n,16);if(r!==S)throw new Error(`Failed to switch network. MetaMask is still on chain ${r}, expected ${S}`)}const n=g({chain:T,transport:C(window.ethereum)});return r(n),d(S),E(null),n}catch(e){return E(e.message),null}}),[t,T,S,i]),W=h(t);return u((()=>{if(null!==W.current&&W.current!==t&&i&&(x(),window.ethereum)){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}W.current=t}),[t,i,x]),u((()=>{M()}),[M]),c.createElement(L.Provider,{value:{walletClient:n,publicClient:a,account:i,chainId:l,balance:k,error:v,isConnecting:_,connectWallet:j,disconnectWallet:B,ensureCorrectNetwork:U,expectedChainId:S}},e)},O=({onTransactionComplete:e})=>{const{networkSelector:t,selectedNetwork:n,selectedToken:r,transactionDetails:a,setTransactionDetails:o}=$(),{connectWallet:i,account:s,walletClient:d,publicClient:h,isConnecting:w,ensureCorrectNetwork:k,expectedChainId:g}=(()=>{const e=l(L);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[C,p]=m(null),[b,y]=m(null),[_,T]=m(null),[S,A]=m(""),[D,P]=m(null),[I,B]=m(null),[M,j]=m(!1);if(u((()=>{T(null),y(null),A(""),B(null),P(null)}),[n,r]),u((()=>{(async()=>{if(n&&r)try{const e=t.getSelectedNetworkConfig(),a=t.getReceivingAddress(),i=t.getTokenAmount(r.key),s=new N(e.uri,e.djedAddress);await s.init(),p(s);let c=null;if("native"===r.key)try{c=await s.handleTradeDataBuySc(String(i)),y(c)}catch(e){console.error("Error fetching trade data:",e)}o({network:n,token:r.key,tokenSymbol:r.symbol,amount:i||"0",receivingAddress:a,djedContractAddress:e.djedAddress,isDirectTransfer:r.isDirectTransfer||!1,isNativeToken:r.isNative||!1,tradeAmount:c?c.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[n,r,t,o]),!a)return c.createElement("div",{className:x.loading},"Initializing transaction...");const U=()=>{if(!D||!n)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[n]?`${e[n]}${D}`:null};return c.createElement("div",{className:x.transactionReview},c.createElement("div",{className:x.transactionInfo},c.createElement("span",{className:x.transactionLabel},"Network:"),c.createElement("span",{className:x.transactionValue},a.network)),c.createElement("div",{className:x.transactionInfo},c.createElement("span",{className:x.transactionLabel},"You Pay:"),c.createElement("span",{className:x.transactionValue},"stablecoin"===r.key?`${a.amount} ${a.tokenSymbol}`:`${b||"Calculating..."} ${a.tokenSymbol}`)),c.createElement("button",{className:x.walletButton,onClick:async()=>{await i()},disabled:w},w?"Connecting...":"Connect Wallet"),s&&!_&&c.createElement("button",{className:x.walletButton,onClick:async()=>{if(s&&a&&C)try{T(null),B(null),A("⏳ Preparing transaction...");const e=a.receivingAddress;let n;if("native"===r.key){const t="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=f(String(b||"0"));n=await C.buyStablecoins(s,e,r,t),n={...n,value:r,account:s}}else{const r=t.getSelectedNetworkConfig(),o=r?.tokens?.stablecoin?.address;if(!o)throw new Error("Stablecoin address not found in network configuration");const i=a.amount?v(String(a.amount),a.stableCoinDecimals):"0";n={to:o,value:0n,data:E({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:s}}T(n),A("✅ Transaction ready! Click 'Send Transaction' to proceed.")}catch(e){B(e),A("❌ Transaction preparation failed.")}else A("❌ Wallet not connected or transaction details missing")}},"Prepare Transaction"),s&&_&&c.createElement("button",{className:x.walletButton,onClick:async()=>{B(null);try{if(!s||!_)return void A("❌ Wallet account or transaction data is missing");if(!n)return void A("❌ Network not selected");const o=t.getSelectedNetworkConfig();if(!o)return void A("❌ Network configuration not found");A("⏳ Verifying network...");const i=await k();if(!i)return void A("❌ Failed to switch to correct network. Please approve the network switch in MetaMask and try again.");if(!window.ethereum)return void A("❌ MetaMask not available");const c=await window.ethereum.request({method:"eth_chainId"}),l=parseInt(c,16);if(l!==o.chainId){const e=`Network mismatch. MetaMask is on chain ${l}, but ${n} requires chain ${o.chainId}. Please switch networks in MetaMask.`;return A(`❌ ${e}`),void B(new Error(e))}if(i.chain.id!==o.chainId){const e=`Wallet client chain mismatch. Wallet client is on chain ${i.chain.id}, but expected ${o.chainId}.`;return A(`❌ ${e}`),void B(new Error(e))}A("⏳ Sending transaction...");const d=await i.sendTransaction({..._,account:s});P(d),A("✅ Transaction sent!"),e&&e({txHash:d,network:n,token:r?.key,tokenSymbol:r?.symbol,amount:a?.amount,receivingAddress:a?.receivingAddress})}catch(e){B(e),A("❌ Transaction failed."),console.error("Transaction error:",e)}},disabled:null!==D},"Send Transaction"),S&&c.createElement("div",{className:"message-box"},S,I&&c.createElement("button",{onClick:()=>j(!M),className:x.detailsButton},M?"Hide Details":"Show Details")),M&&I&&c.createElement("div",{className:x.errorDetails},c.createElement("pre",null,I.message)),D&&c.createElement("div",{className:x.transactionLink},"✅ Transaction Hash:"," ",U()?c.createElement("a",{href:U(),target:"_blank",rel:"noopener noreferrer",className:x.explorerLink,style:{color:"#007bff",textDecoration:"underline",fontWeight:"bold",cursor:"pointer",wordBreak:"break-word"}},D.slice(0,6),"...",D.slice(-6)):c.createElement("span",{style:{wordBreak:"break-word"}},D)))},q=({onClose:e,buttonSize:t,onTransactionComplete:n})=>{const{resetSelections:r}=$();return c.createElement(P,{onClose:()=>{r(),e()},size:t},c.createElement(j,null),c.createElement(U,null),c.createElement(O,{onTransactionComplete:n}))},H=({onClose:e,buttonSize:t,networkSelector:n,onTransactionComplete:r})=>c.createElement(M,{networkSelector:n},c.createElement(W,null,c.createElement(q,{onClose:e,buttonSize:t,onTransactionComplete:r}))),V={NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(_).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:N,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!_[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:t="medium",onTransactionComplete:n,onSuccess:r})=>{const[a,o]=m(!1),i=n||r;return c.createElement("div",{className:x.widgetContainer},!a&&c.createElement(D,{onClick:()=>{o(!0)},size:t}),a&&c.createElement(H,{onClose:()=>{o(!1)},buttonSize:t,networkSelector:e,onTransactionComplete:i}))},PayButton:D,Dialog:P,NetworkDropdown:j};export{V as default}; diff --git a/stablepay-sdk/dist/umd/index.js b/stablepay-sdk/dist/umd/index.js index 0e43e66..f5a6876 100644 --- a/stablepay-sdk/dist/umd/index.js +++ b/stablepay-sdk/dist/umd/index.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("djed-sdk"),require("react"),require("viem"),require("viem/chains")):"function"==typeof define&&define.amd?define(["djed-sdk","react","viem","viem/chains"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).StablePay=t(e.DjedSdk,e.React,e.viem,e.viemChains)}(this,(function(e,t,n,r){"use strict";const a={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class i{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e.getWeb3(this.networkUri),this.djedContract=e.getDjedContract(this.web3,this.djedAddress);try{const{stableCoin:t,reserveCoin:n}=await e.getCoinContracts(this.djedContract,this.web3),{scDecimals:r,rcDecimals:a}=await e.getDecimals(t,n);this.stableCoin=t,this.reserveCoin=n,this.scDecimals=r,this.rcDecimals=a,this.oracleContract=await e.getOracleAddress(this.djedContract).then((t=>e.getOracleContract(this.web3,t,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){if(console.error("[Transaction] Error fetching contract details:",e),e.message&&e.message.includes("execution reverted")){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){if(console.error("[Transaction] Error initializing transaction:",e),e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(t){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof t)throw new Error("Amount must be a string");try{return(await e.tradeDataPriceBuySc(this.djedContract,this.scDecimals,t)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(t,n,r){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const a="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await e.buyScTx(this.djedContract,t,n,r,a,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var o="main_stablePayButton__UA7HC",s="main_logo__ITyEy",c="main_buttonText__N-ewy";const l=({onClick:e,size:n="medium"})=>{const r={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},a={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},i=r[n]||r.medium,l=a[n]||a.medium;return t.createElement("button",{className:o,onClick:e,style:i},t.createElement("div",{className:s,style:l}),t.createElement("span",{className:c},"Pay with StablePay"))};var d={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",infoSection:"PricingCard_infoSection__gyjMQ",infoIcon:"PricingCard_infoIcon__rraxD",infoText:"PricingCard_infoText__l4b7A",walletButton:"PricingCard_walletButton__llw4v",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",networkError:"PricingCard_networkError__zR-36",errorText:"PricingCard_errorText__qZRJt","message-box":"PricingCard_message-box__vkUKy",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",loadingContainer:"PricingCard_loadingContainer__6nOVa",spinner:"PricingCard_spinner__9ucQv",spin:"PricingCard_spin__24tni"};const u=({children:e,onClose:n,size:r="medium"})=>t.createElement("div",{className:d.dialogOverlay},t.createElement("div",{className:`${d.pricingCard} ${d[r]}`},t.createElement("button",{className:d.dialogClose,onClick:n},"×"),t.createElement("div",{className:d.pricingCardHeader},t.createElement("div",{className:d.allianceLogo}),t.createElement("h2",{className:d.stablepayTitle},"StablePay")),t.createElement("div",{className:d.pricingCardBody},e)));class m{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const h=t.createContext(),w=({children:e,networkSelector:n})=>{const[r]=t.useState((()=>new m(n))),[a,i]=t.useState(null),[o,s]=t.useState(null),[c,l]=t.useState(null),d=()=>{s(null),l(null)};return t.useEffect((()=>{i(n.selectedNetwork)}),[n.selectedNetwork]),t.createElement(h.Provider,{value:{networkSelector:n,tokenSelector:r,selectedNetwork:a,selectedToken:o,transactionDetails:c,setTransactionDetails:l,selectNetwork:e=>!!n.selectNetwork(e)&&(i(e),d(),!0),selectToken:e=>{if(r.selectToken(e)){const e=r.getSelectedToken();return s(e),!0}return!1},resetSelections:()=>{n.selectNetwork(null),i(null),d()}}},e)},k=()=>{const e=t.useContext(h);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},g=()=>{const{networkSelector:e,selectedNetwork:n,selectNetwork:r}=k();return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"network-select"},"Select Network"),t.createElement("select",{id:"network-select",onChange:e=>{r(e.target.value)},value:n||""},t.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>t.createElement("option",{key:e,value:e},e)))))},C=()=>{const{networkSelector:e,tokenSelector:n,selectedNetwork:r,selectedToken:a,selectToken:o,setTransactionDetails:s}=k(),[c,l]=t.useState(!1),[u,m]=t.useState(null),h=r?n.getAvailableTokens():[];return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"token-select"},"Select Token"),t.createElement("select",{id:"token-select",onChange:async t=>{const a=t.target.value;m(null),l(!0);try{if(o(a)){const t=e.getSelectedNetworkConfig(),o=new i(t.uri,t.djedAddress);await o.init();const c=e.getTokenAmount(a),l=o.getBlockchainDetails();let d=null;"native"===a&&(d=await o.handleTradeDataBuySc(String(c))),s({network:r,token:a,tokenSymbol:n.getSelectedToken().symbol,amount:c,receivingAddress:e.getReceivingAddress(),djedContractAddress:t.djedAddress,isDirectTransfer:n.getSelectedToken().isDirectTransfer||!1,isNativeToken:n.getSelectedToken().isNative||!1,tradeAmount:d?d.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),m("Failed to fetch transaction details. Please try again.")}finally{l(!1)}},value:a?a.key:"",disabled:!r||c},t.createElement("option",{value:"",disabled:!0},r?c?"Loading...":"Select a token":"Please select a network first"),h.map((e=>t.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),u&&t.createElement("div",{className:d.error},u))};n.defineChain({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const b=n.defineChain({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),p=n.defineChain({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),f=t.createContext(null),v=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${r.sepolia.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:r.sepolia.rpcUrls.default.http,blockExplorerUrls:r.sepolia.blockExplorers?.default?.url?[r.sepolia.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${p.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${b.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},y=({children:e})=>{const{selectedNetwork:a}=k(),[i,o]=t.useState(null),[s,c]=t.useState(null),[l,d]=t.useState(null),[u,m]=t.useState(null),[h,w]=t.useState(null),[g,C]=t.useState(null),[y,E]=t.useState(!1),_=a?(e=>{switch(e){case"sepolia":return r.sepolia;case"ethereum-classic":return p;case"milkomeda-mainnet":return b;default:return null}})(a):null,S=_?_.id:null,N=t.useRef(null),T=t.useRef(null),A=t.useCallback((()=>{o(null),c(null),d(null),m(null),w(null),C(null)}),[]),D=t.useCallback((async e=>{const t=parseInt(e,16);if(m(t),_&&t===S){if(C(null),window.ethereum&&_){const e=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});o(e)}}else if(_&&t!==S){C(`Wrong network detected. Please switch to ${_?.name||a||"selected network"}`)}}),[_,S,a]);T.current=D;const x=t.useCallback((async e=>{if(0===e.length){if(A(),window.ethereum){const e=N.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(d(e[0]),_)try{const t=n.createPublicClient({chain:_,transport:n.http()});c(t);const r=await t.getBalance({address:e[0]});w(parseFloat(r)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}}),[_,A]);N.current=x;const P=t.useCallback((()=>{if(A(),window.ethereum){const e=N.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[A]),I=t.useCallback((()=>{_&&c(n.createPublicClient({chain:_,transport:n.http()}))}),[_]),j=t.useCallback((async()=>{if(!window.ethereum)return C("Please install MetaMask or another Web3 wallet"),!1;if(!a||!_)return C("Please select a network first"),!1;E(!0),C(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const t=await window.ethereum.request({method:"eth_chainId"});parseInt(t,16)!==S&&await v(a);const r=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});o(r),d(e[0]),m(S);const i=n.createPublicClient({chain:_,transport:n.http()});c(i);try{const t=await i.getBalance({address:e[0]});w(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}return N.current=x,T.current=D,window.ethereum.on("accountsChanged",x),window.ethereum.on("chainChanged",D),!0}catch(e){return console.error("Error connecting wallet:",e),C(e.message),!1}finally{E(!1)}}),[a,_,S,x,D]),B=t.useCallback((async()=>{if(!(window.ethereum&&a&&_&&l)){return C("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==S){C(null),await v(a);const e=500;await new Promise((t=>setTimeout(t,e)));const t=await window.ethereum.request({method:"eth_chainId"}),n=parseInt(t,16);if(n!==S)throw new Error(`Failed to switch network. MetaMask is still on chain ${n}, expected ${S}`)}const t=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});return o(t),m(S),C(null),t}catch(e){return C(e.message),null}}),[a,_,S,l]),M=t.useRef(a);return t.useEffect((()=>{if(null!==M.current&&M.current!==a&&l&&(A(),window.ethereum)){const e=N.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}M.current=a}),[a,l,A]),t.useEffect((()=>{I()}),[I]),t.createElement(f.Provider,{value:{walletClient:i,publicClient:s,account:l,chainId:u,balance:h,error:g,isConnecting:y,connectWallet:j,disconnectWallet:P,ensureCorrectNetwork:B,expectedChainId:S}},e)},E=({onTransactionComplete:e})=>{const{networkSelector:r,selectedNetwork:a,selectedToken:o,transactionDetails:s,setTransactionDetails:c}=k(),{connectWallet:l,account:u,walletClient:m,publicClient:h,isConnecting:w,ensureCorrectNetwork:g,expectedChainId:C}=(()=>{const e=t.useContext(f);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[b,p]=t.useState(null),[v,y]=t.useState(null),[E,_]=t.useState(null),[S,N]=t.useState(""),[T,A]=t.useState(null),[D,x]=t.useState(null),[P,I]=t.useState(!1);if(t.useEffect((()=>{_(null),y(null),N(""),x(null),A(null)}),[a,o]),t.useEffect((()=>{(async()=>{if(a&&o)try{const e=r.getSelectedNetworkConfig(),t=r.getReceivingAddress(),n=r.getTokenAmount(o.key),s=new i(e.uri,e.djedAddress);await s.init(),p(s);let l=null;if("native"===o.key)try{l=await s.handleTradeDataBuySc(String(n)),y(l)}catch(e){console.error("Error fetching trade data:",e)}c({network:a,token:o.key,tokenSymbol:o.symbol,amount:n||"0",receivingAddress:t,djedContractAddress:e.djedAddress,isDirectTransfer:o.isDirectTransfer||!1,isNativeToken:o.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[a,o,r,c]),!s)return t.createElement("div",{className:d.loading},"Initializing transaction...");const j=()=>{if(!T||!a)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[a]?`${e[a]}${T}`:null};return t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"Network:"),t.createElement("span",{className:d.transactionValue},s.network)),t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"You Pay:"),t.createElement("span",{className:d.transactionValue},"stablecoin"===o.key?`${s.amount} ${s.tokenSymbol}`:`${v||"Calculating..."} ${s.tokenSymbol}`)),t.createElement("button",{className:d.walletButton,onClick:async()=>{await l()},disabled:w},w?"Connecting...":"Connect Wallet"),u&&!E&&t.createElement("button",{className:d.walletButton,onClick:async()=>{if(u&&s&&b)try{_(null),x(null),N("⏳ Preparing transaction...");const e=s.receivingAddress;let t;if("native"===o.key){const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",a=v||"0",i=n.parseEther(String(a));t=await b.buyStablecoins(u,e,i,r),t={...t,value:i,account:u}}else{const a=r.getSelectedNetworkConfig(),i=a?.tokens?.stablecoin?.address;if(!i)throw new Error("Stablecoin address not found in network configuration");const o=s.amount?n.parseUnits(String(s.amount),s.stableCoinDecimals):"0";t={to:i,value:0n,data:n.encodeFunctionData({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,o]}),account:u}}_(t),N("✅ Transaction ready! Click 'Send Transaction' to proceed.")}catch(e){x(e),N("❌ Transaction preparation failed.")}else N("❌ Wallet not connected or transaction details missing")}},"Prepare Transaction"),u&&E&&t.createElement("button",{className:d.walletButton,onClick:async()=>{x(null);try{if(!u||!E)return void N("❌ Wallet account or transaction data is missing");if(!a)return void N("❌ Network not selected");const t=r.getSelectedNetworkConfig();if(!t)return void N("❌ Network configuration not found");N("⏳ Verifying network...");const n=await g();if(!n)return void N("❌ Failed to switch to correct network. Please approve the network switch in MetaMask and try again.");if(!window.ethereum)return void N("❌ MetaMask not available");const i=await window.ethereum.request({method:"eth_chainId"}),c=parseInt(i,16);if(c!==t.chainId){const e=`Network mismatch. MetaMask is on chain ${c}, but ${a} requires chain ${t.chainId}. Please switch networks in MetaMask.`;return N(`❌ ${e}`),void x(new Error(e))}if(n.chain.id!==t.chainId){const e=`Wallet client chain mismatch. Wallet client is on chain ${n.chain.id}, but expected ${t.chainId}.`;return N(`❌ ${e}`),void x(new Error(e))}N("⏳ Sending transaction...");const l=await n.sendTransaction({...E,account:u});A(l),N("✅ Transaction sent!"),e&&e({txHash:l,network:a,token:o?.key,tokenSymbol:o?.symbol,amount:s?.amount,receivingAddress:s?.receivingAddress})}catch(e){x(e),N("❌ Transaction failed."),console.error("Transaction error:",e)}},disabled:null!==T},"Send Transaction"),S&&t.createElement("div",{className:"message-box"},S,D&&t.createElement("button",{onClick:()=>I(!P),className:d.detailsButton},P?"Hide Details":"Show Details")),P&&D&&t.createElement("div",{className:d.errorDetails},t.createElement("pre",null,D.message)),T&&t.createElement("div",{className:d.transactionLink},"✅ Transaction Hash:"," ",j()?t.createElement("a",{href:j(),target:"_blank",rel:"noopener noreferrer",className:d.explorerLink,style:{color:"#007bff",textDecoration:"underline",fontWeight:"bold",cursor:"pointer",wordBreak:"break-word"}},T.slice(0,6),"...",T.slice(-6)):t.createElement("span",{style:{wordBreak:"break-word"}},T)))},_=({onClose:e,buttonSize:n,onTransactionComplete:r})=>{const{resetSelections:a}=k();return t.createElement(u,{onClose:()=>{a(),e()},size:n},t.createElement(g,null),t.createElement(C,null),t.createElement(E,{onTransactionComplete:r}))},S=({onClose:e,buttonSize:n,networkSelector:r,onTransactionComplete:a})=>t.createElement(w,{networkSelector:r},t.createElement(y,null,t.createElement(_,{onClose:e,buttonSize:n,onTransactionComplete:a})));return{NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(a).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:i,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!a[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:n="medium",onTransactionComplete:r,onSuccess:a})=>{const[i,o]=t.useState(!1),s=r||a;return t.createElement("div",{className:d.widgetContainer},!i&&t.createElement(l,{onClick:()=>{o(!0)},size:n}),i&&t.createElement(S,{onClose:()=>{o(!1)},buttonSize:n,networkSelector:e,onTransactionComplete:s}))},PayButton:l,Dialog:u,NetworkDropdown:g}})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("djed-sdk"),require("react"),require("viem"),require("viem/chains")):"function"==typeof define&&define.amd?define(["djed-sdk","react","viem","viem/chains"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).StablePay=t(e.DjedSdk,e.React,e.viem,e.viemChains)}(this,(function(e,t,n,r){"use strict";const a={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class i{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e.getWeb3(this.networkUri),this.djedContract=e.getDjedContract(this.web3,this.djedAddress);try{const{stableCoin:t,reserveCoin:n}=await e.getCoinContracts(this.djedContract,this.web3),{scDecimals:r,rcDecimals:a}=await e.getDecimals(t,n);this.stableCoin=t,this.reserveCoin=n,this.scDecimals=r,this.rcDecimals=a,this.oracleContract=await e.getOracleAddress(this.djedContract).then((t=>e.getOracleContract(this.web3,t,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){if(console.error("[Transaction] Error fetching contract details:",e),e.message&&e.message.includes("execution reverted")){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){if(console.error("[Transaction] Error initializing transaction:",e),e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(t){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof t)throw new Error("Amount must be a string");try{return(await e.tradeDataPriceBuySc(this.djedContract,this.scDecimals,t)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(t,n,r){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const a="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await e.buyScTx(this.djedContract,t,n,r,a,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var o="main_stablePayButton__UA7HC",s="main_logo__ITyEy",c="main_buttonText__N-ewy";const l=({onClick:e,size:n="medium"})=>{const r={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},a={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},i=r[n]||r.medium,l=a[n]||a.medium;return t.createElement("button",{className:o,onClick:e,style:i},t.createElement("div",{className:s,style:l}),t.createElement("span",{className:c},"Pay with StablePay"))};var d={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",infoSection:"PricingCard_infoSection__gyjMQ",infoIcon:"PricingCard_infoIcon__rraxD",infoText:"PricingCard_infoText__l4b7A",walletButton:"PricingCard_walletButton__llw4v",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",networkError:"PricingCard_networkError__zR-36",errorText:"PricingCard_errorText__qZRJt","message-box":"PricingCard_message-box__vkUKy",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",loadingContainer:"PricingCard_loadingContainer__6nOVa",spinner:"PricingCard_spinner__9ucQv",spin:"PricingCard_spin__24tni"};const u=({children:e,onClose:n,size:r="medium"})=>t.createElement("div",{className:d.dialogOverlay},t.createElement("div",{className:`${d.pricingCard} ${d[r]}`},t.createElement("button",{className:d.dialogClose,onClick:n},"×"),t.createElement("div",{className:d.pricingCardHeader},t.createElement("div",{className:d.allianceLogo}),t.createElement("h2",{className:d.stablepayTitle},"StablePay")),t.createElement("div",{className:d.pricingCardBody},e)));class m{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const h=t.createContext(),w=({children:e,networkSelector:n})=>{const[r]=t.useState((()=>new m(n))),[a,i]=t.useState(null),[o,s]=t.useState(null),[c,l]=t.useState(null),d=()=>{s(null),l(null)};return t.useEffect((()=>{i(n.selectedNetwork)}),[n.selectedNetwork]),t.createElement(h.Provider,{value:{networkSelector:n,tokenSelector:r,selectedNetwork:a,selectedToken:o,transactionDetails:c,setTransactionDetails:l,selectNetwork:e=>!!n.selectNetwork(e)&&(i(e),d(),!0),selectToken:e=>{if(r.selectToken(e)){const e=r.getSelectedToken();return s(e),!0}return!1},resetSelections:()=>{n.selectNetwork(null),i(null),d()}}},e)},k=()=>{const e=t.useContext(h);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},g=()=>{const{networkSelector:e,selectedNetwork:n,selectNetwork:r}=k();return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"network-select"},"Select Network"),t.createElement("select",{id:"network-select",onChange:e=>{r(e.target.value)},value:n||""},t.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>t.createElement("option",{key:e,value:e},e)))))},C=()=>{const{networkSelector:e,tokenSelector:n,selectedNetwork:r,selectedToken:a,selectToken:o,setTransactionDetails:s}=k(),[c,l]=t.useState(!1),[u,m]=t.useState(null),h=r?n.getAvailableTokens():[];return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"token-select"},"Select Token"),t.createElement("select",{id:"token-select",onChange:async t=>{const a=t.target.value;m(null),l(!0);try{if(o(a)){const t=e.getSelectedNetworkConfig(),o=new i(t.uri,t.djedAddress);await o.init();const c=e.getTokenAmount(a),l=o.getBlockchainDetails();let d=null;"native"===a&&(d=await o.handleTradeDataBuySc(String(c))),s({network:r,token:a,tokenSymbol:n.getSelectedToken().symbol,amount:c,receivingAddress:e.getReceivingAddress(),djedContractAddress:t.djedAddress,isDirectTransfer:n.getSelectedToken().isDirectTransfer||!1,isNativeToken:n.getSelectedToken().isNative||!1,tradeAmount:d?d.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),m("Failed to fetch transaction details. Please try again.")}finally{l(!1)}},value:a?a.key:"",disabled:!r||c},t.createElement("option",{value:"",disabled:!0},r?c?"Loading...":"Select a token":"Please select a network first"),h.map((e=>t.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),u&&t.createElement("div",{className:d.error},u))};n.defineChain({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const b=n.defineChain({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),p=n.defineChain({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),f=t.createContext(null),v=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${r.sepolia.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:r.sepolia.rpcUrls.default.http,blockExplorerUrls:r.sepolia.blockExplorers?.default?.url?[r.sepolia.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${p.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${b.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},y=({children:e})=>{const{selectedNetwork:a}=k(),[i,o]=t.useState(null),[s,c]=t.useState(null),[l,d]=t.useState(null),[u,m]=t.useState(null),[h,w]=t.useState(null),[g,C]=t.useState(null),[y,E]=t.useState(!1),_=a?(e=>{switch(e){case"sepolia":return r.sepolia;case"ethereum-classic":return p;case"milkomeda-mainnet":return b;default:return null}})(a):null,S=_?_.id:null,N=t.useRef(null),T=t.useRef(null),A=t.useCallback((()=>{o(null),c(null),d(null),m(null),w(null),C(null)}),[]),D=t.useCallback((async e=>{const t=parseInt(e,16);if(m(t),_&&t===S){if(C(null),window.ethereum&&_){const e=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});o(e)}}else if(_&&t!==S){C(`Wrong network detected. Please switch to ${_?.name||a||"selected network"}`)}}),[_,S,a]);T.current=D;const x=t.useCallback((async e=>{if(0===e.length){if(A(),window.ethereum){const e=N.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(d(e[0]),_)try{const t=n.createPublicClient({chain:_,transport:n.http()});c(t);const r=await t.getBalance({address:e[0]});w(parseFloat(r)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}}),[_,A]);N.current=x;const P=t.useCallback((()=>{if(A(),window.ethereum){const e=N.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[A]),I=t.useCallback((()=>{_&&c(n.createPublicClient({chain:_,transport:n.http()}))}),[_]),j=t.useCallback((async()=>{if(!window.ethereum)return C("Please install MetaMask or another Web3 wallet"),!1;if(!a||!_)return C("Please select a network first"),!1;E(!0),C(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const t=await window.ethereum.request({method:"eth_chainId"});parseInt(t,16)!==S&&await v(a);const r=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});o(r),d(e[0]),m(S);const i=n.createPublicClient({chain:_,transport:n.http()});c(i);try{const t=await i.getBalance({address:e[0]});w(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}return N.current=x,T.current=D,window.ethereum.on("accountsChanged",x),window.ethereum.on("chainChanged",D),!0}catch(e){return console.error("Error connecting wallet:",e),C(e.message),!1}finally{E(!1)}}),[a,_,S,x,D]),B=t.useCallback((async()=>{if(!(window.ethereum&&a&&_&&l)){return C("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==S){C(null),await v(a);const e=500;await new Promise((t=>setTimeout(t,e)));const t=await window.ethereum.request({method:"eth_chainId"}),n=parseInt(t,16);if(n!==S)throw new Error(`Failed to switch network. MetaMask is still on chain ${n}, expected ${S}`)}const t=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});return o(t),m(S),C(null),t}catch(e){return C(e.message),null}}),[a,_,S,l]),M=t.useRef(a);return t.useEffect((()=>{if(null!==M.current&&M.current!==a&&l&&(A(),window.ethereum)){const e=N.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}M.current=a}),[a,l,A]),t.useEffect((()=>{I()}),[I]),t.createElement(f.Provider,{value:{walletClient:i,publicClient:s,account:l,chainId:u,balance:h,error:g,isConnecting:y,connectWallet:j,disconnectWallet:P,ensureCorrectNetwork:B,expectedChainId:S}},e)},E=({onTransactionComplete:e})=>{const{networkSelector:r,selectedNetwork:a,selectedToken:o,transactionDetails:s,setTransactionDetails:c}=k(),{connectWallet:l,account:u,walletClient:m,publicClient:h,isConnecting:w,ensureCorrectNetwork:g,expectedChainId:C}=(()=>{const e=t.useContext(f);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[b,p]=t.useState(null),[v,y]=t.useState(null),[E,_]=t.useState(null),[S,N]=t.useState(""),[T,A]=t.useState(null),[D,x]=t.useState(null),[P,I]=t.useState(!1);if(t.useEffect((()=>{_(null),y(null),N(""),x(null),A(null)}),[a,o]),t.useEffect((()=>{(async()=>{if(a&&o)try{const e=r.getSelectedNetworkConfig(),t=r.getReceivingAddress(),n=r.getTokenAmount(o.key),s=new i(e.uri,e.djedAddress);await s.init(),p(s);let l=null;if("native"===o.key)try{l=await s.handleTradeDataBuySc(String(n)),y(l)}catch(e){console.error("Error fetching trade data:",e)}c({network:a,token:o.key,tokenSymbol:o.symbol,amount:n||"0",receivingAddress:t,djedContractAddress:e.djedAddress,isDirectTransfer:o.isDirectTransfer||!1,isNativeToken:o.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[a,o,r,c]),!s)return t.createElement("div",{className:d.loading},"Initializing transaction...");const j=()=>{if(!T||!a)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[a]?`${e[a]}${T}`:null};return t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"Network:"),t.createElement("span",{className:d.transactionValue},s.network)),t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"You Pay:"),t.createElement("span",{className:d.transactionValue},"stablecoin"===o.key?`${s.amount} ${s.tokenSymbol}`:`${v||"Calculating..."} ${s.tokenSymbol}`)),t.createElement("button",{className:d.walletButton,onClick:async()=>{await l()},disabled:w},w?"Connecting...":"Connect Wallet"),u&&!E&&t.createElement("button",{className:d.walletButton,onClick:async()=>{if(u&&s&&b)try{_(null),x(null),N("⏳ Preparing transaction...");const e=s.receivingAddress;let t;if("native"===o.key){const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",a=v||"0",i=n.parseEther(String(a));t=await b.buyStablecoins(u,e,i,r),t={...t,value:i,account:u}}else{const a=r.getSelectedNetworkConfig(),i=a?.tokens?.stablecoin?.address;if(!i)throw new Error("Stablecoin address not found in network configuration");const o=s.amount?n.parseUnits(String(s.amount),s.stableCoinDecimals):"0";t={to:i,value:0n,data:n.encodeFunctionData({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,o]}),account:u}}_(t),N("✅ Transaction ready! Click 'Send Transaction' to proceed.")}catch(e){x(e),N("❌ Transaction preparation failed.")}else N("❌ Wallet not connected or transaction details missing")}},"Prepare Transaction"),u&&E&&t.createElement("button",{className:d.walletButton,onClick:async()=>{x(null);try{if(!u||!E)return void N("❌ Wallet account or transaction data is missing");if(!a)return void N("❌ Network not selected");const t=r.getSelectedNetworkConfig();if(!t)return void N("❌ Network configuration not found");N("⏳ Verifying network...");const n=await g();if(!n)return void N("❌ Failed to switch to correct network. Please approve the network switch in MetaMask and try again.");if(!window.ethereum)return void N("❌ MetaMask not available");const i=await window.ethereum.request({method:"eth_chainId"}),c=parseInt(i,16);if(c!==t.chainId){const e=`Network mismatch. MetaMask is on chain ${c}, but ${a} requires chain ${t.chainId}. Please switch networks in MetaMask.`;return N(`❌ ${e}`),void x(new Error(e))}if(n.chain.id!==t.chainId){const e=`Wallet client chain mismatch. Wallet client is on chain ${n.chain.id}, but expected ${t.chainId}.`;return N(`❌ ${e}`),void x(new Error(e))}N("⏳ Sending transaction...");const l=await n.sendTransaction({...E,account:u});A(l),N("✅ Transaction sent!"),e&&e({txHash:l,network:a,token:o?.key,tokenSymbol:o?.symbol,amount:s?.amount,receivingAddress:s?.receivingAddress})}catch(e){x(e),N("❌ Transaction failed."),console.error("Transaction error:",e)}},disabled:null!==T},"Send Transaction"),S&&t.createElement("div",{className:"message-box"},S,D&&t.createElement("button",{onClick:()=>I(!P),className:d.detailsButton},P?"Hide Details":"Show Details")),P&&D&&t.createElement("div",{className:d.errorDetails},t.createElement("pre",null,D.message)),T&&t.createElement("div",{className:d.transactionLink},"✅ Transaction Hash:"," ",j()?t.createElement("a",{href:j(),target:"_blank",rel:"noopener noreferrer",className:d.explorerLink,style:{color:"#007bff",textDecoration:"underline",fontWeight:"bold",cursor:"pointer",wordBreak:"break-word"}},T.slice(0,6),"...",T.slice(-6)):t.createElement("span",{style:{wordBreak:"break-word"}},T)))},_=({onClose:e,buttonSize:n,onTransactionComplete:r})=>{const{resetSelections:a}=k();return t.createElement(u,{onClose:()=>{a(),e()},size:n},t.createElement(g,null),t.createElement(C,null),t.createElement(E,{onTransactionComplete:r}))},S=({onClose:e,buttonSize:n,networkSelector:r,onTransactionComplete:a})=>t.createElement(w,{networkSelector:r},t.createElement(y,null,t.createElement(_,{onClose:e,buttonSize:n,onTransactionComplete:a})));return{NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(a).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:i,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!a[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:n="medium",onTransactionComplete:r,onSuccess:a})=>{const[i,o]=t.useState(!1),s=r||a;return t.createElement("div",{className:d.widgetContainer},!i&&t.createElement(l,{onClick:()=>{o(!0)},size:n}),i&&t.createElement(S,{onClose:()=>{o(!1)},buttonSize:n,networkSelector:e,onTransactionComplete:s}))},PayButton:l,Dialog:u,NetworkDropdown:g}})); //# sourceMappingURL=index.js.map diff --git a/stablepay-sdk/dist/umd/index.js.map b/stablepay-sdk/dist/umd/index.js.map index f7c2fad..60f278c 100644 --- a/stablepay-sdk/dist/umd/index.js.map +++ b/stablepay-sdk/dist/umd/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../../src/utils/config.js","../../src/core/Transaction.js","../../src/widget/PayButton.jsx","../../src/widget/Dialog.jsx","../../src/core/TokenSelector.js","../../src/contexts/NetworkContext.jsx","../../src/widget/NetworkDropdown.jsx","../../src/widget/TokenDropdown.jsx","../../src/contexts/chains.js","../../src/contexts/WalletContext.jsx","../../src/widget/TransactionReview.jsx","../../src/widget/Widget.jsx","../../src/index.js","../../src/core/NetworkSelector.js","../../src/core/MerchantConfig.js"],"sourcesContent":["// src/utils/config.js\nexport const networksConfig = {\n 'sepolia': {\n uri: 'https://ethereum-sepolia.publicnode.com/',\n chainId: 11155111,\n djedAddress: '0x624FcD0a1F9B5820c950FefD48087531d38387f4',\n tokens: {\n stablecoin: {\n symbol: 'SOD',\n address: '0x6b930182787F346F18666D167e8d32166dC5eFBD',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETH',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'milkomeda-mainnet': {\n uri: 'https://rpc-mainnet-cardano-evm.c1.milkomeda.com',\n chainId: 2001,\n djedAddress: '0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76',\n tokens: {\n stablecoin: {\n symbol: 'MOD',\n address: '0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'mADA',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'ethereum-classic': {\n uri: 'https://etc.rivet.link',\n chainId: 61,\n djedAddress: '0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf',\n tokens: {\n stablecoin: {\n symbol: 'ECSD',\n address: '0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETC',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n }\n};","import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx } from 'djed-sdk';\n\nexport class Transaction {\n constructor(networkUri, djedAddress) {\n this.networkUri = networkUri;\n this.djedAddress = djedAddress;\n }\n\n async init() {\n if (!this.networkUri || !this.djedAddress) {\n throw new Error('Network URI and DJED address are required');\n }\n\n try {\n this.web3 = await getWeb3(this.networkUri);\n this.djedContract = getDjedContract(this.web3, this.djedAddress);\n \n try {\n const { stableCoin, reserveCoin } = await getCoinContracts(this.djedContract, this.web3);\n const { scDecimals, rcDecimals } = await getDecimals(stableCoin, reserveCoin);\n this.stableCoin = stableCoin;\n this.reserveCoin = reserveCoin;\n this.scDecimals = scDecimals;\n this.rcDecimals = rcDecimals;\n\n this.oracleContract = await getOracleAddress(this.djedContract).then((addr) =>\n getOracleContract(this.web3, addr, this.djedContract._address)\n );\n\n this.oracleAddress = this.oracleContract._address;\n } catch (contractError) {\n console.error('[Transaction] Error fetching contract details:', contractError);\n if (contractError.message && contractError.message.includes('execution reverted')) {\n const getNetworkInfo = (uri) => {\n if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };\n if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' };\n if (uri.includes('sepolia')) return { name: 'Sepolia', chainId: '11155111' };\n if (uri.includes('etc.rivet.link')) return { name: 'Ethereum Classic', chainId: '61' };\n return { name: 'the selected network', chainId: 'unknown' };\n };\n const { name: networkName, chainId } = getNetworkInfo(this.networkUri);\n throw new Error(\n `Failed to interact with Djed contract at ${this.djedAddress} on ${networkName}.\\n\\n` +\n `Possible causes:\\n` +\n `- The contract address may be incorrect\\n` +\n `- The contract may not be deployed on ${networkName}\\n` +\n `- The contract may not be a valid Djed contract\\n\\n` +\n `Please verify the contract address is correct for ${networkName} (Chain ID: ${chainId}).`\n );\n }\n throw contractError;\n }\n } catch (error) {\n console.error('[Transaction] Error initializing transaction:', error);\n if (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED'))) {\n const getNetworkName = (uri) => {\n if (uri.includes('milkomeda')) return 'Milkomeda';\n if (uri.includes('mordor')) return 'Mordor';\n if (uri.includes('sepolia')) return 'Sepolia';\n return 'the selected network';\n };\n const networkName = getNetworkName(this.networkUri);\n throw new Error(\n `Failed to connect to ${networkName} RPC endpoint: ${this.networkUri}\\n\\n` +\n `Possible causes:\\n` +\n `- The RPC endpoint may be temporarily unavailable\\n` +\n `- DNS resolution issue (check your internet connection)\\n` +\n `- Network firewall blocking the connection\\n\\n` +\n `Please try again in a few moments or check the network status.`\n );\n }\n throw error;\n }\n }\n\n getBlockchainDetails() {\n return {\n web3Available: !!this.web3,\n djedContractAvailable: !!this.djedContract,\n stableCoinAddress: this.stableCoin ? this.stableCoin._address : 'N/A',\n reserveCoinAddress: this.reserveCoin ? this.reserveCoin._address : 'N/A',\n stableCoinDecimals: this.scDecimals,\n reserveCoinDecimals: this.rcDecimals,\n oracleAddress: this.oracleAddress || 'N/A',\n oracleContractAvailable: !!this.oracleContract,\n };\n }\n\n async handleTradeDataBuySc(amountScaled) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n if (typeof amountScaled !== 'string') {\n throw new Error(\"Amount must be a string\");\n }\n try {\n const result = await tradeDataPriceBuySc(this.djedContract, this.scDecimals, amountScaled);\n return result.totalBCScaled;\n } catch (error) {\n console.error(\"Error fetching trade data for buying stablecoins: \", error);\n throw error;\n }\n }\n\n async buyStablecoins(payer, receiver, value) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n try {\n const UI = '0x0232556C83791b8291E9b23BfEa7d67405Bd9839';\n\n const txData = await buyScTx(this.djedContract, payer, receiver, value, UI, this.djedAddress);\n\n return txData;\n } catch (error) {\n console.error(\"Error executing buyStablecoins transaction: \", error);\n throw error;\n }\n }\n}\n","import React from \"react\";\nimport styles from \"../styles/main.css\";\n\nconst PayButton = ({ onClick, size = \"medium\" }) => {\n const sizeStyles = {\n small: { width: \"200px\", height: \"50px\", fontSize: \"14px\" },\n medium: { width: \"250px\", height: \"60px\", fontSize: \"16px\" },\n large: { width: \"300px\", height: \"70px\", fontSize: \"18px\" },\n };\n\n const logoSizes = {\n small: { width: \"35px\", height: \"33px\" },\n medium: { width: \"40px\", height: \"38px\" },\n large: { width: \"45px\", height: \"43px\" },\n };\n\n const buttonStyle = sizeStyles[size] || sizeStyles.medium;\n const logoStyle = logoSizes[size] || logoSizes.medium;\n\n return (\n \n
\n Pay with StablePay\n \n );\n};\n\nexport default PayButton;\n","import React from 'react';\nimport styles from '../styles/PricingCard.css';\n\n\nconst Dialog = ({ children, onClose, size = 'medium' }) => {\n return (\n
\n
\n \n
\n
\n\n

StablePay

\n
\n
\n {children}\n
\n
\n
\n );\n};\n\nexport default Dialog;","// TokenSelector.js\n\nexport class TokenSelector {\n constructor(networkSelector) {\n this.networkSelector = networkSelector;\n this.selectedToken = null;\n }\n\n selectToken(tokenKey) {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (networkConfig && networkConfig.tokens[tokenKey]) {\n this.selectedToken = {\n key: tokenKey,\n ...networkConfig.tokens[tokenKey]\n };\n return true;\n }\n return false;\n }\n\n getSelectedToken() {\n return this.selectedToken;\n }\n\n getAvailableTokens() {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) return [];\n\n return Object.entries(networkConfig.tokens).map(([key, config]) => ({\n key,\n ...config\n }));\n }\n\n resetSelection() {\n this.selectedToken = null;\n }\n}","import React, { createContext, useState, useContext, useEffect } from 'react';\nimport { TokenSelector } from '../core/TokenSelector';\n\nconst NetworkContext = createContext();\n\nexport const NetworkProvider = ({ children, networkSelector }) => {\n const [tokenSelector] = useState(() => new TokenSelector(networkSelector));\n const [selectedNetwork, setSelectedNetwork] = useState(null);\n const [selectedToken, setSelectedToken] = useState(null);\n const [transactionDetails, setTransactionDetails] = useState(null);\n\n const resetState = () => {\n setSelectedToken(null);\n setTransactionDetails(null);\n };\n\n const selectNetwork = (networkKey) => {\n if (networkSelector.selectNetwork(networkKey)) {\n setSelectedNetwork(networkKey);\n resetState(); \n return true;\n }\n return false;\n };\n\n const selectToken = (tokenKey) => {\n if (tokenSelector.selectToken(tokenKey)) {\n const token = tokenSelector.getSelectedToken();\n setSelectedToken(token);\n return true;\n }\n return false;\n };\n\n const resetSelections = () => {\n networkSelector.selectNetwork(null);\n setSelectedNetwork(null);\n resetState();\n };\n\n // Synchronize context state with NetworkSelector\n useEffect(() => {\n setSelectedNetwork(networkSelector.selectedNetwork);\n }, [networkSelector.selectedNetwork]);\n\n return (\n \n {children}\n \n );\n};\n\nexport const useNetwork = () => {\n const context = useContext(NetworkContext);\n if (context === undefined) {\n throw new Error('useNetwork must be used within a NetworkProvider');\n }\n return context;\n};\n\nexport default NetworkContext;","import React from 'react';\nimport { useNetwork } from '../contexts/NetworkContext';\nimport styles from '../styles/PricingCard.css';\n\nconst NetworkDropdown = () => {\n const { networkSelector, selectedNetwork, selectNetwork } = useNetwork();\n\n const handleNetworkChange = (event) => {\n selectNetwork(event.target.value);\n };\n\n return (\n
\n \n \n
\n );\n};\n\nexport default NetworkDropdown;","import React, { useState } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst TokenDropdown = () => {\n const {\n networkSelector,\n tokenSelector,\n selectedNetwork,\n selectedToken,\n selectToken,\n setTransactionDetails,\n } = useNetwork();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n const handleTokenChange = async (event) => {\n const newValue = event.target.value;\n setError(null);\n setLoading(true);\n\n try {\n if (selectToken(newValue)) {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const transaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await transaction.init();\n\n const tokenAmount = networkSelector.getTokenAmount(newValue);\n const blockchainDetails = transaction.getBlockchainDetails();\n\n let tradeData = null;\n if (newValue === \"native\") {\n tradeData = await transaction.handleTradeDataBuySc(\n String(tokenAmount)\n );\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: newValue,\n tokenSymbol: tokenSelector.getSelectedToken().symbol,\n amount: tokenAmount,\n receivingAddress: networkSelector.getReceivingAddress(),\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer:\n tokenSelector.getSelectedToken().isDirectTransfer || false,\n isNativeToken: tokenSelector.getSelectedToken().isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...blockchainDetails,\n });\n }\n } catch (err) {\n console.error(\"Error fetching transaction details:\", err);\n setError(\"Failed to fetch transaction details. Please try again.\");\n } finally {\n setLoading(false);\n }\n };\n\n const availableTokens = selectedNetwork\n ? tokenSelector.getAvailableTokens()\n : [];\n\n return (\n
\n \n \n \n {availableTokens.map((token) => (\n \n ))}\n \n {error &&
{error}
}\n
\n );\n};\n\nexport default TokenDropdown;\n","import { defineChain } from 'viem';\nimport { sepolia } from 'viem/chains';\n\nexport const mordor = defineChain({\n id: 63,\n name: 'Mordor Testnet',\n network: 'mordor',\n nativeCurrency: {\n decimals: 18,\n name: 'Mordor Ether',\n symbol: 'METC',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc.mordor.etccooperative.org'],\n webSocket: ['wss://rpc.mordor.etccooperative.org/ws'],\n },\n },\n blockExplorers: {\n default: { name: 'BlockScout', url: 'https://blockscout.com/etc/mordor' },\n },\n testnet: true,\n});\n\nexport const milkomeda = defineChain({\n id: 2001,\n name: 'Milkomeda C1 Mainnet',\n network: 'milkomeda',\n nativeCurrency: {\n decimals: 18,\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n },\n },\n blockExplorers: {\n default: { name: 'Milkomeda Explorer', url: 'https://explorer-mainnet-cardano-evm.c1.milkomeda.com' },\n },\n testnet: false,\n});\n\nexport const etcMainnet = defineChain({\n id: 61,\n name: 'Ethereum Classic',\n network: 'etc',\n nativeCurrency: {\n decimals: 18,\n name: 'Ethereum Classic',\n symbol: 'ETC',\n },\n rpcUrls: {\n default: {\n http: ['https://etc.rivet.link'],\n },\n },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://blockscout.com/etc/mainnet' },\n },\n testnet: false,\n});\n\nexport const getChainByNetworkKey = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return sepolia;\n case 'ethereum-classic':\n return etcMainnet;\n case 'milkomeda-mainnet':\n return milkomeda;\n default:\n return null;\n }\n};\n\nexport const getChainConfigForWallet = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return {\n chainId: `0x${sepolia.id.toString(16)}`,\n chainName: 'Sepolia',\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n rpcUrls: sepolia.rpcUrls.default.http,\n blockExplorerUrls: sepolia.blockExplorers?.default?.url ? [sepolia.blockExplorers.default.url] : [],\n };\n case 'ethereum-classic':\n return {\n chainId: `0x${etcMainnet.id.toString(16)}`,\n chainName: 'Ethereum Classic',\n nativeCurrency: {\n name: 'Ethereum Classic',\n symbol: 'ETC',\n decimals: 18,\n },\n rpcUrls: ['https://etc.rivet.link'],\n blockExplorerUrls: ['https://blockscout.com/etc/mainnet'],\n };\n case 'milkomeda-mainnet':\n return {\n chainId: `0x${milkomeda.id.toString(16)}`,\n chainName: 'Milkomeda C1 Mainnet',\n nativeCurrency: {\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n decimals: 18,\n },\n rpcUrls: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n blockExplorerUrls: ['https://explorer-mainnet-cardano-evm.c1.milkomeda.com'],\n };\n default:\n return null;\n }\n};\n","import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { createWalletClient, createPublicClient, custom, http } from 'viem';\nimport { useNetwork } from './NetworkContext';\nimport { getChainByNetworkKey, getChainConfigForWallet } from './chains';\n\nconst WalletContext = createContext(null);\n\nexport const useWallet = () => {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used within a WalletProvider');\n }\n return context;\n};\n\nconst switchToNetwork = async (networkKey) => {\n if (!window.ethereum) {\n throw new Error('MetaMask not installed');\n }\n\n const chainConfig = getChainConfigForWallet(networkKey);\n if (!chainConfig) {\n throw new Error(`Unsupported network: ${networkKey}`);\n }\n\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: chainConfig.chainId }],\n });\n } catch (switchError) {\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [chainConfig],\n });\n } catch (addError) {\n if (addError.code === 4001) {\n throw new Error(`User rejected adding ${chainConfig.chainName} to MetaMask. Please add it manually.`);\n }\n throw new Error(`Failed to add ${chainConfig.chainName} to MetaMask: ${addError.message}`);\n }\n } else if (switchError.code === 4001) {\n throw new Error(`User rejected switching to ${chainConfig.chainName}. Please switch manually in MetaMask.`);\n } else {\n throw new Error(`Failed to switch to ${chainConfig.chainName}: ${switchError.message}`);\n }\n }\n};\n\nexport const WalletProvider = ({ children }) => {\n const { selectedNetwork } = useNetwork();\n const [walletClient, setWalletClient] = useState(null);\n const [publicClient, setPublicClient] = useState(null);\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [balance, setBalance] = useState(null);\n const [error, setError] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n\n const selectedChain = selectedNetwork ? getChainByNetworkKey(selectedNetwork) : null;\n const expectedChainId = selectedChain ? selectedChain.id : null;\n\n const handleAccountsChangedRef = useRef(null);\n const handleChainChangedRef = useRef(null);\n\n const disconnectWalletInternal = useCallback(() => {\n setWalletClient(null);\n setPublicClient(null);\n setAccount(null);\n setChainId(null);\n setBalance(null);\n setError(null);\n }, []);\n\n const handleChainChanged = useCallback(async (chainIdHex) => {\n const newChainId = parseInt(chainIdHex, 16);\n setChainId(newChainId);\n\n if (selectedChain && newChainId === expectedChainId) {\n setError(null);\n if (window.ethereum && selectedChain) {\n const newWalletClient = createWalletClient({ \n chain: selectedChain, \n transport: custom(window.ethereum) \n });\n setWalletClient(newWalletClient);\n }\n } else if (selectedChain && newChainId !== expectedChainId) {\n const chainName = selectedChain?.name || selectedNetwork || 'selected network';\n setError(`Wrong network detected. Please switch to ${chainName}`);\n }\n }, [selectedChain, expectedChainId, selectedNetwork]);\n\n handleChainChangedRef.current = handleChainChanged;\n\n const handleAccountsChanged = useCallback(async (accounts) => {\n if (accounts.length === 0) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n } else {\n setAccount(accounts[0]);\n if (selectedChain) {\n try {\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n }\n }\n }, [selectedChain, disconnectWalletInternal]);\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n\n const disconnectWallet = useCallback(() => {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }, [disconnectWalletInternal]);\n\n const connectPublicClient = useCallback(() => {\n if (selectedChain) {\n setPublicClient(createPublicClient({ chain: selectedChain, transport: http() }));\n }\n }, [selectedChain]);\n\n const connectWallet = useCallback(async () => {\n if (!window.ethereum) {\n setError('Please install MetaMask or another Web3 wallet');\n return false;\n }\n\n if (!selectedNetwork || !selectedChain) {\n setError('Please select a network first');\n return false;\n }\n\n setIsConnecting(true);\n setError(null);\n\n try {\n const accounts = await window.ethereum.request({ \n method: 'eth_requestAccounts' \n });\n\n if (accounts.length === 0) {\n throw new Error('No wallet address found. Please unlock your wallet.');\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n await switchToNetwork(selectedNetwork);\n }\n\n const newWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(newWalletClient);\n setAccount(accounts[0]);\n setChainId(expectedChainId);\n\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n try {\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n handleChainChangedRef.current = handleChainChanged;\n window.ethereum.on('accountsChanged', handleAccountsChanged);\n window.ethereum.on('chainChanged', handleChainChanged);\n\n return true;\n } catch (err) {\n console.error('Error connecting wallet:', err);\n setError(err.message);\n return false;\n } finally {\n setIsConnecting(false);\n }\n }, [selectedNetwork, selectedChain, expectedChainId, handleAccountsChanged, handleChainChanged]);\n\n const ensureCorrectNetwork = useCallback(async () => {\n if (!window.ethereum || !selectedNetwork || !selectedChain || !account) {\n const errorMsg = 'Wallet not connected or network not selected';\n setError(errorMsg);\n return null;\n }\n\n try {\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n setError(null);\n await switchToNetwork(selectedNetwork);\n const NETWORK_SWITCH_DELAY_MS = 500;\n await new Promise(resolve => setTimeout(resolve, NETWORK_SWITCH_DELAY_MS));\n \n const newChainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const newChainId = parseInt(newChainIdHex, 16);\n if (newChainId !== expectedChainId) {\n throw new Error(`Failed to switch network. MetaMask is still on chain ${newChainId}, expected ${expectedChainId}`);\n }\n }\n\n const freshWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(freshWalletClient);\n setChainId(expectedChainId);\n setError(null);\n return freshWalletClient;\n } catch (err) {\n setError(err.message);\n return null;\n }\n }, [selectedNetwork, selectedChain, expectedChainId, account]);\n\n const prevNetworkRef = useRef(selectedNetwork);\n\n useEffect(() => {\n if (prevNetworkRef.current !== null && \n prevNetworkRef.current !== selectedNetwork && \n account) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }\n prevNetworkRef.current = selectedNetwork;\n }, [selectedNetwork, account, disconnectWalletInternal]);\n\n useEffect(() => {\n connectPublicClient();\n }, [connectPublicClient]);\n\n return (\n \n {children}\n \n );\n};","import React, { useState, useEffect } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { useWallet } from \"../contexts/WalletContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport { parseEther, encodeFunctionData, parseUnits } from \"viem\"; \nimport styles from \"../styles/PricingCard.css\"; \n\nconst TransactionReview = ({ onTransactionComplete }) => {\n const {\n networkSelector,\n selectedNetwork,\n selectedToken,\n transactionDetails: contextTransactionDetails,\n setTransactionDetails,\n } = useNetwork();\n\n const {\n connectWallet,\n account,\n walletClient,\n publicClient,\n isConnecting,\n ensureCorrectNetwork,\n expectedChainId,\n } = useWallet();\n\n const [transaction, setTransaction] = useState(null);\n const [tradeDataBuySc, setTradeDataBuySc] = useState(null);\n const [txData, setTxData] = useState(null);\n const [message, setMessage] = useState(\"\");\n const [txHash, setTxHash] = useState(null);\n const [error, setError] = useState(null);\n const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false);\n\n useEffect(() => {\n setTxData(null);\n setTradeDataBuySc(null);\n setMessage(\"\");\n setError(null);\n setTxHash(null);\n }, [selectedNetwork, selectedToken]);\n\n useEffect(() => {\n const initializeTransaction = async () => {\n if (!selectedNetwork || !selectedToken) return;\n\n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const receivingAddress = networkSelector.getReceivingAddress();\n const tokenAmount = networkSelector.getTokenAmount(selectedToken.key);\n\n const newTransaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await newTransaction.init();\n setTransaction(newTransaction);\n\n let tradeData = null;\n if (selectedToken.key === \"native\") {\n try {\n tradeData = await newTransaction.handleTradeDataBuySc(String(tokenAmount));\n setTradeDataBuySc(tradeData);\n } catch (tradeError) {\n console.error(\"Error fetching trade data:\", tradeError);\n }\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: selectedToken.key,\n tokenSymbol: selectedToken.symbol,\n amount: tokenAmount || \"0\",\n receivingAddress,\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer: selectedToken.isDirectTransfer || false,\n isNativeToken: selectedToken.isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...newTransaction.getBlockchainDetails(),\n });\n } catch (err) {\n console.error(\"Error initializing transaction:\", err);\n }\n };\n\n initializeTransaction();\n }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]);\n\n if (!contextTransactionDetails) {\n return
Initializing transaction...
;\n }\n\n const handleConnectWallet = async () => {\n await connectWallet();\n };\n\n const handleSendTransaction = async () => {\n if (!account || !contextTransactionDetails || !transaction) {\n setMessage(\"❌ Wallet not connected or transaction details missing\");\n return;\n }\n\n try {\n setTxData(null);\n setError(null);\n setMessage(\"⏳ Preparing transaction...\");\n\n const receiver = contextTransactionDetails.receivingAddress;\n let builtTx;\n\n if (selectedToken.key === \"native\") {\n const UI = \"0x0232556C83791b8291E9b23BfEa7d67405Bd9839\";\n const amountToSend = tradeDataBuySc || \"0\";\n const valueInWei = parseEther(String(amountToSend));\n\n builtTx = await transaction.buyStablecoins(\n account,\n receiver,\n valueInWei,\n UI\n );\n\n builtTx = {\n ...builtTx,\n value: valueInWei,\n account: account,\n };\n } else {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const stablecoinAddress = networkConfig?.tokens?.stablecoin?.address;\n \n if (!stablecoinAddress) {\n throw new Error('Stablecoin address not found in network configuration');\n }\n\n const amountToSend = contextTransactionDetails.amount\n ? parseUnits(\n String(contextTransactionDetails.amount),\n contextTransactionDetails.stableCoinDecimals\n )\n : \"0\";\n\n builtTx = {\n to: stablecoinAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: [\n {\n inputs: [\n { internalType: \"address\", name: \"to\", type: \"address\" },\n { internalType: \"uint256\", name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ],\n functionName: \"transfer\",\n args: [receiver, amountToSend],\n }),\n account: account,\n };\n }\n\n setTxData(builtTx);\n setMessage(\"✅ Transaction ready! Click 'Send Transaction' to proceed.\");\n } catch (error) {\n setError(error);\n setMessage(`❌ Transaction preparation failed.`);\n }\n };\n\n const handleBuySc = async () => {\n setError(null);\n \n try {\n if (!account || !txData) {\n setMessage(\"❌ Wallet account or transaction data is missing\");\n return;\n }\n\n if (!selectedNetwork) {\n setMessage(\"❌ Network not selected\");\n return;\n }\n\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) {\n setMessage(\"❌ Network configuration not found\");\n return;\n }\n\n setMessage(\"⏳ Verifying network...\");\n\n const freshWalletClient = await ensureCorrectNetwork();\n if (!freshWalletClient) {\n setMessage(\"❌ Failed to switch to correct network. Please approve the network switch in MetaMask and try again.\");\n return;\n }\n\n if (!window.ethereum) {\n setMessage(\"❌ MetaMask not available\");\n return;\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== networkConfig.chainId) {\n const errorMsg = `Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`;\n setMessage(`❌ ${errorMsg}`);\n setError(new Error(errorMsg));\n return;\n }\n\n if (freshWalletClient.chain.id !== networkConfig.chainId) {\n const errorMsg = `Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`;\n setMessage(`❌ ${errorMsg}`);\n setError(new Error(errorMsg));\n return;\n }\n\n setMessage(\"⏳ Sending transaction...\");\n\n const txHash = await freshWalletClient.sendTransaction({\n ...txData,\n account: account,\n });\n\n setTxHash(txHash);\n setMessage(`✅ Transaction sent!`);\n \n if (onTransactionComplete) {\n onTransactionComplete({\n txHash,\n network: selectedNetwork,\n token: selectedToken?.key,\n tokenSymbol: selectedToken?.symbol,\n amount: contextTransactionDetails?.amount,\n receivingAddress: contextTransactionDetails?.receivingAddress,\n });\n }\n } catch (error) {\n setError(error);\n setMessage(`❌ Transaction failed.`);\n console.error('Transaction error:', error);\n }\n };\n\n const getExplorerUrl = () => {\n if (!txHash || !selectedNetwork) return null;\n\n const explorerBaseUrls = {\n \"ethereum-classic\": \"https://blockscout.com/etc/mainnet/tx/\",\n \"sepolia\": \"https://sepolia.etherscan.io/tx/\",\n \"milkomeda-mainnet\": \"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/\",\n };\n\n return explorerBaseUrls[selectedNetwork]\n ? `${explorerBaseUrls[selectedNetwork]}${txHash}`\n : null;\n };\n\n return (\n
\n
\n Network:\n {contextTransactionDetails.network}\n
\n\n
\n You Pay:\n \n {selectedToken.key === \"stablecoin\"\n ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}`\n : `${tradeDataBuySc ? tradeDataBuySc : \"Calculating...\"} ${\n contextTransactionDetails.tokenSymbol\n }`}\n \n
\n\n \n\n {account && !txData && (\n \n )}\n {account && txData && (\n \n)}\n\n\n {message && (\n
\n {message}\n {error && (\n setIsErrorDetailsVisible(!isErrorDetailsVisible)}\n className={styles.detailsButton}\n >\n {isErrorDetailsVisible ? \"Hide Details\" : \"Show Details\"}\n \n )}\n
\n )}\n\n {isErrorDetailsVisible && error && (\n
\n
{error.message}
\n
\n )}\n\n \n {txHash && (\n
\n ✅ Transaction Hash:{\" \"}\n {getExplorerUrl() ? (\n \n {txHash.slice(0, 6)}...{txHash.slice(-6)}\n \n ) : (\n \n {txHash}\n \n )}\n
\n)}\n\n
\n );\n};\n\nexport default TransactionReview;\n","import React, { useState } from \"react\";\nimport PayButton from \"./PayButton\";\nimport Dialog from \"./Dialog\";\nimport NetworkDropdown from \"./NetworkDropdown\";\nimport TokenDropdown from \"./TokenDropdown\";\nimport TransactionReview from \"./TransactionReview\";\nimport { NetworkProvider, useNetwork } from \"../contexts/NetworkContext\";\nimport { WalletProvider } from \"../contexts/WalletContext\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst WidgetContent = ({ onClose, buttonSize, onTransactionComplete }) => {\n const { resetSelections } = useNetwork(); \n\n const handleClose = () => {\n resetSelections(); // Reset selections when closing the widget\n onClose();\n };\n\n return (\n \n \n \n \n \n );\n};\n\nconst WidgetWithProviders = ({ onClose, buttonSize, networkSelector, onTransactionComplete }) => {\n return (\n \n \n \n \n \n );\n};\n\nexport const Widget = ({ networkSelector, buttonSize = \"medium\", onTransactionComplete, onSuccess }) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const handleOpenDialog = () => {\n setIsDialogOpen(true);\n };\n\n const handleCloseDialog = () => {\n setIsDialogOpen(false);\n };\n\n // Support both onTransactionComplete and onSuccess for backwards compatibility\n const handleTransactionComplete = onTransactionComplete || onSuccess;\n\n return (\n
\n {!isDialogOpen && (\n \n )}\n {isDialogOpen && (\n \n )}\n
\n );\n};\n\nexport default Widget;\n","// src/index.js\nimport { NetworkSelector } from './core/NetworkSelector';\nimport { Transaction } from './core/Transaction';\nimport { Config } from './core/MerchantConfig';\nimport Widget from './widget/Widget.jsx';\nimport PayButton from './widget/PayButton.jsx';\nimport Dialog from './widget/Dialog.jsx';\nimport NetworkDropdown from './widget/NetworkDropdown.jsx';\nimport './styles/main.css';\nimport './styles/PricingCard.css';\n\nconst StablePay = {\n NetworkSelector,\n Transaction,\n Config,\n Widget,\n PayButton,\n Dialog,\n NetworkDropdown\n};\n\nexport default StablePay;","import { networksConfig } from \"../utils/config\";\n\nexport class NetworkSelector {\n constructor(merchantConfig) {\n this.merchantConfig = merchantConfig;\n this.blacklist = merchantConfig.getBlacklist();\n this.availableNetworks = this.getAvailableNetworks();\n this.selectedNetwork = null;\n }\n\n getAvailableNetworks() {\n return Object.entries(networksConfig).reduce(\n (acc, [networkKey, networkConfig]) => {\n if (!this.blacklist.includes(networkConfig.chainId)) {\n acc[networkKey] = networkConfig;\n }\n return acc;\n },\n {}\n );\n }\n\n selectNetwork(networkKey) {\n if (networkKey === null) {\n this.selectedNetwork = null;\n console.log(\"Network selection reset\");\n return true;\n }\n if (this.availableNetworks[networkKey]) {\n this.selectedNetwork = networkKey;\n console.log(`Network selected: ${networkKey}`);\n return true;\n }\n console.error(`Invalid network: ${networkKey}`);\n return false;\n }\n\n getSelectedNetworkConfig() {\n return this.selectedNetwork\n ? this.availableNetworks[this.selectedNetwork]\n : null;\n }\n\n getReceivingAddress() {\n return this.merchantConfig.getReceivingAddress();\n }\n\n getTokenAmount(token) {\n return this.merchantConfig.getTokenAmount(this.selectedNetwork, token);\n }\n}\n","import { networksConfig } from \"../utils/config\";\n\nexport class Config {\n constructor(options = {}) {\n this.receivingAddress = options.receivingAddress || \"\";\n this.blacklist = options.blacklist || [];\n this.amounts = options.Amounts || {}; // Note the capital 'A' in Amounts\n this.validateConfig();\n }\n\n validateConfig() {\n if (!this.receivingAddress) {\n throw new Error(\"Receiving address is required\");\n }\n // Validate stablecoin amounts\n for (const [network, tokens] of Object.entries(this.amounts)) {\n if (!networksConfig[network]) {\n throw new Error(`Invalid network: ${network}`);\n }\n if (\n !tokens.stablecoin ||\n typeof tokens.stablecoin !== \"number\" ||\n tokens.stablecoin <= 0\n ) {\n throw new Error(`Invalid stablecoin amount for network ${network}`);\n }\n }\n }\n\n getBlacklist() {\n return this.blacklist;\n }\n\n getReceivingAddress() {\n return this.receivingAddress;\n }\n\n // getTokenAmount(network, token) {\n // const networkConfig = networksConfig[network];\n // if (!networkConfig) return 0;\n\n // const stablecoinSymbol = networkConfig.tokens.stablecoin.symbol;\n\n // if (token === 'stablecoin') {\n // return this.amounts[network]?.stablecoin || 0;\n // }\n // // For native tokens, return 0 as it's not specified in the new structure\n // return 0;\n // }\n getTokenAmount(network) {\n console.log(\"Getting amount for network:\", network);\n console.log(\"Amounts object:\", this.amounts);\n\n // Directly return the stablecoin amount for the network\n const amount = this.amounts[network]?.stablecoin;\n console.log(\"Returning amount:\", amount);\n\n return amount || 0;\n }\n}\n\nexport default Config;\n"],"names":["networksConfig","sepolia","uri","chainId","djedAddress","tokens","stablecoin","symbol","address","decimals","isDirectTransfer","native","isNative","feeUI","Transaction","constructor","networkUri","this","init","Error","web3","getWeb3","djedContract","getDjedContract","stableCoin","reserveCoin","getCoinContracts","scDecimals","rcDecimals","getDecimals","oracleContract","getOracleAddress","then","addr","getOracleContract","_address","oracleAddress","contractError","console","error","message","includes","getNetworkInfo","name","networkName","getNetworkName","getBlockchainDetails","web3Available","djedContractAvailable","stableCoinAddress","reserveCoinAddress","stableCoinDecimals","reserveCoinDecimals","oracleContractAvailable","handleTradeDataBuySc","amountScaled","tradeDataPriceBuySc","totalBCScaled","buyStablecoins","payer","receiver","value","UI","buyScTx","PayButton","onClick","size","sizeStyles","small","width","height","fontSize","medium","large","logoSizes","buttonStyle","logoStyle","React","createElement","className","styles","style","Dialog","children","onClose","dialogOverlay","pricingCard","dialogClose","pricingCardHeader","allianceLogo","stablepayTitle","pricingCardBody","TokenSelector","networkSelector","selectedToken","selectToken","tokenKey","networkConfig","getSelectedNetworkConfig","key","getSelectedToken","getAvailableTokens","Object","entries","map","config","resetSelection","NetworkContext","createContext","NetworkProvider","tokenSelector","useState","selectedNetwork","setSelectedNetwork","setSelectedToken","transactionDetails","setTransactionDetails","resetState","useEffect","Provider","selectNetwork","networkKey","token","resetSelections","useNetwork","context","useContext","undefined","NetworkDropdown","selectField","htmlFor","id","onChange","event","target","disabled","keys","availableNetworks","TokenDropdown","loading","setLoading","setError","availableTokens","async","newValue","transaction","tokenAmount","getTokenAmount","blockchainDetails","tradeData","String","network","tokenSymbol","amount","receivingAddress","getReceivingAddress","djedContractAddress","isNativeToken","tradeAmount","err","defineChain","nativeCurrency","rpcUrls","default","http","webSocket","blockExplorers","url","testnet","milkomeda","etcMainnet","WalletContext","switchToNetwork","window","ethereum","chainConfig","toString","chainName","blockExplorerUrls","getChainConfigForWallet","request","method","params","switchError","code","addError","WalletProvider","walletClient","setWalletClient","publicClient","setPublicClient","account","setAccount","setChainId","balance","setBalance","isConnecting","setIsConnecting","selectedChain","getChainByNetworkKey","expectedChainId","handleAccountsChangedRef","useRef","handleChainChangedRef","disconnectWalletInternal","useCallback","handleChainChanged","newChainId","parseInt","chainIdHex","newWalletClient","createWalletClient","chain","transport","custom","current","handleAccountsChanged","accounts","length","accountsHandler","chainHandler","removeListener","newPublicClient","createPublicClient","getBalance","parseFloat","Math","pow","disconnectWallet","connectPublicClient","connectWallet","on","ensureCorrectNetwork","NETWORK_SWITCH_DELAY_MS","Promise","resolve","setTimeout","newChainIdHex","freshWalletClient","prevNetworkRef","TransactionReview","onTransactionComplete","contextTransactionDetails","useWallet","setTransaction","tradeDataBuySc","setTradeDataBuySc","txData","setTxData","setMessage","txHash","setTxHash","isErrorDetailsVisible","setIsErrorDetailsVisible","newTransaction","tradeError","initializeTransaction","getExplorerUrl","explorerBaseUrls","transactionReview","transactionInfo","transactionLabel","transactionValue","walletButton","builtTx","amountToSend","valueInWei","parseEther","stablecoinAddress","parseUnits","to","data","encodeFunctionData","abi","inputs","internalType","type","outputs","stateMutability","functionName","args","currentChainId","errorMsg","sendTransaction","detailsButton","errorDetails","transactionLink","href","rel","explorerLink","color","textDecoration","fontWeight","cursor","wordBreak","slice","WidgetContent","buttonSize","handleClose","WidgetWithProviders","NetworkSelector","merchantConfig","blacklist","getBlacklist","getAvailableNetworks","reduce","acc","log","Config","options","amounts","Amounts","validateConfig","Widget","onSuccess","isDialogOpen","setIsDialogOpen","handleTransactionComplete","widgetContainer","handleOpenDialog","handleCloseDialog"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../../src/utils/config.js","../../src/core/Transaction.js","../../src/widget/PayButton.jsx","../../src/widget/Dialog.jsx","../../src/core/TokenSelector.js","../../src/contexts/NetworkContext.jsx","../../src/widget/NetworkDropdown.jsx","../../src/widget/TokenDropdown.jsx","../../src/contexts/chains.js","../../src/contexts/WalletContext.jsx","../../src/widget/TransactionReview.jsx","../../src/widget/Widget.jsx","../../src/index.js","../../src/core/NetworkSelector.js","../../src/core/MerchantConfig.js"],"sourcesContent":["// src/utils/config.js\nexport const networksConfig = {\n 'sepolia': {\n uri: 'https://ethereum-sepolia.publicnode.com/',\n chainId: 11155111,\n djedAddress: '0x624FcD0a1F9B5820c950FefD48087531d38387f4',\n tokens: {\n stablecoin: {\n symbol: 'SOD',\n address: '0x6b930182787F346F18666D167e8d32166dC5eFBD',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETH',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'milkomeda-mainnet': {\n uri: 'https://rpc-mainnet-cardano-evm.c1.milkomeda.com',\n chainId: 2001,\n djedAddress: '0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76',\n tokens: {\n stablecoin: {\n symbol: 'MOD',\n address: '0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'mADA',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'ethereum-classic': {\n uri: 'https://etc.rivet.link',\n chainId: 61,\n djedAddress: '0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf',\n tokens: {\n stablecoin: {\n symbol: 'ECSD',\n address: '0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETC',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n }\n};","import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx } from 'djed-sdk';\n\nexport class Transaction {\n constructor(networkUri, djedAddress) {\n this.networkUri = networkUri;\n this.djedAddress = djedAddress;\n }\n\n async init() {\n if (!this.networkUri || !this.djedAddress) {\n throw new Error('Network URI and DJED address are required');\n }\n\n try {\n this.web3 = await getWeb3(this.networkUri);\n this.djedContract = getDjedContract(this.web3, this.djedAddress);\n \n try {\n const { stableCoin, reserveCoin } = await getCoinContracts(this.djedContract, this.web3);\n const { scDecimals, rcDecimals } = await getDecimals(stableCoin, reserveCoin);\n this.stableCoin = stableCoin;\n this.reserveCoin = reserveCoin;\n this.scDecimals = scDecimals;\n this.rcDecimals = rcDecimals;\n\n this.oracleContract = await getOracleAddress(this.djedContract).then((addr) =>\n getOracleContract(this.web3, addr, this.djedContract._address)\n );\n\n this.oracleAddress = this.oracleContract._address;\n } catch (contractError) {\n console.error('[Transaction] Error fetching contract details:', contractError);\n if (contractError.message && contractError.message.includes('execution reverted')) {\n const getNetworkInfo = (uri) => {\n if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };\n if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' };\n if (uri.includes('sepolia')) return { name: 'Sepolia', chainId: '11155111' };\n if (uri.includes('etc.rivet.link')) return { name: 'Ethereum Classic', chainId: '61' };\n return { name: 'the selected network', chainId: 'unknown' };\n };\n const { name: networkName, chainId } = getNetworkInfo(this.networkUri);\n throw new Error(\n `Failed to interact with Djed contract at ${this.djedAddress} on ${networkName}.\\n\\n` +\n `Possible causes:\\n` +\n `- The contract address may be incorrect\\n` +\n `- The contract may not be deployed on ${networkName}\\n` +\n `- The contract may not be a valid Djed contract\\n\\n` +\n `Please verify the contract address is correct for ${networkName} (Chain ID: ${chainId}).`\n );\n }\n throw contractError;\n }\n } catch (error) {\n console.error('[Transaction] Error initializing transaction:', error);\n if (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED'))) {\n const getNetworkName = (uri) => {\n if (uri.includes('milkomeda')) return 'Milkomeda';\n if (uri.includes('mordor')) return 'Mordor';\n if (uri.includes('sepolia')) return 'Sepolia';\n return 'the selected network';\n };\n const networkName = getNetworkName(this.networkUri);\n throw new Error(\n `Failed to connect to ${networkName} RPC endpoint: ${this.networkUri}\\n\\n` +\n `Possible causes:\\n` +\n `- The RPC endpoint may be temporarily unavailable\\n` +\n `- DNS resolution issue (check your internet connection)\\n` +\n `- Network firewall blocking the connection\\n\\n` +\n `Please try again in a few moments or check the network status.`\n );\n }\n throw error;\n }\n }\n\n getBlockchainDetails() {\n return {\n web3Available: !!this.web3,\n djedContractAvailable: !!this.djedContract,\n stableCoinAddress: this.stableCoin ? this.stableCoin._address : 'N/A',\n reserveCoinAddress: this.reserveCoin ? this.reserveCoin._address : 'N/A',\n stableCoinDecimals: this.scDecimals,\n reserveCoinDecimals: this.rcDecimals,\n oracleAddress: this.oracleAddress || 'N/A',\n oracleContractAvailable: !!this.oracleContract,\n };\n }\n\n async handleTradeDataBuySc(amountScaled) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n if (typeof amountScaled !== 'string') {\n throw new Error(\"Amount must be a string\");\n }\n try {\n const result = await tradeDataPriceBuySc(this.djedContract, this.scDecimals, amountScaled);\n return result.totalBCScaled;\n } catch (error) {\n console.error(\"Error fetching trade data for buying stablecoins: \", error);\n throw error;\n }\n }\n\n async buyStablecoins(payer, receiver, value) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n try {\n const UI = '0x0232556C83791b8291E9b23BfEa7d67405Bd9839';\n\n const txData = await buyScTx(this.djedContract, payer, receiver, value, UI, this.djedAddress);\n\n return txData;\n } catch (error) {\n console.error(\"Error executing buyStablecoins transaction: \", error);\n throw error;\n }\n }\n}\n","import React from \"react\";\nimport styles from \"../styles/main.css\";\n\nconst PayButton = ({ onClick, size = \"medium\" }) => {\n const sizeStyles = {\n small: { width: \"200px\", height: \"50px\", fontSize: \"14px\" },\n medium: { width: \"250px\", height: \"60px\", fontSize: \"16px\" },\n large: { width: \"300px\", height: \"70px\", fontSize: \"18px\" },\n };\n\n const logoSizes = {\n small: { width: \"35px\", height: \"33px\" },\n medium: { width: \"40px\", height: \"38px\" },\n large: { width: \"45px\", height: \"43px\" },\n };\n\n const buttonStyle = sizeStyles[size] || sizeStyles.medium;\n const logoStyle = logoSizes[size] || logoSizes.medium;\n\n return (\n \n
\n Pay with StablePay\n \n );\n};\n\nexport default PayButton;\n","import React from 'react';\nimport styles from '../styles/PricingCard.css';\n\n\nconst Dialog = ({ children, onClose, size = 'medium' }) => {\n return (\n
\n
\n \n
\n
\n\n

StablePay

\n
\n
\n {children}\n
\n
\n
\n );\n};\n\nexport default Dialog;","// TokenSelector.js\n\nexport class TokenSelector {\n constructor(networkSelector) {\n this.networkSelector = networkSelector;\n this.selectedToken = null;\n }\n\n selectToken(tokenKey) {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (networkConfig && networkConfig.tokens[tokenKey]) {\n this.selectedToken = {\n key: tokenKey,\n ...networkConfig.tokens[tokenKey]\n };\n return true;\n }\n return false;\n }\n\n getSelectedToken() {\n return this.selectedToken;\n }\n\n getAvailableTokens() {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) return [];\n\n return Object.entries(networkConfig.tokens).map(([key, config]) => ({\n key,\n ...config\n }));\n }\n\n resetSelection() {\n this.selectedToken = null;\n }\n}","import React, { createContext, useState, useContext, useEffect } from 'react';\nimport { TokenSelector } from '../core/TokenSelector';\n\nconst NetworkContext = createContext();\n\nexport const NetworkProvider = ({ children, networkSelector }) => {\n const [tokenSelector] = useState(() => new TokenSelector(networkSelector));\n const [selectedNetwork, setSelectedNetwork] = useState(null);\n const [selectedToken, setSelectedToken] = useState(null);\n const [transactionDetails, setTransactionDetails] = useState(null);\n\n const resetState = () => {\n setSelectedToken(null);\n setTransactionDetails(null);\n };\n\n const selectNetwork = (networkKey) => {\n if (networkSelector.selectNetwork(networkKey)) {\n setSelectedNetwork(networkKey);\n resetState(); \n return true;\n }\n return false;\n };\n\n const selectToken = (tokenKey) => {\n if (tokenSelector.selectToken(tokenKey)) {\n const token = tokenSelector.getSelectedToken();\n setSelectedToken(token);\n return true;\n }\n return false;\n };\n\n const resetSelections = () => {\n networkSelector.selectNetwork(null);\n setSelectedNetwork(null);\n resetState();\n };\n\n // Synchronize context state with NetworkSelector\n useEffect(() => {\n setSelectedNetwork(networkSelector.selectedNetwork);\n }, [networkSelector.selectedNetwork]);\n\n return (\n \n {children}\n \n );\n};\n\nexport const useNetwork = () => {\n const context = useContext(NetworkContext);\n if (context === undefined) {\n throw new Error('useNetwork must be used within a NetworkProvider');\n }\n return context;\n};\n\nexport default NetworkContext;","import React from 'react';\nimport { useNetwork } from '../contexts/NetworkContext';\nimport styles from '../styles/PricingCard.css';\n\nconst NetworkDropdown = () => {\n const { networkSelector, selectedNetwork, selectNetwork } = useNetwork();\n\n const handleNetworkChange = (event) => {\n selectNetwork(event.target.value);\n };\n\n return (\n
\n \n \n
\n );\n};\n\nexport default NetworkDropdown;","import React, { useState } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst TokenDropdown = () => {\n const {\n networkSelector,\n tokenSelector,\n selectedNetwork,\n selectedToken,\n selectToken,\n setTransactionDetails,\n } = useNetwork();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n const handleTokenChange = async (event) => {\n const newValue = event.target.value;\n setError(null);\n setLoading(true);\n\n try {\n if (selectToken(newValue)) {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const transaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await transaction.init();\n\n const tokenAmount = networkSelector.getTokenAmount(newValue);\n const blockchainDetails = transaction.getBlockchainDetails();\n\n let tradeData = null;\n if (newValue === \"native\") {\n tradeData = await transaction.handleTradeDataBuySc(\n String(tokenAmount)\n );\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: newValue,\n tokenSymbol: tokenSelector.getSelectedToken().symbol,\n amount: tokenAmount,\n receivingAddress: networkSelector.getReceivingAddress(),\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer:\n tokenSelector.getSelectedToken().isDirectTransfer || false,\n isNativeToken: tokenSelector.getSelectedToken().isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...blockchainDetails,\n });\n }\n } catch (err) {\n console.error(\"Error fetching transaction details:\", err);\n setError(\"Failed to fetch transaction details. Please try again.\");\n } finally {\n setLoading(false);\n }\n };\n\n const availableTokens = selectedNetwork\n ? tokenSelector.getAvailableTokens()\n : [];\n\n return (\n
\n \n \n \n {availableTokens.map((token) => (\n \n ))}\n \n {error &&
{error}
}\n
\n );\n};\n\nexport default TokenDropdown;\n","import { defineChain } from 'viem';\nimport { sepolia } from 'viem/chains';\n\nexport const mordor = defineChain({\n id: 63,\n name: 'Mordor Testnet',\n network: 'mordor',\n nativeCurrency: {\n decimals: 18,\n name: 'Mordor Ether',\n symbol: 'METC',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc.mordor.etccooperative.org'],\n webSocket: ['wss://rpc.mordor.etccooperative.org/ws'],\n },\n },\n blockExplorers: {\n default: { name: 'BlockScout', url: 'https://blockscout.com/etc/mordor' },\n },\n testnet: true,\n});\n\nexport const milkomeda = defineChain({\n id: 2001,\n name: 'Milkomeda C1 Mainnet',\n network: 'milkomeda',\n nativeCurrency: {\n decimals: 18,\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n },\n },\n blockExplorers: {\n default: { name: 'Milkomeda Explorer', url: 'https://explorer-mainnet-cardano-evm.c1.milkomeda.com' },\n },\n testnet: false,\n});\n\nexport const etcMainnet = defineChain({\n id: 61,\n name: 'Ethereum Classic',\n network: 'etc',\n nativeCurrency: {\n decimals: 18,\n name: 'Ethereum Classic',\n symbol: 'ETC',\n },\n rpcUrls: {\n default: {\n http: ['https://etc.rivet.link'],\n },\n },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://blockscout.com/etc/mainnet' },\n },\n testnet: false,\n});\n\nexport const getChainByNetworkKey = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return sepolia;\n case 'ethereum-classic':\n return etcMainnet;\n case 'milkomeda-mainnet':\n return milkomeda;\n default:\n return null;\n }\n};\n\nexport const getChainConfigForWallet = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return {\n chainId: `0x${sepolia.id.toString(16)}`,\n chainName: 'Sepolia',\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n rpcUrls: sepolia.rpcUrls.default.http,\n blockExplorerUrls: sepolia.blockExplorers?.default?.url ? [sepolia.blockExplorers.default.url] : [],\n };\n case 'ethereum-classic':\n return {\n chainId: `0x${etcMainnet.id.toString(16)}`,\n chainName: 'Ethereum Classic',\n nativeCurrency: {\n name: 'Ethereum Classic',\n symbol: 'ETC',\n decimals: 18,\n },\n rpcUrls: ['https://etc.rivet.link'],\n blockExplorerUrls: ['https://blockscout.com/etc/mainnet'],\n };\n case 'milkomeda-mainnet':\n return {\n chainId: `0x${milkomeda.id.toString(16)}`,\n chainName: 'Milkomeda C1 Mainnet',\n nativeCurrency: {\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n decimals: 18,\n },\n rpcUrls: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n blockExplorerUrls: ['https://explorer-mainnet-cardano-evm.c1.milkomeda.com'],\n };\n default:\n return null;\n }\n};\n","import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { createWalletClient, createPublicClient, custom, http } from 'viem';\nimport { useNetwork } from './NetworkContext';\nimport { getChainByNetworkKey, getChainConfigForWallet } from './chains';\n\nconst WalletContext = createContext(null);\n\nexport const useWallet = () => {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used within a WalletProvider');\n }\n return context;\n};\n\nconst switchToNetwork = async (networkKey) => {\n if (!window.ethereum) {\n throw new Error('MetaMask not installed');\n }\n\n const chainConfig = getChainConfigForWallet(networkKey);\n if (!chainConfig) {\n throw new Error(`Unsupported network: ${networkKey}`);\n }\n\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: chainConfig.chainId }],\n });\n } catch (switchError) {\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [chainConfig],\n });\n } catch (addError) {\n if (addError.code === 4001) {\n throw new Error(`User rejected adding ${chainConfig.chainName} to MetaMask. Please add it manually.`);\n }\n throw new Error(`Failed to add ${chainConfig.chainName} to MetaMask: ${addError.message}`);\n }\n } else if (switchError.code === 4001) {\n throw new Error(`User rejected switching to ${chainConfig.chainName}. Please switch manually in MetaMask.`);\n } else {\n throw new Error(`Failed to switch to ${chainConfig.chainName}: ${switchError.message}`);\n }\n }\n};\n\nexport const WalletProvider = ({ children }) => {\n const { selectedNetwork } = useNetwork();\n const [walletClient, setWalletClient] = useState(null);\n const [publicClient, setPublicClient] = useState(null);\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [balance, setBalance] = useState(null);\n const [error, setError] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n\n const selectedChain = selectedNetwork ? getChainByNetworkKey(selectedNetwork) : null;\n const expectedChainId = selectedChain ? selectedChain.id : null;\n\n const handleAccountsChangedRef = useRef(null);\n const handleChainChangedRef = useRef(null);\n\n const disconnectWalletInternal = useCallback(() => {\n setWalletClient(null);\n setPublicClient(null);\n setAccount(null);\n setChainId(null);\n setBalance(null);\n setError(null);\n }, []);\n\n const handleChainChanged = useCallback(async (chainIdHex) => {\n const newChainId = parseInt(chainIdHex, 16);\n setChainId(newChainId);\n\n if (selectedChain && newChainId === expectedChainId) {\n setError(null);\n if (window.ethereum && selectedChain) {\n const newWalletClient = createWalletClient({ \n chain: selectedChain, \n transport: custom(window.ethereum) \n });\n setWalletClient(newWalletClient);\n }\n } else if (selectedChain && newChainId !== expectedChainId) {\n const chainName = selectedChain?.name || selectedNetwork || 'selected network';\n setError(`Wrong network detected. Please switch to ${chainName}`);\n }\n }, [selectedChain, expectedChainId, selectedNetwork]);\n\n handleChainChangedRef.current = handleChainChanged;\n\n const handleAccountsChanged = useCallback(async (accounts) => {\n if (accounts.length === 0) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n } else {\n setAccount(accounts[0]);\n if (selectedChain) {\n try {\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n }\n }\n }, [selectedChain, disconnectWalletInternal]);\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n\n const disconnectWallet = useCallback(() => {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }, [disconnectWalletInternal]);\n\n const connectPublicClient = useCallback(() => {\n if (selectedChain) {\n setPublicClient(createPublicClient({ chain: selectedChain, transport: http() }));\n }\n }, [selectedChain]);\n\n const connectWallet = useCallback(async () => {\n if (!window.ethereum) {\n setError('Please install MetaMask or another Web3 wallet');\n return false;\n }\n\n if (!selectedNetwork || !selectedChain) {\n setError('Please select a network first');\n return false;\n }\n\n setIsConnecting(true);\n setError(null);\n\n try {\n const accounts = await window.ethereum.request({ \n method: 'eth_requestAccounts' \n });\n\n if (accounts.length === 0) {\n throw new Error('No wallet address found. Please unlock your wallet.');\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n await switchToNetwork(selectedNetwork);\n }\n\n const newWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(newWalletClient);\n setAccount(accounts[0]);\n setChainId(expectedChainId);\n\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n try {\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n handleChainChangedRef.current = handleChainChanged;\n window.ethereum.on('accountsChanged', handleAccountsChanged);\n window.ethereum.on('chainChanged', handleChainChanged);\n\n return true;\n } catch (err) {\n console.error('Error connecting wallet:', err);\n setError(err.message);\n return false;\n } finally {\n setIsConnecting(false);\n }\n }, [selectedNetwork, selectedChain, expectedChainId, handleAccountsChanged, handleChainChanged]);\n\n const ensureCorrectNetwork = useCallback(async () => {\n if (!window.ethereum || !selectedNetwork || !selectedChain || !account) {\n const errorMsg = 'Wallet not connected or network not selected';\n setError(errorMsg);\n return null;\n }\n\n try {\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n setError(null);\n await switchToNetwork(selectedNetwork);\n const NETWORK_SWITCH_DELAY_MS = 500;\n await new Promise(resolve => setTimeout(resolve, NETWORK_SWITCH_DELAY_MS));\n \n const newChainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const newChainId = parseInt(newChainIdHex, 16);\n if (newChainId !== expectedChainId) {\n throw new Error(`Failed to switch network. MetaMask is still on chain ${newChainId}, expected ${expectedChainId}`);\n }\n }\n\n const freshWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(freshWalletClient);\n setChainId(expectedChainId);\n setError(null);\n return freshWalletClient;\n } catch (err) {\n setError(err.message);\n return null;\n }\n }, [selectedNetwork, selectedChain, expectedChainId, account]);\n\n const prevNetworkRef = useRef(selectedNetwork);\n\n useEffect(() => {\n if (prevNetworkRef.current !== null && \n prevNetworkRef.current !== selectedNetwork && \n account) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }\n prevNetworkRef.current = selectedNetwork;\n }, [selectedNetwork, account, disconnectWalletInternal]);\n\n useEffect(() => {\n connectPublicClient();\n }, [connectPublicClient]);\n\n return (\n \n {children}\n \n );\n};","import React, { useState, useEffect } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { useWallet } from \"../contexts/WalletContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport { parseEther, encodeFunctionData, parseUnits } from \"viem\"; \nimport styles from \"../styles/PricingCard.css\"; \n\nconst TransactionReview = ({ onTransactionComplete }) => {\n const {\n networkSelector,\n selectedNetwork,\n selectedToken,\n transactionDetails: contextTransactionDetails,\n setTransactionDetails,\n } = useNetwork();\n\n const {\n connectWallet,\n account,\n walletClient,\n publicClient,\n isConnecting,\n ensureCorrectNetwork,\n expectedChainId,\n } = useWallet();\n\n const [transaction, setTransaction] = useState(null);\n const [tradeDataBuySc, setTradeDataBuySc] = useState(null);\n const [txData, setTxData] = useState(null);\n const [message, setMessage] = useState(\"\");\n const [txHash, setTxHash] = useState(null);\n const [error, setError] = useState(null);\n const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false);\n\n useEffect(() => {\n setTxData(null);\n setTradeDataBuySc(null);\n setMessage(\"\");\n setError(null);\n setTxHash(null);\n }, [selectedNetwork, selectedToken]);\n\n useEffect(() => {\n const initializeTransaction = async () => {\n if (!selectedNetwork || !selectedToken) return;\n\n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const receivingAddress = networkSelector.getReceivingAddress();\n const tokenAmount = networkSelector.getTokenAmount(selectedToken.key);\n\n const newTransaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await newTransaction.init();\n setTransaction(newTransaction);\n\n let tradeData = null;\n if (selectedToken.key === \"native\") {\n try {\n tradeData = await newTransaction.handleTradeDataBuySc(String(tokenAmount));\n setTradeDataBuySc(tradeData);\n } catch (tradeError) {\n console.error(\"Error fetching trade data:\", tradeError);\n }\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: selectedToken.key,\n tokenSymbol: selectedToken.symbol,\n amount: tokenAmount || \"0\",\n receivingAddress,\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer: selectedToken.isDirectTransfer || false,\n isNativeToken: selectedToken.isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...newTransaction.getBlockchainDetails(),\n });\n } catch (err) {\n console.error(\"Error initializing transaction:\", err);\n }\n };\n\n initializeTransaction();\n }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]);\n\n if (!contextTransactionDetails) {\n return
Initializing transaction...
;\n }\n\n const handleConnectWallet = async () => {\n await connectWallet();\n };\n\n const handleSendTransaction = async () => {\n if (!account || !contextTransactionDetails || !transaction) {\n setMessage(\"❌ Wallet not connected or transaction details missing\");\n return;\n }\n\n try {\n setTxData(null);\n setError(null);\n setMessage(\"⏳ Preparing transaction...\");\n\n const receiver = contextTransactionDetails.receivingAddress;\n let builtTx;\n\n if (selectedToken.key === \"native\") {\n const UI = \"0x0232556C83791b8291E9b23BfEa7d67405Bd9839\";\n const amountToSend = tradeDataBuySc || \"0\";\n const valueInWei = parseEther(String(amountToSend));\n\n builtTx = await transaction.buyStablecoins(\n account,\n receiver,\n valueInWei,\n UI\n );\n\n builtTx = {\n ...builtTx,\n value: valueInWei,\n account: account,\n };\n } else {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const stablecoinAddress = networkConfig?.tokens?.stablecoin?.address;\n \n if (!stablecoinAddress) {\n throw new Error('Stablecoin address not found in network configuration');\n }\n\n const amountToSend = contextTransactionDetails.amount\n ? parseUnits(\n String(contextTransactionDetails.amount),\n contextTransactionDetails.stableCoinDecimals\n )\n : \"0\";\n\n builtTx = {\n to: stablecoinAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: [\n {\n inputs: [\n { internalType: \"address\", name: \"to\", type: \"address\" },\n { internalType: \"uint256\", name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ],\n functionName: \"transfer\",\n args: [receiver, amountToSend],\n }),\n account: account,\n };\n }\n\n setTxData(builtTx);\n setMessage(\"✅ Transaction ready! Click 'Send Transaction' to proceed.\");\n } catch (error) {\n setError(error);\n setMessage(`❌ Transaction preparation failed.`);\n }\n };\n\n const handleBuySc = async () => {\n setError(null);\n \n try {\n if (!account || !txData) {\n setMessage(\"❌ Wallet account or transaction data is missing\");\n return;\n }\n\n if (!selectedNetwork) {\n setMessage(\"❌ Network not selected\");\n return;\n }\n\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) {\n setMessage(\"❌ Network configuration not found\");\n return;\n }\n\n setMessage(\"⏳ Verifying network...\");\n\n const freshWalletClient = await ensureCorrectNetwork();\n if (!freshWalletClient) {\n setMessage(\"❌ Failed to switch to correct network. Please approve the network switch in MetaMask and try again.\");\n return;\n }\n\n if (!window.ethereum) {\n setMessage(\"❌ MetaMask not available\");\n return;\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== networkConfig.chainId) {\n const errorMsg = `Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`;\n setMessage(`❌ ${errorMsg}`);\n setError(new Error(errorMsg));\n return;\n }\n\n if (freshWalletClient.chain.id !== networkConfig.chainId) {\n const errorMsg = `Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`;\n setMessage(`❌ ${errorMsg}`);\n setError(new Error(errorMsg));\n return;\n }\n\n setMessage(\"⏳ Sending transaction...\");\n\n const txHash = await freshWalletClient.sendTransaction({\n ...txData,\n account: account,\n });\n\n setTxHash(txHash);\n setMessage(`✅ Transaction sent!`);\n \n if (onTransactionComplete) {\n onTransactionComplete({\n txHash,\n network: selectedNetwork,\n token: selectedToken?.key,\n tokenSymbol: selectedToken?.symbol,\n amount: contextTransactionDetails?.amount,\n receivingAddress: contextTransactionDetails?.receivingAddress,\n });\n }\n } catch (error) {\n setError(error);\n setMessage(`❌ Transaction failed.`);\n console.error('Transaction error:', error);\n }\n };\n\n const getExplorerUrl = () => {\n if (!txHash || !selectedNetwork) return null;\n\n const explorerBaseUrls = {\n \"ethereum-classic\": \"https://blockscout.com/etc/mainnet/tx/\",\n \"sepolia\": \"https://sepolia.etherscan.io/tx/\",\n \"milkomeda-mainnet\": \"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/\",\n };\n\n return explorerBaseUrls[selectedNetwork]\n ? `${explorerBaseUrls[selectedNetwork]}${txHash}`\n : null;\n };\n\n return (\n
\n
\n Network:\n {contextTransactionDetails.network}\n
\n\n
\n You Pay:\n \n {selectedToken.key === \"stablecoin\"\n ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}`\n : `${tradeDataBuySc ? tradeDataBuySc : \"Calculating...\"} ${\n contextTransactionDetails.tokenSymbol\n }`}\n \n
\n\n \n\n {account && !txData && (\n \n )}\n {account && txData && (\n \n)}\n\n\n {message && (\n
\n {message}\n {error && (\n setIsErrorDetailsVisible(!isErrorDetailsVisible)}\n className={styles.detailsButton}\n >\n {isErrorDetailsVisible ? \"Hide Details\" : \"Show Details\"}\n \n )}\n
\n )}\n\n {isErrorDetailsVisible && error && (\n
\n
{error.message}
\n
\n )}\n\n \n {txHash && (\n
\n ✅ Transaction Hash:{\" \"}\n {getExplorerUrl() ? (\n \n {txHash.slice(0, 6)}...{txHash.slice(-6)}\n \n ) : (\n \n {txHash}\n \n )}\n
\n)}\n\n
\n );\n};\n\nexport default TransactionReview;\n","import React, { useState } from \"react\";\nimport PayButton from \"./PayButton\";\nimport Dialog from \"./Dialog\";\nimport NetworkDropdown from \"./NetworkDropdown\";\nimport TokenDropdown from \"./TokenDropdown\";\nimport TransactionReview from \"./TransactionReview\";\nimport { NetworkProvider, useNetwork } from \"../contexts/NetworkContext\";\nimport { WalletProvider } from \"../contexts/WalletContext\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst WidgetContent = ({ onClose, buttonSize, onTransactionComplete }) => {\n const { resetSelections } = useNetwork(); \n\n const handleClose = () => {\n resetSelections(); // Reset selections when closing the widget\n onClose();\n };\n\n return (\n \n \n \n \n \n );\n};\n\nconst WidgetWithProviders = ({ onClose, buttonSize, networkSelector, onTransactionComplete }) => {\n return (\n \n \n \n \n \n );\n};\n\nexport const Widget = ({ networkSelector, buttonSize = \"medium\", onTransactionComplete, onSuccess }) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const handleOpenDialog = () => {\n setIsDialogOpen(true);\n };\n\n const handleCloseDialog = () => {\n setIsDialogOpen(false);\n };\n\n // Support both onTransactionComplete and onSuccess for backwards compatibility\n const handleTransactionComplete = onTransactionComplete || onSuccess;\n\n return (\n
\n {!isDialogOpen && (\n \n )}\n {isDialogOpen && (\n \n )}\n
\n );\n};\n\nexport default Widget;\n","// src/index.js\nimport { NetworkSelector } from './core/NetworkSelector';\nimport { Transaction } from './core/Transaction';\nimport { Config } from './core/MerchantConfig';\nimport Widget from './widget/Widget.jsx';\nimport PayButton from './widget/PayButton.jsx';\nimport Dialog from './widget/Dialog.jsx';\nimport NetworkDropdown from './widget/NetworkDropdown.jsx';\nimport './styles/main.css';\nimport './styles/PricingCard.css';\n\nconst StablePay = {\n NetworkSelector,\n Transaction,\n Config,\n Widget,\n PayButton,\n Dialog,\n NetworkDropdown\n};\n\nexport default StablePay;","import { networksConfig } from \"../utils/config\";\n\nexport class NetworkSelector {\n constructor(merchantConfig) {\n this.merchantConfig = merchantConfig;\n this.blacklist = merchantConfig.getBlacklist();\n this.availableNetworks = this.getAvailableNetworks();\n this.selectedNetwork = null;\n }\n\n getAvailableNetworks() {\n return Object.entries(networksConfig).reduce(\n (acc, [networkKey, networkConfig]) => {\n if (!this.blacklist.includes(networkConfig.chainId)) {\n acc[networkKey] = networkConfig;\n }\n return acc;\n },\n {}\n );\n }\n\n selectNetwork(networkKey) {\n if (networkKey === null) {\n this.selectedNetwork = null;\n console.log(\"Network selection reset\");\n return true;\n }\n if (this.availableNetworks[networkKey]) {\n this.selectedNetwork = networkKey;\n console.log(`Network selected: ${networkKey}`);\n return true;\n }\n console.error(`Invalid network: ${networkKey}`);\n return false;\n }\n\n getSelectedNetworkConfig() {\n return this.selectedNetwork\n ? this.availableNetworks[this.selectedNetwork]\n : null;\n }\n\n getReceivingAddress() {\n return this.merchantConfig.getReceivingAddress();\n }\n\n getTokenAmount(token) {\n return this.merchantConfig.getTokenAmount(this.selectedNetwork, token);\n }\n}\n","import { networksConfig } from \"../utils/config\";\n\nexport class Config {\n constructor(options = {}) {\n this.receivingAddress = options.receivingAddress || \"\";\n this.blacklist = options.blacklist || [];\n this.amounts = options.amounts || options.Amounts || {};\n this.validateConfig();\n }\n\n validateConfig() {\n if (!this.receivingAddress) {\n throw new Error(\"Receiving address is required\");\n }\n // Validate stablecoin amounts\n for (const [network, tokens] of Object.entries(this.amounts)) {\n if (!networksConfig[network]) {\n throw new Error(`Invalid network: ${network}`);\n }\n if (\n !tokens.stablecoin ||\n typeof tokens.stablecoin !== \"number\" ||\n tokens.stablecoin <= 0\n ) {\n throw new Error(`Invalid stablecoin amount for network ${network}`);\n }\n }\n }\n\n getBlacklist() {\n return this.blacklist;\n }\n\n getReceivingAddress() {\n return this.receivingAddress;\n }\n\n // getTokenAmount(network, token) {\n // const networkConfig = networksConfig[network];\n // if (!networkConfig) return 0;\n\n // const stablecoinSymbol = networkConfig.tokens.stablecoin.symbol;\n\n // if (token === 'stablecoin') {\n // return this.amounts[network]?.stablecoin || 0;\n // }\n // // For native tokens, return 0 as it's not specified in the new structure\n // return 0;\n // }\n getTokenAmount(network) {\n console.log(\"Getting amount for network:\", network);\n console.log(\"Amounts object:\", this.amounts);\n\n // Directly return the stablecoin amount for the network\n const amount = this.amounts[network]?.stablecoin;\n console.log(\"Returning amount:\", amount);\n\n return amount || 0;\n }\n}\n\nexport default Config;\n"],"names":["networksConfig","sepolia","uri","chainId","djedAddress","tokens","stablecoin","symbol","address","decimals","isDirectTransfer","native","isNative","feeUI","Transaction","constructor","networkUri","this","init","Error","web3","getWeb3","djedContract","getDjedContract","stableCoin","reserveCoin","getCoinContracts","scDecimals","rcDecimals","getDecimals","oracleContract","getOracleAddress","then","addr","getOracleContract","_address","oracleAddress","contractError","console","error","message","includes","getNetworkInfo","name","networkName","getNetworkName","getBlockchainDetails","web3Available","djedContractAvailable","stableCoinAddress","reserveCoinAddress","stableCoinDecimals","reserveCoinDecimals","oracleContractAvailable","handleTradeDataBuySc","amountScaled","tradeDataPriceBuySc","totalBCScaled","buyStablecoins","payer","receiver","value","UI","buyScTx","PayButton","onClick","size","sizeStyles","small","width","height","fontSize","medium","large","logoSizes","buttonStyle","logoStyle","React","createElement","className","styles","style","Dialog","children","onClose","dialogOverlay","pricingCard","dialogClose","pricingCardHeader","allianceLogo","stablepayTitle","pricingCardBody","TokenSelector","networkSelector","selectedToken","selectToken","tokenKey","networkConfig","getSelectedNetworkConfig","key","getSelectedToken","getAvailableTokens","Object","entries","map","config","resetSelection","NetworkContext","createContext","NetworkProvider","tokenSelector","useState","selectedNetwork","setSelectedNetwork","setSelectedToken","transactionDetails","setTransactionDetails","resetState","useEffect","Provider","selectNetwork","networkKey","token","resetSelections","useNetwork","context","useContext","undefined","NetworkDropdown","selectField","htmlFor","id","onChange","event","target","disabled","keys","availableNetworks","TokenDropdown","loading","setLoading","setError","availableTokens","async","newValue","transaction","tokenAmount","getTokenAmount","blockchainDetails","tradeData","String","network","tokenSymbol","amount","receivingAddress","getReceivingAddress","djedContractAddress","isNativeToken","tradeAmount","err","defineChain","nativeCurrency","rpcUrls","default","http","webSocket","blockExplorers","url","testnet","milkomeda","etcMainnet","WalletContext","switchToNetwork","window","ethereum","chainConfig","toString","chainName","blockExplorerUrls","getChainConfigForWallet","request","method","params","switchError","code","addError","WalletProvider","walletClient","setWalletClient","publicClient","setPublicClient","account","setAccount","setChainId","balance","setBalance","isConnecting","setIsConnecting","selectedChain","getChainByNetworkKey","expectedChainId","handleAccountsChangedRef","useRef","handleChainChangedRef","disconnectWalletInternal","useCallback","handleChainChanged","newChainId","parseInt","chainIdHex","newWalletClient","createWalletClient","chain","transport","custom","current","handleAccountsChanged","accounts","length","accountsHandler","chainHandler","removeListener","newPublicClient","createPublicClient","getBalance","parseFloat","Math","pow","disconnectWallet","connectPublicClient","connectWallet","on","ensureCorrectNetwork","NETWORK_SWITCH_DELAY_MS","Promise","resolve","setTimeout","newChainIdHex","freshWalletClient","prevNetworkRef","TransactionReview","onTransactionComplete","contextTransactionDetails","useWallet","setTransaction","tradeDataBuySc","setTradeDataBuySc","txData","setTxData","setMessage","txHash","setTxHash","isErrorDetailsVisible","setIsErrorDetailsVisible","newTransaction","tradeError","initializeTransaction","getExplorerUrl","explorerBaseUrls","transactionReview","transactionInfo","transactionLabel","transactionValue","walletButton","builtTx","amountToSend","valueInWei","parseEther","stablecoinAddress","parseUnits","to","data","encodeFunctionData","abi","inputs","internalType","type","outputs","stateMutability","functionName","args","currentChainId","errorMsg","sendTransaction","detailsButton","errorDetails","transactionLink","href","rel","explorerLink","color","textDecoration","fontWeight","cursor","wordBreak","slice","WidgetContent","buttonSize","handleClose","WidgetWithProviders","NetworkSelector","merchantConfig","blacklist","getBlacklist","getAvailableNetworks","reduce","acc","log","Config","options","amounts","Amounts","validateConfig","Widget","onSuccess","isDialogOpen","setIsDialogOpen","handleTransactionComplete","widgetContainer","handleOpenDialog","handleCloseDialog"],"mappings":"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"} \ No newline at end of file diff --git a/stablepay-sdk/example/.gitignore b/stablepay-sdk/example/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/stablepay-sdk/example/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/stablepay-sdk/example/README.md b/stablepay-sdk/example/README.md new file mode 100644 index 0000000..a36934d --- /dev/null +++ b/stablepay-sdk/example/README.md @@ -0,0 +1,16 @@ +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. diff --git a/stablepay-sdk/example/eslint.config.js b/stablepay-sdk/example/eslint.config.js new file mode 100644 index 0000000..ea36dd3 --- /dev/null +++ b/stablepay-sdk/example/eslint.config.js @@ -0,0 +1,21 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{js,jsx}'], + extends: [ + js.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + languageOptions: { + globals: globals.browser, + parserOptions: { ecmaFeatures: { jsx: true } }, + }, + }, +]) diff --git a/stablepay-sdk/example/index.html b/stablepay-sdk/example/index.html new file mode 100644 index 0000000..306cc15 --- /dev/null +++ b/stablepay-sdk/example/index.html @@ -0,0 +1,13 @@ + + + + + + + example + + +
+ + + diff --git a/stablepay-sdk/example/package-lock.json b/stablepay-sdk/example/package-lock.json new file mode 100644 index 0000000..6edec53 --- /dev/null +++ b/stablepay-sdk/example/package-lock.json @@ -0,0 +1,2835 @@ +{ + "name": "example", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "example", + "version": "0.0.0", + "dependencies": { + "ethers": "^6.16.0", + "react": "^19.2.6", + "react-dom": "^19.2.6", + "stablepay-sdk": "file:..", + "viem": "^2.52.2" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^10.3.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.6.0", + "vite": "^8.0.12" + } + }, + "..": { + "version": "1.0.3", + "license": "ISC", + "dependencies": { + "djed-sdk": "^1.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "viem": "^2.21.53", + "web3": "^1.7.3" + }, + "devDependencies": { + "@babel/preset-react": "^7.25.7", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-commonjs": "^28.0.8", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-url": "^8.0.2", + "@rollup/pluginutils": "^5.1.2", + "autoprefixer": "^10.4.20", + "cssnano": "^7.0.6", + "rollup": "^4.24.0", + "rollup-plugin-commonjs": "^10.1.0", + "rollup-plugin-copy": "^3.5.0", + "rollup-plugin-node-resolve": "^5.2.0", + "rollup-plugin-postcss": "^4.0.2" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", + "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@noble/ciphers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", + "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.133.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", + "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", + "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", + "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", + "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", + "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", + "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", + "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", + "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", + "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", + "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", + "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", + "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", + "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", + "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", + "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", + "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", + "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz", + "integrity": "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } + } + }, + "node_modules/abitype": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", + "integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3.22.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "license": "MIT" + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.34", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.34.tgz", + "integrity": "sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001797", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001797.tgz", + "integrity": "sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.368", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.368.tgz", + "integrity": "sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw==", + "dev": true, + "license": "ISC" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.4.1.tgz", + "integrity": "sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.6.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.5.2.tgz", + "integrity": "sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": "^9 || ^10" + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ethers": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz", + "integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "22.7.5", + "aes-js": "4.0.0-beta.5", + "tslib": "2.7.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/ethers/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, + "node_modules/ethers/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", + "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isows": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", + "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ox": { + "version": "0.14.29", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.29.tgz", + "integrity": "sha512-M5j87Ec4V99MQdRct/g09eWXW60g6zhHTUs1lr4deUtrPDnezBdCJTgKd7pxqTpSZBFveV0ALi9jMMuT1qKyNg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.11.0", + "@noble/ciphers": "^1.3.0", + "@noble/curves": "1.9.1", + "@noble/hashes": "^1.8.0", + "@scure/bip32": "^1.7.0", + "@scure/bip39": "^1.6.0", + "abitype": "^1.2.3", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/ox/node_modules/@adraffy/ens-normalize": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", + "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", + "license": "MIT" + }, + "node_modules/ox/node_modules/@noble/curves": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ox/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/rolldown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", + "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.133.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.3", + "@rolldown/binding-darwin-arm64": "1.0.3", + "@rolldown/binding-darwin-x64": "1.0.3", + "@rolldown/binding-freebsd-x64": "1.0.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", + "@rolldown/binding-linux-arm64-gnu": "1.0.3", + "@rolldown/binding-linux-arm64-musl": "1.0.3", + "@rolldown/binding-linux-ppc64-gnu": "1.0.3", + "@rolldown/binding-linux-s390x-gnu": "1.0.3", + "@rolldown/binding-linux-x64-gnu": "1.0.3", + "@rolldown/binding-linux-x64-musl": "1.0.3", + "@rolldown/binding-openharmony-arm64": "1.0.3", + "@rolldown/binding-wasm32-wasi": "1.0.3", + "@rolldown/binding-win32-arm64-msvc": "1.0.3", + "@rolldown/binding-win32-x64-msvc": "1.0.3" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stablepay-sdk": { + "resolved": "..", + "link": true + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/viem": { + "version": "2.52.2", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.52.2.tgz", + "integrity": "sha512-HSU12p5aD/kAPZfrlbCUqdiP4P/c6hQ9AhfTS51VbLUQIjkWd1d5EjrCx/SCxZ0zhZVRn4Iv5X5WDqXPG8Ubew==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@noble/curves": "1.9.1", + "@noble/hashes": "1.8.0", + "@scure/bip32": "1.7.0", + "@scure/bip39": "1.6.0", + "abitype": "1.2.3", + "isows": "1.0.7", + "ox": "0.14.29", + "ws": "8.20.1" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/viem/node_modules/@noble/curves": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/ws": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", + "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/vite": { + "version": "8.0.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", + "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.15", + "rolldown": "1.0.3", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "devOptional": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + } + } +} diff --git a/stablepay-sdk/example/package.json b/stablepay-sdk/example/package.json new file mode 100644 index 0000000..2197b9f --- /dev/null +++ b/stablepay-sdk/example/package.json @@ -0,0 +1,30 @@ +{ + "name": "example", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "ethers": "^6.16.0", + "react": "^19.2.6", + "react-dom": "^19.2.6", + "stablepay-sdk": "file:..", + "viem": "^2.52.2" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^10.3.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.6.0", + "vite": "^8.0.12" + } +} diff --git a/stablepay-sdk/example/public/favicon.svg b/stablepay-sdk/example/public/favicon.svg new file mode 100644 index 0000000..6893eb1 --- /dev/null +++ b/stablepay-sdk/example/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stablepay-sdk/example/public/icons.svg b/stablepay-sdk/example/public/icons.svg new file mode 100644 index 0000000..e952219 --- /dev/null +++ b/stablepay-sdk/example/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stablepay-sdk/example/src/App.css b/stablepay-sdk/example/src/App.css new file mode 100644 index 0000000..fc4020a --- /dev/null +++ b/stablepay-sdk/example/src/App.css @@ -0,0 +1,91 @@ +* { + box-sizing: border-box; + margin: 0; + padding: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; +} + +body { + background-color: #f4f6f8; + color: #333; +} + +.app-container { + min-height: 100vh; + display: flex; + flex-direction: column; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 2rem; + background-color: #ffffff; + box-shadow: 0 2px 4px rgba(0,0,0,0.05); +} + +.logo { + font-size: 1.5rem; + font-weight: 700; + color: #0052cc; +} + +.connect-wallet-btn { + background-color: #f6851b; + color: white; + border: none; + border-radius: 8px; + padding: 0.6rem 1.2rem; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.connect-wallet-btn:hover { + background-color: #e27618; +} + +.main-content { + flex: 1; + display: flex; + justify-content: center; + align-items: center; + padding: 2rem; +} + +.card { + background: white; + padding: 3rem; + border-radius: 16px; + box-shadow: 0 10px 25px rgba(0,0,0,0.05); + text-align: center; + max-width: 400px; + width: 100%; +} + +.card h2 { + margin-bottom: 0.5rem; + font-size: 1.5rem; + color: #2c3e50; +} + +.price { + font-size: 2.5rem; + font-weight: bold; + color: #0052cc; + margin-bottom: 1rem; +} + +.description { + color: #666; + margin-bottom: 2rem; + line-height: 1.5; +} + +.widget-wrapper { + display: flex; + justify-content: center; + margin-top: 1rem; +} diff --git a/stablepay-sdk/example/src/App.jsx b/stablepay-sdk/example/src/App.jsx new file mode 100644 index 0000000..d6cb169 --- /dev/null +++ b/stablepay-sdk/example/src/App.jsx @@ -0,0 +1,68 @@ +import { useState } from 'react'; +import StablePay from 'stablepay-sdk'; +import './App.css'; + +function App() { + const [account, setAccount] = useState(''); + + const connectWallet = async () => { + if (window.ethereum) { + try { + const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }); + setAccount(accounts[0]); + } catch (err) { + console.error("User denied account access", err); + } + } else { + alert("Please install MetaMask to connect your wallet."); + } + }; + + // Configure merchant for a $5 demo payment + const merchantConfig = new StablePay.Config({ + receivingAddress: '0x000000000000000000000000000000000000dEaD', // Demo receiving address + amounts: { + 'sepolia': { stablecoin: 5 }, + 'milkomeda-mainnet': { stablecoin: 5 }, + 'ethereum-classic': { stablecoin: 5 } + } + }); + + const networkSelector = new StablePay.NetworkSelector(merchantConfig); + + const handleTransactionComplete = (hash) => { + alert(`Payment Successful! Transaction Hash: ${hash}`); + }; + + return ( +
+
+
Demo Shop
+ +
+ +
+
+

Premium Subscription

+

$5.00

+

+ Get access to premium features for a one-time payment of $5. + Powered by StablePay. +

+
+ +
+
+
+
+ ); +} + +export default App; diff --git a/stablepay-sdk/example/src/assets/hero.png b/stablepay-sdk/example/src/assets/hero.png new file mode 100644 index 0000000000000000000000000000000000000000..02251f4b956c55af2d76fd0788124d7eee2b45eb GIT binary patch literal 13057 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 P00000NkvXXu0mjft=yBf literal 0 HcmV?d00001 diff --git a/stablepay-sdk/example/src/assets/react.svg b/stablepay-sdk/example/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/stablepay-sdk/example/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stablepay-sdk/example/src/assets/vite.svg b/stablepay-sdk/example/src/assets/vite.svg new file mode 100644 index 0000000..5101b67 --- /dev/null +++ b/stablepay-sdk/example/src/assets/vite.svg @@ -0,0 +1 @@ +Vite diff --git a/stablepay-sdk/example/src/index.css b/stablepay-sdk/example/src/index.css new file mode 100644 index 0000000..7a9cb4c --- /dev/null +++ b/stablepay-sdk/example/src/index.css @@ -0,0 +1,9 @@ +body { + margin: 0; + padding: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/stablepay-sdk/example/src/main.jsx b/stablepay-sdk/example/src/main.jsx new file mode 100644 index 0000000..c5b9245 --- /dev/null +++ b/stablepay-sdk/example/src/main.jsx @@ -0,0 +1,11 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import 'stablepay-sdk/dist/esm/styles.css' +import App from './App.jsx' + +createRoot(document.getElementById('root')).render( + + + , +) diff --git a/stablepay-sdk/example/vite.config.js b/stablepay-sdk/example/vite.config.js new file mode 100644 index 0000000..8b0f57b --- /dev/null +++ b/stablepay-sdk/example/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/stablepay-sdk/examples/index.txt b/stablepay-sdk/examples/index.txt deleted file mode 100644 index 171515b..0000000 --- a/stablepay-sdk/examples/index.txt +++ /dev/null @@ -1 +0,0 @@ -this folder will contain the testing file and examples of vite project,react project on how to use the stable-pay,sdk \ No newline at end of file From d882f0956553a5c47e9aa8d22d61876f90e6353f Mon Sep 17 00:00:00 2001 From: DeveloperAmrit Date: Sun, 7 Jun 2026 18:47:58 +0530 Subject: [PATCH 2/6] fix: Improved UI/UX of stablepay-sdk widgets --- stablepay-sdk/example/vite.config.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stablepay-sdk/example/vite.config.js b/stablepay-sdk/example/vite.config.js index 8b0f57b..a9f4da2 100644 --- a/stablepay-sdk/example/vite.config.js +++ b/stablepay-sdk/example/vite.config.js @@ -4,4 +4,9 @@ import react from '@vitejs/plugin-react' // https://vite.dev/config/ export default defineConfig({ plugins: [react()], + server: { + fs: { + allow: ['..'] + } + } }) From 95a00b7bbbf278389a538f06d388554d6d58cc6e Mon Sep 17 00:00:00 2001 From: DeveloperAmrit Date: Sun, 7 Jun 2026 18:49:01 +0530 Subject: [PATCH 3/6] fix: Imroved UI/UX of stablepay-sdk widgets --- stablepay-sdk/dist/esm/index.js | 2 +- stablepay-sdk/dist/esm/styles.css | 2 +- stablepay-sdk/dist/umd/index.js | 2 +- stablepay-sdk/dist/umd/index.js.map | 2 +- stablepay-sdk/dist/umd/styles.css | 2 +- stablepay-sdk/src/styles/PricingCard.css | 396 ++++++++++-------- stablepay-sdk/src/widget/Dialog.jsx | 2 +- .../src/widget/TransactionReview.jsx | 113 ++--- 8 files changed, 281 insertions(+), 240 deletions(-) diff --git a/stablepay-sdk/dist/esm/index.js b/stablepay-sdk/dist/esm/index.js index 116101c..0748fc3 100644 --- a/stablepay-sdk/dist/esm/index.js +++ b/stablepay-sdk/dist/esm/index.js @@ -1 +1 @@ -import{getWeb3 as e,getDjedContract as t,getCoinContracts as n,getDecimals as r,getOracleAddress as a,getOracleContract as o,tradeDataPriceBuySc as i,buyScTx as s}from"djed-sdk";import c,{useContext as l,createContext as d,useState as m,useEffect as u,useRef as h,useCallback as w}from"react";import{defineChain as k,createWalletClient as g,custom as C,createPublicClient as p,http as b,parseEther as f,parseUnits as v,encodeFunctionData as E}from"viem";import{sepolia as y}from"viem/chains";const _={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class N{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e(this.networkUri),this.djedContract=t(this.web3,this.djedAddress);try{const{stableCoin:e,reserveCoin:t}=await n(this.djedContract,this.web3),{scDecimals:i,rcDecimals:s}=await r(e,t);this.stableCoin=e,this.reserveCoin=t,this.scDecimals=i,this.rcDecimals=s,this.oracleContract=await a(this.djedContract).then((e=>o(this.web3,e,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){if(console.error("[Transaction] Error fetching contract details:",e),e.message&&e.message.includes("execution reverted")){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){if(console.error("[Transaction] Error initializing transaction:",e),e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(e){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof e)throw new Error("Amount must be a string");try{return(await i(this.djedContract,this.scDecimals,e)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(e,t,n){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await s(this.djedContract,e,t,n,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var T="main_stablePayButton__UA7HC",S="main_logo__ITyEy",A="main_buttonText__N-ewy";const D=({onClick:e,size:t="medium"})=>{const n={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},a=n[t]||n.medium,o=r[t]||r.medium;return c.createElement("button",{className:T,onClick:e,style:a},c.createElement("div",{className:S,style:o}),c.createElement("span",{className:A},"Pay with StablePay"))};var x={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",infoSection:"PricingCard_infoSection__gyjMQ",infoIcon:"PricingCard_infoIcon__rraxD",infoText:"PricingCard_infoText__l4b7A",walletButton:"PricingCard_walletButton__llw4v",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",networkError:"PricingCard_networkError__zR-36",errorText:"PricingCard_errorText__qZRJt","message-box":"PricingCard_message-box__vkUKy",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",loadingContainer:"PricingCard_loadingContainer__6nOVa",spinner:"PricingCard_spinner__9ucQv",spin:"PricingCard_spin__24tni"};const P=({children:e,onClose:t,size:n="medium"})=>c.createElement("div",{className:x.dialogOverlay},c.createElement("div",{className:`${x.pricingCard} ${x[n]}`},c.createElement("button",{className:x.dialogClose,onClick:t},"×"),c.createElement("div",{className:x.pricingCardHeader},c.createElement("div",{className:x.allianceLogo}),c.createElement("h2",{className:x.stablepayTitle},"StablePay")),c.createElement("div",{className:x.pricingCardBody},e)));class I{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const B=d(),M=({children:e,networkSelector:t})=>{const[n]=m((()=>new I(t))),[r,a]=m(null),[o,i]=m(null),[s,l]=m(null),d=()=>{i(null),l(null)};return u((()=>{a(t.selectedNetwork)}),[t.selectedNetwork]),c.createElement(B.Provider,{value:{networkSelector:t,tokenSelector:n,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:l,selectNetwork:e=>!!t.selectNetwork(e)&&(a(e),d(),!0),selectToken:e=>{if(n.selectToken(e)){const e=n.getSelectedToken();return i(e),!0}return!1},resetSelections:()=>{t.selectNetwork(null),a(null),d()}}},e)},$=()=>{const e=l(B);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},j=()=>{const{networkSelector:e,selectedNetwork:t,selectNetwork:n}=$();return c.createElement("div",{className:x.selectField},c.createElement("label",{htmlFor:"network-select"},"Select Network"),c.createElement("select",{id:"network-select",onChange:e=>{n(e.target.value)},value:t||""},c.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>c.createElement("option",{key:e,value:e},e)))))},U=()=>{const{networkSelector:e,tokenSelector:t,selectedNetwork:n,selectedToken:r,selectToken:a,setTransactionDetails:o}=$(),[i,s]=m(!1),[l,d]=m(null),u=n?t.getAvailableTokens():[];return c.createElement("div",{className:x.selectField},c.createElement("label",{htmlFor:"token-select"},"Select Token"),c.createElement("select",{id:"token-select",onChange:async r=>{const i=r.target.value;d(null),s(!0);try{if(a(i)){const r=e.getSelectedNetworkConfig(),a=new N(r.uri,r.djedAddress);await a.init();const s=e.getTokenAmount(i),c=a.getBlockchainDetails();let l=null;"native"===i&&(l=await a.handleTradeDataBuySc(String(s))),o({network:n,token:i,tokenSymbol:t.getSelectedToken().symbol,amount:s,receivingAddress:e.getReceivingAddress(),djedContractAddress:r.djedAddress,isDirectTransfer:t.getSelectedToken().isDirectTransfer||!1,isNativeToken:t.getSelectedToken().isNative||!1,tradeAmount:l?l.amount:null,...c})}}catch(e){console.error("Error fetching transaction details:",e),d("Failed to fetch transaction details. Please try again.")}finally{s(!1)}},value:r?r.key:"",disabled:!n||i},c.createElement("option",{value:"",disabled:!0},n?i?"Loading...":"Select a token":"Please select a network first"),u.map((e=>c.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),l&&c.createElement("div",{className:x.error},l))};k({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const F=k({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),R=k({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),L=d(null),z=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${y.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:y.rpcUrls.default.http,blockExplorerUrls:y.blockExplorers?.default?.url?[y.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${R.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${F.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},W=({children:e})=>{const{selectedNetwork:t}=$(),[n,r]=m(null),[a,o]=m(null),[i,s]=m(null),[l,d]=m(null),[k,f]=m(null),[v,E]=m(null),[_,N]=m(!1),T=t?(e=>{switch(e){case"sepolia":return y;case"ethereum-classic":return R;case"milkomeda-mainnet":return F;default:return null}})(t):null,S=T?T.id:null,A=h(null),D=h(null),x=w((()=>{r(null),o(null),s(null),d(null),f(null),E(null)}),[]),P=w((async e=>{const n=parseInt(e,16);if(d(n),T&&n===S){if(E(null),window.ethereum&&T){const e=g({chain:T,transport:C(window.ethereum)});r(e)}}else if(T&&n!==S){E(`Wrong network detected. Please switch to ${T?.name||t||"selected network"}`)}}),[T,S,t]);D.current=P;const I=w((async e=>{if(0===e.length){if(x(),window.ethereum){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(s(e[0]),T)try{const t=p({chain:T,transport:b()});o(t);const n=await t.getBalance({address:e[0]});f(parseFloat(n)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}}),[T,x]);A.current=I;const B=w((()=>{if(x(),window.ethereum){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[x]),M=w((()=>{T&&o(p({chain:T,transport:b()}))}),[T]),j=w((async()=>{if(!window.ethereum)return E("Please install MetaMask or another Web3 wallet"),!1;if(!t||!T)return E("Please select a network first"),!1;N(!0),E(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const n=await window.ethereum.request({method:"eth_chainId"});parseInt(n,16)!==S&&await z(t);const a=g({chain:T,transport:C(window.ethereum)});r(a),s(e[0]),d(S);const i=p({chain:T,transport:b()});o(i);try{const t=await i.getBalance({address:e[0]});f(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}return A.current=I,D.current=P,window.ethereum.on("accountsChanged",I),window.ethereum.on("chainChanged",P),!0}catch(e){return console.error("Error connecting wallet:",e),E(e.message),!1}finally{N(!1)}}),[t,T,S,I,P]),U=w((async()=>{if(!(window.ethereum&&t&&T&&i)){return E("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==S){E(null),await z(t);const e=500;await new Promise((t=>setTimeout(t,e)));const n=await window.ethereum.request({method:"eth_chainId"}),r=parseInt(n,16);if(r!==S)throw new Error(`Failed to switch network. MetaMask is still on chain ${r}, expected ${S}`)}const n=g({chain:T,transport:C(window.ethereum)});return r(n),d(S),E(null),n}catch(e){return E(e.message),null}}),[t,T,S,i]),W=h(t);return u((()=>{if(null!==W.current&&W.current!==t&&i&&(x(),window.ethereum)){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}W.current=t}),[t,i,x]),u((()=>{M()}),[M]),c.createElement(L.Provider,{value:{walletClient:n,publicClient:a,account:i,chainId:l,balance:k,error:v,isConnecting:_,connectWallet:j,disconnectWallet:B,ensureCorrectNetwork:U,expectedChainId:S}},e)},O=({onTransactionComplete:e})=>{const{networkSelector:t,selectedNetwork:n,selectedToken:r,transactionDetails:a,setTransactionDetails:o}=$(),{connectWallet:i,account:s,walletClient:d,publicClient:h,isConnecting:w,ensureCorrectNetwork:k,expectedChainId:g}=(()=>{const e=l(L);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[C,p]=m(null),[b,y]=m(null),[_,T]=m(null),[S,A]=m(""),[D,P]=m(null),[I,B]=m(null),[M,j]=m(!1);if(u((()=>{T(null),y(null),A(""),B(null),P(null)}),[n,r]),u((()=>{(async()=>{if(n&&r)try{const e=t.getSelectedNetworkConfig(),a=t.getReceivingAddress(),i=t.getTokenAmount(r.key),s=new N(e.uri,e.djedAddress);await s.init(),p(s);let c=null;if("native"===r.key)try{c=await s.handleTradeDataBuySc(String(i)),y(c)}catch(e){console.error("Error fetching trade data:",e)}o({network:n,token:r.key,tokenSymbol:r.symbol,amount:i||"0",receivingAddress:a,djedContractAddress:e.djedAddress,isDirectTransfer:r.isDirectTransfer||!1,isNativeToken:r.isNative||!1,tradeAmount:c?c.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[n,r,t,o]),!a)return c.createElement("div",{className:x.loading},"Initializing transaction...");const U=()=>{if(!D||!n)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[n]?`${e[n]}${D}`:null};return c.createElement("div",{className:x.transactionReview},c.createElement("div",{className:x.transactionInfo},c.createElement("span",{className:x.transactionLabel},"Network:"),c.createElement("span",{className:x.transactionValue},a.network)),c.createElement("div",{className:x.transactionInfo},c.createElement("span",{className:x.transactionLabel},"You Pay:"),c.createElement("span",{className:x.transactionValue},"stablecoin"===r.key?`${a.amount} ${a.tokenSymbol}`:`${b||"Calculating..."} ${a.tokenSymbol}`)),c.createElement("button",{className:x.walletButton,onClick:async()=>{await i()},disabled:w},w?"Connecting...":"Connect Wallet"),s&&!_&&c.createElement("button",{className:x.walletButton,onClick:async()=>{if(s&&a&&C)try{T(null),B(null),A("⏳ Preparing transaction...");const e=a.receivingAddress;let n;if("native"===r.key){const t="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=f(String(b||"0"));n=await C.buyStablecoins(s,e,r,t),n={...n,value:r,account:s}}else{const r=t.getSelectedNetworkConfig(),o=r?.tokens?.stablecoin?.address;if(!o)throw new Error("Stablecoin address not found in network configuration");const i=a.amount?v(String(a.amount),a.stableCoinDecimals):"0";n={to:o,value:0n,data:E({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:s}}T(n),A("✅ Transaction ready! Click 'Send Transaction' to proceed.")}catch(e){B(e),A("❌ Transaction preparation failed.")}else A("❌ Wallet not connected or transaction details missing")}},"Prepare Transaction"),s&&_&&c.createElement("button",{className:x.walletButton,onClick:async()=>{B(null);try{if(!s||!_)return void A("❌ Wallet account or transaction data is missing");if(!n)return void A("❌ Network not selected");const o=t.getSelectedNetworkConfig();if(!o)return void A("❌ Network configuration not found");A("⏳ Verifying network...");const i=await k();if(!i)return void A("❌ Failed to switch to correct network. Please approve the network switch in MetaMask and try again.");if(!window.ethereum)return void A("❌ MetaMask not available");const c=await window.ethereum.request({method:"eth_chainId"}),l=parseInt(c,16);if(l!==o.chainId){const e=`Network mismatch. MetaMask is on chain ${l}, but ${n} requires chain ${o.chainId}. Please switch networks in MetaMask.`;return A(`❌ ${e}`),void B(new Error(e))}if(i.chain.id!==o.chainId){const e=`Wallet client chain mismatch. Wallet client is on chain ${i.chain.id}, but expected ${o.chainId}.`;return A(`❌ ${e}`),void B(new Error(e))}A("⏳ Sending transaction...");const d=await i.sendTransaction({..._,account:s});P(d),A("✅ Transaction sent!"),e&&e({txHash:d,network:n,token:r?.key,tokenSymbol:r?.symbol,amount:a?.amount,receivingAddress:a?.receivingAddress})}catch(e){B(e),A("❌ Transaction failed."),console.error("Transaction error:",e)}},disabled:null!==D},"Send Transaction"),S&&c.createElement("div",{className:"message-box"},S,I&&c.createElement("button",{onClick:()=>j(!M),className:x.detailsButton},M?"Hide Details":"Show Details")),M&&I&&c.createElement("div",{className:x.errorDetails},c.createElement("pre",null,I.message)),D&&c.createElement("div",{className:x.transactionLink},"✅ Transaction Hash:"," ",U()?c.createElement("a",{href:U(),target:"_blank",rel:"noopener noreferrer",className:x.explorerLink,style:{color:"#007bff",textDecoration:"underline",fontWeight:"bold",cursor:"pointer",wordBreak:"break-word"}},D.slice(0,6),"...",D.slice(-6)):c.createElement("span",{style:{wordBreak:"break-word"}},D)))},q=({onClose:e,buttonSize:t,onTransactionComplete:n})=>{const{resetSelections:r}=$();return c.createElement(P,{onClose:()=>{r(),e()},size:t},c.createElement(j,null),c.createElement(U,null),c.createElement(O,{onTransactionComplete:n}))},H=({onClose:e,buttonSize:t,networkSelector:n,onTransactionComplete:r})=>c.createElement(M,{networkSelector:n},c.createElement(W,null,c.createElement(q,{onClose:e,buttonSize:t,onTransactionComplete:r}))),V={NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(_).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:N,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!_[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:t="medium",onTransactionComplete:n,onSuccess:r})=>{const[a,o]=m(!1),i=n||r;return c.createElement("div",{className:x.widgetContainer},!a&&c.createElement(D,{onClick:()=>{o(!0)},size:t}),a&&c.createElement(H,{onClose:()=>{o(!1)},buttonSize:t,networkSelector:e,onTransactionComplete:i}))},PayButton:D,Dialog:P,NetworkDropdown:j};export{V as default}; +import{getWeb3 as e,getDjedContract as t,getCoinContracts as n,getDecimals as r,getOracleAddress as a,getOracleContract as o,tradeDataPriceBuySc as i,buyScTx as s}from"djed-sdk";import l,{useContext as c,createContext as d,useState as m,useEffect as u,useRef as h,useCallback as w}from"react";import{defineChain as k,createWalletClient as g,custom as C,createPublicClient as p,http as b,parseEther as f,parseUnits as v,encodeFunctionData as E}from"viem";import{sepolia as y}from"viem/chains";const _={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class N{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e(this.networkUri),this.djedContract=t(this.web3,this.djedAddress);try{const{stableCoin:e,reserveCoin:t}=await n(this.djedContract,this.web3),{scDecimals:i,rcDecimals:s}=await r(e,t);this.stableCoin=e,this.reserveCoin=t,this.scDecimals=i,this.rcDecimals=s,this.oracleContract=await a(this.djedContract).then((e=>o(this.web3,e,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){if(console.error("[Transaction] Error fetching contract details:",e),e.message&&e.message.includes("execution reverted")){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){if(console.error("[Transaction] Error initializing transaction:",e),e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(e){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof e)throw new Error("Amount must be a string");try{return(await i(this.djedContract,this.scDecimals,e)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(e,t,n){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await s(this.djedContract,e,t,n,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var T="main_stablePayButton__UA7HC",S="main_logo__ITyEy",A="main_buttonText__N-ewy";const D=({onClick:e,size:t="medium"})=>{const n={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},a=n[t]||n.medium,o=r[t]||r.medium;return l.createElement("button",{className:T,onClick:e,style:a},l.createElement("div",{className:S,style:o}),l.createElement("span",{className:A},"Pay with StablePay"))};var x={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const P=({children:e,onClose:t,size:n="medium"})=>l.createElement("div",{className:x.dialogOverlay},l.createElement("div",{className:`${x.pricingCard} ${x[n]}`},l.createElement("button",{className:x.dialogClose,onClick:t},"×"),l.createElement("div",{className:x.pricingCardHeader},l.createElement("div",{className:x.allianceLogo}),l.createElement("div",{className:x.stablepayTitle},"StablePay")),l.createElement("div",{className:x.pricingCardBody},e)));class I{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const B=d(),M=({children:e,networkSelector:t})=>{const[n]=m((()=>new I(t))),[r,a]=m(null),[o,i]=m(null),[s,c]=m(null),d=()=>{i(null),c(null)};return u((()=>{a(t.selectedNetwork)}),[t.selectedNetwork]),l.createElement(B.Provider,{value:{networkSelector:t,tokenSelector:n,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:c,selectNetwork:e=>!!t.selectNetwork(e)&&(a(e),d(),!0),selectToken:e=>{if(n.selectToken(e)){const e=n.getSelectedToken();return i(e),!0}return!1},resetSelections:()=>{t.selectNetwork(null),a(null),d()}}},e)},$=()=>{const e=c(B);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},j=()=>{const{networkSelector:e,selectedNetwork:t,selectNetwork:n}=$();return l.createElement("div",{className:x.selectField},l.createElement("label",{htmlFor:"network-select"},"Select Network"),l.createElement("select",{id:"network-select",onChange:e=>{n(e.target.value)},value:t||""},l.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>l.createElement("option",{key:e,value:e},e)))))},F=()=>{const{networkSelector:e,tokenSelector:t,selectedNetwork:n,selectedToken:r,selectToken:a,setTransactionDetails:o}=$(),[i,s]=m(!1),[c,d]=m(null),u=n?t.getAvailableTokens():[];return l.createElement("div",{className:x.selectField},l.createElement("label",{htmlFor:"token-select"},"Select Token"),l.createElement("select",{id:"token-select",onChange:async r=>{const i=r.target.value;d(null),s(!0);try{if(a(i)){const r=e.getSelectedNetworkConfig(),a=new N(r.uri,r.djedAddress);await a.init();const s=e.getTokenAmount(i),l=a.getBlockchainDetails();let c=null;"native"===i&&(c=await a.handleTradeDataBuySc(String(s))),o({network:n,token:i,tokenSymbol:t.getSelectedToken().symbol,amount:s,receivingAddress:e.getReceivingAddress(),djedContractAddress:r.djedAddress,isDirectTransfer:t.getSelectedToken().isDirectTransfer||!1,isNativeToken:t.getSelectedToken().isNative||!1,tradeAmount:c?c.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),d("Failed to fetch transaction details. Please try again.")}finally{s(!1)}},value:r?r.key:"",disabled:!n||i},l.createElement("option",{value:"",disabled:!0},n?i?"Loading...":"Select a token":"Please select a network first"),u.map((e=>l.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),c&&l.createElement("div",{className:x.error},c))};k({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const U=k({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),L=k({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),R=d(null),z=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${y.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:y.rpcUrls.default.http,blockExplorerUrls:y.blockExplorers?.default?.url?[y.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${L.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${U.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},W=({children:e})=>{const{selectedNetwork:t}=$(),[n,r]=m(null),[a,o]=m(null),[i,s]=m(null),[c,d]=m(null),[k,f]=m(null),[v,E]=m(null),[_,N]=m(!1),T=t?(e=>{switch(e){case"sepolia":return y;case"ethereum-classic":return L;case"milkomeda-mainnet":return U;default:return null}})(t):null,S=T?T.id:null,A=h(null),D=h(null),x=w((()=>{r(null),o(null),s(null),d(null),f(null),E(null)}),[]),P=w((async e=>{const n=parseInt(e,16);if(d(n),T&&n===S){if(E(null),window.ethereum&&T){const e=g({chain:T,transport:C(window.ethereum)});r(e)}}else if(T&&n!==S){E(`Wrong network detected. Please switch to ${T?.name||t||"selected network"}`)}}),[T,S,t]);D.current=P;const I=w((async e=>{if(0===e.length){if(x(),window.ethereum){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(s(e[0]),T)try{const t=p({chain:T,transport:b()});o(t);const n=await t.getBalance({address:e[0]});f(parseFloat(n)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}}),[T,x]);A.current=I;const B=w((()=>{if(x(),window.ethereum){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[x]),M=w((()=>{T&&o(p({chain:T,transport:b()}))}),[T]),j=w((async()=>{if(!window.ethereum)return E("Please install MetaMask or another Web3 wallet"),!1;if(!t||!T)return E("Please select a network first"),!1;N(!0),E(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const n=await window.ethereum.request({method:"eth_chainId"});parseInt(n,16)!==S&&await z(t);const a=g({chain:T,transport:C(window.ethereum)});r(a),s(e[0]),d(S);const i=p({chain:T,transport:b()});o(i);try{const t=await i.getBalance({address:e[0]});f(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}return A.current=I,D.current=P,window.ethereum.on("accountsChanged",I),window.ethereum.on("chainChanged",P),!0}catch(e){return console.error("Error connecting wallet:",e),E(e.message),!1}finally{N(!1)}}),[t,T,S,I,P]),F=w((async()=>{if(!(window.ethereum&&t&&T&&i)){return E("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==S){E(null),await z(t);const e=500;await new Promise((t=>setTimeout(t,e)));const n=await window.ethereum.request({method:"eth_chainId"}),r=parseInt(n,16);if(r!==S)throw new Error(`Failed to switch network. MetaMask is still on chain ${r}, expected ${S}`)}const n=g({chain:T,transport:C(window.ethereum)});return r(n),d(S),E(null),n}catch(e){return E(e.message),null}}),[t,T,S,i]),W=h(t);return u((()=>{if(null!==W.current&&W.current!==t&&i&&(x(),window.ethereum)){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}W.current=t}),[t,i,x]),u((()=>{M()}),[M]),l.createElement(R.Provider,{value:{walletClient:n,publicClient:a,account:i,chainId:c,balance:k,error:v,isConnecting:_,connectWallet:j,disconnectWallet:B,ensureCorrectNetwork:F,expectedChainId:S}},e)},O=({onTransactionComplete:e})=>{const{networkSelector:t,selectedNetwork:n,selectedToken:r,transactionDetails:a,setTransactionDetails:o}=$(),{connectWallet:i,account:s,walletClient:d,publicClient:h,isConnecting:w,ensureCorrectNetwork:k,expectedChainId:g}=(()=>{const e=c(R);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[C,p]=m(null),[b,y]=m(null),[_,T]=m(null),[S,A]=m(""),[D,P]=m(null),[I,B]=m(null),[M,j]=m(!1);if(u((()=>{T(null),y(null),A(""),B(null),P(null)}),[n,r]),u((()=>{(async()=>{if(n&&r)try{const e=t.getSelectedNetworkConfig(),a=t.getReceivingAddress(),i=t.getTokenAmount(r.key),s=new N(e.uri,e.djedAddress);await s.init(),p(s);let l=null;if("native"===r.key)try{l=await s.handleTradeDataBuySc(String(i)),y(l)}catch(e){console.error("Error fetching trade data:",e)}o({network:n,token:r.key,tokenSymbol:r.symbol,amount:i||"0",receivingAddress:a,djedContractAddress:e.djedAddress,isDirectTransfer:r.isDirectTransfer||!1,isNativeToken:r.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[n,r,t,o]),!n||!r)return null;if(!a)return l.createElement("div",{className:x.loading},"Initializing transaction...");const F=()=>{if(!D||!n)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[n]?`${e[n]}${D}`:null};return l.createElement("div",{className:x.transactionReview},l.createElement("div",{className:x.transactionInfo},l.createElement("span",{className:x.transactionLabel},"Network:"),l.createElement("span",{className:x.transactionValue},a.network)),l.createElement("div",{className:x.transactionInfo},l.createElement("span",{className:x.transactionLabel},"You Pay:"),l.createElement("span",{className:`${x.transactionValue} ${x.highlight}`},"stablecoin"===r.key?`${a.amount} ${a.tokenSymbol}`:`${b||"Calculating..."} ${a.tokenSymbol}`)),S&&l.createElement("div",{className:x.messageBox},S,I&&l.createElement("button",{onClick:()=>j(!M),className:x.detailsButton},M?"Hide Details":"Show Details")),M&&I&&l.createElement("div",{className:x.errorDetails},l.createElement("pre",null,I.message)),D&&l.createElement("div",{className:x.transactionLink},"Transaction Hash:"," ",F()?l.createElement("a",{href:F(),target:"_blank",rel:"noopener noreferrer",className:x.explorerLink},D.slice(0,6),"...",D.slice(-6)):l.createElement("span",{style:{wordBreak:"break-word"}},D)),l.createElement("div",{className:x.walletButtonContainer},!s&&l.createElement("button",{className:x.walletButton,onClick:async()=>{await i()},disabled:w},w?"Connecting...":"Connect Wallet"),s&&!_&&l.createElement("button",{className:x.walletButton,onClick:async()=>{if(s&&a&&C)try{T(null),B(null),A("Preparing transaction...");const e=a.receivingAddress;let n;if("native"===r.key){const t="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=f(String(b||"0"));n=await C.buyStablecoins(s,e,r,t),n={...n,value:r,account:s}}else{const r=t.getSelectedNetworkConfig(),o=r?.tokens?.stablecoin?.address;if(!o)throw new Error("Stablecoin address not found in network configuration");const i=a.amount?v(String(a.amount),a.stableCoinDecimals):"0";n={to:o,value:0n,data:E({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:s}}T(n),A("Transaction ready. Please confirm to proceed.")}catch(e){B(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");A(`Transaction preparation failed: ${t}`)}else A("Wallet not connected or transaction details missing")}},"Prepare Transaction"),s&&_&&l.createElement("button",{className:x.walletButton,onClick:async()=>{B(null);try{if(!s||!_)return void A("Wallet account or transaction data is missing");if(!n)return void A("Network not selected");const o=t.getSelectedNetworkConfig();if(!o)return void A("Network configuration not found");A("Verifying network...");const i=await k();if(!i)return void A("Failed to switch to correct network. Please approve the network switch in MetaMask and try again.");if(!window.ethereum)return void A("MetaMask not available");const l=await window.ethereum.request({method:"eth_chainId"}),c=parseInt(l,16);if(c!==o.chainId){const e=`Network mismatch. MetaMask is on chain ${c}, but ${n} requires chain ${o.chainId}. Please switch networks in MetaMask.`;return A(e),void B(new Error(e))}if(i.chain.id!==o.chainId){const e=`Wallet client chain mismatch. Wallet client is on chain ${i.chain.id}, but expected ${o.chainId}.`;return A(e),void B(new Error(e))}A("Sending transaction...");const d=await i.sendTransaction({..._,account:s});P(d),A("Transaction sent!"),e&&e({txHash:d,network:n,token:r?.key,tokenSymbol:r?.symbol,amount:a?.amount,receivingAddress:a?.receivingAddress})}catch(e){B(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");A(`Transaction failed: ${t}`),console.error("Transaction error:",e)}},disabled:null!==D},"Send Transaction")))},q=({onClose:e,buttonSize:t,onTransactionComplete:n})=>{const{resetSelections:r}=$();return l.createElement(P,{onClose:()=>{r(),e()},size:t},l.createElement(j,null),l.createElement(F,null),l.createElement(O,{onTransactionComplete:n}))},H=({onClose:e,buttonSize:t,networkSelector:n,onTransactionComplete:r})=>l.createElement(M,{networkSelector:n},l.createElement(W,null,l.createElement(q,{onClose:e,buttonSize:t,onTransactionComplete:r}))),V={NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(_).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:N,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!_[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:t="medium",onTransactionComplete:n,onSuccess:r})=>{const[a,o]=m(!1),i=n||r;return l.createElement("div",{className:x.widgetContainer},!a&&l.createElement(D,{onClick:()=>{o(!0)},size:t}),a&&l.createElement(H,{onClose:()=>{o(!1)},buttonSize:t,networkSelector:e,onTransactionComplete:i}))},PayButton:D,Dialog:P,NetworkDropdown:j};export{V as default}; diff --git a/stablepay-sdk/dist/esm/styles.css b/stablepay-sdk/dist/esm/styles.css index a6df6b0..24e94a1 100644 --- a/stablepay-sdk/dist/esm/styles.css +++ b/stablepay-sdk/dist/esm/styles.css @@ -1 +1 @@ -.main_stablePayButton__UA7HC{align-items:center;background:linear-gradient(90deg,#000,#f7941d);border:1px solid #bc5f26;border-radius:3px;box-sizing:border-box;color:#fff;cursor:pointer;display:flex;font-size:24px;font-weight:700;height:104px;justify-content:flex-start;overflow:hidden;padding:0 20px;position:relative;width:372px}.main_stablePayButton__UA7HC:hover{opacity:.9}.main_stablePayButton__UA7HC .main_logo__ITyEy{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;flex-shrink:0;height:25px;margin-right:20px;width:25px}.main_stablePayButton__UA7HC .main_buttonText__N-ewy{flex-grow:1;text-align:center}.PricingCard_dialogOverlay__0XJrE{align-items:center;backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px);background-color:hsla(0,0%,100%,.1);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:1000}.PricingCard_pricingCard__LrWb9{align-items:center;background:#2c2c2c;border:1px solid hsla(0,0%,85%,.1);border-radius:8px;box-sizing:border-box;display:flex;flex-direction:column;padding:24px;position:relative}.PricingCard_pricingCard__LrWb9.PricingCard_small__J4CHj{height:600px;width:360px}.PricingCard_pricingCard__LrWb9.PricingCard_medium__EVmTB{height:680px;width:400px}.PricingCard_pricingCard__LrWb9.PricingCard_large__A6pnX{height:760px;width:440px}.PricingCard_dialogClose__jJ1tM{background:none;border:none;color:#fff;cursor:pointer;font-size:20px;position:absolute;right:16px;top:16px;z-index:5}.PricingCard_pricingCardHeader__wGczA{align-items:center;display:flex;gap:12px;margin-bottom:40px;width:100%}.PricingCard_allianceLogo__URa-U{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:55px;width:55px}.PricingCard_stablepayTitle__4t848{align-items:center;color:#f6941c;display:flex;font-family:Inter,sans-serif;font-size:29.2px;font-style:normal;font-weight:600;line-height:35px}.PricingCard_pricingCardBody__0wKQn{display:flex;flex-direction:column;gap:30px;width:100%}.PricingCard_selectField__LBPoZ{align-items:flex-start;display:flex;flex-direction:column;gap:8px;margin-bottom:30px;width:100%}.PricingCard_selectField__LBPoZ label{align-self:flex-start;color:#636a77;margin-bottom:6px;text-align:left}.PricingCard_selectField__LBPoZ label,.PricingCard_selectField__LBPoZ select{font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:500;line-height:19px;width:100%}.PricingCard_selectField__LBPoZ select{appearance:none;background:#fff;background-image:url(../assets/chevron-down-icon.svg);background-position:right 18px center;background-repeat:no-repeat;border:1px solid #d9d9d9;border-radius:6px;box-sizing:border-box;color:#000;height:49px;padding:10px 14px}.PricingCard_selectField__LBPoZ select:disabled{background-color:#f5f5f5;cursor:not-allowed}.PricingCard_transactionReview__Ix-eL{padding:20px 0;width:100%}.PricingCard_transactionInfo__Ck-Rc{align-items:center;display:flex;justify-content:space-between;margin:15px 0;padding:0 5px;width:100%}.PricingCard_transactionLabel__GDux7{color:#636a77;font-weight:500}.PricingCard_transactionLabel__GDux7,.PricingCard_transactionValue__q-xxp{font-family:Inter,sans-serif;font-size:16px;font-style:normal;line-height:19px}.PricingCard_transactionValue__q-xxp{color:#fff;font-weight:600;text-align:right}.PricingCard_infoSection__gyjMQ{align-items:flex-start;display:flex;gap:16px;margin-bottom:40px;margin-top:20px;padding:0 26px}.PricingCard_infoIcon__rraxD{align-items:center;background:#d5d6d9;border-radius:50%;color:#434a58;display:flex;font-size:13px;height:21px;justify-content:center;min-width:22px;width:22px}.PricingCard_infoText__l4b7A{color:#636a77;font-family:Inter,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:17px}.PricingCard_walletButton__llw4v{align-items:center;background:#f6941c;border:1px solid #c66c20;border-radius:0;bottom:31px;color:#fde5cb;cursor:pointer;display:flex;font-family:Inter,sans-serif;font-size:18px;font-style:normal;font-weight:600;height:65px;justify-content:center;left:30px;line-height:22px;position:absolute;width:calc(100% - 60px)}.PricingCard_walletButton__llw4v:disabled{background:#ccc;border-color:#bbb;cursor:not-allowed}.PricingCard_loading__2-tGA{color:#636a77;font-family:Inter,sans-serif;padding:20px;text-align:center}.PricingCard_error__m5fK-{color:#ff4d4f;font-family:Inter,sans-serif;padding:10px;text-align:center}.PricingCard_networkError__zR-36{background:rgba(255,77,79,.1);border:1px solid rgba(255,77,79,.2);border-radius:4px;margin:10px 0;padding:10px}.PricingCard_errorText__qZRJt{color:#ff4d4f;font-family:Inter,sans-serif;font-size:14px;line-height:1.5}.PricingCard_message-box__vkUKy{align-items:center;background-color:hsla(0,0%,100%,.1);border-radius:4px;color:#fff;display:flex;font-family:Inter,sans-serif;font-size:14px;justify-content:space-between;margin-top:20px;padding:10px}.PricingCard_detailsButton__jHglL{background:none;border:none;color:#f6941c;cursor:pointer;font-size:12px;margin-left:10px;text-decoration:underline}.PricingCard_errorDetails__CzN-7{background-color:rgba(0,0,0,.2);border:1px solid rgba(255,77,79,.3);border-radius:4px;color:#ff4d4f;font-family:monospace;font-size:12px;line-height:1.4;margin-top:10px;max-height:150px;max-width:100%;overflow:auto;overflow-wrap:break-word;padding:10px;white-space:pre-wrap;word-break:break-word}.PricingCard_errorDetails__CzN-7::-webkit-scrollbar{height:6px;width:6px}.PricingCard_errorDetails__CzN-7::-webkit-scrollbar-track{background:rgba(0,0,0,.1);border-radius:3px}.PricingCard_errorDetails__CzN-7::-webkit-scrollbar-thumb{background:rgba(255,77,79,.5);border-radius:3px}.PricingCard_errorDetails__CzN-7::-webkit-scrollbar-thumb:hover{background:rgba(255,77,79,.7)}@media (max-width:520px){.PricingCard_pricingCard__LrWb9{height:auto;min-height:600px;padding:20px;width:95vw}.PricingCard_selectField__LBPoZ{margin-bottom:20px}.PricingCard_walletButton__llw4v{left:20px;margin-top:20px;position:relative;width:calc(100% - 40px)}.PricingCard_infoSection__gyjMQ{padding:0 20px}.PricingCard_loadingContainer__6nOVa{align-items:center;display:flex;height:100vh;justify-content:center}.PricingCard_spinner__9ucQv{animation:PricingCard_spin__24tni .8s linear infinite;border:4px solid hsla(0,0%,100%,.3);border-radius:50%;border-top-color:#fff;height:40px;width:40px}@keyframes PricingCard_spin__24tni{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}} \ No newline at end of file +.main_stablePayButton__UA7HC{align-items:center;background:linear-gradient(90deg,#000,#f7941d);border:1px solid #bc5f26;border-radius:3px;box-sizing:border-box;color:#fff;cursor:pointer;display:flex;font-size:24px;font-weight:700;height:104px;justify-content:flex-start;overflow:hidden;padding:0 20px;position:relative;width:372px}.main_stablePayButton__UA7HC:hover{opacity:.9}.main_stablePayButton__UA7HC .main_logo__ITyEy{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;flex-shrink:0;height:25px;margin-right:20px;width:25px}.main_stablePayButton__UA7HC .main_buttonText__N-ewy{flex-grow:1;text-align:center}@keyframes PricingCard_fadeInScale__2MTi3{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.PricingCard_dialogOverlay__0XJrE{align-items:center;animation:PricingCard_fadeInScale__2MTi3 .2s ease-out;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background-color:rgba(0,0,0,.4);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:1000}.PricingCard_pricingCard__LrWb9{background:#242529;border:1px solid hsla(0,0%,100%,.08);border-radius:20px;box-shadow:0 15px 35px rgba(0,0,0,.4),inset 0 1px 0 hsla(0,0%,100%,.05);box-sizing:border-box;display:flex;flex-direction:column;padding:32px;position:relative}.PricingCard_pricingCard__LrWb9.PricingCard_small__J4CHj{min-height:520px;width:360px}.PricingCard_pricingCard__LrWb9.PricingCard_medium__EVmTB{min-height:580px;width:400px}.PricingCard_pricingCard__LrWb9.PricingCard_large__A6pnX{min-height:640px;width:440px}.PricingCard_dialogClose__jJ1tM{align-items:center;background:hsla(0,0%,100%,.1);border:none;border-radius:50%;color:#a0aec0;cursor:pointer;display:flex;font-size:20px;height:32px;justify-content:center;line-height:1;padding:0 0 3px;position:absolute;right:20px;top:20px;transition:all .2s ease;width:32px;z-index:5}.PricingCard_dialogClose__jJ1tM:hover{background:hsla(0,0%,100%,.2);color:#fff}.PricingCard_pricingCardHeader__wGczA{align-items:center;border-bottom:1px solid hsla(0,0%,100%,.05);display:flex;gap:16px;margin-bottom:30px;padding-bottom:20px;width:100%}.PricingCard_allianceLogo__URa-U{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:48px;width:48px}.PricingCard_stablepayTitle__4t848{align-items:center;color:#f6941c;display:flex;font-family:Inter,sans-serif;font-size:26px;font-style:normal;font-weight:700;letter-spacing:-.5px}.PricingCard_pricingCardBody__0wKQn{display:flex;flex:1;flex-direction:column;width:100%}.PricingCard_selectField__LBPoZ{display:flex;flex-direction:column;gap:10px;margin-bottom:24px;width:100%}.PricingCard_selectField__LBPoZ label{align-self:flex-start;color:#a0aec0;font-family:Inter,sans-serif;font-size:14px;font-style:normal;font-weight:500;text-align:left;width:100%}.PricingCard_selectField__LBPoZ select{appearance:none;background:hsla(0,0%,100%,.05);background-image:url(../assets/chevron-down-icon.svg);background-position:right 18px center;background-repeat:no-repeat;border:1px solid hsla(0,0%,100%,.1);border-radius:12px;box-sizing:border-box;color:#fff;cursor:pointer;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:500;height:52px;padding:12px 16px;transition:all .2s ease;width:100%}.PricingCard_selectField__LBPoZ select:hover:not(:disabled){background:hsla(0,0%,100%,.08);border-color:rgba(246,148,28,.5)}.PricingCard_selectField__LBPoZ select:focus{border-color:#f6941c;box-shadow:0 0 0 3px rgba(246,148,28,.2);outline:none}.PricingCard_selectField__LBPoZ select:disabled{cursor:not-allowed;opacity:.5}.PricingCard_selectField__LBPoZ select option{background:#242529;color:#fff}.PricingCard_transactionReview__Ix-eL{display:flex;flex:1;flex-direction:column;padding-top:10px;width:100%}.PricingCard_transactionInfo__Ck-Rc{align-items:center;background:rgba(0,0,0,.2);border:1px solid hsla(0,0%,100%,.05);border-radius:12px;display:flex;justify-content:space-between;margin-bottom:16px;padding:14px 18px;width:100%}.PricingCard_transactionLabel__GDux7{color:#a0aec0;font-family:Inter,sans-serif;font-size:15px;font-style:normal;font-weight:500}.PricingCard_transactionValue__q-xxp{color:#fff;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:700;text-align:right}.PricingCard_transactionValue__q-xxp.PricingCard_highlight__WZZ6N{color:#f6941c;font-size:18px}.PricingCard_walletButtonContainer__a6MwB{margin-top:auto;padding-top:24px}.PricingCard_walletButton__llw4v{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:14px;box-shadow:0 4px 14px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;font-family:Inter,sans-serif;font-size:17px;font-style:normal;font-weight:600;height:56px;justify-content:center;transition:all .2s ease;width:100%}.PricingCard_walletButton__llw4v:hover:not(:disabled){box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_walletButton__llw4v:active:not(:disabled){transform:translateY(0)}.PricingCard_walletButton__llw4v:disabled{background:hsla(0,0%,100%,.1);box-shadow:none;color:#636a77;cursor:not-allowed}.PricingCard_loading__2-tGA{align-items:center;color:#a0aec0;display:flex;flex-direction:column;font-family:Inter,sans-serif;gap:16px;padding:40px;text-align:center}.PricingCard_error__m5fK-{color:#ff4d4f;font-family:Inter,sans-serif;font-size:14px;margin-top:4px;text-align:left}.PricingCard_messageBox__wnx0F{align-items:center;animation:PricingCard_fadeIn__L63q8 .3s ease-out;color:#e2e8f0;display:flex;flex-direction:column;font-family:Inter,sans-serif;font-size:13.5px;font-weight:500;gap:8px;margin-bottom:16px;padding:8px 0;text-align:center}@keyframes PricingCard_fadeIn__L63q8{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.PricingCard_detailsButton__jHglL{background:none;border:none;color:#f6941c;cursor:pointer;font-size:13px;font-weight:600;margin-top:4px;padding:0;text-decoration:none}.PricingCard_detailsButton__jHglL:hover{text-decoration:underline}.PricingCard_errorDetails__CzN-7{background-color:rgba(0,0,0,.2);border-left:3px solid #ff4d4f;border-radius:8px;color:#fc8181;font-family:monospace;font-size:11px;line-height:1.5;margin-top:10px;max-height:150px;overflow-y:auto;padding:12px;text-align:left;white-space:pre-wrap;word-break:break-all}.PricingCard_transactionLink__RFRWW{background:rgba(40,167,69,.1);border:1px solid rgba(40,167,69,.2);border-radius:12px;color:#fff;font-family:Inter,sans-serif;font-size:14px;margin-top:20px;padding:16px;text-align:center}.PricingCard_explorerLink__-a82-{color:#f6941c;font-weight:600;text-decoration:none;transition:color .2s ease}.PricingCard_explorerLink__-a82-:hover{color:#ffad42;text-decoration:underline}.PricingCard_stablePayButton__Y4Rr4{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:16px;box-shadow:0 4px 15px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;gap:12px;justify-content:center;transition:all .2s ease}.PricingCard_stablePayButton__Y4Rr4:hover{box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_stablePayButton__Y4Rr4:active{transform:translateY(0)}.PricingCard_buttonText__8LnPv{font-family:Inter,sans-serif;font-weight:600}@media (max-width:520px){.PricingCard_pricingCard__LrWb9{border:none;border-radius:0;height:100%;min-height:100vh;padding:24px;width:100%}.PricingCard_dialogOverlay__0XJrE{align-items:flex-start;background-color:#242529}} \ No newline at end of file diff --git a/stablepay-sdk/dist/umd/index.js b/stablepay-sdk/dist/umd/index.js index f5a6876..04b91d0 100644 --- a/stablepay-sdk/dist/umd/index.js +++ b/stablepay-sdk/dist/umd/index.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("djed-sdk"),require("react"),require("viem"),require("viem/chains")):"function"==typeof define&&define.amd?define(["djed-sdk","react","viem","viem/chains"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).StablePay=t(e.DjedSdk,e.React,e.viem,e.viemChains)}(this,(function(e,t,n,r){"use strict";const a={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class i{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e.getWeb3(this.networkUri),this.djedContract=e.getDjedContract(this.web3,this.djedAddress);try{const{stableCoin:t,reserveCoin:n}=await e.getCoinContracts(this.djedContract,this.web3),{scDecimals:r,rcDecimals:a}=await e.getDecimals(t,n);this.stableCoin=t,this.reserveCoin=n,this.scDecimals=r,this.rcDecimals=a,this.oracleContract=await e.getOracleAddress(this.djedContract).then((t=>e.getOracleContract(this.web3,t,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){if(console.error("[Transaction] Error fetching contract details:",e),e.message&&e.message.includes("execution reverted")){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){if(console.error("[Transaction] Error initializing transaction:",e),e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(t){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof t)throw new Error("Amount must be a string");try{return(await e.tradeDataPriceBuySc(this.djedContract,this.scDecimals,t)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(t,n,r){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const a="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await e.buyScTx(this.djedContract,t,n,r,a,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var o="main_stablePayButton__UA7HC",s="main_logo__ITyEy",c="main_buttonText__N-ewy";const l=({onClick:e,size:n="medium"})=>{const r={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},a={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},i=r[n]||r.medium,l=a[n]||a.medium;return t.createElement("button",{className:o,onClick:e,style:i},t.createElement("div",{className:s,style:l}),t.createElement("span",{className:c},"Pay with StablePay"))};var d={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",infoSection:"PricingCard_infoSection__gyjMQ",infoIcon:"PricingCard_infoIcon__rraxD",infoText:"PricingCard_infoText__l4b7A",walletButton:"PricingCard_walletButton__llw4v",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",networkError:"PricingCard_networkError__zR-36",errorText:"PricingCard_errorText__qZRJt","message-box":"PricingCard_message-box__vkUKy",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",loadingContainer:"PricingCard_loadingContainer__6nOVa",spinner:"PricingCard_spinner__9ucQv",spin:"PricingCard_spin__24tni"};const u=({children:e,onClose:n,size:r="medium"})=>t.createElement("div",{className:d.dialogOverlay},t.createElement("div",{className:`${d.pricingCard} ${d[r]}`},t.createElement("button",{className:d.dialogClose,onClick:n},"×"),t.createElement("div",{className:d.pricingCardHeader},t.createElement("div",{className:d.allianceLogo}),t.createElement("h2",{className:d.stablepayTitle},"StablePay")),t.createElement("div",{className:d.pricingCardBody},e)));class m{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const h=t.createContext(),w=({children:e,networkSelector:n})=>{const[r]=t.useState((()=>new m(n))),[a,i]=t.useState(null),[o,s]=t.useState(null),[c,l]=t.useState(null),d=()=>{s(null),l(null)};return t.useEffect((()=>{i(n.selectedNetwork)}),[n.selectedNetwork]),t.createElement(h.Provider,{value:{networkSelector:n,tokenSelector:r,selectedNetwork:a,selectedToken:o,transactionDetails:c,setTransactionDetails:l,selectNetwork:e=>!!n.selectNetwork(e)&&(i(e),d(),!0),selectToken:e=>{if(r.selectToken(e)){const e=r.getSelectedToken();return s(e),!0}return!1},resetSelections:()=>{n.selectNetwork(null),i(null),d()}}},e)},k=()=>{const e=t.useContext(h);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},g=()=>{const{networkSelector:e,selectedNetwork:n,selectNetwork:r}=k();return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"network-select"},"Select Network"),t.createElement("select",{id:"network-select",onChange:e=>{r(e.target.value)},value:n||""},t.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>t.createElement("option",{key:e,value:e},e)))))},C=()=>{const{networkSelector:e,tokenSelector:n,selectedNetwork:r,selectedToken:a,selectToken:o,setTransactionDetails:s}=k(),[c,l]=t.useState(!1),[u,m]=t.useState(null),h=r?n.getAvailableTokens():[];return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"token-select"},"Select Token"),t.createElement("select",{id:"token-select",onChange:async t=>{const a=t.target.value;m(null),l(!0);try{if(o(a)){const t=e.getSelectedNetworkConfig(),o=new i(t.uri,t.djedAddress);await o.init();const c=e.getTokenAmount(a),l=o.getBlockchainDetails();let d=null;"native"===a&&(d=await o.handleTradeDataBuySc(String(c))),s({network:r,token:a,tokenSymbol:n.getSelectedToken().symbol,amount:c,receivingAddress:e.getReceivingAddress(),djedContractAddress:t.djedAddress,isDirectTransfer:n.getSelectedToken().isDirectTransfer||!1,isNativeToken:n.getSelectedToken().isNative||!1,tradeAmount:d?d.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),m("Failed to fetch transaction details. Please try again.")}finally{l(!1)}},value:a?a.key:"",disabled:!r||c},t.createElement("option",{value:"",disabled:!0},r?c?"Loading...":"Select a token":"Please select a network first"),h.map((e=>t.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),u&&t.createElement("div",{className:d.error},u))};n.defineChain({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const b=n.defineChain({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),p=n.defineChain({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),f=t.createContext(null),v=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${r.sepolia.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:r.sepolia.rpcUrls.default.http,blockExplorerUrls:r.sepolia.blockExplorers?.default?.url?[r.sepolia.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${p.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${b.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},y=({children:e})=>{const{selectedNetwork:a}=k(),[i,o]=t.useState(null),[s,c]=t.useState(null),[l,d]=t.useState(null),[u,m]=t.useState(null),[h,w]=t.useState(null),[g,C]=t.useState(null),[y,E]=t.useState(!1),_=a?(e=>{switch(e){case"sepolia":return r.sepolia;case"ethereum-classic":return p;case"milkomeda-mainnet":return b;default:return null}})(a):null,S=_?_.id:null,N=t.useRef(null),T=t.useRef(null),A=t.useCallback((()=>{o(null),c(null),d(null),m(null),w(null),C(null)}),[]),D=t.useCallback((async e=>{const t=parseInt(e,16);if(m(t),_&&t===S){if(C(null),window.ethereum&&_){const e=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});o(e)}}else if(_&&t!==S){C(`Wrong network detected. Please switch to ${_?.name||a||"selected network"}`)}}),[_,S,a]);T.current=D;const x=t.useCallback((async e=>{if(0===e.length){if(A(),window.ethereum){const e=N.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(d(e[0]),_)try{const t=n.createPublicClient({chain:_,transport:n.http()});c(t);const r=await t.getBalance({address:e[0]});w(parseFloat(r)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}}),[_,A]);N.current=x;const P=t.useCallback((()=>{if(A(),window.ethereum){const e=N.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[A]),I=t.useCallback((()=>{_&&c(n.createPublicClient({chain:_,transport:n.http()}))}),[_]),j=t.useCallback((async()=>{if(!window.ethereum)return C("Please install MetaMask or another Web3 wallet"),!1;if(!a||!_)return C("Please select a network first"),!1;E(!0),C(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const t=await window.ethereum.request({method:"eth_chainId"});parseInt(t,16)!==S&&await v(a);const r=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});o(r),d(e[0]),m(S);const i=n.createPublicClient({chain:_,transport:n.http()});c(i);try{const t=await i.getBalance({address:e[0]});w(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}return N.current=x,T.current=D,window.ethereum.on("accountsChanged",x),window.ethereum.on("chainChanged",D),!0}catch(e){return console.error("Error connecting wallet:",e),C(e.message),!1}finally{E(!1)}}),[a,_,S,x,D]),B=t.useCallback((async()=>{if(!(window.ethereum&&a&&_&&l)){return C("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==S){C(null),await v(a);const e=500;await new Promise((t=>setTimeout(t,e)));const t=await window.ethereum.request({method:"eth_chainId"}),n=parseInt(t,16);if(n!==S)throw new Error(`Failed to switch network. MetaMask is still on chain ${n}, expected ${S}`)}const t=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});return o(t),m(S),C(null),t}catch(e){return C(e.message),null}}),[a,_,S,l]),M=t.useRef(a);return t.useEffect((()=>{if(null!==M.current&&M.current!==a&&l&&(A(),window.ethereum)){const e=N.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}M.current=a}),[a,l,A]),t.useEffect((()=>{I()}),[I]),t.createElement(f.Provider,{value:{walletClient:i,publicClient:s,account:l,chainId:u,balance:h,error:g,isConnecting:y,connectWallet:j,disconnectWallet:P,ensureCorrectNetwork:B,expectedChainId:S}},e)},E=({onTransactionComplete:e})=>{const{networkSelector:r,selectedNetwork:a,selectedToken:o,transactionDetails:s,setTransactionDetails:c}=k(),{connectWallet:l,account:u,walletClient:m,publicClient:h,isConnecting:w,ensureCorrectNetwork:g,expectedChainId:C}=(()=>{const e=t.useContext(f);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[b,p]=t.useState(null),[v,y]=t.useState(null),[E,_]=t.useState(null),[S,N]=t.useState(""),[T,A]=t.useState(null),[D,x]=t.useState(null),[P,I]=t.useState(!1);if(t.useEffect((()=>{_(null),y(null),N(""),x(null),A(null)}),[a,o]),t.useEffect((()=>{(async()=>{if(a&&o)try{const e=r.getSelectedNetworkConfig(),t=r.getReceivingAddress(),n=r.getTokenAmount(o.key),s=new i(e.uri,e.djedAddress);await s.init(),p(s);let l=null;if("native"===o.key)try{l=await s.handleTradeDataBuySc(String(n)),y(l)}catch(e){console.error("Error fetching trade data:",e)}c({network:a,token:o.key,tokenSymbol:o.symbol,amount:n||"0",receivingAddress:t,djedContractAddress:e.djedAddress,isDirectTransfer:o.isDirectTransfer||!1,isNativeToken:o.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[a,o,r,c]),!s)return t.createElement("div",{className:d.loading},"Initializing transaction...");const j=()=>{if(!T||!a)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[a]?`${e[a]}${T}`:null};return t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"Network:"),t.createElement("span",{className:d.transactionValue},s.network)),t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"You Pay:"),t.createElement("span",{className:d.transactionValue},"stablecoin"===o.key?`${s.amount} ${s.tokenSymbol}`:`${v||"Calculating..."} ${s.tokenSymbol}`)),t.createElement("button",{className:d.walletButton,onClick:async()=>{await l()},disabled:w},w?"Connecting...":"Connect Wallet"),u&&!E&&t.createElement("button",{className:d.walletButton,onClick:async()=>{if(u&&s&&b)try{_(null),x(null),N("⏳ Preparing transaction...");const e=s.receivingAddress;let t;if("native"===o.key){const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",a=v||"0",i=n.parseEther(String(a));t=await b.buyStablecoins(u,e,i,r),t={...t,value:i,account:u}}else{const a=r.getSelectedNetworkConfig(),i=a?.tokens?.stablecoin?.address;if(!i)throw new Error("Stablecoin address not found in network configuration");const o=s.amount?n.parseUnits(String(s.amount),s.stableCoinDecimals):"0";t={to:i,value:0n,data:n.encodeFunctionData({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,o]}),account:u}}_(t),N("✅ Transaction ready! Click 'Send Transaction' to proceed.")}catch(e){x(e),N("❌ Transaction preparation failed.")}else N("❌ Wallet not connected or transaction details missing")}},"Prepare Transaction"),u&&E&&t.createElement("button",{className:d.walletButton,onClick:async()=>{x(null);try{if(!u||!E)return void N("❌ Wallet account or transaction data is missing");if(!a)return void N("❌ Network not selected");const t=r.getSelectedNetworkConfig();if(!t)return void N("❌ Network configuration not found");N("⏳ Verifying network...");const n=await g();if(!n)return void N("❌ Failed to switch to correct network. Please approve the network switch in MetaMask and try again.");if(!window.ethereum)return void N("❌ MetaMask not available");const i=await window.ethereum.request({method:"eth_chainId"}),c=parseInt(i,16);if(c!==t.chainId){const e=`Network mismatch. MetaMask is on chain ${c}, but ${a} requires chain ${t.chainId}. Please switch networks in MetaMask.`;return N(`❌ ${e}`),void x(new Error(e))}if(n.chain.id!==t.chainId){const e=`Wallet client chain mismatch. Wallet client is on chain ${n.chain.id}, but expected ${t.chainId}.`;return N(`❌ ${e}`),void x(new Error(e))}N("⏳ Sending transaction...");const l=await n.sendTransaction({...E,account:u});A(l),N("✅ Transaction sent!"),e&&e({txHash:l,network:a,token:o?.key,tokenSymbol:o?.symbol,amount:s?.amount,receivingAddress:s?.receivingAddress})}catch(e){x(e),N("❌ Transaction failed."),console.error("Transaction error:",e)}},disabled:null!==T},"Send Transaction"),S&&t.createElement("div",{className:"message-box"},S,D&&t.createElement("button",{onClick:()=>I(!P),className:d.detailsButton},P?"Hide Details":"Show Details")),P&&D&&t.createElement("div",{className:d.errorDetails},t.createElement("pre",null,D.message)),T&&t.createElement("div",{className:d.transactionLink},"✅ Transaction Hash:"," ",j()?t.createElement("a",{href:j(),target:"_blank",rel:"noopener noreferrer",className:d.explorerLink,style:{color:"#007bff",textDecoration:"underline",fontWeight:"bold",cursor:"pointer",wordBreak:"break-word"}},T.slice(0,6),"...",T.slice(-6)):t.createElement("span",{style:{wordBreak:"break-word"}},T)))},_=({onClose:e,buttonSize:n,onTransactionComplete:r})=>{const{resetSelections:a}=k();return t.createElement(u,{onClose:()=>{a(),e()},size:n},t.createElement(g,null),t.createElement(C,null),t.createElement(E,{onTransactionComplete:r}))},S=({onClose:e,buttonSize:n,networkSelector:r,onTransactionComplete:a})=>t.createElement(w,{networkSelector:r},t.createElement(y,null,t.createElement(_,{onClose:e,buttonSize:n,onTransactionComplete:a})));return{NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(a).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:i,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!a[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:n="medium",onTransactionComplete:r,onSuccess:a})=>{const[i,o]=t.useState(!1),s=r||a;return t.createElement("div",{className:d.widgetContainer},!i&&t.createElement(l,{onClick:()=>{o(!0)},size:n}),i&&t.createElement(S,{onClose:()=>{o(!1)},buttonSize:n,networkSelector:e,onTransactionComplete:s}))},PayButton:l,Dialog:u,NetworkDropdown:g}})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("djed-sdk"),require("react"),require("viem"),require("viem/chains")):"function"==typeof define&&define.amd?define(["djed-sdk","react","viem","viem/chains"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).StablePay=t(e.DjedSdk,e.React,e.viem,e.viemChains)}(this,(function(e,t,n,a){"use strict";const r={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class i{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e.getWeb3(this.networkUri),this.djedContract=e.getDjedContract(this.web3,this.djedAddress);try{const{stableCoin:t,reserveCoin:n}=await e.getCoinContracts(this.djedContract,this.web3),{scDecimals:a,rcDecimals:r}=await e.getDecimals(t,n);this.stableCoin=t,this.reserveCoin=n,this.scDecimals=a,this.rcDecimals=r,this.oracleContract=await e.getOracleAddress(this.djedContract).then((t=>e.getOracleContract(this.web3,t,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){if(console.error("[Transaction] Error fetching contract details:",e),e.message&&e.message.includes("execution reverted")){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){if(console.error("[Transaction] Error initializing transaction:",e),e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(t){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof t)throw new Error("Amount must be a string");try{return(await e.tradeDataPriceBuySc(this.djedContract,this.scDecimals,t)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(t,n,a){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await e.buyScTx(this.djedContract,t,n,a,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var o="main_stablePayButton__UA7HC",s="main_logo__ITyEy",l="main_buttonText__N-ewy";const c=({onClick:e,size:n="medium"})=>{const a={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},i=a[n]||a.medium,c=r[n]||r.medium;return t.createElement("button",{className:o,onClick:e,style:i},t.createElement("div",{className:s,style:c}),t.createElement("span",{className:l},"Pay with StablePay"))};var d={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const u=({children:e,onClose:n,size:a="medium"})=>t.createElement("div",{className:d.dialogOverlay},t.createElement("div",{className:`${d.pricingCard} ${d[a]}`},t.createElement("button",{className:d.dialogClose,onClick:n},"×"),t.createElement("div",{className:d.pricingCardHeader},t.createElement("div",{className:d.allianceLogo}),t.createElement("div",{className:d.stablepayTitle},"StablePay")),t.createElement("div",{className:d.pricingCardBody},e)));class m{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const h=t.createContext(),w=({children:e,networkSelector:n})=>{const[a]=t.useState((()=>new m(n))),[r,i]=t.useState(null),[o,s]=t.useState(null),[l,c]=t.useState(null),d=()=>{s(null),c(null)};return t.useEffect((()=>{i(n.selectedNetwork)}),[n.selectedNetwork]),t.createElement(h.Provider,{value:{networkSelector:n,tokenSelector:a,selectedNetwork:r,selectedToken:o,transactionDetails:l,setTransactionDetails:c,selectNetwork:e=>!!n.selectNetwork(e)&&(i(e),d(),!0),selectToken:e=>{if(a.selectToken(e)){const e=a.getSelectedToken();return s(e),!0}return!1},resetSelections:()=>{n.selectNetwork(null),i(null),d()}}},e)},k=()=>{const e=t.useContext(h);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},g=()=>{const{networkSelector:e,selectedNetwork:n,selectNetwork:a}=k();return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"network-select"},"Select Network"),t.createElement("select",{id:"network-select",onChange:e=>{a(e.target.value)},value:n||""},t.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>t.createElement("option",{key:e,value:e},e)))))},C=()=>{const{networkSelector:e,tokenSelector:n,selectedNetwork:a,selectedToken:r,selectToken:o,setTransactionDetails:s}=k(),[l,c]=t.useState(!1),[u,m]=t.useState(null),h=a?n.getAvailableTokens():[];return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"token-select"},"Select Token"),t.createElement("select",{id:"token-select",onChange:async t=>{const r=t.target.value;m(null),c(!0);try{if(o(r)){const t=e.getSelectedNetworkConfig(),o=new i(t.uri,t.djedAddress);await o.init();const l=e.getTokenAmount(r),c=o.getBlockchainDetails();let d=null;"native"===r&&(d=await o.handleTradeDataBuySc(String(l))),s({network:a,token:r,tokenSymbol:n.getSelectedToken().symbol,amount:l,receivingAddress:e.getReceivingAddress(),djedContractAddress:t.djedAddress,isDirectTransfer:n.getSelectedToken().isDirectTransfer||!1,isNativeToken:n.getSelectedToken().isNative||!1,tradeAmount:d?d.amount:null,...c})}}catch(e){console.error("Error fetching transaction details:",e),m("Failed to fetch transaction details. Please try again.")}finally{c(!1)}},value:r?r.key:"",disabled:!a||l},t.createElement("option",{value:"",disabled:!0},a?l?"Loading...":"Select a token":"Please select a network first"),h.map((e=>t.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),u&&t.createElement("div",{className:d.error},u))};n.defineChain({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const p=n.defineChain({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),b=n.defineChain({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),f=t.createContext(null),v=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${a.sepolia.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:a.sepolia.rpcUrls.default.http,blockExplorerUrls:a.sepolia.blockExplorers?.default?.url?[a.sepolia.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${b.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${p.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},y=({children:e})=>{const{selectedNetwork:r}=k(),[i,o]=t.useState(null),[s,l]=t.useState(null),[c,d]=t.useState(null),[u,m]=t.useState(null),[h,w]=t.useState(null),[g,C]=t.useState(null),[y,E]=t.useState(!1),_=r?(e=>{switch(e){case"sepolia":return a.sepolia;case"ethereum-classic":return b;case"milkomeda-mainnet":return p;default:return null}})(r):null,N=_?_.id:null,S=t.useRef(null),T=t.useRef(null),A=t.useCallback((()=>{o(null),l(null),d(null),m(null),w(null),C(null)}),[]),x=t.useCallback((async e=>{const t=parseInt(e,16);if(m(t),_&&t===N){if(C(null),window.ethereum&&_){const e=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});o(e)}}else if(_&&t!==N){C(`Wrong network detected. Please switch to ${_?.name||r||"selected network"}`)}}),[_,N,r]);T.current=x;const D=t.useCallback((async e=>{if(0===e.length){if(A(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(d(e[0]),_)try{const t=n.createPublicClient({chain:_,transport:n.http()});l(t);const a=await t.getBalance({address:e[0]});w(parseFloat(a)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}}),[_,A]);S.current=D;const P=t.useCallback((()=>{if(A(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[A]),I=t.useCallback((()=>{_&&l(n.createPublicClient({chain:_,transport:n.http()}))}),[_]),B=t.useCallback((async()=>{if(!window.ethereum)return C("Please install MetaMask or another Web3 wallet"),!1;if(!r||!_)return C("Please select a network first"),!1;E(!0),C(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const t=await window.ethereum.request({method:"eth_chainId"});parseInt(t,16)!==N&&await v(r);const a=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});o(a),d(e[0]),m(N);const i=n.createPublicClient({chain:_,transport:n.http()});l(i);try{const t=await i.getBalance({address:e[0]});w(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}return S.current=D,T.current=x,window.ethereum.on("accountsChanged",D),window.ethereum.on("chainChanged",x),!0}catch(e){return console.error("Error connecting wallet:",e),C(e.message),!1}finally{E(!1)}}),[r,_,N,D,x]),M=t.useCallback((async()=>{if(!(window.ethereum&&r&&_&&c)){return C("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==N){C(null),await v(r);const e=500;await new Promise((t=>setTimeout(t,e)));const t=await window.ethereum.request({method:"eth_chainId"}),n=parseInt(t,16);if(n!==N)throw new Error(`Failed to switch network. MetaMask is still on chain ${n}, expected ${N}`)}const t=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});return o(t),m(N),C(null),t}catch(e){return C(e.message),null}}),[r,_,N,c]),j=t.useRef(r);return t.useEffect((()=>{if(null!==j.current&&j.current!==r&&c&&(A(),window.ethereum)){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}j.current=r}),[r,c,A]),t.useEffect((()=>{I()}),[I]),t.createElement(f.Provider,{value:{walletClient:i,publicClient:s,account:c,chainId:u,balance:h,error:g,isConnecting:y,connectWallet:B,disconnectWallet:P,ensureCorrectNetwork:M,expectedChainId:N}},e)},E=({onTransactionComplete:e})=>{const{networkSelector:a,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:l}=k(),{connectWallet:c,account:u,walletClient:m,publicClient:h,isConnecting:w,ensureCorrectNetwork:g,expectedChainId:C}=(()=>{const e=t.useContext(f);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[p,b]=t.useState(null),[v,y]=t.useState(null),[E,_]=t.useState(null),[N,S]=t.useState(""),[T,A]=t.useState(null),[x,D]=t.useState(null),[P,I]=t.useState(!1);if(t.useEffect((()=>{_(null),y(null),S(""),D(null),A(null)}),[r,o]),t.useEffect((()=>{(async()=>{if(r&&o)try{const e=a.getSelectedNetworkConfig(),t=a.getReceivingAddress(),n=a.getTokenAmount(o.key),s=new i(e.uri,e.djedAddress);await s.init(),b(s);let c=null;if("native"===o.key)try{c=await s.handleTradeDataBuySc(String(n)),y(c)}catch(e){console.error("Error fetching trade data:",e)}l({network:r,token:o.key,tokenSymbol:o.symbol,amount:n||"0",receivingAddress:t,djedContractAddress:e.djedAddress,isDirectTransfer:o.isDirectTransfer||!1,isNativeToken:o.isNative||!1,tradeAmount:c?c.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[r,o,a,l]),!r||!o)return null;if(!s)return t.createElement("div",{className:d.loading},"Initializing transaction...");const B=()=>{if(!T||!r)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[r]?`${e[r]}${T}`:null};return t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"Network:"),t.createElement("span",{className:d.transactionValue},s.network)),t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"You Pay:"),t.createElement("span",{className:`${d.transactionValue} ${d.highlight}`},"stablecoin"===o.key?`${s.amount} ${s.tokenSymbol}`:`${v||"Calculating..."} ${s.tokenSymbol}`)),N&&t.createElement("div",{className:d.messageBox},N,x&&t.createElement("button",{onClick:()=>I(!P),className:d.detailsButton},P?"Hide Details":"Show Details")),P&&x&&t.createElement("div",{className:d.errorDetails},t.createElement("pre",null,x.message)),T&&t.createElement("div",{className:d.transactionLink},"Transaction Hash:"," ",B()?t.createElement("a",{href:B(),target:"_blank",rel:"noopener noreferrer",className:d.explorerLink},T.slice(0,6),"...",T.slice(-6)):t.createElement("span",{style:{wordBreak:"break-word"}},T)),t.createElement("div",{className:d.walletButtonContainer},!u&&t.createElement("button",{className:d.walletButton,onClick:async()=>{await c()},disabled:w},w?"Connecting...":"Connect Wallet"),u&&!E&&t.createElement("button",{className:d.walletButton,onClick:async()=>{if(u&&s&&p)try{_(null),D(null),S("Preparing transaction...");const e=s.receivingAddress;let t;if("native"===o.key){const a="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=v||"0",i=n.parseEther(String(r));t=await p.buyStablecoins(u,e,i,a),t={...t,value:i,account:u}}else{const r=a.getSelectedNetworkConfig(),i=r?.tokens?.stablecoin?.address;if(!i)throw new Error("Stablecoin address not found in network configuration");const o=s.amount?n.parseUnits(String(s.amount),s.stableCoinDecimals):"0";t={to:i,value:0n,data:n.encodeFunctionData({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,o]}),account:u}}_(t),S("Transaction ready. Please confirm to proceed.")}catch(e){D(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");S(`Transaction preparation failed: ${t}`)}else S("Wallet not connected or transaction details missing")}},"Prepare Transaction"),u&&E&&t.createElement("button",{className:d.walletButton,onClick:async()=>{D(null);try{if(!u||!E)return void S("Wallet account or transaction data is missing");if(!r)return void S("Network not selected");const t=a.getSelectedNetworkConfig();if(!t)return void S("Network configuration not found");S("Verifying network...");const n=await g();if(!n)return void S("Failed to switch to correct network. Please approve the network switch in MetaMask and try again.");if(!window.ethereum)return void S("MetaMask not available");const i=await window.ethereum.request({method:"eth_chainId"}),l=parseInt(i,16);if(l!==t.chainId){const e=`Network mismatch. MetaMask is on chain ${l}, but ${r} requires chain ${t.chainId}. Please switch networks in MetaMask.`;return S(e),void D(new Error(e))}if(n.chain.id!==t.chainId){const e=`Wallet client chain mismatch. Wallet client is on chain ${n.chain.id}, but expected ${t.chainId}.`;return S(e),void D(new Error(e))}S("Sending transaction...");const c=await n.sendTransaction({...E,account:u});A(c),S("Transaction sent!"),e&&e({txHash:c,network:r,token:o?.key,tokenSymbol:o?.symbol,amount:s?.amount,receivingAddress:s?.receivingAddress})}catch(e){D(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");S(`Transaction failed: ${t}`),console.error("Transaction error:",e)}},disabled:null!==T},"Send Transaction")))},_=({onClose:e,buttonSize:n,onTransactionComplete:a})=>{const{resetSelections:r}=k();return t.createElement(u,{onClose:()=>{r(),e()},size:n},t.createElement(g,null),t.createElement(C,null),t.createElement(E,{onTransactionComplete:a}))},N=({onClose:e,buttonSize:n,networkSelector:a,onTransactionComplete:r})=>t.createElement(w,{networkSelector:a},t.createElement(y,null,t.createElement(_,{onClose:e,buttonSize:n,onTransactionComplete:r})));return{NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(r).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:i,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!r[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:n="medium",onTransactionComplete:a,onSuccess:r})=>{const[i,o]=t.useState(!1),s=a||r;return t.createElement("div",{className:d.widgetContainer},!i&&t.createElement(c,{onClick:()=>{o(!0)},size:n}),i&&t.createElement(N,{onClose:()=>{o(!1)},buttonSize:n,networkSelector:e,onTransactionComplete:s}))},PayButton:c,Dialog:u,NetworkDropdown:g}})); //# sourceMappingURL=index.js.map diff --git a/stablepay-sdk/dist/umd/index.js.map b/stablepay-sdk/dist/umd/index.js.map index 60f278c..44cfa7f 100644 --- a/stablepay-sdk/dist/umd/index.js.map +++ b/stablepay-sdk/dist/umd/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../../src/utils/config.js","../../src/core/Transaction.js","../../src/widget/PayButton.jsx","../../src/widget/Dialog.jsx","../../src/core/TokenSelector.js","../../src/contexts/NetworkContext.jsx","../../src/widget/NetworkDropdown.jsx","../../src/widget/TokenDropdown.jsx","../../src/contexts/chains.js","../../src/contexts/WalletContext.jsx","../../src/widget/TransactionReview.jsx","../../src/widget/Widget.jsx","../../src/index.js","../../src/core/NetworkSelector.js","../../src/core/MerchantConfig.js"],"sourcesContent":["// src/utils/config.js\nexport const networksConfig = {\n 'sepolia': {\n uri: 'https://ethereum-sepolia.publicnode.com/',\n chainId: 11155111,\n djedAddress: '0x624FcD0a1F9B5820c950FefD48087531d38387f4',\n tokens: {\n stablecoin: {\n symbol: 'SOD',\n address: '0x6b930182787F346F18666D167e8d32166dC5eFBD',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETH',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'milkomeda-mainnet': {\n uri: 'https://rpc-mainnet-cardano-evm.c1.milkomeda.com',\n chainId: 2001,\n djedAddress: '0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76',\n tokens: {\n stablecoin: {\n symbol: 'MOD',\n address: '0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'mADA',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'ethereum-classic': {\n uri: 'https://etc.rivet.link',\n chainId: 61,\n djedAddress: '0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf',\n tokens: {\n stablecoin: {\n symbol: 'ECSD',\n address: '0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETC',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n }\n};","import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx } from 'djed-sdk';\n\nexport class Transaction {\n constructor(networkUri, djedAddress) {\n this.networkUri = networkUri;\n this.djedAddress = djedAddress;\n }\n\n async init() {\n if (!this.networkUri || !this.djedAddress) {\n throw new Error('Network URI and DJED address are required');\n }\n\n try {\n this.web3 = await getWeb3(this.networkUri);\n this.djedContract = getDjedContract(this.web3, this.djedAddress);\n \n try {\n const { stableCoin, reserveCoin } = await getCoinContracts(this.djedContract, this.web3);\n const { scDecimals, rcDecimals } = await getDecimals(stableCoin, reserveCoin);\n this.stableCoin = stableCoin;\n this.reserveCoin = reserveCoin;\n this.scDecimals = scDecimals;\n this.rcDecimals = rcDecimals;\n\n this.oracleContract = await getOracleAddress(this.djedContract).then((addr) =>\n getOracleContract(this.web3, addr, this.djedContract._address)\n );\n\n this.oracleAddress = this.oracleContract._address;\n } catch (contractError) {\n console.error('[Transaction] Error fetching contract details:', contractError);\n if (contractError.message && contractError.message.includes('execution reverted')) {\n const getNetworkInfo = (uri) => {\n if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };\n if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' };\n if (uri.includes('sepolia')) return { name: 'Sepolia', chainId: '11155111' };\n if (uri.includes('etc.rivet.link')) return { name: 'Ethereum Classic', chainId: '61' };\n return { name: 'the selected network', chainId: 'unknown' };\n };\n const { name: networkName, chainId } = getNetworkInfo(this.networkUri);\n throw new Error(\n `Failed to interact with Djed contract at ${this.djedAddress} on ${networkName}.\\n\\n` +\n `Possible causes:\\n` +\n `- The contract address may be incorrect\\n` +\n `- The contract may not be deployed on ${networkName}\\n` +\n `- The contract may not be a valid Djed contract\\n\\n` +\n `Please verify the contract address is correct for ${networkName} (Chain ID: ${chainId}).`\n );\n }\n throw contractError;\n }\n } catch (error) {\n console.error('[Transaction] Error initializing transaction:', error);\n if (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED'))) {\n const getNetworkName = (uri) => {\n if (uri.includes('milkomeda')) return 'Milkomeda';\n if (uri.includes('mordor')) return 'Mordor';\n if (uri.includes('sepolia')) return 'Sepolia';\n return 'the selected network';\n };\n const networkName = getNetworkName(this.networkUri);\n throw new Error(\n `Failed to connect to ${networkName} RPC endpoint: ${this.networkUri}\\n\\n` +\n `Possible causes:\\n` +\n `- The RPC endpoint may be temporarily unavailable\\n` +\n `- DNS resolution issue (check your internet connection)\\n` +\n `- Network firewall blocking the connection\\n\\n` +\n `Please try again in a few moments or check the network status.`\n );\n }\n throw error;\n }\n }\n\n getBlockchainDetails() {\n return {\n web3Available: !!this.web3,\n djedContractAvailable: !!this.djedContract,\n stableCoinAddress: this.stableCoin ? this.stableCoin._address : 'N/A',\n reserveCoinAddress: this.reserveCoin ? this.reserveCoin._address : 'N/A',\n stableCoinDecimals: this.scDecimals,\n reserveCoinDecimals: this.rcDecimals,\n oracleAddress: this.oracleAddress || 'N/A',\n oracleContractAvailable: !!this.oracleContract,\n };\n }\n\n async handleTradeDataBuySc(amountScaled) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n if (typeof amountScaled !== 'string') {\n throw new Error(\"Amount must be a string\");\n }\n try {\n const result = await tradeDataPriceBuySc(this.djedContract, this.scDecimals, amountScaled);\n return result.totalBCScaled;\n } catch (error) {\n console.error(\"Error fetching trade data for buying stablecoins: \", error);\n throw error;\n }\n }\n\n async buyStablecoins(payer, receiver, value) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n try {\n const UI = '0x0232556C83791b8291E9b23BfEa7d67405Bd9839';\n\n const txData = await buyScTx(this.djedContract, payer, receiver, value, UI, this.djedAddress);\n\n return txData;\n } catch (error) {\n console.error(\"Error executing buyStablecoins transaction: \", error);\n throw error;\n }\n }\n}\n","import React from \"react\";\nimport styles from \"../styles/main.css\";\n\nconst PayButton = ({ onClick, size = \"medium\" }) => {\n const sizeStyles = {\n small: { width: \"200px\", height: \"50px\", fontSize: \"14px\" },\n medium: { width: \"250px\", height: \"60px\", fontSize: \"16px\" },\n large: { width: \"300px\", height: \"70px\", fontSize: \"18px\" },\n };\n\n const logoSizes = {\n small: { width: \"35px\", height: \"33px\" },\n medium: { width: \"40px\", height: \"38px\" },\n large: { width: \"45px\", height: \"43px\" },\n };\n\n const buttonStyle = sizeStyles[size] || sizeStyles.medium;\n const logoStyle = logoSizes[size] || logoSizes.medium;\n\n return (\n \n
\n Pay with StablePay\n \n );\n};\n\nexport default PayButton;\n","import React from 'react';\nimport styles from '../styles/PricingCard.css';\n\n\nconst Dialog = ({ children, onClose, size = 'medium' }) => {\n return (\n
\n
\n \n
\n
\n\n

StablePay

\n
\n
\n {children}\n
\n
\n
\n );\n};\n\nexport default Dialog;","// TokenSelector.js\n\nexport class TokenSelector {\n constructor(networkSelector) {\n this.networkSelector = networkSelector;\n this.selectedToken = null;\n }\n\n selectToken(tokenKey) {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (networkConfig && networkConfig.tokens[tokenKey]) {\n this.selectedToken = {\n key: tokenKey,\n ...networkConfig.tokens[tokenKey]\n };\n return true;\n }\n return false;\n }\n\n getSelectedToken() {\n return this.selectedToken;\n }\n\n getAvailableTokens() {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) return [];\n\n return Object.entries(networkConfig.tokens).map(([key, config]) => ({\n key,\n ...config\n }));\n }\n\n resetSelection() {\n this.selectedToken = null;\n }\n}","import React, { createContext, useState, useContext, useEffect } from 'react';\nimport { TokenSelector } from '../core/TokenSelector';\n\nconst NetworkContext = createContext();\n\nexport const NetworkProvider = ({ children, networkSelector }) => {\n const [tokenSelector] = useState(() => new TokenSelector(networkSelector));\n const [selectedNetwork, setSelectedNetwork] = useState(null);\n const [selectedToken, setSelectedToken] = useState(null);\n const [transactionDetails, setTransactionDetails] = useState(null);\n\n const resetState = () => {\n setSelectedToken(null);\n setTransactionDetails(null);\n };\n\n const selectNetwork = (networkKey) => {\n if (networkSelector.selectNetwork(networkKey)) {\n setSelectedNetwork(networkKey);\n resetState(); \n return true;\n }\n return false;\n };\n\n const selectToken = (tokenKey) => {\n if (tokenSelector.selectToken(tokenKey)) {\n const token = tokenSelector.getSelectedToken();\n setSelectedToken(token);\n return true;\n }\n return false;\n };\n\n const resetSelections = () => {\n networkSelector.selectNetwork(null);\n setSelectedNetwork(null);\n resetState();\n };\n\n // Synchronize context state with NetworkSelector\n useEffect(() => {\n setSelectedNetwork(networkSelector.selectedNetwork);\n }, [networkSelector.selectedNetwork]);\n\n return (\n \n {children}\n \n );\n};\n\nexport const useNetwork = () => {\n const context = useContext(NetworkContext);\n if (context === undefined) {\n throw new Error('useNetwork must be used within a NetworkProvider');\n }\n return context;\n};\n\nexport default NetworkContext;","import React from 'react';\nimport { useNetwork } from '../contexts/NetworkContext';\nimport styles from '../styles/PricingCard.css';\n\nconst NetworkDropdown = () => {\n const { networkSelector, selectedNetwork, selectNetwork } = useNetwork();\n\n const handleNetworkChange = (event) => {\n selectNetwork(event.target.value);\n };\n\n return (\n
\n \n \n
\n );\n};\n\nexport default NetworkDropdown;","import React, { useState } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst TokenDropdown = () => {\n const {\n networkSelector,\n tokenSelector,\n selectedNetwork,\n selectedToken,\n selectToken,\n setTransactionDetails,\n } = useNetwork();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n const handleTokenChange = async (event) => {\n const newValue = event.target.value;\n setError(null);\n setLoading(true);\n\n try {\n if (selectToken(newValue)) {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const transaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await transaction.init();\n\n const tokenAmount = networkSelector.getTokenAmount(newValue);\n const blockchainDetails = transaction.getBlockchainDetails();\n\n let tradeData = null;\n if (newValue === \"native\") {\n tradeData = await transaction.handleTradeDataBuySc(\n String(tokenAmount)\n );\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: newValue,\n tokenSymbol: tokenSelector.getSelectedToken().symbol,\n amount: tokenAmount,\n receivingAddress: networkSelector.getReceivingAddress(),\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer:\n tokenSelector.getSelectedToken().isDirectTransfer || false,\n isNativeToken: tokenSelector.getSelectedToken().isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...blockchainDetails,\n });\n }\n } catch (err) {\n console.error(\"Error fetching transaction details:\", err);\n setError(\"Failed to fetch transaction details. Please try again.\");\n } finally {\n setLoading(false);\n }\n };\n\n const availableTokens = selectedNetwork\n ? tokenSelector.getAvailableTokens()\n : [];\n\n return (\n
\n \n \n \n {availableTokens.map((token) => (\n \n ))}\n \n {error &&
{error}
}\n
\n );\n};\n\nexport default TokenDropdown;\n","import { defineChain } from 'viem';\nimport { sepolia } from 'viem/chains';\n\nexport const mordor = defineChain({\n id: 63,\n name: 'Mordor Testnet',\n network: 'mordor',\n nativeCurrency: {\n decimals: 18,\n name: 'Mordor Ether',\n symbol: 'METC',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc.mordor.etccooperative.org'],\n webSocket: ['wss://rpc.mordor.etccooperative.org/ws'],\n },\n },\n blockExplorers: {\n default: { name: 'BlockScout', url: 'https://blockscout.com/etc/mordor' },\n },\n testnet: true,\n});\n\nexport const milkomeda = defineChain({\n id: 2001,\n name: 'Milkomeda C1 Mainnet',\n network: 'milkomeda',\n nativeCurrency: {\n decimals: 18,\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n },\n },\n blockExplorers: {\n default: { name: 'Milkomeda Explorer', url: 'https://explorer-mainnet-cardano-evm.c1.milkomeda.com' },\n },\n testnet: false,\n});\n\nexport const etcMainnet = defineChain({\n id: 61,\n name: 'Ethereum Classic',\n network: 'etc',\n nativeCurrency: {\n decimals: 18,\n name: 'Ethereum Classic',\n symbol: 'ETC',\n },\n rpcUrls: {\n default: {\n http: ['https://etc.rivet.link'],\n },\n },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://blockscout.com/etc/mainnet' },\n },\n testnet: false,\n});\n\nexport const getChainByNetworkKey = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return sepolia;\n case 'ethereum-classic':\n return etcMainnet;\n case 'milkomeda-mainnet':\n return milkomeda;\n default:\n return null;\n }\n};\n\nexport const getChainConfigForWallet = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return {\n chainId: `0x${sepolia.id.toString(16)}`,\n chainName: 'Sepolia',\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n rpcUrls: sepolia.rpcUrls.default.http,\n blockExplorerUrls: sepolia.blockExplorers?.default?.url ? [sepolia.blockExplorers.default.url] : [],\n };\n case 'ethereum-classic':\n return {\n chainId: `0x${etcMainnet.id.toString(16)}`,\n chainName: 'Ethereum Classic',\n nativeCurrency: {\n name: 'Ethereum Classic',\n symbol: 'ETC',\n decimals: 18,\n },\n rpcUrls: ['https://etc.rivet.link'],\n blockExplorerUrls: ['https://blockscout.com/etc/mainnet'],\n };\n case 'milkomeda-mainnet':\n return {\n chainId: `0x${milkomeda.id.toString(16)}`,\n chainName: 'Milkomeda C1 Mainnet',\n nativeCurrency: {\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n decimals: 18,\n },\n rpcUrls: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n blockExplorerUrls: ['https://explorer-mainnet-cardano-evm.c1.milkomeda.com'],\n };\n default:\n return null;\n }\n};\n","import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { createWalletClient, createPublicClient, custom, http } from 'viem';\nimport { useNetwork } from './NetworkContext';\nimport { getChainByNetworkKey, getChainConfigForWallet } from './chains';\n\nconst WalletContext = createContext(null);\n\nexport const useWallet = () => {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used within a WalletProvider');\n }\n return context;\n};\n\nconst switchToNetwork = async (networkKey) => {\n if (!window.ethereum) {\n throw new Error('MetaMask not installed');\n }\n\n const chainConfig = getChainConfigForWallet(networkKey);\n if (!chainConfig) {\n throw new Error(`Unsupported network: ${networkKey}`);\n }\n\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: chainConfig.chainId }],\n });\n } catch (switchError) {\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [chainConfig],\n });\n } catch (addError) {\n if (addError.code === 4001) {\n throw new Error(`User rejected adding ${chainConfig.chainName} to MetaMask. Please add it manually.`);\n }\n throw new Error(`Failed to add ${chainConfig.chainName} to MetaMask: ${addError.message}`);\n }\n } else if (switchError.code === 4001) {\n throw new Error(`User rejected switching to ${chainConfig.chainName}. Please switch manually in MetaMask.`);\n } else {\n throw new Error(`Failed to switch to ${chainConfig.chainName}: ${switchError.message}`);\n }\n }\n};\n\nexport const WalletProvider = ({ children }) => {\n const { selectedNetwork } = useNetwork();\n const [walletClient, setWalletClient] = useState(null);\n const [publicClient, setPublicClient] = useState(null);\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [balance, setBalance] = useState(null);\n const [error, setError] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n\n const selectedChain = selectedNetwork ? getChainByNetworkKey(selectedNetwork) : null;\n const expectedChainId = selectedChain ? selectedChain.id : null;\n\n const handleAccountsChangedRef = useRef(null);\n const handleChainChangedRef = useRef(null);\n\n const disconnectWalletInternal = useCallback(() => {\n setWalletClient(null);\n setPublicClient(null);\n setAccount(null);\n setChainId(null);\n setBalance(null);\n setError(null);\n }, []);\n\n const handleChainChanged = useCallback(async (chainIdHex) => {\n const newChainId = parseInt(chainIdHex, 16);\n setChainId(newChainId);\n\n if (selectedChain && newChainId === expectedChainId) {\n setError(null);\n if (window.ethereum && selectedChain) {\n const newWalletClient = createWalletClient({ \n chain: selectedChain, \n transport: custom(window.ethereum) \n });\n setWalletClient(newWalletClient);\n }\n } else if (selectedChain && newChainId !== expectedChainId) {\n const chainName = selectedChain?.name || selectedNetwork || 'selected network';\n setError(`Wrong network detected. Please switch to ${chainName}`);\n }\n }, [selectedChain, expectedChainId, selectedNetwork]);\n\n handleChainChangedRef.current = handleChainChanged;\n\n const handleAccountsChanged = useCallback(async (accounts) => {\n if (accounts.length === 0) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n } else {\n setAccount(accounts[0]);\n if (selectedChain) {\n try {\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n }\n }\n }, [selectedChain, disconnectWalletInternal]);\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n\n const disconnectWallet = useCallback(() => {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }, [disconnectWalletInternal]);\n\n const connectPublicClient = useCallback(() => {\n if (selectedChain) {\n setPublicClient(createPublicClient({ chain: selectedChain, transport: http() }));\n }\n }, [selectedChain]);\n\n const connectWallet = useCallback(async () => {\n if (!window.ethereum) {\n setError('Please install MetaMask or another Web3 wallet');\n return false;\n }\n\n if (!selectedNetwork || !selectedChain) {\n setError('Please select a network first');\n return false;\n }\n\n setIsConnecting(true);\n setError(null);\n\n try {\n const accounts = await window.ethereum.request({ \n method: 'eth_requestAccounts' \n });\n\n if (accounts.length === 0) {\n throw new Error('No wallet address found. Please unlock your wallet.');\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n await switchToNetwork(selectedNetwork);\n }\n\n const newWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(newWalletClient);\n setAccount(accounts[0]);\n setChainId(expectedChainId);\n\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n try {\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n handleChainChangedRef.current = handleChainChanged;\n window.ethereum.on('accountsChanged', handleAccountsChanged);\n window.ethereum.on('chainChanged', handleChainChanged);\n\n return true;\n } catch (err) {\n console.error('Error connecting wallet:', err);\n setError(err.message);\n return false;\n } finally {\n setIsConnecting(false);\n }\n }, [selectedNetwork, selectedChain, expectedChainId, handleAccountsChanged, handleChainChanged]);\n\n const ensureCorrectNetwork = useCallback(async () => {\n if (!window.ethereum || !selectedNetwork || !selectedChain || !account) {\n const errorMsg = 'Wallet not connected or network not selected';\n setError(errorMsg);\n return null;\n }\n\n try {\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n setError(null);\n await switchToNetwork(selectedNetwork);\n const NETWORK_SWITCH_DELAY_MS = 500;\n await new Promise(resolve => setTimeout(resolve, NETWORK_SWITCH_DELAY_MS));\n \n const newChainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const newChainId = parseInt(newChainIdHex, 16);\n if (newChainId !== expectedChainId) {\n throw new Error(`Failed to switch network. MetaMask is still on chain ${newChainId}, expected ${expectedChainId}`);\n }\n }\n\n const freshWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(freshWalletClient);\n setChainId(expectedChainId);\n setError(null);\n return freshWalletClient;\n } catch (err) {\n setError(err.message);\n return null;\n }\n }, [selectedNetwork, selectedChain, expectedChainId, account]);\n\n const prevNetworkRef = useRef(selectedNetwork);\n\n useEffect(() => {\n if (prevNetworkRef.current !== null && \n prevNetworkRef.current !== selectedNetwork && \n account) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }\n prevNetworkRef.current = selectedNetwork;\n }, [selectedNetwork, account, disconnectWalletInternal]);\n\n useEffect(() => {\n connectPublicClient();\n }, [connectPublicClient]);\n\n return (\n \n {children}\n \n );\n};","import React, { useState, useEffect } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { useWallet } from \"../contexts/WalletContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport { parseEther, encodeFunctionData, parseUnits } from \"viem\"; \nimport styles from \"../styles/PricingCard.css\"; \n\nconst TransactionReview = ({ onTransactionComplete }) => {\n const {\n networkSelector,\n selectedNetwork,\n selectedToken,\n transactionDetails: contextTransactionDetails,\n setTransactionDetails,\n } = useNetwork();\n\n const {\n connectWallet,\n account,\n walletClient,\n publicClient,\n isConnecting,\n ensureCorrectNetwork,\n expectedChainId,\n } = useWallet();\n\n const [transaction, setTransaction] = useState(null);\n const [tradeDataBuySc, setTradeDataBuySc] = useState(null);\n const [txData, setTxData] = useState(null);\n const [message, setMessage] = useState(\"\");\n const [txHash, setTxHash] = useState(null);\n const [error, setError] = useState(null);\n const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false);\n\n useEffect(() => {\n setTxData(null);\n setTradeDataBuySc(null);\n setMessage(\"\");\n setError(null);\n setTxHash(null);\n }, [selectedNetwork, selectedToken]);\n\n useEffect(() => {\n const initializeTransaction = async () => {\n if (!selectedNetwork || !selectedToken) return;\n\n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const receivingAddress = networkSelector.getReceivingAddress();\n const tokenAmount = networkSelector.getTokenAmount(selectedToken.key);\n\n const newTransaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await newTransaction.init();\n setTransaction(newTransaction);\n\n let tradeData = null;\n if (selectedToken.key === \"native\") {\n try {\n tradeData = await newTransaction.handleTradeDataBuySc(String(tokenAmount));\n setTradeDataBuySc(tradeData);\n } catch (tradeError) {\n console.error(\"Error fetching trade data:\", tradeError);\n }\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: selectedToken.key,\n tokenSymbol: selectedToken.symbol,\n amount: tokenAmount || \"0\",\n receivingAddress,\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer: selectedToken.isDirectTransfer || false,\n isNativeToken: selectedToken.isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...newTransaction.getBlockchainDetails(),\n });\n } catch (err) {\n console.error(\"Error initializing transaction:\", err);\n }\n };\n\n initializeTransaction();\n }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]);\n\n if (!contextTransactionDetails) {\n return
Initializing transaction...
;\n }\n\n const handleConnectWallet = async () => {\n await connectWallet();\n };\n\n const handleSendTransaction = async () => {\n if (!account || !contextTransactionDetails || !transaction) {\n setMessage(\"❌ Wallet not connected or transaction details missing\");\n return;\n }\n\n try {\n setTxData(null);\n setError(null);\n setMessage(\"⏳ Preparing transaction...\");\n\n const receiver = contextTransactionDetails.receivingAddress;\n let builtTx;\n\n if (selectedToken.key === \"native\") {\n const UI = \"0x0232556C83791b8291E9b23BfEa7d67405Bd9839\";\n const amountToSend = tradeDataBuySc || \"0\";\n const valueInWei = parseEther(String(amountToSend));\n\n builtTx = await transaction.buyStablecoins(\n account,\n receiver,\n valueInWei,\n UI\n );\n\n builtTx = {\n ...builtTx,\n value: valueInWei,\n account: account,\n };\n } else {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const stablecoinAddress = networkConfig?.tokens?.stablecoin?.address;\n \n if (!stablecoinAddress) {\n throw new Error('Stablecoin address not found in network configuration');\n }\n\n const amountToSend = contextTransactionDetails.amount\n ? parseUnits(\n String(contextTransactionDetails.amount),\n contextTransactionDetails.stableCoinDecimals\n )\n : \"0\";\n\n builtTx = {\n to: stablecoinAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: [\n {\n inputs: [\n { internalType: \"address\", name: \"to\", type: \"address\" },\n { internalType: \"uint256\", name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ],\n functionName: \"transfer\",\n args: [receiver, amountToSend],\n }),\n account: account,\n };\n }\n\n setTxData(builtTx);\n setMessage(\"✅ Transaction ready! Click 'Send Transaction' to proceed.\");\n } catch (error) {\n setError(error);\n setMessage(`❌ Transaction preparation failed.`);\n }\n };\n\n const handleBuySc = async () => {\n setError(null);\n \n try {\n if (!account || !txData) {\n setMessage(\"❌ Wallet account or transaction data is missing\");\n return;\n }\n\n if (!selectedNetwork) {\n setMessage(\"❌ Network not selected\");\n return;\n }\n\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) {\n setMessage(\"❌ Network configuration not found\");\n return;\n }\n\n setMessage(\"⏳ Verifying network...\");\n\n const freshWalletClient = await ensureCorrectNetwork();\n if (!freshWalletClient) {\n setMessage(\"❌ Failed to switch to correct network. Please approve the network switch in MetaMask and try again.\");\n return;\n }\n\n if (!window.ethereum) {\n setMessage(\"❌ MetaMask not available\");\n return;\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== networkConfig.chainId) {\n const errorMsg = `Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`;\n setMessage(`❌ ${errorMsg}`);\n setError(new Error(errorMsg));\n return;\n }\n\n if (freshWalletClient.chain.id !== networkConfig.chainId) {\n const errorMsg = `Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`;\n setMessage(`❌ ${errorMsg}`);\n setError(new Error(errorMsg));\n return;\n }\n\n setMessage(\"⏳ Sending transaction...\");\n\n const txHash = await freshWalletClient.sendTransaction({\n ...txData,\n account: account,\n });\n\n setTxHash(txHash);\n setMessage(`✅ Transaction sent!`);\n \n if (onTransactionComplete) {\n onTransactionComplete({\n txHash,\n network: selectedNetwork,\n token: selectedToken?.key,\n tokenSymbol: selectedToken?.symbol,\n amount: contextTransactionDetails?.amount,\n receivingAddress: contextTransactionDetails?.receivingAddress,\n });\n }\n } catch (error) {\n setError(error);\n setMessage(`❌ Transaction failed.`);\n console.error('Transaction error:', error);\n }\n };\n\n const getExplorerUrl = () => {\n if (!txHash || !selectedNetwork) return null;\n\n const explorerBaseUrls = {\n \"ethereum-classic\": \"https://blockscout.com/etc/mainnet/tx/\",\n \"sepolia\": \"https://sepolia.etherscan.io/tx/\",\n \"milkomeda-mainnet\": \"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/\",\n };\n\n return explorerBaseUrls[selectedNetwork]\n ? `${explorerBaseUrls[selectedNetwork]}${txHash}`\n : null;\n };\n\n return (\n
\n
\n Network:\n {contextTransactionDetails.network}\n
\n\n
\n You Pay:\n \n {selectedToken.key === \"stablecoin\"\n ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}`\n : `${tradeDataBuySc ? tradeDataBuySc : \"Calculating...\"} ${\n contextTransactionDetails.tokenSymbol\n }`}\n \n
\n\n \n\n {account && !txData && (\n \n )}\n {account && txData && (\n \n)}\n\n\n {message && (\n
\n {message}\n {error && (\n setIsErrorDetailsVisible(!isErrorDetailsVisible)}\n className={styles.detailsButton}\n >\n {isErrorDetailsVisible ? \"Hide Details\" : \"Show Details\"}\n \n )}\n
\n )}\n\n {isErrorDetailsVisible && error && (\n
\n
{error.message}
\n
\n )}\n\n \n {txHash && (\n
\n ✅ Transaction Hash:{\" \"}\n {getExplorerUrl() ? (\n \n {txHash.slice(0, 6)}...{txHash.slice(-6)}\n \n ) : (\n \n {txHash}\n \n )}\n
\n)}\n\n
\n );\n};\n\nexport default TransactionReview;\n","import React, { useState } from \"react\";\nimport PayButton from \"./PayButton\";\nimport Dialog from \"./Dialog\";\nimport NetworkDropdown from \"./NetworkDropdown\";\nimport TokenDropdown from \"./TokenDropdown\";\nimport TransactionReview from \"./TransactionReview\";\nimport { NetworkProvider, useNetwork } from \"../contexts/NetworkContext\";\nimport { WalletProvider } from \"../contexts/WalletContext\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst WidgetContent = ({ onClose, buttonSize, onTransactionComplete }) => {\n const { resetSelections } = useNetwork(); \n\n const handleClose = () => {\n resetSelections(); // Reset selections when closing the widget\n onClose();\n };\n\n return (\n \n \n \n \n \n );\n};\n\nconst WidgetWithProviders = ({ onClose, buttonSize, networkSelector, onTransactionComplete }) => {\n return (\n \n \n \n \n \n );\n};\n\nexport const Widget = ({ networkSelector, buttonSize = \"medium\", onTransactionComplete, onSuccess }) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const handleOpenDialog = () => {\n setIsDialogOpen(true);\n };\n\n const handleCloseDialog = () => {\n setIsDialogOpen(false);\n };\n\n // Support both onTransactionComplete and onSuccess for backwards compatibility\n const handleTransactionComplete = onTransactionComplete || onSuccess;\n\n return (\n
\n {!isDialogOpen && (\n \n )}\n {isDialogOpen && (\n \n )}\n
\n );\n};\n\nexport default Widget;\n","// src/index.js\nimport { NetworkSelector } from './core/NetworkSelector';\nimport { Transaction } from './core/Transaction';\nimport { Config } from './core/MerchantConfig';\nimport Widget from './widget/Widget.jsx';\nimport PayButton from './widget/PayButton.jsx';\nimport Dialog from './widget/Dialog.jsx';\nimport NetworkDropdown from './widget/NetworkDropdown.jsx';\nimport './styles/main.css';\nimport './styles/PricingCard.css';\n\nconst StablePay = {\n NetworkSelector,\n Transaction,\n Config,\n Widget,\n PayButton,\n Dialog,\n NetworkDropdown\n};\n\nexport default StablePay;","import { networksConfig } from \"../utils/config\";\n\nexport class NetworkSelector {\n constructor(merchantConfig) {\n this.merchantConfig = merchantConfig;\n this.blacklist = merchantConfig.getBlacklist();\n this.availableNetworks = this.getAvailableNetworks();\n this.selectedNetwork = null;\n }\n\n getAvailableNetworks() {\n return Object.entries(networksConfig).reduce(\n (acc, [networkKey, networkConfig]) => {\n if (!this.blacklist.includes(networkConfig.chainId)) {\n acc[networkKey] = networkConfig;\n }\n return acc;\n },\n {}\n );\n }\n\n selectNetwork(networkKey) {\n if (networkKey === null) {\n this.selectedNetwork = null;\n console.log(\"Network selection reset\");\n return true;\n }\n if (this.availableNetworks[networkKey]) {\n this.selectedNetwork = networkKey;\n console.log(`Network selected: ${networkKey}`);\n return true;\n }\n console.error(`Invalid network: ${networkKey}`);\n return false;\n }\n\n getSelectedNetworkConfig() {\n return this.selectedNetwork\n ? this.availableNetworks[this.selectedNetwork]\n : null;\n }\n\n getReceivingAddress() {\n return this.merchantConfig.getReceivingAddress();\n }\n\n getTokenAmount(token) {\n return this.merchantConfig.getTokenAmount(this.selectedNetwork, token);\n }\n}\n","import { networksConfig } from \"../utils/config\";\n\nexport class Config {\n constructor(options = {}) {\n this.receivingAddress = options.receivingAddress || \"\";\n this.blacklist = options.blacklist || [];\n this.amounts = options.amounts || options.Amounts || {};\n this.validateConfig();\n }\n\n validateConfig() {\n if (!this.receivingAddress) {\n throw new Error(\"Receiving address is required\");\n }\n // Validate stablecoin amounts\n for (const [network, tokens] of Object.entries(this.amounts)) {\n if (!networksConfig[network]) {\n throw new Error(`Invalid network: ${network}`);\n }\n if (\n !tokens.stablecoin ||\n typeof tokens.stablecoin !== \"number\" ||\n tokens.stablecoin <= 0\n ) {\n throw new Error(`Invalid stablecoin amount for network ${network}`);\n }\n }\n }\n\n getBlacklist() {\n return this.blacklist;\n }\n\n getReceivingAddress() {\n return this.receivingAddress;\n }\n\n // getTokenAmount(network, token) {\n // const networkConfig = networksConfig[network];\n // if (!networkConfig) return 0;\n\n // const stablecoinSymbol = networkConfig.tokens.stablecoin.symbol;\n\n // if (token === 'stablecoin') {\n // return this.amounts[network]?.stablecoin || 0;\n // }\n // // For native tokens, return 0 as it's not specified in the new structure\n // return 0;\n // }\n getTokenAmount(network) {\n console.log(\"Getting amount for network:\", network);\n console.log(\"Amounts object:\", this.amounts);\n\n // Directly return the stablecoin amount for the network\n const amount = this.amounts[network]?.stablecoin;\n console.log(\"Returning amount:\", amount);\n\n return amount || 0;\n }\n}\n\nexport default Config;\n"],"names":["networksConfig","sepolia","uri","chainId","djedAddress","tokens","stablecoin","symbol","address","decimals","isDirectTransfer","native","isNative","feeUI","Transaction","constructor","networkUri","this","init","Error","web3","getWeb3","djedContract","getDjedContract","stableCoin","reserveCoin","getCoinContracts","scDecimals","rcDecimals","getDecimals","oracleContract","getOracleAddress","then","addr","getOracleContract","_address","oracleAddress","contractError","console","error","message","includes","getNetworkInfo","name","networkName","getNetworkName","getBlockchainDetails","web3Available","djedContractAvailable","stableCoinAddress","reserveCoinAddress","stableCoinDecimals","reserveCoinDecimals","oracleContractAvailable","handleTradeDataBuySc","amountScaled","tradeDataPriceBuySc","totalBCScaled","buyStablecoins","payer","receiver","value","UI","buyScTx","PayButton","onClick","size","sizeStyles","small","width","height","fontSize","medium","large","logoSizes","buttonStyle","logoStyle","React","createElement","className","styles","style","Dialog","children","onClose","dialogOverlay","pricingCard","dialogClose","pricingCardHeader","allianceLogo","stablepayTitle","pricingCardBody","TokenSelector","networkSelector","selectedToken","selectToken","tokenKey","networkConfig","getSelectedNetworkConfig","key","getSelectedToken","getAvailableTokens","Object","entries","map","config","resetSelection","NetworkContext","createContext","NetworkProvider","tokenSelector","useState","selectedNetwork","setSelectedNetwork","setSelectedToken","transactionDetails","setTransactionDetails","resetState","useEffect","Provider","selectNetwork","networkKey","token","resetSelections","useNetwork","context","useContext","undefined","NetworkDropdown","selectField","htmlFor","id","onChange","event","target","disabled","keys","availableNetworks","TokenDropdown","loading","setLoading","setError","availableTokens","async","newValue","transaction","tokenAmount","getTokenAmount","blockchainDetails","tradeData","String","network","tokenSymbol","amount","receivingAddress","getReceivingAddress","djedContractAddress","isNativeToken","tradeAmount","err","defineChain","nativeCurrency","rpcUrls","default","http","webSocket","blockExplorers","url","testnet","milkomeda","etcMainnet","WalletContext","switchToNetwork","window","ethereum","chainConfig","toString","chainName","blockExplorerUrls","getChainConfigForWallet","request","method","params","switchError","code","addError","WalletProvider","walletClient","setWalletClient","publicClient","setPublicClient","account","setAccount","setChainId","balance","setBalance","isConnecting","setIsConnecting","selectedChain","getChainByNetworkKey","expectedChainId","handleAccountsChangedRef","useRef","handleChainChangedRef","disconnectWalletInternal","useCallback","handleChainChanged","newChainId","parseInt","chainIdHex","newWalletClient","createWalletClient","chain","transport","custom","current","handleAccountsChanged","accounts","length","accountsHandler","chainHandler","removeListener","newPublicClient","createPublicClient","getBalance","parseFloat","Math","pow","disconnectWallet","connectPublicClient","connectWallet","on","ensureCorrectNetwork","NETWORK_SWITCH_DELAY_MS","Promise","resolve","setTimeout","newChainIdHex","freshWalletClient","prevNetworkRef","TransactionReview","onTransactionComplete","contextTransactionDetails","useWallet","setTransaction","tradeDataBuySc","setTradeDataBuySc","txData","setTxData","setMessage","txHash","setTxHash","isErrorDetailsVisible","setIsErrorDetailsVisible","newTransaction","tradeError","initializeTransaction","getExplorerUrl","explorerBaseUrls","transactionReview","transactionInfo","transactionLabel","transactionValue","walletButton","builtTx","amountToSend","valueInWei","parseEther","stablecoinAddress","parseUnits","to","data","encodeFunctionData","abi","inputs","internalType","type","outputs","stateMutability","functionName","args","currentChainId","errorMsg","sendTransaction","detailsButton","errorDetails","transactionLink","href","rel","explorerLink","color","textDecoration","fontWeight","cursor","wordBreak","slice","WidgetContent","buttonSize","handleClose","WidgetWithProviders","NetworkSelector","merchantConfig","blacklist","getBlacklist","getAvailableNetworks","reduce","acc","log","Config","options","amounts","Amounts","validateConfig","Widget","onSuccess","isDialogOpen","setIsDialogOpen","handleTransactionComplete","widgetContainer","handleOpenDialog","handleCloseDialog"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../../src/utils/config.js","../../src/core/Transaction.js","../../src/widget/PayButton.jsx","../../src/widget/Dialog.jsx","../../src/core/TokenSelector.js","../../src/contexts/NetworkContext.jsx","../../src/widget/NetworkDropdown.jsx","../../src/widget/TokenDropdown.jsx","../../src/contexts/chains.js","../../src/contexts/WalletContext.jsx","../../src/widget/TransactionReview.jsx","../../src/widget/Widget.jsx","../../src/index.js","../../src/core/NetworkSelector.js","../../src/core/MerchantConfig.js"],"sourcesContent":["// src/utils/config.js\nexport const networksConfig = {\n 'sepolia': {\n uri: 'https://ethereum-sepolia.publicnode.com/',\n chainId: 11155111,\n djedAddress: '0x624FcD0a1F9B5820c950FefD48087531d38387f4',\n tokens: {\n stablecoin: {\n symbol: 'SOD',\n address: '0x6b930182787F346F18666D167e8d32166dC5eFBD',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETH',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'milkomeda-mainnet': {\n uri: 'https://rpc-mainnet-cardano-evm.c1.milkomeda.com',\n chainId: 2001,\n djedAddress: '0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76',\n tokens: {\n stablecoin: {\n symbol: 'MOD',\n address: '0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'mADA',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'ethereum-classic': {\n uri: 'https://etc.rivet.link',\n chainId: 61,\n djedAddress: '0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf',\n tokens: {\n stablecoin: {\n symbol: 'ECSD',\n address: '0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETC',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n }\n};","import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx } from 'djed-sdk';\n\nexport class Transaction {\n constructor(networkUri, djedAddress) {\n this.networkUri = networkUri;\n this.djedAddress = djedAddress;\n }\n\n async init() {\n if (!this.networkUri || !this.djedAddress) {\n throw new Error('Network URI and DJED address are required');\n }\n\n try {\n this.web3 = await getWeb3(this.networkUri);\n this.djedContract = getDjedContract(this.web3, this.djedAddress);\n \n try {\n const { stableCoin, reserveCoin } = await getCoinContracts(this.djedContract, this.web3);\n const { scDecimals, rcDecimals } = await getDecimals(stableCoin, reserveCoin);\n this.stableCoin = stableCoin;\n this.reserveCoin = reserveCoin;\n this.scDecimals = scDecimals;\n this.rcDecimals = rcDecimals;\n\n this.oracleContract = await getOracleAddress(this.djedContract).then((addr) =>\n getOracleContract(this.web3, addr, this.djedContract._address)\n );\n\n this.oracleAddress = this.oracleContract._address;\n } catch (contractError) {\n console.error('[Transaction] Error fetching contract details:', contractError);\n if (contractError.message && contractError.message.includes('execution reverted')) {\n const getNetworkInfo = (uri) => {\n if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };\n if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' };\n if (uri.includes('sepolia')) return { name: 'Sepolia', chainId: '11155111' };\n if (uri.includes('etc.rivet.link')) return { name: 'Ethereum Classic', chainId: '61' };\n return { name: 'the selected network', chainId: 'unknown' };\n };\n const { name: networkName, chainId } = getNetworkInfo(this.networkUri);\n throw new Error(\n `Failed to interact with Djed contract at ${this.djedAddress} on ${networkName}.\\n\\n` +\n `Possible causes:\\n` +\n `- The contract address may be incorrect\\n` +\n `- The contract may not be deployed on ${networkName}\\n` +\n `- The contract may not be a valid Djed contract\\n\\n` +\n `Please verify the contract address is correct for ${networkName} (Chain ID: ${chainId}).`\n );\n }\n throw contractError;\n }\n } catch (error) {\n console.error('[Transaction] Error initializing transaction:', error);\n if (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED'))) {\n const getNetworkName = (uri) => {\n if (uri.includes('milkomeda')) return 'Milkomeda';\n if (uri.includes('mordor')) return 'Mordor';\n if (uri.includes('sepolia')) return 'Sepolia';\n return 'the selected network';\n };\n const networkName = getNetworkName(this.networkUri);\n throw new Error(\n `Failed to connect to ${networkName} RPC endpoint: ${this.networkUri}\\n\\n` +\n `Possible causes:\\n` +\n `- The RPC endpoint may be temporarily unavailable\\n` +\n `- DNS resolution issue (check your internet connection)\\n` +\n `- Network firewall blocking the connection\\n\\n` +\n `Please try again in a few moments or check the network status.`\n );\n }\n throw error;\n }\n }\n\n getBlockchainDetails() {\n return {\n web3Available: !!this.web3,\n djedContractAvailable: !!this.djedContract,\n stableCoinAddress: this.stableCoin ? this.stableCoin._address : 'N/A',\n reserveCoinAddress: this.reserveCoin ? this.reserveCoin._address : 'N/A',\n stableCoinDecimals: this.scDecimals,\n reserveCoinDecimals: this.rcDecimals,\n oracleAddress: this.oracleAddress || 'N/A',\n oracleContractAvailable: !!this.oracleContract,\n };\n }\n\n async handleTradeDataBuySc(amountScaled) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n if (typeof amountScaled !== 'string') {\n throw new Error(\"Amount must be a string\");\n }\n try {\n const result = await tradeDataPriceBuySc(this.djedContract, this.scDecimals, amountScaled);\n return result.totalBCScaled;\n } catch (error) {\n console.error(\"Error fetching trade data for buying stablecoins: \", error);\n throw error;\n }\n }\n\n async buyStablecoins(payer, receiver, value) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n try {\n const UI = '0x0232556C83791b8291E9b23BfEa7d67405Bd9839';\n\n const txData = await buyScTx(this.djedContract, payer, receiver, value, UI, this.djedAddress);\n\n return txData;\n } catch (error) {\n console.error(\"Error executing buyStablecoins transaction: \", error);\n throw error;\n }\n }\n}\n","import React from \"react\";\nimport styles from \"../styles/main.css\";\n\nconst PayButton = ({ onClick, size = \"medium\" }) => {\n const sizeStyles = {\n small: { width: \"200px\", height: \"50px\", fontSize: \"14px\" },\n medium: { width: \"250px\", height: \"60px\", fontSize: \"16px\" },\n large: { width: \"300px\", height: \"70px\", fontSize: \"18px\" },\n };\n\n const logoSizes = {\n small: { width: \"35px\", height: \"33px\" },\n medium: { width: \"40px\", height: \"38px\" },\n large: { width: \"45px\", height: \"43px\" },\n };\n\n const buttonStyle = sizeStyles[size] || sizeStyles.medium;\n const logoStyle = logoSizes[size] || logoSizes.medium;\n\n return (\n \n
\n Pay with StablePay\n \n );\n};\n\nexport default PayButton;\n","import React from 'react';\nimport styles from '../styles/PricingCard.css';\n\n\nconst Dialog = ({ children, onClose, size = 'medium' }) => {\n return (\n
\n
\n \n
\n
\n\n
StablePay
\n
\n
\n {children}\n
\n
\n
\n );\n};\n\nexport default Dialog;","// TokenSelector.js\n\nexport class TokenSelector {\n constructor(networkSelector) {\n this.networkSelector = networkSelector;\n this.selectedToken = null;\n }\n\n selectToken(tokenKey) {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (networkConfig && networkConfig.tokens[tokenKey]) {\n this.selectedToken = {\n key: tokenKey,\n ...networkConfig.tokens[tokenKey]\n };\n return true;\n }\n return false;\n }\n\n getSelectedToken() {\n return this.selectedToken;\n }\n\n getAvailableTokens() {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) return [];\n\n return Object.entries(networkConfig.tokens).map(([key, config]) => ({\n key,\n ...config\n }));\n }\n\n resetSelection() {\n this.selectedToken = null;\n }\n}","import React, { createContext, useState, useContext, useEffect } from 'react';\nimport { TokenSelector } from '../core/TokenSelector';\n\nconst NetworkContext = createContext();\n\nexport const NetworkProvider = ({ children, networkSelector }) => {\n const [tokenSelector] = useState(() => new TokenSelector(networkSelector));\n const [selectedNetwork, setSelectedNetwork] = useState(null);\n const [selectedToken, setSelectedToken] = useState(null);\n const [transactionDetails, setTransactionDetails] = useState(null);\n\n const resetState = () => {\n setSelectedToken(null);\n setTransactionDetails(null);\n };\n\n const selectNetwork = (networkKey) => {\n if (networkSelector.selectNetwork(networkKey)) {\n setSelectedNetwork(networkKey);\n resetState(); \n return true;\n }\n return false;\n };\n\n const selectToken = (tokenKey) => {\n if (tokenSelector.selectToken(tokenKey)) {\n const token = tokenSelector.getSelectedToken();\n setSelectedToken(token);\n return true;\n }\n return false;\n };\n\n const resetSelections = () => {\n networkSelector.selectNetwork(null);\n setSelectedNetwork(null);\n resetState();\n };\n\n // Synchronize context state with NetworkSelector\n useEffect(() => {\n setSelectedNetwork(networkSelector.selectedNetwork);\n }, [networkSelector.selectedNetwork]);\n\n return (\n \n {children}\n \n );\n};\n\nexport const useNetwork = () => {\n const context = useContext(NetworkContext);\n if (context === undefined) {\n throw new Error('useNetwork must be used within a NetworkProvider');\n }\n return context;\n};\n\nexport default NetworkContext;","import React from 'react';\nimport { useNetwork } from '../contexts/NetworkContext';\nimport styles from '../styles/PricingCard.css';\n\nconst NetworkDropdown = () => {\n const { networkSelector, selectedNetwork, selectNetwork } = useNetwork();\n\n const handleNetworkChange = (event) => {\n selectNetwork(event.target.value);\n };\n\n return (\n
\n \n \n
\n );\n};\n\nexport default NetworkDropdown;","import React, { useState } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst TokenDropdown = () => {\n const {\n networkSelector,\n tokenSelector,\n selectedNetwork,\n selectedToken,\n selectToken,\n setTransactionDetails,\n } = useNetwork();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n const handleTokenChange = async (event) => {\n const newValue = event.target.value;\n setError(null);\n setLoading(true);\n\n try {\n if (selectToken(newValue)) {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const transaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await transaction.init();\n\n const tokenAmount = networkSelector.getTokenAmount(newValue);\n const blockchainDetails = transaction.getBlockchainDetails();\n\n let tradeData = null;\n if (newValue === \"native\") {\n tradeData = await transaction.handleTradeDataBuySc(\n String(tokenAmount)\n );\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: newValue,\n tokenSymbol: tokenSelector.getSelectedToken().symbol,\n amount: tokenAmount,\n receivingAddress: networkSelector.getReceivingAddress(),\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer:\n tokenSelector.getSelectedToken().isDirectTransfer || false,\n isNativeToken: tokenSelector.getSelectedToken().isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...blockchainDetails,\n });\n }\n } catch (err) {\n console.error(\"Error fetching transaction details:\", err);\n setError(\"Failed to fetch transaction details. Please try again.\");\n } finally {\n setLoading(false);\n }\n };\n\n const availableTokens = selectedNetwork\n ? tokenSelector.getAvailableTokens()\n : [];\n\n return (\n
\n \n \n \n {availableTokens.map((token) => (\n \n ))}\n \n {error &&
{error}
}\n
\n );\n};\n\nexport default TokenDropdown;\n","import { defineChain } from 'viem';\nimport { sepolia } from 'viem/chains';\n\nexport const mordor = defineChain({\n id: 63,\n name: 'Mordor Testnet',\n network: 'mordor',\n nativeCurrency: {\n decimals: 18,\n name: 'Mordor Ether',\n symbol: 'METC',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc.mordor.etccooperative.org'],\n webSocket: ['wss://rpc.mordor.etccooperative.org/ws'],\n },\n },\n blockExplorers: {\n default: { name: 'BlockScout', url: 'https://blockscout.com/etc/mordor' },\n },\n testnet: true,\n});\n\nexport const milkomeda = defineChain({\n id: 2001,\n name: 'Milkomeda C1 Mainnet',\n network: 'milkomeda',\n nativeCurrency: {\n decimals: 18,\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n },\n },\n blockExplorers: {\n default: { name: 'Milkomeda Explorer', url: 'https://explorer-mainnet-cardano-evm.c1.milkomeda.com' },\n },\n testnet: false,\n});\n\nexport const etcMainnet = defineChain({\n id: 61,\n name: 'Ethereum Classic',\n network: 'etc',\n nativeCurrency: {\n decimals: 18,\n name: 'Ethereum Classic',\n symbol: 'ETC',\n },\n rpcUrls: {\n default: {\n http: ['https://etc.rivet.link'],\n },\n },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://blockscout.com/etc/mainnet' },\n },\n testnet: false,\n});\n\nexport const getChainByNetworkKey = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return sepolia;\n case 'ethereum-classic':\n return etcMainnet;\n case 'milkomeda-mainnet':\n return milkomeda;\n default:\n return null;\n }\n};\n\nexport const getChainConfigForWallet = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return {\n chainId: `0x${sepolia.id.toString(16)}`,\n chainName: 'Sepolia',\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n rpcUrls: sepolia.rpcUrls.default.http,\n blockExplorerUrls: sepolia.blockExplorers?.default?.url ? [sepolia.blockExplorers.default.url] : [],\n };\n case 'ethereum-classic':\n return {\n chainId: `0x${etcMainnet.id.toString(16)}`,\n chainName: 'Ethereum Classic',\n nativeCurrency: {\n name: 'Ethereum Classic',\n symbol: 'ETC',\n decimals: 18,\n },\n rpcUrls: ['https://etc.rivet.link'],\n blockExplorerUrls: ['https://blockscout.com/etc/mainnet'],\n };\n case 'milkomeda-mainnet':\n return {\n chainId: `0x${milkomeda.id.toString(16)}`,\n chainName: 'Milkomeda C1 Mainnet',\n nativeCurrency: {\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n decimals: 18,\n },\n rpcUrls: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n blockExplorerUrls: ['https://explorer-mainnet-cardano-evm.c1.milkomeda.com'],\n };\n default:\n return null;\n }\n};\n","import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { createWalletClient, createPublicClient, custom, http } from 'viem';\nimport { useNetwork } from './NetworkContext';\nimport { getChainByNetworkKey, getChainConfigForWallet } from './chains';\n\nconst WalletContext = createContext(null);\n\nexport const useWallet = () => {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used within a WalletProvider');\n }\n return context;\n};\n\nconst switchToNetwork = async (networkKey) => {\n if (!window.ethereum) {\n throw new Error('MetaMask not installed');\n }\n\n const chainConfig = getChainConfigForWallet(networkKey);\n if (!chainConfig) {\n throw new Error(`Unsupported network: ${networkKey}`);\n }\n\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: chainConfig.chainId }],\n });\n } catch (switchError) {\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [chainConfig],\n });\n } catch (addError) {\n if (addError.code === 4001) {\n throw new Error(`User rejected adding ${chainConfig.chainName} to MetaMask. Please add it manually.`);\n }\n throw new Error(`Failed to add ${chainConfig.chainName} to MetaMask: ${addError.message}`);\n }\n } else if (switchError.code === 4001) {\n throw new Error(`User rejected switching to ${chainConfig.chainName}. Please switch manually in MetaMask.`);\n } else {\n throw new Error(`Failed to switch to ${chainConfig.chainName}: ${switchError.message}`);\n }\n }\n};\n\nexport const WalletProvider = ({ children }) => {\n const { selectedNetwork } = useNetwork();\n const [walletClient, setWalletClient] = useState(null);\n const [publicClient, setPublicClient] = useState(null);\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [balance, setBalance] = useState(null);\n const [error, setError] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n\n const selectedChain = selectedNetwork ? getChainByNetworkKey(selectedNetwork) : null;\n const expectedChainId = selectedChain ? selectedChain.id : null;\n\n const handleAccountsChangedRef = useRef(null);\n const handleChainChangedRef = useRef(null);\n\n const disconnectWalletInternal = useCallback(() => {\n setWalletClient(null);\n setPublicClient(null);\n setAccount(null);\n setChainId(null);\n setBalance(null);\n setError(null);\n }, []);\n\n const handleChainChanged = useCallback(async (chainIdHex) => {\n const newChainId = parseInt(chainIdHex, 16);\n setChainId(newChainId);\n\n if (selectedChain && newChainId === expectedChainId) {\n setError(null);\n if (window.ethereum && selectedChain) {\n const newWalletClient = createWalletClient({ \n chain: selectedChain, \n transport: custom(window.ethereum) \n });\n setWalletClient(newWalletClient);\n }\n } else if (selectedChain && newChainId !== expectedChainId) {\n const chainName = selectedChain?.name || selectedNetwork || 'selected network';\n setError(`Wrong network detected. Please switch to ${chainName}`);\n }\n }, [selectedChain, expectedChainId, selectedNetwork]);\n\n handleChainChangedRef.current = handleChainChanged;\n\n const handleAccountsChanged = useCallback(async (accounts) => {\n if (accounts.length === 0) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n } else {\n setAccount(accounts[0]);\n if (selectedChain) {\n try {\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n }\n }\n }, [selectedChain, disconnectWalletInternal]);\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n\n const disconnectWallet = useCallback(() => {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }, [disconnectWalletInternal]);\n\n const connectPublicClient = useCallback(() => {\n if (selectedChain) {\n setPublicClient(createPublicClient({ chain: selectedChain, transport: http() }));\n }\n }, [selectedChain]);\n\n const connectWallet = useCallback(async () => {\n if (!window.ethereum) {\n setError('Please install MetaMask or another Web3 wallet');\n return false;\n }\n\n if (!selectedNetwork || !selectedChain) {\n setError('Please select a network first');\n return false;\n }\n\n setIsConnecting(true);\n setError(null);\n\n try {\n const accounts = await window.ethereum.request({ \n method: 'eth_requestAccounts' \n });\n\n if (accounts.length === 0) {\n throw new Error('No wallet address found. Please unlock your wallet.');\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n await switchToNetwork(selectedNetwork);\n }\n\n const newWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(newWalletClient);\n setAccount(accounts[0]);\n setChainId(expectedChainId);\n\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n try {\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n handleChainChangedRef.current = handleChainChanged;\n window.ethereum.on('accountsChanged', handleAccountsChanged);\n window.ethereum.on('chainChanged', handleChainChanged);\n\n return true;\n } catch (err) {\n console.error('Error connecting wallet:', err);\n setError(err.message);\n return false;\n } finally {\n setIsConnecting(false);\n }\n }, [selectedNetwork, selectedChain, expectedChainId, handleAccountsChanged, handleChainChanged]);\n\n const ensureCorrectNetwork = useCallback(async () => {\n if (!window.ethereum || !selectedNetwork || !selectedChain || !account) {\n const errorMsg = 'Wallet not connected or network not selected';\n setError(errorMsg);\n return null;\n }\n\n try {\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n setError(null);\n await switchToNetwork(selectedNetwork);\n const NETWORK_SWITCH_DELAY_MS = 500;\n await new Promise(resolve => setTimeout(resolve, NETWORK_SWITCH_DELAY_MS));\n \n const newChainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const newChainId = parseInt(newChainIdHex, 16);\n if (newChainId !== expectedChainId) {\n throw new Error(`Failed to switch network. MetaMask is still on chain ${newChainId}, expected ${expectedChainId}`);\n }\n }\n\n const freshWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(freshWalletClient);\n setChainId(expectedChainId);\n setError(null);\n return freshWalletClient;\n } catch (err) {\n setError(err.message);\n return null;\n }\n }, [selectedNetwork, selectedChain, expectedChainId, account]);\n\n const prevNetworkRef = useRef(selectedNetwork);\n\n useEffect(() => {\n if (prevNetworkRef.current !== null && \n prevNetworkRef.current !== selectedNetwork && \n account) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }\n prevNetworkRef.current = selectedNetwork;\n }, [selectedNetwork, account, disconnectWalletInternal]);\n\n useEffect(() => {\n connectPublicClient();\n }, [connectPublicClient]);\n\n return (\n \n {children}\n \n );\n};","import React, { useState, useEffect } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { useWallet } from \"../contexts/WalletContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport { parseEther, encodeFunctionData, parseUnits } from \"viem\"; \nimport styles from \"../styles/PricingCard.css\"; \n\nconst TransactionReview = ({ onTransactionComplete }) => {\n const {\n networkSelector,\n selectedNetwork,\n selectedToken,\n transactionDetails: contextTransactionDetails,\n setTransactionDetails,\n } = useNetwork();\n\n const {\n connectWallet,\n account,\n walletClient,\n publicClient,\n isConnecting,\n ensureCorrectNetwork,\n expectedChainId,\n } = useWallet();\n\n const [transaction, setTransaction] = useState(null);\n const [tradeDataBuySc, setTradeDataBuySc] = useState(null);\n const [txData, setTxData] = useState(null);\n const [message, setMessage] = useState(\"\");\n const [txHash, setTxHash] = useState(null);\n const [error, setError] = useState(null);\n const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false);\n\n useEffect(() => {\n setTxData(null);\n setTradeDataBuySc(null);\n setMessage(\"\");\n setError(null);\n setTxHash(null);\n }, [selectedNetwork, selectedToken]);\n\n useEffect(() => {\n const initializeTransaction = async () => {\n if (!selectedNetwork || !selectedToken) return;\n\n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const receivingAddress = networkSelector.getReceivingAddress();\n const tokenAmount = networkSelector.getTokenAmount(selectedToken.key);\n\n const newTransaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await newTransaction.init();\n setTransaction(newTransaction);\n\n let tradeData = null;\n if (selectedToken.key === \"native\") {\n try {\n tradeData = await newTransaction.handleTradeDataBuySc(String(tokenAmount));\n setTradeDataBuySc(tradeData);\n } catch (tradeError) {\n console.error(\"Error fetching trade data:\", tradeError);\n }\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: selectedToken.key,\n tokenSymbol: selectedToken.symbol,\n amount: tokenAmount || \"0\",\n receivingAddress,\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer: selectedToken.isDirectTransfer || false,\n isNativeToken: selectedToken.isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...newTransaction.getBlockchainDetails(),\n });\n } catch (err) {\n console.error(\"Error initializing transaction:\", err);\n }\n };\n\n initializeTransaction();\n }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]);\n\n if (!selectedNetwork || !selectedToken) {\n return null;\n }\n\n if (!contextTransactionDetails) {\n return
Initializing transaction...
;\n }\n\n const handleConnectWallet = async () => {\n await connectWallet();\n };\n\n const handleSendTransaction = async () => {\n if (!account || !contextTransactionDetails || !transaction) {\n setMessage(\"Wallet not connected or transaction details missing\");\n return;\n }\n\n try {\n setTxData(null);\n setError(null);\n setMessage(\"Preparing transaction...\");\n\n const receiver = contextTransactionDetails.receivingAddress;\n let builtTx;\n\n if (selectedToken.key === \"native\") {\n const UI = \"0x0232556C83791b8291E9b23BfEa7d67405Bd9839\";\n const amountToSend = tradeDataBuySc || \"0\";\n const valueInWei = parseEther(String(amountToSend));\n\n builtTx = await transaction.buyStablecoins(\n account,\n receiver,\n valueInWei,\n UI\n );\n\n builtTx = {\n ...builtTx,\n value: valueInWei,\n account: account,\n };\n } else {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const stablecoinAddress = networkConfig?.tokens?.stablecoin?.address;\n \n if (!stablecoinAddress) {\n throw new Error('Stablecoin address not found in network configuration');\n }\n\n const amountToSend = contextTransactionDetails.amount\n ? parseUnits(\n String(contextTransactionDetails.amount),\n contextTransactionDetails.stableCoinDecimals\n )\n : \"0\";\n\n builtTx = {\n to: stablecoinAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: [\n {\n inputs: [\n { internalType: \"address\", name: \"to\", type: \"address\" },\n { internalType: \"uint256\", name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ],\n functionName: \"transfer\",\n args: [receiver, amountToSend],\n }),\n account: account,\n };\n }\n\n setTxData(builtTx);\n setMessage(\"Transaction ready. Please confirm to proceed.\");\n } catch (error) {\n setError(error);\n const reason = error.shortMessage || (error.message ? error.message.split('\\n')[0] : \"Unknown error\");\n setMessage(`Transaction preparation failed: ${reason}`);\n }\n };\n\n const handleBuySc = async () => {\n setError(null);\n \n try {\n if (!account || !txData) {\n setMessage(\"Wallet account or transaction data is missing\");\n return;\n }\n\n if (!selectedNetwork) {\n setMessage(\"Network not selected\");\n return;\n }\n\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) {\n setMessage(\"Network configuration not found\");\n return;\n }\n\n setMessage(\"Verifying network...\");\n\n const freshWalletClient = await ensureCorrectNetwork();\n if (!freshWalletClient) {\n setMessage(\"Failed to switch to correct network. Please approve the network switch in MetaMask and try again.\");\n return;\n }\n\n if (!window.ethereum) {\n setMessage(\"MetaMask not available\");\n return;\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== networkConfig.chainId) {\n const errorMsg = `Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`;\n setMessage(errorMsg);\n setError(new Error(errorMsg));\n return;\n }\n\n if (freshWalletClient.chain.id !== networkConfig.chainId) {\n const errorMsg = `Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`;\n setMessage(errorMsg);\n setError(new Error(errorMsg));\n return;\n }\n\n setMessage(\"Sending transaction...\");\n\n const txHash = await freshWalletClient.sendTransaction({\n ...txData,\n account: account,\n });\n\n setTxHash(txHash);\n setMessage(`Transaction sent!`);\n \n if (onTransactionComplete) {\n onTransactionComplete({\n txHash,\n network: selectedNetwork,\n token: selectedToken?.key,\n tokenSymbol: selectedToken?.symbol,\n amount: contextTransactionDetails?.amount,\n receivingAddress: contextTransactionDetails?.receivingAddress,\n });\n }\n } catch (error) {\n setError(error);\n const reason = error.shortMessage || (error.message ? error.message.split('\\n')[0] : \"Unknown error\");\n setMessage(`Transaction failed: ${reason}`);\n console.error('Transaction error:', error);\n }\n };\n\n const getExplorerUrl = () => {\n if (!txHash || !selectedNetwork) return null;\n\n const explorerBaseUrls = {\n \"ethereum-classic\": \"https://blockscout.com/etc/mainnet/tx/\",\n \"sepolia\": \"https://sepolia.etherscan.io/tx/\",\n \"milkomeda-mainnet\": \"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/\",\n };\n\n return explorerBaseUrls[selectedNetwork]\n ? `${explorerBaseUrls[selectedNetwork]}${txHash}`\n : null;\n };\n\n return (\n
\n
\n Network:\n {contextTransactionDetails.network}\n
\n\n
\n You Pay:\n \n {selectedToken.key === \"stablecoin\"\n ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}`\n : `${tradeDataBuySc ? tradeDataBuySc : \"Calculating...\"} ${\n contextTransactionDetails.tokenSymbol\n }`}\n \n
\n\n {message && (\n
\n {message}\n {error && (\n setIsErrorDetailsVisible(!isErrorDetailsVisible)}\n className={styles.detailsButton}\n >\n {isErrorDetailsVisible ? \"Hide Details\" : \"Show Details\"}\n \n )}\n
\n )}\n\n {isErrorDetailsVisible && error && (\n
\n
{error.message}
\n
\n )}\n\n {txHash && (\n
\n Transaction Hash:{\" \"}\n {getExplorerUrl() ? (\n \n {txHash.slice(0, 6)}...{txHash.slice(-6)}\n \n ) : (\n \n {txHash}\n \n )}\n
\n )}\n\n
\n {!account && (\n \n )}\n\n {account && !txData && (\n \n )}\n \n {account && txData && (\n \n )}\n
\n
\n );\n};\n\nexport default TransactionReview;\n","import React, { useState } from \"react\";\nimport PayButton from \"./PayButton\";\nimport Dialog from \"./Dialog\";\nimport NetworkDropdown from \"./NetworkDropdown\";\nimport TokenDropdown from \"./TokenDropdown\";\nimport TransactionReview from \"./TransactionReview\";\nimport { NetworkProvider, useNetwork } from \"../contexts/NetworkContext\";\nimport { WalletProvider } from \"../contexts/WalletContext\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst WidgetContent = ({ onClose, buttonSize, onTransactionComplete }) => {\n const { resetSelections } = useNetwork(); \n\n const handleClose = () => {\n resetSelections(); // Reset selections when closing the widget\n onClose();\n };\n\n return (\n \n \n \n \n \n );\n};\n\nconst WidgetWithProviders = ({ onClose, buttonSize, networkSelector, onTransactionComplete }) => {\n return (\n \n \n \n \n \n );\n};\n\nexport const Widget = ({ networkSelector, buttonSize = \"medium\", onTransactionComplete, onSuccess }) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const handleOpenDialog = () => {\n setIsDialogOpen(true);\n };\n\n const handleCloseDialog = () => {\n setIsDialogOpen(false);\n };\n\n // Support both onTransactionComplete and onSuccess for backwards compatibility\n const handleTransactionComplete = onTransactionComplete || onSuccess;\n\n return (\n
\n {!isDialogOpen && (\n \n )}\n {isDialogOpen && (\n \n )}\n
\n );\n};\n\nexport default Widget;\n","// src/index.js\nimport { NetworkSelector } from './core/NetworkSelector';\nimport { Transaction } from './core/Transaction';\nimport { Config } from './core/MerchantConfig';\nimport Widget from './widget/Widget.jsx';\nimport PayButton from './widget/PayButton.jsx';\nimport Dialog from './widget/Dialog.jsx';\nimport NetworkDropdown from './widget/NetworkDropdown.jsx';\nimport './styles/main.css';\nimport './styles/PricingCard.css';\n\nconst StablePay = {\n NetworkSelector,\n Transaction,\n Config,\n Widget,\n PayButton,\n Dialog,\n NetworkDropdown\n};\n\nexport default StablePay;","import { networksConfig } from \"../utils/config\";\n\nexport class NetworkSelector {\n constructor(merchantConfig) {\n this.merchantConfig = merchantConfig;\n this.blacklist = merchantConfig.getBlacklist();\n this.availableNetworks = this.getAvailableNetworks();\n this.selectedNetwork = null;\n }\n\n getAvailableNetworks() {\n return Object.entries(networksConfig).reduce(\n (acc, [networkKey, networkConfig]) => {\n if (!this.blacklist.includes(networkConfig.chainId)) {\n acc[networkKey] = networkConfig;\n }\n return acc;\n },\n {}\n );\n }\n\n selectNetwork(networkKey) {\n if (networkKey === null) {\n this.selectedNetwork = null;\n console.log(\"Network selection reset\");\n return true;\n }\n if (this.availableNetworks[networkKey]) {\n this.selectedNetwork = networkKey;\n console.log(`Network selected: ${networkKey}`);\n return true;\n }\n console.error(`Invalid network: ${networkKey}`);\n return false;\n }\n\n getSelectedNetworkConfig() {\n return this.selectedNetwork\n ? this.availableNetworks[this.selectedNetwork]\n : null;\n }\n\n getReceivingAddress() {\n return this.merchantConfig.getReceivingAddress();\n }\n\n getTokenAmount(token) {\n return this.merchantConfig.getTokenAmount(this.selectedNetwork, token);\n }\n}\n","import { networksConfig } from \"../utils/config\";\n\nexport class Config {\n constructor(options = {}) {\n this.receivingAddress = options.receivingAddress || \"\";\n this.blacklist = options.blacklist || [];\n this.amounts = options.amounts || options.Amounts || {};\n this.validateConfig();\n }\n\n validateConfig() {\n if (!this.receivingAddress) {\n throw new Error(\"Receiving address is required\");\n }\n // Validate stablecoin amounts\n for (const [network, tokens] of Object.entries(this.amounts)) {\n if (!networksConfig[network]) {\n throw new Error(`Invalid network: ${network}`);\n }\n if (\n !tokens.stablecoin ||\n typeof tokens.stablecoin !== \"number\" ||\n tokens.stablecoin <= 0\n ) {\n throw new Error(`Invalid stablecoin amount for network ${network}`);\n }\n }\n }\n\n getBlacklist() {\n return this.blacklist;\n }\n\n getReceivingAddress() {\n return this.receivingAddress;\n }\n\n // getTokenAmount(network, token) {\n // const networkConfig = networksConfig[network];\n // if (!networkConfig) return 0;\n\n // const stablecoinSymbol = networkConfig.tokens.stablecoin.symbol;\n\n // if (token === 'stablecoin') {\n // return this.amounts[network]?.stablecoin || 0;\n // }\n // // For native tokens, return 0 as it's not specified in the new structure\n // return 0;\n // }\n getTokenAmount(network) {\n console.log(\"Getting amount for network:\", network);\n console.log(\"Amounts object:\", this.amounts);\n\n // Directly return the stablecoin amount for the network\n const amount = this.amounts[network]?.stablecoin;\n console.log(\"Returning amount:\", amount);\n\n return amount || 0;\n }\n}\n\nexport default Config;\n"],"names":["networksConfig","sepolia","uri","chainId","djedAddress","tokens","stablecoin","symbol","address","decimals","isDirectTransfer","native","isNative","feeUI","Transaction","constructor","networkUri","this","init","Error","web3","getWeb3","djedContract","getDjedContract","stableCoin","reserveCoin","getCoinContracts","scDecimals","rcDecimals","getDecimals","oracleContract","getOracleAddress","then","addr","getOracleContract","_address","oracleAddress","contractError","console","error","message","includes","getNetworkInfo","name","networkName","getNetworkName","getBlockchainDetails","web3Available","djedContractAvailable","stableCoinAddress","reserveCoinAddress","stableCoinDecimals","reserveCoinDecimals","oracleContractAvailable","handleTradeDataBuySc","amountScaled","tradeDataPriceBuySc","totalBCScaled","buyStablecoins","payer","receiver","value","UI","buyScTx","PayButton","onClick","size","sizeStyles","small","width","height","fontSize","medium","large","logoSizes","buttonStyle","logoStyle","React","createElement","className","styles","style","Dialog","children","onClose","dialogOverlay","pricingCard","dialogClose","pricingCardHeader","allianceLogo","stablepayTitle","pricingCardBody","TokenSelector","networkSelector","selectedToken","selectToken","tokenKey","networkConfig","getSelectedNetworkConfig","key","getSelectedToken","getAvailableTokens","Object","entries","map","config","resetSelection","NetworkContext","createContext","NetworkProvider","tokenSelector","useState","selectedNetwork","setSelectedNetwork","setSelectedToken","transactionDetails","setTransactionDetails","resetState","useEffect","Provider","selectNetwork","networkKey","token","resetSelections","useNetwork","context","useContext","undefined","NetworkDropdown","selectField","htmlFor","id","onChange","event","target","disabled","keys","availableNetworks","TokenDropdown","loading","setLoading","setError","availableTokens","async","newValue","transaction","tokenAmount","getTokenAmount","blockchainDetails","tradeData","String","network","tokenSymbol","amount","receivingAddress","getReceivingAddress","djedContractAddress","isNativeToken","tradeAmount","err","defineChain","nativeCurrency","rpcUrls","default","http","webSocket","blockExplorers","url","testnet","milkomeda","etcMainnet","WalletContext","switchToNetwork","window","ethereum","chainConfig","toString","chainName","blockExplorerUrls","getChainConfigForWallet","request","method","params","switchError","code","addError","WalletProvider","walletClient","setWalletClient","publicClient","setPublicClient","account","setAccount","setChainId","balance","setBalance","isConnecting","setIsConnecting","selectedChain","getChainByNetworkKey","expectedChainId","handleAccountsChangedRef","useRef","handleChainChangedRef","disconnectWalletInternal","useCallback","handleChainChanged","newChainId","parseInt","chainIdHex","newWalletClient","createWalletClient","chain","transport","custom","current","handleAccountsChanged","accounts","length","accountsHandler","chainHandler","removeListener","newPublicClient","createPublicClient","getBalance","parseFloat","Math","pow","disconnectWallet","connectPublicClient","connectWallet","on","ensureCorrectNetwork","NETWORK_SWITCH_DELAY_MS","Promise","resolve","setTimeout","newChainIdHex","freshWalletClient","prevNetworkRef","TransactionReview","onTransactionComplete","contextTransactionDetails","useWallet","setTransaction","tradeDataBuySc","setTradeDataBuySc","txData","setTxData","setMessage","txHash","setTxHash","isErrorDetailsVisible","setIsErrorDetailsVisible","newTransaction","tradeError","initializeTransaction","getExplorerUrl","explorerBaseUrls","transactionReview","transactionInfo","transactionLabel","transactionValue","highlight","messageBox","detailsButton","errorDetails","transactionLink","href","rel","explorerLink","slice","wordBreak","walletButtonContainer","walletButton","builtTx","amountToSend","valueInWei","parseEther","stablecoinAddress","parseUnits","to","data","encodeFunctionData","abi","inputs","internalType","type","outputs","stateMutability","functionName","args","reason","shortMessage","split","currentChainId","errorMsg","sendTransaction","WidgetContent","buttonSize","handleClose","WidgetWithProviders","NetworkSelector","merchantConfig","blacklist","getBlacklist","getAvailableNetworks","reduce","acc","log","Config","options","amounts","Amounts","validateConfig","Widget","onSuccess","isDialogOpen","setIsDialogOpen","handleTransactionComplete","widgetContainer","handleOpenDialog","handleCloseDialog"],"mappings":"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"} \ No newline at end of file diff --git a/stablepay-sdk/dist/umd/styles.css b/stablepay-sdk/dist/umd/styles.css index a6df6b0..24e94a1 100644 --- a/stablepay-sdk/dist/umd/styles.css +++ b/stablepay-sdk/dist/umd/styles.css @@ -1 +1 @@ -.main_stablePayButton__UA7HC{align-items:center;background:linear-gradient(90deg,#000,#f7941d);border:1px solid #bc5f26;border-radius:3px;box-sizing:border-box;color:#fff;cursor:pointer;display:flex;font-size:24px;font-weight:700;height:104px;justify-content:flex-start;overflow:hidden;padding:0 20px;position:relative;width:372px}.main_stablePayButton__UA7HC:hover{opacity:.9}.main_stablePayButton__UA7HC .main_logo__ITyEy{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;flex-shrink:0;height:25px;margin-right:20px;width:25px}.main_stablePayButton__UA7HC .main_buttonText__N-ewy{flex-grow:1;text-align:center}.PricingCard_dialogOverlay__0XJrE{align-items:center;backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px);background-color:hsla(0,0%,100%,.1);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:1000}.PricingCard_pricingCard__LrWb9{align-items:center;background:#2c2c2c;border:1px solid hsla(0,0%,85%,.1);border-radius:8px;box-sizing:border-box;display:flex;flex-direction:column;padding:24px;position:relative}.PricingCard_pricingCard__LrWb9.PricingCard_small__J4CHj{height:600px;width:360px}.PricingCard_pricingCard__LrWb9.PricingCard_medium__EVmTB{height:680px;width:400px}.PricingCard_pricingCard__LrWb9.PricingCard_large__A6pnX{height:760px;width:440px}.PricingCard_dialogClose__jJ1tM{background:none;border:none;color:#fff;cursor:pointer;font-size:20px;position:absolute;right:16px;top:16px;z-index:5}.PricingCard_pricingCardHeader__wGczA{align-items:center;display:flex;gap:12px;margin-bottom:40px;width:100%}.PricingCard_allianceLogo__URa-U{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:55px;width:55px}.PricingCard_stablepayTitle__4t848{align-items:center;color:#f6941c;display:flex;font-family:Inter,sans-serif;font-size:29.2px;font-style:normal;font-weight:600;line-height:35px}.PricingCard_pricingCardBody__0wKQn{display:flex;flex-direction:column;gap:30px;width:100%}.PricingCard_selectField__LBPoZ{align-items:flex-start;display:flex;flex-direction:column;gap:8px;margin-bottom:30px;width:100%}.PricingCard_selectField__LBPoZ label{align-self:flex-start;color:#636a77;margin-bottom:6px;text-align:left}.PricingCard_selectField__LBPoZ label,.PricingCard_selectField__LBPoZ select{font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:500;line-height:19px;width:100%}.PricingCard_selectField__LBPoZ select{appearance:none;background:#fff;background-image:url(../assets/chevron-down-icon.svg);background-position:right 18px center;background-repeat:no-repeat;border:1px solid #d9d9d9;border-radius:6px;box-sizing:border-box;color:#000;height:49px;padding:10px 14px}.PricingCard_selectField__LBPoZ select:disabled{background-color:#f5f5f5;cursor:not-allowed}.PricingCard_transactionReview__Ix-eL{padding:20px 0;width:100%}.PricingCard_transactionInfo__Ck-Rc{align-items:center;display:flex;justify-content:space-between;margin:15px 0;padding:0 5px;width:100%}.PricingCard_transactionLabel__GDux7{color:#636a77;font-weight:500}.PricingCard_transactionLabel__GDux7,.PricingCard_transactionValue__q-xxp{font-family:Inter,sans-serif;font-size:16px;font-style:normal;line-height:19px}.PricingCard_transactionValue__q-xxp{color:#fff;font-weight:600;text-align:right}.PricingCard_infoSection__gyjMQ{align-items:flex-start;display:flex;gap:16px;margin-bottom:40px;margin-top:20px;padding:0 26px}.PricingCard_infoIcon__rraxD{align-items:center;background:#d5d6d9;border-radius:50%;color:#434a58;display:flex;font-size:13px;height:21px;justify-content:center;min-width:22px;width:22px}.PricingCard_infoText__l4b7A{color:#636a77;font-family:Inter,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:17px}.PricingCard_walletButton__llw4v{align-items:center;background:#f6941c;border:1px solid #c66c20;border-radius:0;bottom:31px;color:#fde5cb;cursor:pointer;display:flex;font-family:Inter,sans-serif;font-size:18px;font-style:normal;font-weight:600;height:65px;justify-content:center;left:30px;line-height:22px;position:absolute;width:calc(100% - 60px)}.PricingCard_walletButton__llw4v:disabled{background:#ccc;border-color:#bbb;cursor:not-allowed}.PricingCard_loading__2-tGA{color:#636a77;font-family:Inter,sans-serif;padding:20px;text-align:center}.PricingCard_error__m5fK-{color:#ff4d4f;font-family:Inter,sans-serif;padding:10px;text-align:center}.PricingCard_networkError__zR-36{background:rgba(255,77,79,.1);border:1px solid rgba(255,77,79,.2);border-radius:4px;margin:10px 0;padding:10px}.PricingCard_errorText__qZRJt{color:#ff4d4f;font-family:Inter,sans-serif;font-size:14px;line-height:1.5}.PricingCard_message-box__vkUKy{align-items:center;background-color:hsla(0,0%,100%,.1);border-radius:4px;color:#fff;display:flex;font-family:Inter,sans-serif;font-size:14px;justify-content:space-between;margin-top:20px;padding:10px}.PricingCard_detailsButton__jHglL{background:none;border:none;color:#f6941c;cursor:pointer;font-size:12px;margin-left:10px;text-decoration:underline}.PricingCard_errorDetails__CzN-7{background-color:rgba(0,0,0,.2);border:1px solid rgba(255,77,79,.3);border-radius:4px;color:#ff4d4f;font-family:monospace;font-size:12px;line-height:1.4;margin-top:10px;max-height:150px;max-width:100%;overflow:auto;overflow-wrap:break-word;padding:10px;white-space:pre-wrap;word-break:break-word}.PricingCard_errorDetails__CzN-7::-webkit-scrollbar{height:6px;width:6px}.PricingCard_errorDetails__CzN-7::-webkit-scrollbar-track{background:rgba(0,0,0,.1);border-radius:3px}.PricingCard_errorDetails__CzN-7::-webkit-scrollbar-thumb{background:rgba(255,77,79,.5);border-radius:3px}.PricingCard_errorDetails__CzN-7::-webkit-scrollbar-thumb:hover{background:rgba(255,77,79,.7)}@media (max-width:520px){.PricingCard_pricingCard__LrWb9{height:auto;min-height:600px;padding:20px;width:95vw}.PricingCard_selectField__LBPoZ{margin-bottom:20px}.PricingCard_walletButton__llw4v{left:20px;margin-top:20px;position:relative;width:calc(100% - 40px)}.PricingCard_infoSection__gyjMQ{padding:0 20px}.PricingCard_loadingContainer__6nOVa{align-items:center;display:flex;height:100vh;justify-content:center}.PricingCard_spinner__9ucQv{animation:PricingCard_spin__24tni .8s linear infinite;border:4px solid hsla(0,0%,100%,.3);border-radius:50%;border-top-color:#fff;height:40px;width:40px}@keyframes PricingCard_spin__24tni{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}} \ No newline at end of file +.main_stablePayButton__UA7HC{align-items:center;background:linear-gradient(90deg,#000,#f7941d);border:1px solid #bc5f26;border-radius:3px;box-sizing:border-box;color:#fff;cursor:pointer;display:flex;font-size:24px;font-weight:700;height:104px;justify-content:flex-start;overflow:hidden;padding:0 20px;position:relative;width:372px}.main_stablePayButton__UA7HC:hover{opacity:.9}.main_stablePayButton__UA7HC .main_logo__ITyEy{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;flex-shrink:0;height:25px;margin-right:20px;width:25px}.main_stablePayButton__UA7HC .main_buttonText__N-ewy{flex-grow:1;text-align:center}@keyframes PricingCard_fadeInScale__2MTi3{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.PricingCard_dialogOverlay__0XJrE{align-items:center;animation:PricingCard_fadeInScale__2MTi3 .2s ease-out;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background-color:rgba(0,0,0,.4);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:1000}.PricingCard_pricingCard__LrWb9{background:#242529;border:1px solid hsla(0,0%,100%,.08);border-radius:20px;box-shadow:0 15px 35px rgba(0,0,0,.4),inset 0 1px 0 hsla(0,0%,100%,.05);box-sizing:border-box;display:flex;flex-direction:column;padding:32px;position:relative}.PricingCard_pricingCard__LrWb9.PricingCard_small__J4CHj{min-height:520px;width:360px}.PricingCard_pricingCard__LrWb9.PricingCard_medium__EVmTB{min-height:580px;width:400px}.PricingCard_pricingCard__LrWb9.PricingCard_large__A6pnX{min-height:640px;width:440px}.PricingCard_dialogClose__jJ1tM{align-items:center;background:hsla(0,0%,100%,.1);border:none;border-radius:50%;color:#a0aec0;cursor:pointer;display:flex;font-size:20px;height:32px;justify-content:center;line-height:1;padding:0 0 3px;position:absolute;right:20px;top:20px;transition:all .2s ease;width:32px;z-index:5}.PricingCard_dialogClose__jJ1tM:hover{background:hsla(0,0%,100%,.2);color:#fff}.PricingCard_pricingCardHeader__wGczA{align-items:center;border-bottom:1px solid hsla(0,0%,100%,.05);display:flex;gap:16px;margin-bottom:30px;padding-bottom:20px;width:100%}.PricingCard_allianceLogo__URa-U{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:48px;width:48px}.PricingCard_stablepayTitle__4t848{align-items:center;color:#f6941c;display:flex;font-family:Inter,sans-serif;font-size:26px;font-style:normal;font-weight:700;letter-spacing:-.5px}.PricingCard_pricingCardBody__0wKQn{display:flex;flex:1;flex-direction:column;width:100%}.PricingCard_selectField__LBPoZ{display:flex;flex-direction:column;gap:10px;margin-bottom:24px;width:100%}.PricingCard_selectField__LBPoZ label{align-self:flex-start;color:#a0aec0;font-family:Inter,sans-serif;font-size:14px;font-style:normal;font-weight:500;text-align:left;width:100%}.PricingCard_selectField__LBPoZ select{appearance:none;background:hsla(0,0%,100%,.05);background-image:url(../assets/chevron-down-icon.svg);background-position:right 18px center;background-repeat:no-repeat;border:1px solid hsla(0,0%,100%,.1);border-radius:12px;box-sizing:border-box;color:#fff;cursor:pointer;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:500;height:52px;padding:12px 16px;transition:all .2s ease;width:100%}.PricingCard_selectField__LBPoZ select:hover:not(:disabled){background:hsla(0,0%,100%,.08);border-color:rgba(246,148,28,.5)}.PricingCard_selectField__LBPoZ select:focus{border-color:#f6941c;box-shadow:0 0 0 3px rgba(246,148,28,.2);outline:none}.PricingCard_selectField__LBPoZ select:disabled{cursor:not-allowed;opacity:.5}.PricingCard_selectField__LBPoZ select option{background:#242529;color:#fff}.PricingCard_transactionReview__Ix-eL{display:flex;flex:1;flex-direction:column;padding-top:10px;width:100%}.PricingCard_transactionInfo__Ck-Rc{align-items:center;background:rgba(0,0,0,.2);border:1px solid hsla(0,0%,100%,.05);border-radius:12px;display:flex;justify-content:space-between;margin-bottom:16px;padding:14px 18px;width:100%}.PricingCard_transactionLabel__GDux7{color:#a0aec0;font-family:Inter,sans-serif;font-size:15px;font-style:normal;font-weight:500}.PricingCard_transactionValue__q-xxp{color:#fff;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:700;text-align:right}.PricingCard_transactionValue__q-xxp.PricingCard_highlight__WZZ6N{color:#f6941c;font-size:18px}.PricingCard_walletButtonContainer__a6MwB{margin-top:auto;padding-top:24px}.PricingCard_walletButton__llw4v{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:14px;box-shadow:0 4px 14px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;font-family:Inter,sans-serif;font-size:17px;font-style:normal;font-weight:600;height:56px;justify-content:center;transition:all .2s ease;width:100%}.PricingCard_walletButton__llw4v:hover:not(:disabled){box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_walletButton__llw4v:active:not(:disabled){transform:translateY(0)}.PricingCard_walletButton__llw4v:disabled{background:hsla(0,0%,100%,.1);box-shadow:none;color:#636a77;cursor:not-allowed}.PricingCard_loading__2-tGA{align-items:center;color:#a0aec0;display:flex;flex-direction:column;font-family:Inter,sans-serif;gap:16px;padding:40px;text-align:center}.PricingCard_error__m5fK-{color:#ff4d4f;font-family:Inter,sans-serif;font-size:14px;margin-top:4px;text-align:left}.PricingCard_messageBox__wnx0F{align-items:center;animation:PricingCard_fadeIn__L63q8 .3s ease-out;color:#e2e8f0;display:flex;flex-direction:column;font-family:Inter,sans-serif;font-size:13.5px;font-weight:500;gap:8px;margin-bottom:16px;padding:8px 0;text-align:center}@keyframes PricingCard_fadeIn__L63q8{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.PricingCard_detailsButton__jHglL{background:none;border:none;color:#f6941c;cursor:pointer;font-size:13px;font-weight:600;margin-top:4px;padding:0;text-decoration:none}.PricingCard_detailsButton__jHglL:hover{text-decoration:underline}.PricingCard_errorDetails__CzN-7{background-color:rgba(0,0,0,.2);border-left:3px solid #ff4d4f;border-radius:8px;color:#fc8181;font-family:monospace;font-size:11px;line-height:1.5;margin-top:10px;max-height:150px;overflow-y:auto;padding:12px;text-align:left;white-space:pre-wrap;word-break:break-all}.PricingCard_transactionLink__RFRWW{background:rgba(40,167,69,.1);border:1px solid rgba(40,167,69,.2);border-radius:12px;color:#fff;font-family:Inter,sans-serif;font-size:14px;margin-top:20px;padding:16px;text-align:center}.PricingCard_explorerLink__-a82-{color:#f6941c;font-weight:600;text-decoration:none;transition:color .2s ease}.PricingCard_explorerLink__-a82-:hover{color:#ffad42;text-decoration:underline}.PricingCard_stablePayButton__Y4Rr4{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:16px;box-shadow:0 4px 15px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;gap:12px;justify-content:center;transition:all .2s ease}.PricingCard_stablePayButton__Y4Rr4:hover{box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_stablePayButton__Y4Rr4:active{transform:translateY(0)}.PricingCard_buttonText__8LnPv{font-family:Inter,sans-serif;font-weight:600}@media (max-width:520px){.PricingCard_pricingCard__LrWb9{border:none;border-radius:0;height:100%;min-height:100vh;padding:24px;width:100%}.PricingCard_dialogOverlay__0XJrE{align-items:flex-start;background-color:#242529}} \ No newline at end of file diff --git a/stablepay-sdk/src/styles/PricingCard.css b/stablepay-sdk/src/styles/PricingCard.css index 187ff2d..740d8fd 100644 --- a/stablepay-sdk/src/styles/PricingCard.css +++ b/stablepay-sdk/src/styles/PricingCard.css @@ -1,68 +1,96 @@ +@keyframes fadeInScale { + 0% { + opacity: 0; + transform: scale(0.95); + } + 100% { + opacity: 1; + transform: scale(1); + } +} + .dialogOverlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; - background-color: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(5px); - -webkit-backdrop-filter: blur(5px); + background-color: rgba(0, 0, 0, 0.4); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); display: flex; justify-content: center; align-items: center; z-index: 1000; + animation: fadeInScale 0.2s ease-out; } .pricingCard { box-sizing: border-box; display: flex; flex-direction: column; - align-items: center; - padding: 24px; - background: #2c2c2c; - border: 1px solid rgba(217, 217, 217, 0.1); - border-radius: 8px; + padding: 32px; + background: #242529; + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 20px; position: relative; + box-shadow: 0 15px 35px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05); } .pricingCard.small { width: 360px; - height: 600px; + min-height: 520px; } .pricingCard.medium { width: 400px; - height: 680px; + min-height: 580px; } .pricingCard.large { width: 440px; - height: 760px; + min-height: 640px; } .dialogClose { position: absolute; - right: 16px; - top: 16px; - background: none; + right: 20px; + top: 20px; + background: rgba(255, 255, 255, 0.1); border: none; - color: #ffffff; + border-radius: 50%; + width: 32px; + height: 32px; + display: flex; + justify-content: center; + align-items: center; + color: #a0aec0; font-size: 20px; cursor: pointer; z-index: 5; + transition: all 0.2s ease; + line-height: 1; + padding: 0 0 3px 0; /* Optical adjustment to center the 'x' vertically */ +} + +.dialogClose:hover { + background: rgba(255, 255, 255, 0.2); + color: #ffffff; } .pricingCardHeader { display: flex; align-items: center; width: 100%; - margin-bottom: 40px; - gap: 12px; + margin-bottom: 30px; + padding-bottom: 20px; + border-bottom: 1px solid rgba(255, 255, 255, 0.05); + gap: 16px; } .allianceLogo { - width: 55px; - height: 55px; + width: 48px; + height: 48px; background-image: url("../assets/stablepay-logo.svg"); background-position: center; background-size: contain; @@ -72,70 +100,88 @@ .stablepayTitle { font-family: "Inter", sans-serif; font-style: normal; - font-weight: 600; - font-size: 29.2px; - line-height: 35px; + font-weight: 700; + font-size: 26px; color: #f6941c; display: flex; align-items: center; + letter-spacing: -0.5px; } .pricingCardBody { width: 100%; display: flex; flex-direction: column; - gap: 30px; + flex: 1; } .selectField { display: flex; flex-direction: column; - gap: 8px; + gap: 10px; width: 100%; - margin-bottom: 30px; - align-items: flex-start; /* Added this line */ + margin-bottom: 24px; } .selectField label { font-family: "Inter", sans-serif; font-style: normal; font-weight: 500; - font-size: 16px; - line-height: 19px; - color: #636a77; - margin-bottom: 6px; - align-self: flex-start; /* Added this line */ - text-align: left; /* Added this line */ - width: 100%; /* Added this line */ + font-size: 14px; + color: #a0aec0; + align-self: flex-start; + text-align: left; + width: 100%; } .selectField select { box-sizing: border-box; width: 100%; - height: 49px; - padding: 10px 14px; - background: #ffffff; - border: 1px solid #d9d9d9; - border-radius: 6px; + height: 52px; + padding: 12px 16px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 12px; font-family: "Inter", sans-serif; font-style: normal; font-weight: 500; font-size: 16px; - line-height: 19px; - color: #000000; + color: #ffffff; appearance: none; background-image: url("../assets/chevron-down-icon.svg"); background-repeat: no-repeat; background-position: right 18px center; + transition: all 0.2s ease; + cursor: pointer; +} + +.selectField select:hover:not(:disabled) { + border-color: rgba(246, 148, 28, 0.5); + background: rgba(255, 255, 255, 0.08); +} + +.selectField select:focus { + outline: none; + border-color: #f6941c; + box-shadow: 0 0 0 3px rgba(246, 148, 28, 0.2); } + .selectField select:disabled { - background-color: #f5f5f5; + opacity: 0.5; cursor: not-allowed; } +.selectField select option { + background: #242529; + color: #ffffff; +} + .transactionReview { width: 100%; - padding: 20px 0; + padding-top: 10px; + display: flex; + flex-direction: column; + flex: 1; } .transactionInfo { @@ -143,219 +189,213 @@ justify-content: space-between; align-items: center; width: 100%; - margin: 15px 0; - padding: 0 5px; + margin-bottom: 16px; + padding: 14px 18px; + background: rgba(0, 0, 0, 0.2); + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.05); } .transactionLabel { font-family: "Inter", sans-serif; font-style: normal; font-weight: 500; - font-size: 16px; - line-height: 19px; - color: #636a77; + font-size: 15px; + color: #a0aec0; } .transactionValue { font-family: "Inter", sans-serif; font-style: normal; - font-weight: 600; + font-weight: 700; font-size: 16px; - line-height: 19px; color: #ffffff; text-align: right; } -.infoSection { - display: flex; - align-items: flex-start; - gap: 16px; - padding: 0 26px; - margin-top: 20px; - margin-bottom: 40px; -} - -.infoIcon { - width: 22px; - height: 21px; - min-width: 22px; - background: #d5d6d9; - border-radius: 50%; - display: flex; - justify-content: center; - align-items: center; - font-size: 13px; - color: #434a58; +.transactionValue.highlight { + color: #f6941c; + font-size: 18px; } -.infoText { - font-family: "Inter", sans-serif; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 17px; - color: #636a77; +.walletButtonContainer { + margin-top: auto; + padding-top: 24px; } .walletButton { - width: calc(100% - 60px); - height: 65px; - position: absolute; - bottom: 31px; - left: 30px; - background: #f6941c; - border: 1px solid #c66c20; - border-radius: 0; + width: 100%; + height: 56px; + background: linear-gradient(135deg, #f6941c 0%, #d87c12 100%); + border: none; + border-radius: 14px; font-family: "Inter", sans-serif; font-style: normal; font-weight: 600; - font-size: 18px; - line-height: 22px; - color: #fde5cb; + font-size: 17px; + color: #ffffff; cursor: pointer; display: flex; align-items: center; justify-content: center; + transition: all 0.2s ease; + box-shadow: 0 4px 14px rgba(246, 148, 28, 0.3); +} + +.walletButton:hover:not(:disabled) { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(246, 148, 28, 0.4); +} + +.walletButton:active:not(:disabled) { + transform: translateY(0); } .walletButton:disabled { - background: #cccccc; - border-color: #bbbbbb; + background: rgba(255, 255, 255, 0.1); + color: #636a77; + box-shadow: none; cursor: not-allowed; } .loading { text-align: center; - color: #636a77; + color: #a0aec0; font-family: "Inter", sans-serif; - padding: 20px; + padding: 40px; + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; } .error { color: #ff4d4f; - text-align: center; - padding: 10px; - font-family: "Inter", sans-serif; -} - -.networkError { - margin: 10px 0; - padding: 10px; - background: rgba(255, 77, 79, 0.1); - border: 1px solid rgba(255, 77, 79, 0.2); - border-radius: 4px; -} - -.errorText { - color: #ff4d4f; + text-align: left; font-family: "Inter", sans-serif; font-size: 14px; - line-height: 1.5; + margin-top: 4px; } -.message-box { - margin-top: 20px; - padding: 10px; - border-radius: 4px; +.messageBox { + margin-bottom: 16px; + padding: 8px 0; font-family: "Inter", sans-serif; - font-size: 14px; - color: #ffffff; - background-color: rgba(255, 255, 255, 0.1); + font-size: 13.5px; + font-weight: 500; + color: #e2e8f0; + text-align: center; display: flex; - justify-content: space-between; + flex-direction: column; align-items: center; + gap: 8px; + animation: fadeIn 0.3s ease-out; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(-4px); } + to { opacity: 1; transform: translateY(0); } } .detailsButton { background: none; border: none; color: #f6941c; - text-decoration: underline; + text-decoration: none; cursor: pointer; - font-size: 12px; - margin-left: 10px; + font-size: 13px; + font-weight: 600; + padding: 0; + margin-top: 4px; +} + +.detailsButton:hover { + text-decoration: underline; } .errorDetails { margin-top: 10px; - padding: 10px; + padding: 12px; background-color: rgba(0, 0, 0, 0.2); - border-radius: 4px; - color: #ff4d4f; + border-radius: 8px; + color: #fc8181; font-family: monospace; - font-size: 12px; - line-height: 1.4; + font-size: 11px; + line-height: 1.5; white-space: pre-wrap; - word-break: break-word; - overflow-wrap: break-word; - max-width: 100%; + word-break: break-all; max-height: 150px; - overflow: auto; - border: 1px solid rgba(255, 77, 79, 0.3); + overflow-y: auto; + border-left: 3px solid #ff4d4f; + text-align: left; +} + +.transactionLink { + margin-top: 20px; + padding: 16px; + background: rgba(40, 167, 69, 0.1); + border: 1px solid rgba(40, 167, 69, 0.2); + border-radius: 12px; + font-family: "Inter", sans-serif; + font-size: 14px; + color: #ffffff; + text-align: center; +} + +.explorerLink { + color: #f6941c; + text-decoration: none; + font-weight: 600; + transition: color 0.2s ease; +} + +.explorerLink:hover { + color: #ffad42; + text-decoration: underline; } -.errorDetails::-webkit-scrollbar { - width: 6px; - height: 6px; +/* Base button styles for PayButton */ +.stablePayButton { + background: linear-gradient(135deg, #f6941c 0%, #d87c12 100%); + border: none; + border-radius: 16px; + color: white; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + transition: all 0.2s ease; + box-shadow: 0 4px 15px rgba(246, 148, 28, 0.3); } -.errorDetails::-webkit-scrollbar-track { - background: rgba(0, 0, 0, 0.1); - border-radius: 3px; +.stablePayButton:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(246, 148, 28, 0.4); } -.errorDetails::-webkit-scrollbar-thumb { - background: rgba(255, 77, 79, 0.5); - border-radius: 3px; +.stablePayButton:active { + transform: translateY(0); } -.errorDetails::-webkit-scrollbar-thumb:hover { - background: rgba(255, 77, 79, 0.7); +.buttonText { + font-family: "Inter", sans-serif; + font-weight: 600; } /* Responsive styles */ @media (max-width: 520px) { .pricingCard { - width: 95vw; - height: auto; - min-height: 600px; - padding: 20px; + width: 100%; + height: 100%; + min-height: 100vh; + border-radius: 0; + padding: 24px; + border: none; } - .selectField { - margin-bottom: 20px; - } - - .walletButton { - width: calc(100% - 40px); - left: 20px; - position: relative; - margin-top: 20px; - } - - .infoSection { - padding: 0 20px; - } - - .loadingContainer { - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - } - - .spinner { - border: 4px solid rgba(255, 255, 255, 0.3); - border-top: 4px solid #ffffff; - border-radius: 50%; - width: 40px; - height: 40px; - animation: spin 0.8s linear infinite; - } - - @keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } + .dialogOverlay { + background-color: #242529; + align-items: flex-start; } - } diff --git a/stablepay-sdk/src/widget/Dialog.jsx b/stablepay-sdk/src/widget/Dialog.jsx index 363432e..1de95c0 100644 --- a/stablepay-sdk/src/widget/Dialog.jsx +++ b/stablepay-sdk/src/widget/Dialog.jsx @@ -10,7 +10,7 @@ const Dialog = ({ children, onClose, size = 'medium' }) => {
-

StablePay

+
StablePay
{children} diff --git a/stablepay-sdk/src/widget/TransactionReview.jsx b/stablepay-sdk/src/widget/TransactionReview.jsx index 23805f3..ea66cdb 100644 --- a/stablepay-sdk/src/widget/TransactionReview.jsx +++ b/stablepay-sdk/src/widget/TransactionReview.jsx @@ -86,6 +86,10 @@ const TransactionReview = ({ onTransactionComplete }) => { initializeTransaction(); }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]); + if (!selectedNetwork || !selectedToken) { + return null; + } + if (!contextTransactionDetails) { return
Initializing transaction...
; } @@ -96,14 +100,14 @@ const TransactionReview = ({ onTransactionComplete }) => { const handleSendTransaction = async () => { if (!account || !contextTransactionDetails || !transaction) { - setMessage("❌ Wallet not connected or transaction details missing"); + setMessage("Wallet not connected or transaction details missing"); return; } try { setTxData(null); setError(null); - setMessage("⏳ Preparing transaction..."); + setMessage("Preparing transaction..."); const receiver = contextTransactionDetails.receivingAddress; let builtTx; @@ -164,10 +168,11 @@ const TransactionReview = ({ onTransactionComplete }) => { } setTxData(builtTx); - setMessage("✅ Transaction ready! Click 'Send Transaction' to proceed."); + setMessage("Transaction ready. Please confirm to proceed."); } catch (error) { setError(error); - setMessage(`❌ Transaction preparation failed.`); + const reason = error.shortMessage || (error.message ? error.message.split('\n')[0] : "Unknown error"); + setMessage(`Transaction preparation failed: ${reason}`); } }; @@ -176,31 +181,31 @@ const TransactionReview = ({ onTransactionComplete }) => { try { if (!account || !txData) { - setMessage("❌ Wallet account or transaction data is missing"); + setMessage("Wallet account or transaction data is missing"); return; } if (!selectedNetwork) { - setMessage("❌ Network not selected"); + setMessage("Network not selected"); return; } const networkConfig = networkSelector.getSelectedNetworkConfig(); if (!networkConfig) { - setMessage("❌ Network configuration not found"); + setMessage("Network configuration not found"); return; } - setMessage("⏳ Verifying network..."); + setMessage("Verifying network..."); const freshWalletClient = await ensureCorrectNetwork(); if (!freshWalletClient) { - setMessage("❌ Failed to switch to correct network. Please approve the network switch in MetaMask and try again."); + setMessage("Failed to switch to correct network. Please approve the network switch in MetaMask and try again."); return; } if (!window.ethereum) { - setMessage("❌ MetaMask not available"); + setMessage("MetaMask not available"); return; } @@ -209,19 +214,19 @@ const TransactionReview = ({ onTransactionComplete }) => { if (currentChainId !== networkConfig.chainId) { const errorMsg = `Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`; - setMessage(`❌ ${errorMsg}`); + setMessage(errorMsg); setError(new Error(errorMsg)); return; } if (freshWalletClient.chain.id !== networkConfig.chainId) { const errorMsg = `Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`; - setMessage(`❌ ${errorMsg}`); + setMessage(errorMsg); setError(new Error(errorMsg)); return; } - setMessage("⏳ Sending transaction..."); + setMessage("Sending transaction..."); const txHash = await freshWalletClient.sendTransaction({ ...txData, @@ -229,7 +234,7 @@ const TransactionReview = ({ onTransactionComplete }) => { }); setTxHash(txHash); - setMessage(`✅ Transaction sent!`); + setMessage(`Transaction sent!`); if (onTransactionComplete) { onTransactionComplete({ @@ -243,7 +248,8 @@ const TransactionReview = ({ onTransactionComplete }) => { } } catch (error) { setError(error); - setMessage(`❌ Transaction failed.`); + const reason = error.shortMessage || (error.message ? error.message.split('\n')[0] : "Unknown error"); + setMessage(`Transaction failed: ${reason}`); console.error('Transaction error:', error); } }; @@ -271,7 +277,7 @@ const TransactionReview = ({ onTransactionComplete }) => {
You Pay: - + {selectedToken.key === "stablecoin" ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}` : `${tradeDataBuySc ? tradeDataBuySc : "Calculating..."} ${ @@ -280,28 +286,8 @@ const TransactionReview = ({ onTransactionComplete }) => {
- - - {account && !txData && ( - - )} - {account && txData && ( - -)} - - {message && ( -
+
{message} {error && (
)} - {txHash && ( -
- ✅ Transaction Hash:{" "} +
+ Transaction Hash:{" "} {getExplorerUrl() ? ( - - {txHash.slice(0, 6)}...{txHash.slice(-6)} - + target="_blank" + rel="noopener noreferrer" + className={styles.explorerLink} + > + {txHash.slice(0, 6)}...{txHash.slice(-6)} + ) : ( {txHash} )} -
-)} +
+ )} +
+ {!account && ( + + )} + + {account && !txData && ( + + )} + + {account && txData && ( + + )} +
); }; From ed5e5cfa25488a45bad74aaea065ddf51fe35b80 Mon Sep 17 00:00:00 2001 From: DeveloperAmrit Date: Sun, 7 Jun 2026 19:06:29 +0530 Subject: [PATCH 4/6] fix: Improved user validation and flow --- stablepay-sdk/dist/esm/index.js | 2 +- stablepay-sdk/dist/esm/styles.css | 2 +- stablepay-sdk/dist/umd/index.js | 2 +- stablepay-sdk/dist/umd/index.js.map | 2 +- stablepay-sdk/dist/umd/styles.css | 2 +- stablepay-sdk/src/core/Transaction.js | 6 +- stablepay-sdk/src/styles/PricingCard.css | 42 +++++ .../src/widget/TransactionReview.jsx | 146 +++++++++--------- 8 files changed, 123 insertions(+), 81 deletions(-) diff --git a/stablepay-sdk/dist/esm/index.js b/stablepay-sdk/dist/esm/index.js index 0748fc3..d766331 100644 --- a/stablepay-sdk/dist/esm/index.js +++ b/stablepay-sdk/dist/esm/index.js @@ -1 +1 @@ -import{getWeb3 as e,getDjedContract as t,getCoinContracts as n,getDecimals as r,getOracleAddress as a,getOracleContract as o,tradeDataPriceBuySc as i,buyScTx as s}from"djed-sdk";import l,{useContext as c,createContext as d,useState as m,useEffect as u,useRef as h,useCallback as w}from"react";import{defineChain as k,createWalletClient as g,custom as C,createPublicClient as p,http as b,parseEther as f,parseUnits as v,encodeFunctionData as E}from"viem";import{sepolia as y}from"viem/chains";const _={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class N{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e(this.networkUri),this.djedContract=t(this.web3,this.djedAddress);try{const{stableCoin:e,reserveCoin:t}=await n(this.djedContract,this.web3),{scDecimals:i,rcDecimals:s}=await r(e,t);this.stableCoin=e,this.reserveCoin=t,this.scDecimals=i,this.rcDecimals=s,this.oracleContract=await a(this.djedContract).then((e=>o(this.web3,e,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){if(console.error("[Transaction] Error fetching contract details:",e),e.message&&e.message.includes("execution reverted")){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){if(console.error("[Transaction] Error initializing transaction:",e),e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(e){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof e)throw new Error("Amount must be a string");try{return(await i(this.djedContract,this.scDecimals,e)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(e,t,n){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await s(this.djedContract,e,t,n,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var T="main_stablePayButton__UA7HC",S="main_logo__ITyEy",A="main_buttonText__N-ewy";const D=({onClick:e,size:t="medium"})=>{const n={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},a=n[t]||n.medium,o=r[t]||r.medium;return l.createElement("button",{className:T,onClick:e,style:a},l.createElement("div",{className:S,style:o}),l.createElement("span",{className:A},"Pay with StablePay"))};var x={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const P=({children:e,onClose:t,size:n="medium"})=>l.createElement("div",{className:x.dialogOverlay},l.createElement("div",{className:`${x.pricingCard} ${x[n]}`},l.createElement("button",{className:x.dialogClose,onClick:t},"×"),l.createElement("div",{className:x.pricingCardHeader},l.createElement("div",{className:x.allianceLogo}),l.createElement("div",{className:x.stablepayTitle},"StablePay")),l.createElement("div",{className:x.pricingCardBody},e)));class I{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const B=d(),M=({children:e,networkSelector:t})=>{const[n]=m((()=>new I(t))),[r,a]=m(null),[o,i]=m(null),[s,c]=m(null),d=()=>{i(null),c(null)};return u((()=>{a(t.selectedNetwork)}),[t.selectedNetwork]),l.createElement(B.Provider,{value:{networkSelector:t,tokenSelector:n,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:c,selectNetwork:e=>!!t.selectNetwork(e)&&(a(e),d(),!0),selectToken:e=>{if(n.selectToken(e)){const e=n.getSelectedToken();return i(e),!0}return!1},resetSelections:()=>{t.selectNetwork(null),a(null),d()}}},e)},$=()=>{const e=c(B);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},j=()=>{const{networkSelector:e,selectedNetwork:t,selectNetwork:n}=$();return l.createElement("div",{className:x.selectField},l.createElement("label",{htmlFor:"network-select"},"Select Network"),l.createElement("select",{id:"network-select",onChange:e=>{n(e.target.value)},value:t||""},l.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>l.createElement("option",{key:e,value:e},e)))))},F=()=>{const{networkSelector:e,tokenSelector:t,selectedNetwork:n,selectedToken:r,selectToken:a,setTransactionDetails:o}=$(),[i,s]=m(!1),[c,d]=m(null),u=n?t.getAvailableTokens():[];return l.createElement("div",{className:x.selectField},l.createElement("label",{htmlFor:"token-select"},"Select Token"),l.createElement("select",{id:"token-select",onChange:async r=>{const i=r.target.value;d(null),s(!0);try{if(a(i)){const r=e.getSelectedNetworkConfig(),a=new N(r.uri,r.djedAddress);await a.init();const s=e.getTokenAmount(i),l=a.getBlockchainDetails();let c=null;"native"===i&&(c=await a.handleTradeDataBuySc(String(s))),o({network:n,token:i,tokenSymbol:t.getSelectedToken().symbol,amount:s,receivingAddress:e.getReceivingAddress(),djedContractAddress:r.djedAddress,isDirectTransfer:t.getSelectedToken().isDirectTransfer||!1,isNativeToken:t.getSelectedToken().isNative||!1,tradeAmount:c?c.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),d("Failed to fetch transaction details. Please try again.")}finally{s(!1)}},value:r?r.key:"",disabled:!n||i},l.createElement("option",{value:"",disabled:!0},n?i?"Loading...":"Select a token":"Please select a network first"),u.map((e=>l.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),c&&l.createElement("div",{className:x.error},c))};k({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const U=k({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),L=k({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),R=d(null),z=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${y.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:y.rpcUrls.default.http,blockExplorerUrls:y.blockExplorers?.default?.url?[y.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${L.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${U.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},W=({children:e})=>{const{selectedNetwork:t}=$(),[n,r]=m(null),[a,o]=m(null),[i,s]=m(null),[c,d]=m(null),[k,f]=m(null),[v,E]=m(null),[_,N]=m(!1),T=t?(e=>{switch(e){case"sepolia":return y;case"ethereum-classic":return L;case"milkomeda-mainnet":return U;default:return null}})(t):null,S=T?T.id:null,A=h(null),D=h(null),x=w((()=>{r(null),o(null),s(null),d(null),f(null),E(null)}),[]),P=w((async e=>{const n=parseInt(e,16);if(d(n),T&&n===S){if(E(null),window.ethereum&&T){const e=g({chain:T,transport:C(window.ethereum)});r(e)}}else if(T&&n!==S){E(`Wrong network detected. Please switch to ${T?.name||t||"selected network"}`)}}),[T,S,t]);D.current=P;const I=w((async e=>{if(0===e.length){if(x(),window.ethereum){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(s(e[0]),T)try{const t=p({chain:T,transport:b()});o(t);const n=await t.getBalance({address:e[0]});f(parseFloat(n)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}}),[T,x]);A.current=I;const B=w((()=>{if(x(),window.ethereum){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[x]),M=w((()=>{T&&o(p({chain:T,transport:b()}))}),[T]),j=w((async()=>{if(!window.ethereum)return E("Please install MetaMask or another Web3 wallet"),!1;if(!t||!T)return E("Please select a network first"),!1;N(!0),E(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const n=await window.ethereum.request({method:"eth_chainId"});parseInt(n,16)!==S&&await z(t);const a=g({chain:T,transport:C(window.ethereum)});r(a),s(e[0]),d(S);const i=p({chain:T,transport:b()});o(i);try{const t=await i.getBalance({address:e[0]});f(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}return A.current=I,D.current=P,window.ethereum.on("accountsChanged",I),window.ethereum.on("chainChanged",P),!0}catch(e){return console.error("Error connecting wallet:",e),E(e.message),!1}finally{N(!1)}}),[t,T,S,I,P]),F=w((async()=>{if(!(window.ethereum&&t&&T&&i)){return E("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==S){E(null),await z(t);const e=500;await new Promise((t=>setTimeout(t,e)));const n=await window.ethereum.request({method:"eth_chainId"}),r=parseInt(n,16);if(r!==S)throw new Error(`Failed to switch network. MetaMask is still on chain ${r}, expected ${S}`)}const n=g({chain:T,transport:C(window.ethereum)});return r(n),d(S),E(null),n}catch(e){return E(e.message),null}}),[t,T,S,i]),W=h(t);return u((()=>{if(null!==W.current&&W.current!==t&&i&&(x(),window.ethereum)){const e=A.current,t=D.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}W.current=t}),[t,i,x]),u((()=>{M()}),[M]),l.createElement(R.Provider,{value:{walletClient:n,publicClient:a,account:i,chainId:c,balance:k,error:v,isConnecting:_,connectWallet:j,disconnectWallet:B,ensureCorrectNetwork:F,expectedChainId:S}},e)},O=({onTransactionComplete:e})=>{const{networkSelector:t,selectedNetwork:n,selectedToken:r,transactionDetails:a,setTransactionDetails:o}=$(),{connectWallet:i,account:s,walletClient:d,publicClient:h,isConnecting:w,ensureCorrectNetwork:k,expectedChainId:g}=(()=>{const e=c(R);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[C,p]=m(null),[b,y]=m(null),[_,T]=m(null),[S,A]=m(""),[D,P]=m(null),[I,B]=m(null),[M,j]=m(!1);if(u((()=>{T(null),y(null),A(""),B(null),P(null)}),[n,r]),u((()=>{(async()=>{if(n&&r)try{const e=t.getSelectedNetworkConfig(),a=t.getReceivingAddress(),i=t.getTokenAmount(r.key),s=new N(e.uri,e.djedAddress);await s.init(),p(s);let l=null;if("native"===r.key)try{l=await s.handleTradeDataBuySc(String(i)),y(l)}catch(e){console.error("Error fetching trade data:",e)}o({network:n,token:r.key,tokenSymbol:r.symbol,amount:i||"0",receivingAddress:a,djedContractAddress:e.djedAddress,isDirectTransfer:r.isDirectTransfer||!1,isNativeToken:r.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[n,r,t,o]),!n||!r)return null;if(!a)return l.createElement("div",{className:x.loading},"Initializing transaction...");const F=()=>{if(!D||!n)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[n]?`${e[n]}${D}`:null};return l.createElement("div",{className:x.transactionReview},l.createElement("div",{className:x.transactionInfo},l.createElement("span",{className:x.transactionLabel},"Network:"),l.createElement("span",{className:x.transactionValue},a.network)),l.createElement("div",{className:x.transactionInfo},l.createElement("span",{className:x.transactionLabel},"You Pay:"),l.createElement("span",{className:`${x.transactionValue} ${x.highlight}`},"stablecoin"===r.key?`${a.amount} ${a.tokenSymbol}`:`${b||"Calculating..."} ${a.tokenSymbol}`)),S&&l.createElement("div",{className:x.messageBox},S,I&&l.createElement("button",{onClick:()=>j(!M),className:x.detailsButton},M?"Hide Details":"Show Details")),M&&I&&l.createElement("div",{className:x.errorDetails},l.createElement("pre",null,I.message)),D&&l.createElement("div",{className:x.transactionLink},"Transaction Hash:"," ",F()?l.createElement("a",{href:F(),target:"_blank",rel:"noopener noreferrer",className:x.explorerLink},D.slice(0,6),"...",D.slice(-6)):l.createElement("span",{style:{wordBreak:"break-word"}},D)),l.createElement("div",{className:x.walletButtonContainer},!s&&l.createElement("button",{className:x.walletButton,onClick:async()=>{await i()},disabled:w},w?"Connecting...":"Connect Wallet"),s&&!_&&l.createElement("button",{className:x.walletButton,onClick:async()=>{if(s&&a&&C)try{T(null),B(null),A("Preparing transaction...");const e=a.receivingAddress;let n;if("native"===r.key){const t="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=f(String(b||"0"));n=await C.buyStablecoins(s,e,r,t),n={...n,value:r,account:s}}else{const r=t.getSelectedNetworkConfig(),o=r?.tokens?.stablecoin?.address;if(!o)throw new Error("Stablecoin address not found in network configuration");const i=a.amount?v(String(a.amount),a.stableCoinDecimals):"0";n={to:o,value:0n,data:E({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:s}}T(n),A("Transaction ready. Please confirm to proceed.")}catch(e){B(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");A(`Transaction preparation failed: ${t}`)}else A("Wallet not connected or transaction details missing")}},"Prepare Transaction"),s&&_&&l.createElement("button",{className:x.walletButton,onClick:async()=>{B(null);try{if(!s||!_)return void A("Wallet account or transaction data is missing");if(!n)return void A("Network not selected");const o=t.getSelectedNetworkConfig();if(!o)return void A("Network configuration not found");A("Verifying network...");const i=await k();if(!i)return void A("Failed to switch to correct network. Please approve the network switch in MetaMask and try again.");if(!window.ethereum)return void A("MetaMask not available");const l=await window.ethereum.request({method:"eth_chainId"}),c=parseInt(l,16);if(c!==o.chainId){const e=`Network mismatch. MetaMask is on chain ${c}, but ${n} requires chain ${o.chainId}. Please switch networks in MetaMask.`;return A(e),void B(new Error(e))}if(i.chain.id!==o.chainId){const e=`Wallet client chain mismatch. Wallet client is on chain ${i.chain.id}, but expected ${o.chainId}.`;return A(e),void B(new Error(e))}A("Sending transaction...");const d=await i.sendTransaction({..._,account:s});P(d),A("Transaction sent!"),e&&e({txHash:d,network:n,token:r?.key,tokenSymbol:r?.symbol,amount:a?.amount,receivingAddress:a?.receivingAddress})}catch(e){B(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");A(`Transaction failed: ${t}`),console.error("Transaction error:",e)}},disabled:null!==D},"Send Transaction")))},q=({onClose:e,buttonSize:t,onTransactionComplete:n})=>{const{resetSelections:r}=$();return l.createElement(P,{onClose:()=>{r(),e()},size:t},l.createElement(j,null),l.createElement(F,null),l.createElement(O,{onTransactionComplete:n}))},H=({onClose:e,buttonSize:t,networkSelector:n,onTransactionComplete:r})=>l.createElement(M,{networkSelector:n},l.createElement(W,null,l.createElement(q,{onClose:e,buttonSize:t,onTransactionComplete:r}))),V={NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(_).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:N,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!_[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:t="medium",onTransactionComplete:n,onSuccess:r})=>{const[a,o]=m(!1),i=n||r;return l.createElement("div",{className:x.widgetContainer},!a&&l.createElement(D,{onClick:()=>{o(!0)},size:t}),a&&l.createElement(H,{onClose:()=>{o(!1)},buttonSize:t,networkSelector:e,onTransactionComplete:i}))},PayButton:D,Dialog:P,NetworkDropdown:j};export{V as default}; +import{getWeb3 as e,getDjedContract as t,getCoinContracts as n,getDecimals as r,getOracleAddress as a,getOracleContract as o,tradeDataPriceBuySc as i,buyScTx as s}from"djed-sdk";import c,{useContext as l,createContext as d,useState as m,useEffect as u,useRef as h,useCallback as w}from"react";import{defineChain as k,createWalletClient as g,custom as C,createPublicClient as p,http as b,parseEther as f,parseUnits as E,encodeFunctionData as y}from"viem";import{sepolia as v}from"viem/chains";const _={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class N{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e(this.networkUri),this.djedContract=t(this.web3,this.djedAddress);try{const{stableCoin:e,reserveCoin:t}=await n(this.djedContract,this.web3),{scDecimals:i,rcDecimals:s}=await r(e,t);this.stableCoin=e,this.reserveCoin=t,this.scDecimals=i,this.rcDecimals=s,this.oracleContract=await a(this.djedContract).then((e=>o(this.web3,e,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){console.error("[Transaction] Error fetching contract details:",e);if(-32e3===e.code||3===e.code||e.data){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){console.error("[Transaction] Error initializing transaction:",e);if(-32603===e.code||4001===e.code||-32005===e.code||e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(e){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof e)throw new Error("Amount must be a string");try{return(await i(this.djedContract,this.scDecimals,e)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(e,t,n){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await s(this.djedContract,e,t,n,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var S="main_stablePayButton__UA7HC",T="main_logo__ITyEy",A="main_buttonText__N-ewy";const P=({onClick:e,size:t="medium"})=>{const n={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},a=n[t]||n.medium,o=r[t]||r.medium;return c.createElement("button",{className:S,onClick:e,style:a},c.createElement("div",{className:T,style:o}),c.createElement("span",{className:A},"Pay with StablePay"))};var D={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",confirmContainer:"PricingCard_confirmContainer__vNq4n",confirmText:"PricingCard_confirmText__FP0WS",confirmButtons:"PricingCard_confirmButtons__fZ7jt",secondaryButton:"PricingCard_secondaryButton__OTpW4",primaryButton:"PricingCard_primaryButton__bmYo9",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const x=({children:e,onClose:t,size:n="medium"})=>c.createElement("div",{className:D.dialogOverlay},c.createElement("div",{className:`${D.pricingCard} ${D[n]}`},c.createElement("button",{className:D.dialogClose,onClick:t},"×"),c.createElement("div",{className:D.pricingCardHeader},c.createElement("div",{className:D.allianceLogo}),c.createElement("div",{className:D.stablepayTitle},"StablePay")),c.createElement("div",{className:D.pricingCardBody},e)));class I{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const B=d(),M=({children:e,networkSelector:t})=>{const[n]=m((()=>new I(t))),[r,a]=m(null),[o,i]=m(null),[s,l]=m(null),d=()=>{i(null),l(null)};return u((()=>{a(t.selectedNetwork)}),[t.selectedNetwork]),c.createElement(B.Provider,{value:{networkSelector:t,tokenSelector:n,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:l,selectNetwork:e=>!!t.selectNetwork(e)&&(a(e),d(),!0),selectToken:e=>{if(n.selectToken(e)){const e=n.getSelectedToken();return i(e),!0}return!1},resetSelections:()=>{t.selectNetwork(null),a(null),d()}}},e)},$=()=>{const e=l(B);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},j=()=>{const{networkSelector:e,selectedNetwork:t,selectNetwork:n}=$();return c.createElement("div",{className:D.selectField},c.createElement("label",{htmlFor:"network-select"},"Select Network"),c.createElement("select",{id:"network-select",onChange:e=>{n(e.target.value)},value:t||""},c.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>c.createElement("option",{key:e,value:e},e)))))},L=()=>{const{networkSelector:e,tokenSelector:t,selectedNetwork:n,selectedToken:r,selectToken:a,setTransactionDetails:o}=$(),[i,s]=m(!1),[l,d]=m(null),u=n?t.getAvailableTokens():[];return c.createElement("div",{className:D.selectField},c.createElement("label",{htmlFor:"token-select"},"Select Token"),c.createElement("select",{id:"token-select",onChange:async r=>{const i=r.target.value;d(null),s(!0);try{if(a(i)){const r=e.getSelectedNetworkConfig(),a=new N(r.uri,r.djedAddress);await a.init();const s=e.getTokenAmount(i),c=a.getBlockchainDetails();let l=null;"native"===i&&(l=await a.handleTradeDataBuySc(String(s))),o({network:n,token:i,tokenSymbol:t.getSelectedToken().symbol,amount:s,receivingAddress:e.getReceivingAddress(),djedContractAddress:r.djedAddress,isDirectTransfer:t.getSelectedToken().isDirectTransfer||!1,isNativeToken:t.getSelectedToken().isNative||!1,tradeAmount:l?l.amount:null,...c})}}catch(e){console.error("Error fetching transaction details:",e),d("Failed to fetch transaction details. Please try again.")}finally{s(!1)}},value:r?r.key:"",disabled:!n||i},c.createElement("option",{value:"",disabled:!0},n?i?"Loading...":"Select a token":"Please select a network first"),u.map((e=>c.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),l&&c.createElement("div",{className:D.error},l))};k({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const F=k({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),U=k({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),R=d(null),z=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${v.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:v.rpcUrls.default.http,blockExplorerUrls:v.blockExplorers?.default?.url?[v.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${U.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${F.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},O=({children:e})=>{const{selectedNetwork:t}=$(),[n,r]=m(null),[a,o]=m(null),[i,s]=m(null),[l,d]=m(null),[k,f]=m(null),[E,y]=m(null),[_,N]=m(!1),S=t?(e=>{switch(e){case"sepolia":return v;case"ethereum-classic":return U;case"milkomeda-mainnet":return F;default:return null}})(t):null,T=S?S.id:null,A=h(null),P=h(null),D=w((()=>{r(null),o(null),s(null),d(null),f(null),y(null)}),[]),x=w((async e=>{const n=parseInt(e,16);if(d(n),S&&n===T){if(y(null),window.ethereum&&S){const e=g({chain:S,transport:C(window.ethereum)});r(e)}}else if(S&&n!==T){y(`Wrong network detected. Please switch to ${S?.name||t||"selected network"}`)}}),[S,T,t]);P.current=x;const I=w((async e=>{if(0===e.length){if(D(),window.ethereum){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(s(e[0]),S)try{const t=p({chain:S,transport:b()});o(t);const n=await t.getBalance({address:e[0]});f(parseFloat(n)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}}),[S,D]);A.current=I;const B=w((()=>{if(D(),window.ethereum){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[D]),M=w((()=>{S&&o(p({chain:S,transport:b()}))}),[S]),j=w((async()=>{if(!window.ethereum)return y("Please install MetaMask or another Web3 wallet"),!1;if(!t||!S)return y("Please select a network first"),!1;N(!0),y(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const n=await window.ethereum.request({method:"eth_chainId"});parseInt(n,16)!==T&&await z(t);const a=g({chain:S,transport:C(window.ethereum)});r(a),s(e[0]),d(T);const i=p({chain:S,transport:b()});o(i);try{const t=await i.getBalance({address:e[0]});f(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}return A.current=I,P.current=x,window.ethereum.on("accountsChanged",I),window.ethereum.on("chainChanged",x),!0}catch(e){return console.error("Error connecting wallet:",e),y(e.message),!1}finally{N(!1)}}),[t,S,T,I,x]),L=w((async()=>{if(!(window.ethereum&&t&&S&&i)){return y("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==T){y(null),await z(t);const e=500;await new Promise((t=>setTimeout(t,e)));const n=await window.ethereum.request({method:"eth_chainId"}),r=parseInt(n,16);if(r!==T)throw new Error(`Failed to switch network. MetaMask is still on chain ${r}, expected ${T}`)}const n=g({chain:S,transport:C(window.ethereum)});return r(n),d(T),y(null),n}catch(e){return y(e.message),null}}),[t,S,T,i]),O=h(t);return u((()=>{if(null!==O.current&&O.current!==t&&i&&(D(),window.ethereum)){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}O.current=t}),[t,i,D]),u((()=>{M()}),[M]),c.createElement(R.Provider,{value:{walletClient:n,publicClient:a,account:i,chainId:l,balance:k,error:E,isConnecting:_,connectWallet:j,disconnectWallet:B,ensureCorrectNetwork:L,expectedChainId:T}},e)},W=({onTransactionComplete:e})=>{const{networkSelector:t,selectedNetwork:n,selectedToken:r,transactionDetails:a,setTransactionDetails:o}=$(),{connectWallet:i,account:s,walletClient:d,publicClient:h,isConnecting:w,ensureCorrectNetwork:k,expectedChainId:g}=(()=>{const e=l(R);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[C,p]=m(null),[b,v]=m(null),[_,S]=m(""),[T,A]=m(null),[P,x]=m(null),[I,B]=m(!1),[M,j]=m("IDLE");if(u((()=>{v(null),S(""),x(null),A(null),j("IDLE")}),[n,r]),u((()=>{(async()=>{if(n&&r)try{const e=t.getSelectedNetworkConfig(),a=t.getReceivingAddress(),i=t.getTokenAmount(r.key),s=new N(e.uri,e.djedAddress);await s.init(),p(s);let c=null;if("native"===r.key)try{c=await s.handleTradeDataBuySc(String(i)),v(c)}catch(e){console.error("Error fetching trade data:",e)}o({network:n,token:r.key,tokenSymbol:r.symbol,amount:i||"0",receivingAddress:a,djedContractAddress:e.djedAddress,isDirectTransfer:r.isDirectTransfer||!1,isNativeToken:r.isNative||!1,tradeAmount:c?c.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[n,r,t,o]),!n||!r)return null;if(!a)return c.createElement("div",{className:D.loading},"Initializing transaction...");const L=()=>{if(!T||!n)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[n]?`${e[n]}${T}`:null};return c.createElement("div",{className:D.transactionReview},c.createElement("div",{className:D.transactionInfo},c.createElement("span",{className:D.transactionLabel},"Network:"),c.createElement("span",{className:D.transactionValue},a.network)),c.createElement("div",{className:D.transactionInfo},c.createElement("span",{className:D.transactionLabel},"You Pay:"),c.createElement("span",{className:`${D.transactionValue} ${D.highlight}`},"stablecoin"===r.key?`${a.amount} ${a.tokenSymbol}`:`${b||"Calculating..."} ${a.tokenSymbol}`)),_&&c.createElement("div",{className:D.messageBox},_,P&&c.createElement("button",{onClick:()=>B(!I),className:D.detailsButton},I?"Hide Details":"Show Details")),I&&P&&c.createElement("div",{className:D.errorDetails},c.createElement("pre",null,P.message)),T&&c.createElement("div",{className:D.transactionLink},"Transaction Hash:"," ",L()?c.createElement("a",{href:L(),target:"_blank",rel:"noopener noreferrer",className:D.explorerLink},T.slice(0,6),"...",T.slice(-6)):c.createElement("span",{style:{wordBreak:"break-word"}},T)),"SUCCESS"!==M&&c.createElement("div",{className:D.walletButtonContainer},!s&&c.createElement("button",{className:D.walletButton,onClick:async()=>{await i()},disabled:w},w?"Connecting...":"Connect Wallet"),s&&"IDLE"===M&&c.createElement("button",{className:D.walletButton,onClick:()=>j("CONFIRMING")},"Pay ",a.amount," ",a.tokenSymbol),s&&"CONFIRMING"===M&&c.createElement("div",{className:D.confirmContainer},c.createElement("span",{className:D.confirmText},"Confirm payment?"),c.createElement("div",{className:D.confirmButtons},c.createElement("button",{className:D.secondaryButton,onClick:()=>j("IDLE")},"No"),c.createElement("button",{className:`${D.walletButton} ${D.primaryButton}`,onClick:async()=>{if(!s||!a||!C)return void S("Wallet not connected or transaction details missing");let o;j("PROCESSING"),S("Preparing transaction..."),x(null),A(null);try{const e=a.receivingAddress;if("native"===r.key){const t="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",n=f(String(b||"0"));o=await C.buyStablecoins(s,e,n,t),o={...o,value:n,account:s}}else{const n=t.getSelectedNetworkConfig(),r=n?.tokens?.stablecoin?.address;if(!r)throw new Error("Stablecoin address not found in network configuration");const i=a.amount?E(String(a.amount),a.stableCoinDecimals):"0";o={to:r,value:0n,data:y({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:s}}}catch(e){x(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");return S(`Transaction preparation failed: ${t}`),void j("IDLE")}S("Please check your wallet to confirm the transaction...");try{const i=t.getSelectedNetworkConfig();if(!i)throw new Error("Network configuration not found");const c=await k();if(!c)throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask.");if(!window.ethereum)throw new Error("MetaMask not available");const l=await window.ethereum.request({method:"eth_chainId"}),d=parseInt(l,16);if(d!==i.chainId)throw new Error(`Network mismatch. MetaMask is on chain ${d}, but ${n} requires chain ${i.chainId}. Please switch networks in MetaMask.`);if(c.chain.id!==i.chainId)throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${c.chain.id}, but expected ${i.chainId}.`);const m=await c.sendTransaction({...o,account:s});A(m),S("Transaction sent successfully!"),j("SUCCESS"),e&&e({txHash:m,network:n,token:r?.key,tokenSymbol:r?.symbol,amount:a?.amount,receivingAddress:a?.receivingAddress})}catch(e){x(e);let t="Unknown error";t="UserRejectedRequestError"===e.name||4001===e.code?"User denied transaction":"ContractFunctionRevertedError"===e.name||e.data&&e.data.message?e.shortMessage||e.data?.message||e.message:e.shortMessage||(e.message?e.message.split("\n")[0]:"Transaction failed"),S(`Transaction failed: ${t}`),j("IDLE"),console.error("Transaction error:",e)}}},"Yes, Pay"))),s&&"PROCESSING"===M&&c.createElement("button",{className:D.walletButton,disabled:!0},"Processing...")))},q=({onClose:e,buttonSize:t,onTransactionComplete:n})=>{const{resetSelections:r}=$();return c.createElement(x,{onClose:()=>{r(),e()},size:t},c.createElement(j,null),c.createElement(L,null),c.createElement(W,{onTransactionComplete:n}))},H=({onClose:e,buttonSize:t,networkSelector:n,onTransactionComplete:r})=>c.createElement(M,{networkSelector:n},c.createElement(O,null,c.createElement(q,{onClose:e,buttonSize:t,onTransactionComplete:r}))),G={NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(_).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:N,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!_[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:t="medium",onTransactionComplete:n,onSuccess:r})=>{const[a,o]=m(!1),i=n||r;return c.createElement("div",{className:D.widgetContainer},!a&&c.createElement(P,{onClick:()=>{o(!0)},size:t}),a&&c.createElement(H,{onClose:()=>{o(!1)},buttonSize:t,networkSelector:e,onTransactionComplete:i}))},PayButton:P,Dialog:x,NetworkDropdown:j};export{G as default}; diff --git a/stablepay-sdk/dist/esm/styles.css b/stablepay-sdk/dist/esm/styles.css index 24e94a1..c6cb414 100644 --- a/stablepay-sdk/dist/esm/styles.css +++ b/stablepay-sdk/dist/esm/styles.css @@ -1 +1 @@ -.main_stablePayButton__UA7HC{align-items:center;background:linear-gradient(90deg,#000,#f7941d);border:1px solid #bc5f26;border-radius:3px;box-sizing:border-box;color:#fff;cursor:pointer;display:flex;font-size:24px;font-weight:700;height:104px;justify-content:flex-start;overflow:hidden;padding:0 20px;position:relative;width:372px}.main_stablePayButton__UA7HC:hover{opacity:.9}.main_stablePayButton__UA7HC .main_logo__ITyEy{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;flex-shrink:0;height:25px;margin-right:20px;width:25px}.main_stablePayButton__UA7HC .main_buttonText__N-ewy{flex-grow:1;text-align:center}@keyframes PricingCard_fadeInScale__2MTi3{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.PricingCard_dialogOverlay__0XJrE{align-items:center;animation:PricingCard_fadeInScale__2MTi3 .2s ease-out;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background-color:rgba(0,0,0,.4);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:1000}.PricingCard_pricingCard__LrWb9{background:#242529;border:1px solid hsla(0,0%,100%,.08);border-radius:20px;box-shadow:0 15px 35px rgba(0,0,0,.4),inset 0 1px 0 hsla(0,0%,100%,.05);box-sizing:border-box;display:flex;flex-direction:column;padding:32px;position:relative}.PricingCard_pricingCard__LrWb9.PricingCard_small__J4CHj{min-height:520px;width:360px}.PricingCard_pricingCard__LrWb9.PricingCard_medium__EVmTB{min-height:580px;width:400px}.PricingCard_pricingCard__LrWb9.PricingCard_large__A6pnX{min-height:640px;width:440px}.PricingCard_dialogClose__jJ1tM{align-items:center;background:hsla(0,0%,100%,.1);border:none;border-radius:50%;color:#a0aec0;cursor:pointer;display:flex;font-size:20px;height:32px;justify-content:center;line-height:1;padding:0 0 3px;position:absolute;right:20px;top:20px;transition:all .2s ease;width:32px;z-index:5}.PricingCard_dialogClose__jJ1tM:hover{background:hsla(0,0%,100%,.2);color:#fff}.PricingCard_pricingCardHeader__wGczA{align-items:center;border-bottom:1px solid hsla(0,0%,100%,.05);display:flex;gap:16px;margin-bottom:30px;padding-bottom:20px;width:100%}.PricingCard_allianceLogo__URa-U{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:48px;width:48px}.PricingCard_stablepayTitle__4t848{align-items:center;color:#f6941c;display:flex;font-family:Inter,sans-serif;font-size:26px;font-style:normal;font-weight:700;letter-spacing:-.5px}.PricingCard_pricingCardBody__0wKQn{display:flex;flex:1;flex-direction:column;width:100%}.PricingCard_selectField__LBPoZ{display:flex;flex-direction:column;gap:10px;margin-bottom:24px;width:100%}.PricingCard_selectField__LBPoZ label{align-self:flex-start;color:#a0aec0;font-family:Inter,sans-serif;font-size:14px;font-style:normal;font-weight:500;text-align:left;width:100%}.PricingCard_selectField__LBPoZ select{appearance:none;background:hsla(0,0%,100%,.05);background-image:url(../assets/chevron-down-icon.svg);background-position:right 18px center;background-repeat:no-repeat;border:1px solid hsla(0,0%,100%,.1);border-radius:12px;box-sizing:border-box;color:#fff;cursor:pointer;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:500;height:52px;padding:12px 16px;transition:all .2s ease;width:100%}.PricingCard_selectField__LBPoZ select:hover:not(:disabled){background:hsla(0,0%,100%,.08);border-color:rgba(246,148,28,.5)}.PricingCard_selectField__LBPoZ select:focus{border-color:#f6941c;box-shadow:0 0 0 3px rgba(246,148,28,.2);outline:none}.PricingCard_selectField__LBPoZ select:disabled{cursor:not-allowed;opacity:.5}.PricingCard_selectField__LBPoZ select option{background:#242529;color:#fff}.PricingCard_transactionReview__Ix-eL{display:flex;flex:1;flex-direction:column;padding-top:10px;width:100%}.PricingCard_transactionInfo__Ck-Rc{align-items:center;background:rgba(0,0,0,.2);border:1px solid hsla(0,0%,100%,.05);border-radius:12px;display:flex;justify-content:space-between;margin-bottom:16px;padding:14px 18px;width:100%}.PricingCard_transactionLabel__GDux7{color:#a0aec0;font-family:Inter,sans-serif;font-size:15px;font-style:normal;font-weight:500}.PricingCard_transactionValue__q-xxp{color:#fff;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:700;text-align:right}.PricingCard_transactionValue__q-xxp.PricingCard_highlight__WZZ6N{color:#f6941c;font-size:18px}.PricingCard_walletButtonContainer__a6MwB{margin-top:auto;padding-top:24px}.PricingCard_walletButton__llw4v{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:14px;box-shadow:0 4px 14px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;font-family:Inter,sans-serif;font-size:17px;font-style:normal;font-weight:600;height:56px;justify-content:center;transition:all .2s ease;width:100%}.PricingCard_walletButton__llw4v:hover:not(:disabled){box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_walletButton__llw4v:active:not(:disabled){transform:translateY(0)}.PricingCard_walletButton__llw4v:disabled{background:hsla(0,0%,100%,.1);box-shadow:none;color:#636a77;cursor:not-allowed}.PricingCard_loading__2-tGA{align-items:center;color:#a0aec0;display:flex;flex-direction:column;font-family:Inter,sans-serif;gap:16px;padding:40px;text-align:center}.PricingCard_error__m5fK-{color:#ff4d4f;font-family:Inter,sans-serif;font-size:14px;margin-top:4px;text-align:left}.PricingCard_messageBox__wnx0F{align-items:center;animation:PricingCard_fadeIn__L63q8 .3s ease-out;color:#e2e8f0;display:flex;flex-direction:column;font-family:Inter,sans-serif;font-size:13.5px;font-weight:500;gap:8px;margin-bottom:16px;padding:8px 0;text-align:center}@keyframes PricingCard_fadeIn__L63q8{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.PricingCard_detailsButton__jHglL{background:none;border:none;color:#f6941c;cursor:pointer;font-size:13px;font-weight:600;margin-top:4px;padding:0;text-decoration:none}.PricingCard_detailsButton__jHglL:hover{text-decoration:underline}.PricingCard_errorDetails__CzN-7{background-color:rgba(0,0,0,.2);border-left:3px solid #ff4d4f;border-radius:8px;color:#fc8181;font-family:monospace;font-size:11px;line-height:1.5;margin-top:10px;max-height:150px;overflow-y:auto;padding:12px;text-align:left;white-space:pre-wrap;word-break:break-all}.PricingCard_transactionLink__RFRWW{background:rgba(40,167,69,.1);border:1px solid rgba(40,167,69,.2);border-radius:12px;color:#fff;font-family:Inter,sans-serif;font-size:14px;margin-top:20px;padding:16px;text-align:center}.PricingCard_explorerLink__-a82-{color:#f6941c;font-weight:600;text-decoration:none;transition:color .2s ease}.PricingCard_explorerLink__-a82-:hover{color:#ffad42;text-decoration:underline}.PricingCard_stablePayButton__Y4Rr4{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:16px;box-shadow:0 4px 15px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;gap:12px;justify-content:center;transition:all .2s ease}.PricingCard_stablePayButton__Y4Rr4:hover{box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_stablePayButton__Y4Rr4:active{transform:translateY(0)}.PricingCard_buttonText__8LnPv{font-family:Inter,sans-serif;font-weight:600}@media (max-width:520px){.PricingCard_pricingCard__LrWb9{border:none;border-radius:0;height:100%;min-height:100vh;padding:24px;width:100%}.PricingCard_dialogOverlay__0XJrE{align-items:flex-start;background-color:#242529}} \ No newline at end of file +.main_stablePayButton__UA7HC{align-items:center;background:linear-gradient(90deg,#000,#f7941d);border:1px solid #bc5f26;border-radius:3px;box-sizing:border-box;color:#fff;cursor:pointer;display:flex;font-size:24px;font-weight:700;height:104px;justify-content:flex-start;overflow:hidden;padding:0 20px;position:relative;width:372px}.main_stablePayButton__UA7HC:hover{opacity:.9}.main_stablePayButton__UA7HC .main_logo__ITyEy{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;flex-shrink:0;height:25px;margin-right:20px;width:25px}.main_stablePayButton__UA7HC .main_buttonText__N-ewy{flex-grow:1;text-align:center}@keyframes PricingCard_fadeInScale__2MTi3{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.PricingCard_dialogOverlay__0XJrE{align-items:center;animation:PricingCard_fadeInScale__2MTi3 .2s ease-out;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background-color:rgba(0,0,0,.4);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:1000}.PricingCard_pricingCard__LrWb9{background:#242529;border:1px solid hsla(0,0%,100%,.08);border-radius:20px;box-shadow:0 15px 35px rgba(0,0,0,.4),inset 0 1px 0 hsla(0,0%,100%,.05);box-sizing:border-box;display:flex;flex-direction:column;padding:32px;position:relative}.PricingCard_pricingCard__LrWb9.PricingCard_small__J4CHj{min-height:520px;width:360px}.PricingCard_pricingCard__LrWb9.PricingCard_medium__EVmTB{min-height:580px;width:400px}.PricingCard_pricingCard__LrWb9.PricingCard_large__A6pnX{min-height:640px;width:440px}.PricingCard_dialogClose__jJ1tM{align-items:center;background:hsla(0,0%,100%,.1);border:none;border-radius:50%;color:#a0aec0;cursor:pointer;display:flex;font-size:20px;height:32px;justify-content:center;line-height:1;padding:0 0 3px;position:absolute;right:20px;top:20px;transition:all .2s ease;width:32px;z-index:5}.PricingCard_dialogClose__jJ1tM:hover{background:hsla(0,0%,100%,.2);color:#fff}.PricingCard_pricingCardHeader__wGczA{align-items:center;border-bottom:1px solid hsla(0,0%,100%,.05);display:flex;gap:16px;margin-bottom:30px;padding-bottom:20px;width:100%}.PricingCard_allianceLogo__URa-U{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:48px;width:48px}.PricingCard_stablepayTitle__4t848{align-items:center;color:#f6941c;display:flex;font-family:Inter,sans-serif;font-size:26px;font-style:normal;font-weight:700;letter-spacing:-.5px}.PricingCard_pricingCardBody__0wKQn{display:flex;flex:1;flex-direction:column;width:100%}.PricingCard_selectField__LBPoZ{display:flex;flex-direction:column;gap:10px;margin-bottom:24px;width:100%}.PricingCard_selectField__LBPoZ label{align-self:flex-start;color:#a0aec0;font-family:Inter,sans-serif;font-size:14px;font-style:normal;font-weight:500;text-align:left;width:100%}.PricingCard_selectField__LBPoZ select{appearance:none;background:hsla(0,0%,100%,.05);background-image:url(../assets/chevron-down-icon.svg);background-position:right 18px center;background-repeat:no-repeat;border:1px solid hsla(0,0%,100%,.1);border-radius:12px;box-sizing:border-box;color:#fff;cursor:pointer;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:500;height:52px;padding:12px 16px;transition:all .2s ease;width:100%}.PricingCard_selectField__LBPoZ select:hover:not(:disabled){background:hsla(0,0%,100%,.08);border-color:rgba(246,148,28,.5)}.PricingCard_selectField__LBPoZ select:focus{border-color:#f6941c;box-shadow:0 0 0 3px rgba(246,148,28,.2);outline:none}.PricingCard_selectField__LBPoZ select:disabled{cursor:not-allowed;opacity:.5}.PricingCard_selectField__LBPoZ select option{background:#242529;color:#fff}.PricingCard_transactionReview__Ix-eL{display:flex;flex:1;flex-direction:column;padding-top:10px;width:100%}.PricingCard_transactionInfo__Ck-Rc{align-items:center;background:rgba(0,0,0,.2);border:1px solid hsla(0,0%,100%,.05);border-radius:12px;display:flex;justify-content:space-between;margin-bottom:16px;padding:14px 18px;width:100%}.PricingCard_transactionLabel__GDux7{color:#a0aec0;font-family:Inter,sans-serif;font-size:15px;font-style:normal;font-weight:500}.PricingCard_transactionValue__q-xxp{color:#fff;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:700;text-align:right}.PricingCard_transactionValue__q-xxp.PricingCard_highlight__WZZ6N{color:#f6941c;font-size:18px}.PricingCard_walletButtonContainer__a6MwB{margin-top:auto;padding-top:24px}.PricingCard_walletButton__llw4v{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:14px;box-shadow:0 4px 14px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;font-family:Inter,sans-serif;font-size:17px;font-style:normal;font-weight:600;height:56px;justify-content:center;transition:all .2s ease;width:100%}.PricingCard_walletButton__llw4v:hover:not(:disabled){box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_walletButton__llw4v:active:not(:disabled){transform:translateY(0)}.PricingCard_walletButton__llw4v:disabled{background:hsla(0,0%,100%,.1);box-shadow:none;color:#636a77;cursor:not-allowed}.PricingCard_confirmContainer__vNq4n{align-items:center;display:flex;flex-direction:column;width:100%}.PricingCard_confirmText__FP0WS{color:#a0aec0;font-family:Inter,sans-serif;font-size:15px;margin-bottom:12px}.PricingCard_confirmButtons__fZ7jt{display:flex;gap:12px;width:100%}.PricingCard_secondaryButton__OTpW4{background:hsla(0,0%,100%,.05);border:1px solid hsla(0,0%,100%,.1);border-radius:14px;color:#fff;cursor:pointer;flex:1;font-family:Inter,sans-serif;font-size:17px;font-weight:600;height:56px;transition:all .2s ease}.PricingCard_secondaryButton__OTpW4:hover{background:hsla(0,0%,100%,.1)}.PricingCard_primaryButton__bmYo9{flex:1}.PricingCard_loading__2-tGA{align-items:center;color:#a0aec0;display:flex;flex-direction:column;font-family:Inter,sans-serif;gap:16px;padding:40px;text-align:center}.PricingCard_error__m5fK-{color:#ff4d4f;font-family:Inter,sans-serif;font-size:14px;margin-top:4px;text-align:left}.PricingCard_messageBox__wnx0F{align-items:center;animation:PricingCard_fadeIn__L63q8 .3s ease-out;color:#e2e8f0;display:flex;flex-direction:column;font-family:Inter,sans-serif;font-size:13.5px;font-weight:500;gap:8px;margin-bottom:16px;padding:8px 0;text-align:center}@keyframes PricingCard_fadeIn__L63q8{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.PricingCard_detailsButton__jHglL{background:none;border:none;color:#f6941c;cursor:pointer;font-size:13px;font-weight:600;margin-top:4px;padding:0;text-decoration:none}.PricingCard_detailsButton__jHglL:hover{text-decoration:underline}.PricingCard_errorDetails__CzN-7{background-color:rgba(0,0,0,.2);border-left:3px solid #ff4d4f;border-radius:8px;color:#fc8181;font-family:monospace;font-size:11px;line-height:1.5;margin-top:10px;max-height:150px;overflow-y:auto;padding:12px;text-align:left;white-space:pre-wrap;word-break:break-all}.PricingCard_transactionLink__RFRWW{background:rgba(40,167,69,.1);border:1px solid rgba(40,167,69,.2);border-radius:12px;color:#fff;font-family:Inter,sans-serif;font-size:14px;margin-top:20px;padding:16px;text-align:center}.PricingCard_explorerLink__-a82-{color:#f6941c;font-weight:600;text-decoration:none;transition:color .2s ease}.PricingCard_explorerLink__-a82-:hover{color:#ffad42;text-decoration:underline}.PricingCard_stablePayButton__Y4Rr4{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:16px;box-shadow:0 4px 15px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;gap:12px;justify-content:center;transition:all .2s ease}.PricingCard_stablePayButton__Y4Rr4:hover{box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_stablePayButton__Y4Rr4:active{transform:translateY(0)}.PricingCard_buttonText__8LnPv{font-family:Inter,sans-serif;font-weight:600}@media (max-width:520px){.PricingCard_pricingCard__LrWb9{border:none;border-radius:0;height:100%;min-height:100vh;padding:24px;width:100%}.PricingCard_dialogOverlay__0XJrE{align-items:flex-start;background-color:#242529}} \ No newline at end of file diff --git a/stablepay-sdk/dist/umd/index.js b/stablepay-sdk/dist/umd/index.js index 04b91d0..ba50753 100644 --- a/stablepay-sdk/dist/umd/index.js +++ b/stablepay-sdk/dist/umd/index.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("djed-sdk"),require("react"),require("viem"),require("viem/chains")):"function"==typeof define&&define.amd?define(["djed-sdk","react","viem","viem/chains"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).StablePay=t(e.DjedSdk,e.React,e.viem,e.viemChains)}(this,(function(e,t,n,a){"use strict";const r={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class i{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e.getWeb3(this.networkUri),this.djedContract=e.getDjedContract(this.web3,this.djedAddress);try{const{stableCoin:t,reserveCoin:n}=await e.getCoinContracts(this.djedContract,this.web3),{scDecimals:a,rcDecimals:r}=await e.getDecimals(t,n);this.stableCoin=t,this.reserveCoin=n,this.scDecimals=a,this.rcDecimals=r,this.oracleContract=await e.getOracleAddress(this.djedContract).then((t=>e.getOracleContract(this.web3,t,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){if(console.error("[Transaction] Error fetching contract details:",e),e.message&&e.message.includes("execution reverted")){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){if(console.error("[Transaction] Error initializing transaction:",e),e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(t){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof t)throw new Error("Amount must be a string");try{return(await e.tradeDataPriceBuySc(this.djedContract,this.scDecimals,t)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(t,n,a){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await e.buyScTx(this.djedContract,t,n,a,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var o="main_stablePayButton__UA7HC",s="main_logo__ITyEy",l="main_buttonText__N-ewy";const c=({onClick:e,size:n="medium"})=>{const a={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},i=a[n]||a.medium,c=r[n]||r.medium;return t.createElement("button",{className:o,onClick:e,style:i},t.createElement("div",{className:s,style:c}),t.createElement("span",{className:l},"Pay with StablePay"))};var d={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const u=({children:e,onClose:n,size:a="medium"})=>t.createElement("div",{className:d.dialogOverlay},t.createElement("div",{className:`${d.pricingCard} ${d[a]}`},t.createElement("button",{className:d.dialogClose,onClick:n},"×"),t.createElement("div",{className:d.pricingCardHeader},t.createElement("div",{className:d.allianceLogo}),t.createElement("div",{className:d.stablepayTitle},"StablePay")),t.createElement("div",{className:d.pricingCardBody},e)));class m{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const h=t.createContext(),w=({children:e,networkSelector:n})=>{const[a]=t.useState((()=>new m(n))),[r,i]=t.useState(null),[o,s]=t.useState(null),[l,c]=t.useState(null),d=()=>{s(null),c(null)};return t.useEffect((()=>{i(n.selectedNetwork)}),[n.selectedNetwork]),t.createElement(h.Provider,{value:{networkSelector:n,tokenSelector:a,selectedNetwork:r,selectedToken:o,transactionDetails:l,setTransactionDetails:c,selectNetwork:e=>!!n.selectNetwork(e)&&(i(e),d(),!0),selectToken:e=>{if(a.selectToken(e)){const e=a.getSelectedToken();return s(e),!0}return!1},resetSelections:()=>{n.selectNetwork(null),i(null),d()}}},e)},k=()=>{const e=t.useContext(h);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},g=()=>{const{networkSelector:e,selectedNetwork:n,selectNetwork:a}=k();return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"network-select"},"Select Network"),t.createElement("select",{id:"network-select",onChange:e=>{a(e.target.value)},value:n||""},t.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>t.createElement("option",{key:e,value:e},e)))))},C=()=>{const{networkSelector:e,tokenSelector:n,selectedNetwork:a,selectedToken:r,selectToken:o,setTransactionDetails:s}=k(),[l,c]=t.useState(!1),[u,m]=t.useState(null),h=a?n.getAvailableTokens():[];return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"token-select"},"Select Token"),t.createElement("select",{id:"token-select",onChange:async t=>{const r=t.target.value;m(null),c(!0);try{if(o(r)){const t=e.getSelectedNetworkConfig(),o=new i(t.uri,t.djedAddress);await o.init();const l=e.getTokenAmount(r),c=o.getBlockchainDetails();let d=null;"native"===r&&(d=await o.handleTradeDataBuySc(String(l))),s({network:a,token:r,tokenSymbol:n.getSelectedToken().symbol,amount:l,receivingAddress:e.getReceivingAddress(),djedContractAddress:t.djedAddress,isDirectTransfer:n.getSelectedToken().isDirectTransfer||!1,isNativeToken:n.getSelectedToken().isNative||!1,tradeAmount:d?d.amount:null,...c})}}catch(e){console.error("Error fetching transaction details:",e),m("Failed to fetch transaction details. Please try again.")}finally{c(!1)}},value:r?r.key:"",disabled:!a||l},t.createElement("option",{value:"",disabled:!0},a?l?"Loading...":"Select a token":"Please select a network first"),h.map((e=>t.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),u&&t.createElement("div",{className:d.error},u))};n.defineChain({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const p=n.defineChain({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),b=n.defineChain({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),f=t.createContext(null),v=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${a.sepolia.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:a.sepolia.rpcUrls.default.http,blockExplorerUrls:a.sepolia.blockExplorers?.default?.url?[a.sepolia.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${b.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${p.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},y=({children:e})=>{const{selectedNetwork:r}=k(),[i,o]=t.useState(null),[s,l]=t.useState(null),[c,d]=t.useState(null),[u,m]=t.useState(null),[h,w]=t.useState(null),[g,C]=t.useState(null),[y,E]=t.useState(!1),_=r?(e=>{switch(e){case"sepolia":return a.sepolia;case"ethereum-classic":return b;case"milkomeda-mainnet":return p;default:return null}})(r):null,N=_?_.id:null,S=t.useRef(null),T=t.useRef(null),A=t.useCallback((()=>{o(null),l(null),d(null),m(null),w(null),C(null)}),[]),x=t.useCallback((async e=>{const t=parseInt(e,16);if(m(t),_&&t===N){if(C(null),window.ethereum&&_){const e=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});o(e)}}else if(_&&t!==N){C(`Wrong network detected. Please switch to ${_?.name||r||"selected network"}`)}}),[_,N,r]);T.current=x;const D=t.useCallback((async e=>{if(0===e.length){if(A(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(d(e[0]),_)try{const t=n.createPublicClient({chain:_,transport:n.http()});l(t);const a=await t.getBalance({address:e[0]});w(parseFloat(a)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}}),[_,A]);S.current=D;const P=t.useCallback((()=>{if(A(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[A]),I=t.useCallback((()=>{_&&l(n.createPublicClient({chain:_,transport:n.http()}))}),[_]),B=t.useCallback((async()=>{if(!window.ethereum)return C("Please install MetaMask or another Web3 wallet"),!1;if(!r||!_)return C("Please select a network first"),!1;E(!0),C(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const t=await window.ethereum.request({method:"eth_chainId"});parseInt(t,16)!==N&&await v(r);const a=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});o(a),d(e[0]),m(N);const i=n.createPublicClient({chain:_,transport:n.http()});l(i);try{const t=await i.getBalance({address:e[0]});w(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}return S.current=D,T.current=x,window.ethereum.on("accountsChanged",D),window.ethereum.on("chainChanged",x),!0}catch(e){return console.error("Error connecting wallet:",e),C(e.message),!1}finally{E(!1)}}),[r,_,N,D,x]),M=t.useCallback((async()=>{if(!(window.ethereum&&r&&_&&c)){return C("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==N){C(null),await v(r);const e=500;await new Promise((t=>setTimeout(t,e)));const t=await window.ethereum.request({method:"eth_chainId"}),n=parseInt(t,16);if(n!==N)throw new Error(`Failed to switch network. MetaMask is still on chain ${n}, expected ${N}`)}const t=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});return o(t),m(N),C(null),t}catch(e){return C(e.message),null}}),[r,_,N,c]),j=t.useRef(r);return t.useEffect((()=>{if(null!==j.current&&j.current!==r&&c&&(A(),window.ethereum)){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}j.current=r}),[r,c,A]),t.useEffect((()=>{I()}),[I]),t.createElement(f.Provider,{value:{walletClient:i,publicClient:s,account:c,chainId:u,balance:h,error:g,isConnecting:y,connectWallet:B,disconnectWallet:P,ensureCorrectNetwork:M,expectedChainId:N}},e)},E=({onTransactionComplete:e})=>{const{networkSelector:a,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:l}=k(),{connectWallet:c,account:u,walletClient:m,publicClient:h,isConnecting:w,ensureCorrectNetwork:g,expectedChainId:C}=(()=>{const e=t.useContext(f);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[p,b]=t.useState(null),[v,y]=t.useState(null),[E,_]=t.useState(null),[N,S]=t.useState(""),[T,A]=t.useState(null),[x,D]=t.useState(null),[P,I]=t.useState(!1);if(t.useEffect((()=>{_(null),y(null),S(""),D(null),A(null)}),[r,o]),t.useEffect((()=>{(async()=>{if(r&&o)try{const e=a.getSelectedNetworkConfig(),t=a.getReceivingAddress(),n=a.getTokenAmount(o.key),s=new i(e.uri,e.djedAddress);await s.init(),b(s);let c=null;if("native"===o.key)try{c=await s.handleTradeDataBuySc(String(n)),y(c)}catch(e){console.error("Error fetching trade data:",e)}l({network:r,token:o.key,tokenSymbol:o.symbol,amount:n||"0",receivingAddress:t,djedContractAddress:e.djedAddress,isDirectTransfer:o.isDirectTransfer||!1,isNativeToken:o.isNative||!1,tradeAmount:c?c.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[r,o,a,l]),!r||!o)return null;if(!s)return t.createElement("div",{className:d.loading},"Initializing transaction...");const B=()=>{if(!T||!r)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[r]?`${e[r]}${T}`:null};return t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"Network:"),t.createElement("span",{className:d.transactionValue},s.network)),t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"You Pay:"),t.createElement("span",{className:`${d.transactionValue} ${d.highlight}`},"stablecoin"===o.key?`${s.amount} ${s.tokenSymbol}`:`${v||"Calculating..."} ${s.tokenSymbol}`)),N&&t.createElement("div",{className:d.messageBox},N,x&&t.createElement("button",{onClick:()=>I(!P),className:d.detailsButton},P?"Hide Details":"Show Details")),P&&x&&t.createElement("div",{className:d.errorDetails},t.createElement("pre",null,x.message)),T&&t.createElement("div",{className:d.transactionLink},"Transaction Hash:"," ",B()?t.createElement("a",{href:B(),target:"_blank",rel:"noopener noreferrer",className:d.explorerLink},T.slice(0,6),"...",T.slice(-6)):t.createElement("span",{style:{wordBreak:"break-word"}},T)),t.createElement("div",{className:d.walletButtonContainer},!u&&t.createElement("button",{className:d.walletButton,onClick:async()=>{await c()},disabled:w},w?"Connecting...":"Connect Wallet"),u&&!E&&t.createElement("button",{className:d.walletButton,onClick:async()=>{if(u&&s&&p)try{_(null),D(null),S("Preparing transaction...");const e=s.receivingAddress;let t;if("native"===o.key){const a="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=v||"0",i=n.parseEther(String(r));t=await p.buyStablecoins(u,e,i,a),t={...t,value:i,account:u}}else{const r=a.getSelectedNetworkConfig(),i=r?.tokens?.stablecoin?.address;if(!i)throw new Error("Stablecoin address not found in network configuration");const o=s.amount?n.parseUnits(String(s.amount),s.stableCoinDecimals):"0";t={to:i,value:0n,data:n.encodeFunctionData({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,o]}),account:u}}_(t),S("Transaction ready. Please confirm to proceed.")}catch(e){D(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");S(`Transaction preparation failed: ${t}`)}else S("Wallet not connected or transaction details missing")}},"Prepare Transaction"),u&&E&&t.createElement("button",{className:d.walletButton,onClick:async()=>{D(null);try{if(!u||!E)return void S("Wallet account or transaction data is missing");if(!r)return void S("Network not selected");const t=a.getSelectedNetworkConfig();if(!t)return void S("Network configuration not found");S("Verifying network...");const n=await g();if(!n)return void S("Failed to switch to correct network. Please approve the network switch in MetaMask and try again.");if(!window.ethereum)return void S("MetaMask not available");const i=await window.ethereum.request({method:"eth_chainId"}),l=parseInt(i,16);if(l!==t.chainId){const e=`Network mismatch. MetaMask is on chain ${l}, but ${r} requires chain ${t.chainId}. Please switch networks in MetaMask.`;return S(e),void D(new Error(e))}if(n.chain.id!==t.chainId){const e=`Wallet client chain mismatch. Wallet client is on chain ${n.chain.id}, but expected ${t.chainId}.`;return S(e),void D(new Error(e))}S("Sending transaction...");const c=await n.sendTransaction({...E,account:u});A(c),S("Transaction sent!"),e&&e({txHash:c,network:r,token:o?.key,tokenSymbol:o?.symbol,amount:s?.amount,receivingAddress:s?.receivingAddress})}catch(e){D(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");S(`Transaction failed: ${t}`),console.error("Transaction error:",e)}},disabled:null!==T},"Send Transaction")))},_=({onClose:e,buttonSize:n,onTransactionComplete:a})=>{const{resetSelections:r}=k();return t.createElement(u,{onClose:()=>{r(),e()},size:n},t.createElement(g,null),t.createElement(C,null),t.createElement(E,{onTransactionComplete:a}))},N=({onClose:e,buttonSize:n,networkSelector:a,onTransactionComplete:r})=>t.createElement(w,{networkSelector:a},t.createElement(y,null,t.createElement(_,{onClose:e,buttonSize:n,onTransactionComplete:r})));return{NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(r).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:i,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!r[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:n="medium",onTransactionComplete:a,onSuccess:r})=>{const[i,o]=t.useState(!1),s=a||r;return t.createElement("div",{className:d.widgetContainer},!i&&t.createElement(c,{onClick:()=>{o(!0)},size:n}),i&&t.createElement(N,{onClose:()=>{o(!1)},buttonSize:n,networkSelector:e,onTransactionComplete:s}))},PayButton:c,Dialog:u,NetworkDropdown:g}})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("djed-sdk"),require("react"),require("viem"),require("viem/chains")):"function"==typeof define&&define.amd?define(["djed-sdk","react","viem","viem/chains"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).StablePay=t(e.DjedSdk,e.React,e.viem,e.viemChains)}(this,(function(e,t,n,a){"use strict";const r={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class o{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e.getWeb3(this.networkUri),this.djedContract=e.getDjedContract(this.web3,this.djedAddress);try{const{stableCoin:t,reserveCoin:n}=await e.getCoinContracts(this.djedContract,this.web3),{scDecimals:a,rcDecimals:r}=await e.getDecimals(t,n);this.stableCoin=t,this.reserveCoin=n,this.scDecimals=a,this.rcDecimals=r,this.oracleContract=await e.getOracleAddress(this.djedContract).then((t=>e.getOracleContract(this.web3,t,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){console.error("[Transaction] Error fetching contract details:",e);if(-32e3===e.code||3===e.code||e.data){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){console.error("[Transaction] Error initializing transaction:",e);if(-32603===e.code||4001===e.code||-32005===e.code||e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(t){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof t)throw new Error("Amount must be a string");try{return(await e.tradeDataPriceBuySc(this.djedContract,this.scDecimals,t)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(t,n,a){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await e.buyScTx(this.djedContract,t,n,a,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var i="main_stablePayButton__UA7HC",s="main_logo__ITyEy",c="main_buttonText__N-ewy";const l=({onClick:e,size:n="medium"})=>{const a={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},o=a[n]||a.medium,l=r[n]||r.medium;return t.createElement("button",{className:i,onClick:e,style:o},t.createElement("div",{className:s,style:l}),t.createElement("span",{className:c},"Pay with StablePay"))};var d={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",confirmContainer:"PricingCard_confirmContainer__vNq4n",confirmText:"PricingCard_confirmText__FP0WS",confirmButtons:"PricingCard_confirmButtons__fZ7jt",secondaryButton:"PricingCard_secondaryButton__OTpW4",primaryButton:"PricingCard_primaryButton__bmYo9",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const u=({children:e,onClose:n,size:a="medium"})=>t.createElement("div",{className:d.dialogOverlay},t.createElement("div",{className:`${d.pricingCard} ${d[a]}`},t.createElement("button",{className:d.dialogClose,onClick:n},"×"),t.createElement("div",{className:d.pricingCardHeader},t.createElement("div",{className:d.allianceLogo}),t.createElement("div",{className:d.stablepayTitle},"StablePay")),t.createElement("div",{className:d.pricingCardBody},e)));class m{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const h=t.createContext(),w=({children:e,networkSelector:n})=>{const[a]=t.useState((()=>new m(n))),[r,o]=t.useState(null),[i,s]=t.useState(null),[c,l]=t.useState(null),d=()=>{s(null),l(null)};return t.useEffect((()=>{o(n.selectedNetwork)}),[n.selectedNetwork]),t.createElement(h.Provider,{value:{networkSelector:n,tokenSelector:a,selectedNetwork:r,selectedToken:i,transactionDetails:c,setTransactionDetails:l,selectNetwork:e=>!!n.selectNetwork(e)&&(o(e),d(),!0),selectToken:e=>{if(a.selectToken(e)){const e=a.getSelectedToken();return s(e),!0}return!1},resetSelections:()=>{n.selectNetwork(null),o(null),d()}}},e)},k=()=>{const e=t.useContext(h);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},g=()=>{const{networkSelector:e,selectedNetwork:n,selectNetwork:a}=k();return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"network-select"},"Select Network"),t.createElement("select",{id:"network-select",onChange:e=>{a(e.target.value)},value:n||""},t.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>t.createElement("option",{key:e,value:e},e)))))},C=()=>{const{networkSelector:e,tokenSelector:n,selectedNetwork:a,selectedToken:r,selectToken:i,setTransactionDetails:s}=k(),[c,l]=t.useState(!1),[u,m]=t.useState(null),h=a?n.getAvailableTokens():[];return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"token-select"},"Select Token"),t.createElement("select",{id:"token-select",onChange:async t=>{const r=t.target.value;m(null),l(!0);try{if(i(r)){const t=e.getSelectedNetworkConfig(),i=new o(t.uri,t.djedAddress);await i.init();const c=e.getTokenAmount(r),l=i.getBlockchainDetails();let d=null;"native"===r&&(d=await i.handleTradeDataBuySc(String(c))),s({network:a,token:r,tokenSymbol:n.getSelectedToken().symbol,amount:c,receivingAddress:e.getReceivingAddress(),djedContractAddress:t.djedAddress,isDirectTransfer:n.getSelectedToken().isDirectTransfer||!1,isNativeToken:n.getSelectedToken().isNative||!1,tradeAmount:d?d.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),m("Failed to fetch transaction details. Please try again.")}finally{l(!1)}},value:r?r.key:"",disabled:!a||c},t.createElement("option",{value:"",disabled:!0},a?c?"Loading...":"Select a token":"Please select a network first"),h.map((e=>t.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),u&&t.createElement("div",{className:d.error},u))};n.defineChain({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const p=n.defineChain({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),b=n.defineChain({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),f=t.createContext(null),E=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${a.sepolia.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:a.sepolia.rpcUrls.default.http,blockExplorerUrls:a.sepolia.blockExplorers?.default?.url?[a.sepolia.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${b.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${p.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},y=({children:e})=>{const{selectedNetwork:r}=k(),[o,i]=t.useState(null),[s,c]=t.useState(null),[l,d]=t.useState(null),[u,m]=t.useState(null),[h,w]=t.useState(null),[g,C]=t.useState(null),[y,v]=t.useState(!1),_=r?(e=>{switch(e){case"sepolia":return a.sepolia;case"ethereum-classic":return b;case"milkomeda-mainnet":return p;default:return null}})(r):null,N=_?_.id:null,S=t.useRef(null),T=t.useRef(null),P=t.useCallback((()=>{i(null),c(null),d(null),m(null),w(null),C(null)}),[]),A=t.useCallback((async e=>{const t=parseInt(e,16);if(m(t),_&&t===N){if(C(null),window.ethereum&&_){const e=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});i(e)}}else if(_&&t!==N){C(`Wrong network detected. Please switch to ${_?.name||r||"selected network"}`)}}),[_,N,r]);T.current=A;const D=t.useCallback((async e=>{if(0===e.length){if(P(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(d(e[0]),_)try{const t=n.createPublicClient({chain:_,transport:n.http()});c(t);const a=await t.getBalance({address:e[0]});w(parseFloat(a)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}}),[_,P]);S.current=D;const x=t.useCallback((()=>{if(P(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[P]),I=t.useCallback((()=>{_&&c(n.createPublicClient({chain:_,transport:n.http()}))}),[_]),B=t.useCallback((async()=>{if(!window.ethereum)return C("Please install MetaMask or another Web3 wallet"),!1;if(!r||!_)return C("Please select a network first"),!1;v(!0),C(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const t=await window.ethereum.request({method:"eth_chainId"});parseInt(t,16)!==N&&await E(r);const a=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});i(a),d(e[0]),m(N);const o=n.createPublicClient({chain:_,transport:n.http()});c(o);try{const t=await o.getBalance({address:e[0]});w(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}return S.current=D,T.current=A,window.ethereum.on("accountsChanged",D),window.ethereum.on("chainChanged",A),!0}catch(e){return console.error("Error connecting wallet:",e),C(e.message),!1}finally{v(!1)}}),[r,_,N,D,A]),M=t.useCallback((async()=>{if(!(window.ethereum&&r&&_&&l)){return C("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==N){C(null),await E(r);const e=500;await new Promise((t=>setTimeout(t,e)));const t=await window.ethereum.request({method:"eth_chainId"}),n=parseInt(t,16);if(n!==N)throw new Error(`Failed to switch network. MetaMask is still on chain ${n}, expected ${N}`)}const t=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});return i(t),m(N),C(null),t}catch(e){return C(e.message),null}}),[r,_,N,l]),j=t.useRef(r);return t.useEffect((()=>{if(null!==j.current&&j.current!==r&&l&&(P(),window.ethereum)){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}j.current=r}),[r,l,P]),t.useEffect((()=>{I()}),[I]),t.createElement(f.Provider,{value:{walletClient:o,publicClient:s,account:l,chainId:u,balance:h,error:g,isConnecting:y,connectWallet:B,disconnectWallet:x,ensureCorrectNetwork:M,expectedChainId:N}},e)},v=({onTransactionComplete:e})=>{const{networkSelector:a,selectedNetwork:r,selectedToken:i,transactionDetails:s,setTransactionDetails:c}=k(),{connectWallet:l,account:u,walletClient:m,publicClient:h,isConnecting:w,ensureCorrectNetwork:g,expectedChainId:C}=(()=>{const e=t.useContext(f);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[p,b]=t.useState(null),[E,y]=t.useState(null),[v,_]=t.useState(""),[N,S]=t.useState(null),[T,P]=t.useState(null),[A,D]=t.useState(!1),[x,I]=t.useState("IDLE");if(t.useEffect((()=>{y(null),_(""),P(null),S(null),I("IDLE")}),[r,i]),t.useEffect((()=>{(async()=>{if(r&&i)try{const e=a.getSelectedNetworkConfig(),t=a.getReceivingAddress(),n=a.getTokenAmount(i.key),s=new o(e.uri,e.djedAddress);await s.init(),b(s);let l=null;if("native"===i.key)try{l=await s.handleTradeDataBuySc(String(n)),y(l)}catch(e){console.error("Error fetching trade data:",e)}c({network:r,token:i.key,tokenSymbol:i.symbol,amount:n||"0",receivingAddress:t,djedContractAddress:e.djedAddress,isDirectTransfer:i.isDirectTransfer||!1,isNativeToken:i.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[r,i,a,c]),!r||!i)return null;if(!s)return t.createElement("div",{className:d.loading},"Initializing transaction...");const B=()=>{if(!N||!r)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[r]?`${e[r]}${N}`:null};return t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"Network:"),t.createElement("span",{className:d.transactionValue},s.network)),t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"You Pay:"),t.createElement("span",{className:`${d.transactionValue} ${d.highlight}`},"stablecoin"===i.key?`${s.amount} ${s.tokenSymbol}`:`${E||"Calculating..."} ${s.tokenSymbol}`)),v&&t.createElement("div",{className:d.messageBox},v,T&&t.createElement("button",{onClick:()=>D(!A),className:d.detailsButton},A?"Hide Details":"Show Details")),A&&T&&t.createElement("div",{className:d.errorDetails},t.createElement("pre",null,T.message)),N&&t.createElement("div",{className:d.transactionLink},"Transaction Hash:"," ",B()?t.createElement("a",{href:B(),target:"_blank",rel:"noopener noreferrer",className:d.explorerLink},N.slice(0,6),"...",N.slice(-6)):t.createElement("span",{style:{wordBreak:"break-word"}},N)),"SUCCESS"!==x&&t.createElement("div",{className:d.walletButtonContainer},!u&&t.createElement("button",{className:d.walletButton,onClick:async()=>{await l()},disabled:w},w?"Connecting...":"Connect Wallet"),u&&"IDLE"===x&&t.createElement("button",{className:d.walletButton,onClick:()=>I("CONFIRMING")},"Pay ",s.amount," ",s.tokenSymbol),u&&"CONFIRMING"===x&&t.createElement("div",{className:d.confirmContainer},t.createElement("span",{className:d.confirmText},"Confirm payment?"),t.createElement("div",{className:d.confirmButtons},t.createElement("button",{className:d.secondaryButton,onClick:()=>I("IDLE")},"No"),t.createElement("button",{className:`${d.walletButton} ${d.primaryButton}`,onClick:async()=>{if(!u||!s||!p)return void _("Wallet not connected or transaction details missing");let t;I("PROCESSING"),_("Preparing transaction..."),P(null),S(null);try{const e=s.receivingAddress;if("native"===i.key){const a="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=E||"0",o=n.parseEther(String(r));t=await p.buyStablecoins(u,e,o,a),t={...t,value:o,account:u}}else{const r=a.getSelectedNetworkConfig(),o=r?.tokens?.stablecoin?.address;if(!o)throw new Error("Stablecoin address not found in network configuration");const i=s.amount?n.parseUnits(String(s.amount),s.stableCoinDecimals):"0";t={to:o,value:0n,data:n.encodeFunctionData({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:u}}}catch(e){P(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");return _(`Transaction preparation failed: ${t}`),void I("IDLE")}_("Please check your wallet to confirm the transaction...");try{const n=a.getSelectedNetworkConfig();if(!n)throw new Error("Network configuration not found");const o=await g();if(!o)throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask.");if(!window.ethereum)throw new Error("MetaMask not available");const c=await window.ethereum.request({method:"eth_chainId"}),l=parseInt(c,16);if(l!==n.chainId)throw new Error(`Network mismatch. MetaMask is on chain ${l}, but ${r} requires chain ${n.chainId}. Please switch networks in MetaMask.`);if(o.chain.id!==n.chainId)throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${o.chain.id}, but expected ${n.chainId}.`);const d=await o.sendTransaction({...t,account:u});S(d),_("Transaction sent successfully!"),I("SUCCESS"),e&&e({txHash:d,network:r,token:i?.key,tokenSymbol:i?.symbol,amount:s?.amount,receivingAddress:s?.receivingAddress})}catch(e){P(e);let t="Unknown error";t="UserRejectedRequestError"===e.name||4001===e.code?"User denied transaction":"ContractFunctionRevertedError"===e.name||e.data&&e.data.message?e.shortMessage||e.data?.message||e.message:e.shortMessage||(e.message?e.message.split("\n")[0]:"Transaction failed"),_(`Transaction failed: ${t}`),I("IDLE"),console.error("Transaction error:",e)}}},"Yes, Pay"))),u&&"PROCESSING"===x&&t.createElement("button",{className:d.walletButton,disabled:!0},"Processing...")))},_=({onClose:e,buttonSize:n,onTransactionComplete:a})=>{const{resetSelections:r}=k();return t.createElement(u,{onClose:()=>{r(),e()},size:n},t.createElement(g,null),t.createElement(C,null),t.createElement(v,{onTransactionComplete:a}))},N=({onClose:e,buttonSize:n,networkSelector:a,onTransactionComplete:r})=>t.createElement(w,{networkSelector:a},t.createElement(y,null,t.createElement(_,{onClose:e,buttonSize:n,onTransactionComplete:r})));return{NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(r).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:o,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!r[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:n="medium",onTransactionComplete:a,onSuccess:r})=>{const[o,i]=t.useState(!1),s=a||r;return t.createElement("div",{className:d.widgetContainer},!o&&t.createElement(l,{onClick:()=>{i(!0)},size:n}),o&&t.createElement(N,{onClose:()=>{i(!1)},buttonSize:n,networkSelector:e,onTransactionComplete:s}))},PayButton:l,Dialog:u,NetworkDropdown:g}})); //# sourceMappingURL=index.js.map diff --git a/stablepay-sdk/dist/umd/index.js.map b/stablepay-sdk/dist/umd/index.js.map index 44cfa7f..097fb36 100644 --- a/stablepay-sdk/dist/umd/index.js.map +++ b/stablepay-sdk/dist/umd/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../../src/utils/config.js","../../src/core/Transaction.js","../../src/widget/PayButton.jsx","../../src/widget/Dialog.jsx","../../src/core/TokenSelector.js","../../src/contexts/NetworkContext.jsx","../../src/widget/NetworkDropdown.jsx","../../src/widget/TokenDropdown.jsx","../../src/contexts/chains.js","../../src/contexts/WalletContext.jsx","../../src/widget/TransactionReview.jsx","../../src/widget/Widget.jsx","../../src/index.js","../../src/core/NetworkSelector.js","../../src/core/MerchantConfig.js"],"sourcesContent":["// src/utils/config.js\nexport const networksConfig = {\n 'sepolia': {\n uri: 'https://ethereum-sepolia.publicnode.com/',\n chainId: 11155111,\n djedAddress: '0x624FcD0a1F9B5820c950FefD48087531d38387f4',\n tokens: {\n stablecoin: {\n symbol: 'SOD',\n address: '0x6b930182787F346F18666D167e8d32166dC5eFBD',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETH',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'milkomeda-mainnet': {\n uri: 'https://rpc-mainnet-cardano-evm.c1.milkomeda.com',\n chainId: 2001,\n djedAddress: '0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76',\n tokens: {\n stablecoin: {\n symbol: 'MOD',\n address: '0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'mADA',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'ethereum-classic': {\n uri: 'https://etc.rivet.link',\n chainId: 61,\n djedAddress: '0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf',\n tokens: {\n stablecoin: {\n symbol: 'ECSD',\n address: '0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETC',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n }\n};","import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx } from 'djed-sdk';\n\nexport class Transaction {\n constructor(networkUri, djedAddress) {\n this.networkUri = networkUri;\n this.djedAddress = djedAddress;\n }\n\n async init() {\n if (!this.networkUri || !this.djedAddress) {\n throw new Error('Network URI and DJED address are required');\n }\n\n try {\n this.web3 = await getWeb3(this.networkUri);\n this.djedContract = getDjedContract(this.web3, this.djedAddress);\n \n try {\n const { stableCoin, reserveCoin } = await getCoinContracts(this.djedContract, this.web3);\n const { scDecimals, rcDecimals } = await getDecimals(stableCoin, reserveCoin);\n this.stableCoin = stableCoin;\n this.reserveCoin = reserveCoin;\n this.scDecimals = scDecimals;\n this.rcDecimals = rcDecimals;\n\n this.oracleContract = await getOracleAddress(this.djedContract).then((addr) =>\n getOracleContract(this.web3, addr, this.djedContract._address)\n );\n\n this.oracleAddress = this.oracleContract._address;\n } catch (contractError) {\n console.error('[Transaction] Error fetching contract details:', contractError);\n if (contractError.message && contractError.message.includes('execution reverted')) {\n const getNetworkInfo = (uri) => {\n if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };\n if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' };\n if (uri.includes('sepolia')) return { name: 'Sepolia', chainId: '11155111' };\n if (uri.includes('etc.rivet.link')) return { name: 'Ethereum Classic', chainId: '61' };\n return { name: 'the selected network', chainId: 'unknown' };\n };\n const { name: networkName, chainId } = getNetworkInfo(this.networkUri);\n throw new Error(\n `Failed to interact with Djed contract at ${this.djedAddress} on ${networkName}.\\n\\n` +\n `Possible causes:\\n` +\n `- The contract address may be incorrect\\n` +\n `- The contract may not be deployed on ${networkName}\\n` +\n `- The contract may not be a valid Djed contract\\n\\n` +\n `Please verify the contract address is correct for ${networkName} (Chain ID: ${chainId}).`\n );\n }\n throw contractError;\n }\n } catch (error) {\n console.error('[Transaction] Error initializing transaction:', error);\n if (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED'))) {\n const getNetworkName = (uri) => {\n if (uri.includes('milkomeda')) return 'Milkomeda';\n if (uri.includes('mordor')) return 'Mordor';\n if (uri.includes('sepolia')) return 'Sepolia';\n return 'the selected network';\n };\n const networkName = getNetworkName(this.networkUri);\n throw new Error(\n `Failed to connect to ${networkName} RPC endpoint: ${this.networkUri}\\n\\n` +\n `Possible causes:\\n` +\n `- The RPC endpoint may be temporarily unavailable\\n` +\n `- DNS resolution issue (check your internet connection)\\n` +\n `- Network firewall blocking the connection\\n\\n` +\n `Please try again in a few moments or check the network status.`\n );\n }\n throw error;\n }\n }\n\n getBlockchainDetails() {\n return {\n web3Available: !!this.web3,\n djedContractAvailable: !!this.djedContract,\n stableCoinAddress: this.stableCoin ? this.stableCoin._address : 'N/A',\n reserveCoinAddress: this.reserveCoin ? this.reserveCoin._address : 'N/A',\n stableCoinDecimals: this.scDecimals,\n reserveCoinDecimals: this.rcDecimals,\n oracleAddress: this.oracleAddress || 'N/A',\n oracleContractAvailable: !!this.oracleContract,\n };\n }\n\n async handleTradeDataBuySc(amountScaled) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n if (typeof amountScaled !== 'string') {\n throw new Error(\"Amount must be a string\");\n }\n try {\n const result = await tradeDataPriceBuySc(this.djedContract, this.scDecimals, amountScaled);\n return result.totalBCScaled;\n } catch (error) {\n console.error(\"Error fetching trade data for buying stablecoins: \", error);\n throw error;\n }\n }\n\n async buyStablecoins(payer, receiver, value) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n try {\n const UI = '0x0232556C83791b8291E9b23BfEa7d67405Bd9839';\n\n const txData = await buyScTx(this.djedContract, payer, receiver, value, UI, this.djedAddress);\n\n return txData;\n } catch (error) {\n console.error(\"Error executing buyStablecoins transaction: \", error);\n throw error;\n }\n }\n}\n","import React from \"react\";\nimport styles from \"../styles/main.css\";\n\nconst PayButton = ({ onClick, size = \"medium\" }) => {\n const sizeStyles = {\n small: { width: \"200px\", height: \"50px\", fontSize: \"14px\" },\n medium: { width: \"250px\", height: \"60px\", fontSize: \"16px\" },\n large: { width: \"300px\", height: \"70px\", fontSize: \"18px\" },\n };\n\n const logoSizes = {\n small: { width: \"35px\", height: \"33px\" },\n medium: { width: \"40px\", height: \"38px\" },\n large: { width: \"45px\", height: \"43px\" },\n };\n\n const buttonStyle = sizeStyles[size] || sizeStyles.medium;\n const logoStyle = logoSizes[size] || logoSizes.medium;\n\n return (\n \n
\n Pay with StablePay\n \n );\n};\n\nexport default PayButton;\n","import React from 'react';\nimport styles from '../styles/PricingCard.css';\n\n\nconst Dialog = ({ children, onClose, size = 'medium' }) => {\n return (\n
\n
\n \n
\n
\n\n
StablePay
\n
\n
\n {children}\n
\n
\n
\n );\n};\n\nexport default Dialog;","// TokenSelector.js\n\nexport class TokenSelector {\n constructor(networkSelector) {\n this.networkSelector = networkSelector;\n this.selectedToken = null;\n }\n\n selectToken(tokenKey) {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (networkConfig && networkConfig.tokens[tokenKey]) {\n this.selectedToken = {\n key: tokenKey,\n ...networkConfig.tokens[tokenKey]\n };\n return true;\n }\n return false;\n }\n\n getSelectedToken() {\n return this.selectedToken;\n }\n\n getAvailableTokens() {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) return [];\n\n return Object.entries(networkConfig.tokens).map(([key, config]) => ({\n key,\n ...config\n }));\n }\n\n resetSelection() {\n this.selectedToken = null;\n }\n}","import React, { createContext, useState, useContext, useEffect } from 'react';\nimport { TokenSelector } from '../core/TokenSelector';\n\nconst NetworkContext = createContext();\n\nexport const NetworkProvider = ({ children, networkSelector }) => {\n const [tokenSelector] = useState(() => new TokenSelector(networkSelector));\n const [selectedNetwork, setSelectedNetwork] = useState(null);\n const [selectedToken, setSelectedToken] = useState(null);\n const [transactionDetails, setTransactionDetails] = useState(null);\n\n const resetState = () => {\n setSelectedToken(null);\n setTransactionDetails(null);\n };\n\n const selectNetwork = (networkKey) => {\n if (networkSelector.selectNetwork(networkKey)) {\n setSelectedNetwork(networkKey);\n resetState(); \n return true;\n }\n return false;\n };\n\n const selectToken = (tokenKey) => {\n if (tokenSelector.selectToken(tokenKey)) {\n const token = tokenSelector.getSelectedToken();\n setSelectedToken(token);\n return true;\n }\n return false;\n };\n\n const resetSelections = () => {\n networkSelector.selectNetwork(null);\n setSelectedNetwork(null);\n resetState();\n };\n\n // Synchronize context state with NetworkSelector\n useEffect(() => {\n setSelectedNetwork(networkSelector.selectedNetwork);\n }, [networkSelector.selectedNetwork]);\n\n return (\n \n {children}\n \n );\n};\n\nexport const useNetwork = () => {\n const context = useContext(NetworkContext);\n if (context === undefined) {\n throw new Error('useNetwork must be used within a NetworkProvider');\n }\n return context;\n};\n\nexport default NetworkContext;","import React from 'react';\nimport { useNetwork } from '../contexts/NetworkContext';\nimport styles from '../styles/PricingCard.css';\n\nconst NetworkDropdown = () => {\n const { networkSelector, selectedNetwork, selectNetwork } = useNetwork();\n\n const handleNetworkChange = (event) => {\n selectNetwork(event.target.value);\n };\n\n return (\n
\n \n \n
\n );\n};\n\nexport default NetworkDropdown;","import React, { useState } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst TokenDropdown = () => {\n const {\n networkSelector,\n tokenSelector,\n selectedNetwork,\n selectedToken,\n selectToken,\n setTransactionDetails,\n } = useNetwork();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n const handleTokenChange = async (event) => {\n const newValue = event.target.value;\n setError(null);\n setLoading(true);\n\n try {\n if (selectToken(newValue)) {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const transaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await transaction.init();\n\n const tokenAmount = networkSelector.getTokenAmount(newValue);\n const blockchainDetails = transaction.getBlockchainDetails();\n\n let tradeData = null;\n if (newValue === \"native\") {\n tradeData = await transaction.handleTradeDataBuySc(\n String(tokenAmount)\n );\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: newValue,\n tokenSymbol: tokenSelector.getSelectedToken().symbol,\n amount: tokenAmount,\n receivingAddress: networkSelector.getReceivingAddress(),\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer:\n tokenSelector.getSelectedToken().isDirectTransfer || false,\n isNativeToken: tokenSelector.getSelectedToken().isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...blockchainDetails,\n });\n }\n } catch (err) {\n console.error(\"Error fetching transaction details:\", err);\n setError(\"Failed to fetch transaction details. Please try again.\");\n } finally {\n setLoading(false);\n }\n };\n\n const availableTokens = selectedNetwork\n ? tokenSelector.getAvailableTokens()\n : [];\n\n return (\n
\n \n \n \n {availableTokens.map((token) => (\n \n ))}\n \n {error &&
{error}
}\n
\n );\n};\n\nexport default TokenDropdown;\n","import { defineChain } from 'viem';\nimport { sepolia } from 'viem/chains';\n\nexport const mordor = defineChain({\n id: 63,\n name: 'Mordor Testnet',\n network: 'mordor',\n nativeCurrency: {\n decimals: 18,\n name: 'Mordor Ether',\n symbol: 'METC',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc.mordor.etccooperative.org'],\n webSocket: ['wss://rpc.mordor.etccooperative.org/ws'],\n },\n },\n blockExplorers: {\n default: { name: 'BlockScout', url: 'https://blockscout.com/etc/mordor' },\n },\n testnet: true,\n});\n\nexport const milkomeda = defineChain({\n id: 2001,\n name: 'Milkomeda C1 Mainnet',\n network: 'milkomeda',\n nativeCurrency: {\n decimals: 18,\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n },\n },\n blockExplorers: {\n default: { name: 'Milkomeda Explorer', url: 'https://explorer-mainnet-cardano-evm.c1.milkomeda.com' },\n },\n testnet: false,\n});\n\nexport const etcMainnet = defineChain({\n id: 61,\n name: 'Ethereum Classic',\n network: 'etc',\n nativeCurrency: {\n decimals: 18,\n name: 'Ethereum Classic',\n symbol: 'ETC',\n },\n rpcUrls: {\n default: {\n http: ['https://etc.rivet.link'],\n },\n },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://blockscout.com/etc/mainnet' },\n },\n testnet: false,\n});\n\nexport const getChainByNetworkKey = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return sepolia;\n case 'ethereum-classic':\n return etcMainnet;\n case 'milkomeda-mainnet':\n return milkomeda;\n default:\n return null;\n }\n};\n\nexport const getChainConfigForWallet = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return {\n chainId: `0x${sepolia.id.toString(16)}`,\n chainName: 'Sepolia',\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n rpcUrls: sepolia.rpcUrls.default.http,\n blockExplorerUrls: sepolia.blockExplorers?.default?.url ? [sepolia.blockExplorers.default.url] : [],\n };\n case 'ethereum-classic':\n return {\n chainId: `0x${etcMainnet.id.toString(16)}`,\n chainName: 'Ethereum Classic',\n nativeCurrency: {\n name: 'Ethereum Classic',\n symbol: 'ETC',\n decimals: 18,\n },\n rpcUrls: ['https://etc.rivet.link'],\n blockExplorerUrls: ['https://blockscout.com/etc/mainnet'],\n };\n case 'milkomeda-mainnet':\n return {\n chainId: `0x${milkomeda.id.toString(16)}`,\n chainName: 'Milkomeda C1 Mainnet',\n nativeCurrency: {\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n decimals: 18,\n },\n rpcUrls: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n blockExplorerUrls: ['https://explorer-mainnet-cardano-evm.c1.milkomeda.com'],\n };\n default:\n return null;\n }\n};\n","import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { createWalletClient, createPublicClient, custom, http } from 'viem';\nimport { useNetwork } from './NetworkContext';\nimport { getChainByNetworkKey, getChainConfigForWallet } from './chains';\n\nconst WalletContext = createContext(null);\n\nexport const useWallet = () => {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used within a WalletProvider');\n }\n return context;\n};\n\nconst switchToNetwork = async (networkKey) => {\n if (!window.ethereum) {\n throw new Error('MetaMask not installed');\n }\n\n const chainConfig = getChainConfigForWallet(networkKey);\n if (!chainConfig) {\n throw new Error(`Unsupported network: ${networkKey}`);\n }\n\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: chainConfig.chainId }],\n });\n } catch (switchError) {\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [chainConfig],\n });\n } catch (addError) {\n if (addError.code === 4001) {\n throw new Error(`User rejected adding ${chainConfig.chainName} to MetaMask. Please add it manually.`);\n }\n throw new Error(`Failed to add ${chainConfig.chainName} to MetaMask: ${addError.message}`);\n }\n } else if (switchError.code === 4001) {\n throw new Error(`User rejected switching to ${chainConfig.chainName}. Please switch manually in MetaMask.`);\n } else {\n throw new Error(`Failed to switch to ${chainConfig.chainName}: ${switchError.message}`);\n }\n }\n};\n\nexport const WalletProvider = ({ children }) => {\n const { selectedNetwork } = useNetwork();\n const [walletClient, setWalletClient] = useState(null);\n const [publicClient, setPublicClient] = useState(null);\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [balance, setBalance] = useState(null);\n const [error, setError] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n\n const selectedChain = selectedNetwork ? getChainByNetworkKey(selectedNetwork) : null;\n const expectedChainId = selectedChain ? selectedChain.id : null;\n\n const handleAccountsChangedRef = useRef(null);\n const handleChainChangedRef = useRef(null);\n\n const disconnectWalletInternal = useCallback(() => {\n setWalletClient(null);\n setPublicClient(null);\n setAccount(null);\n setChainId(null);\n setBalance(null);\n setError(null);\n }, []);\n\n const handleChainChanged = useCallback(async (chainIdHex) => {\n const newChainId = parseInt(chainIdHex, 16);\n setChainId(newChainId);\n\n if (selectedChain && newChainId === expectedChainId) {\n setError(null);\n if (window.ethereum && selectedChain) {\n const newWalletClient = createWalletClient({ \n chain: selectedChain, \n transport: custom(window.ethereum) \n });\n setWalletClient(newWalletClient);\n }\n } else if (selectedChain && newChainId !== expectedChainId) {\n const chainName = selectedChain?.name || selectedNetwork || 'selected network';\n setError(`Wrong network detected. Please switch to ${chainName}`);\n }\n }, [selectedChain, expectedChainId, selectedNetwork]);\n\n handleChainChangedRef.current = handleChainChanged;\n\n const handleAccountsChanged = useCallback(async (accounts) => {\n if (accounts.length === 0) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n } else {\n setAccount(accounts[0]);\n if (selectedChain) {\n try {\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n }\n }\n }, [selectedChain, disconnectWalletInternal]);\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n\n const disconnectWallet = useCallback(() => {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }, [disconnectWalletInternal]);\n\n const connectPublicClient = useCallback(() => {\n if (selectedChain) {\n setPublicClient(createPublicClient({ chain: selectedChain, transport: http() }));\n }\n }, [selectedChain]);\n\n const connectWallet = useCallback(async () => {\n if (!window.ethereum) {\n setError('Please install MetaMask or another Web3 wallet');\n return false;\n }\n\n if (!selectedNetwork || !selectedChain) {\n setError('Please select a network first');\n return false;\n }\n\n setIsConnecting(true);\n setError(null);\n\n try {\n const accounts = await window.ethereum.request({ \n method: 'eth_requestAccounts' \n });\n\n if (accounts.length === 0) {\n throw new Error('No wallet address found. Please unlock your wallet.');\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n await switchToNetwork(selectedNetwork);\n }\n\n const newWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(newWalletClient);\n setAccount(accounts[0]);\n setChainId(expectedChainId);\n\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n try {\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n handleChainChangedRef.current = handleChainChanged;\n window.ethereum.on('accountsChanged', handleAccountsChanged);\n window.ethereum.on('chainChanged', handleChainChanged);\n\n return true;\n } catch (err) {\n console.error('Error connecting wallet:', err);\n setError(err.message);\n return false;\n } finally {\n setIsConnecting(false);\n }\n }, [selectedNetwork, selectedChain, expectedChainId, handleAccountsChanged, handleChainChanged]);\n\n const ensureCorrectNetwork = useCallback(async () => {\n if (!window.ethereum || !selectedNetwork || !selectedChain || !account) {\n const errorMsg = 'Wallet not connected or network not selected';\n setError(errorMsg);\n return null;\n }\n\n try {\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n setError(null);\n await switchToNetwork(selectedNetwork);\n const NETWORK_SWITCH_DELAY_MS = 500;\n await new Promise(resolve => setTimeout(resolve, NETWORK_SWITCH_DELAY_MS));\n \n const newChainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const newChainId = parseInt(newChainIdHex, 16);\n if (newChainId !== expectedChainId) {\n throw new Error(`Failed to switch network. MetaMask is still on chain ${newChainId}, expected ${expectedChainId}`);\n }\n }\n\n const freshWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(freshWalletClient);\n setChainId(expectedChainId);\n setError(null);\n return freshWalletClient;\n } catch (err) {\n setError(err.message);\n return null;\n }\n }, [selectedNetwork, selectedChain, expectedChainId, account]);\n\n const prevNetworkRef = useRef(selectedNetwork);\n\n useEffect(() => {\n if (prevNetworkRef.current !== null && \n prevNetworkRef.current !== selectedNetwork && \n account) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }\n prevNetworkRef.current = selectedNetwork;\n }, [selectedNetwork, account, disconnectWalletInternal]);\n\n useEffect(() => {\n connectPublicClient();\n }, [connectPublicClient]);\n\n return (\n \n {children}\n \n );\n};","import React, { useState, useEffect } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { useWallet } from \"../contexts/WalletContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport { parseEther, encodeFunctionData, parseUnits } from \"viem\"; \nimport styles from \"../styles/PricingCard.css\"; \n\nconst TransactionReview = ({ onTransactionComplete }) => {\n const {\n networkSelector,\n selectedNetwork,\n selectedToken,\n transactionDetails: contextTransactionDetails,\n setTransactionDetails,\n } = useNetwork();\n\n const {\n connectWallet,\n account,\n walletClient,\n publicClient,\n isConnecting,\n ensureCorrectNetwork,\n expectedChainId,\n } = useWallet();\n\n const [transaction, setTransaction] = useState(null);\n const [tradeDataBuySc, setTradeDataBuySc] = useState(null);\n const [txData, setTxData] = useState(null);\n const [message, setMessage] = useState(\"\");\n const [txHash, setTxHash] = useState(null);\n const [error, setError] = useState(null);\n const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false);\n\n useEffect(() => {\n setTxData(null);\n setTradeDataBuySc(null);\n setMessage(\"\");\n setError(null);\n setTxHash(null);\n }, [selectedNetwork, selectedToken]);\n\n useEffect(() => {\n const initializeTransaction = async () => {\n if (!selectedNetwork || !selectedToken) return;\n\n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const receivingAddress = networkSelector.getReceivingAddress();\n const tokenAmount = networkSelector.getTokenAmount(selectedToken.key);\n\n const newTransaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await newTransaction.init();\n setTransaction(newTransaction);\n\n let tradeData = null;\n if (selectedToken.key === \"native\") {\n try {\n tradeData = await newTransaction.handleTradeDataBuySc(String(tokenAmount));\n setTradeDataBuySc(tradeData);\n } catch (tradeError) {\n console.error(\"Error fetching trade data:\", tradeError);\n }\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: selectedToken.key,\n tokenSymbol: selectedToken.symbol,\n amount: tokenAmount || \"0\",\n receivingAddress,\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer: selectedToken.isDirectTransfer || false,\n isNativeToken: selectedToken.isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...newTransaction.getBlockchainDetails(),\n });\n } catch (err) {\n console.error(\"Error initializing transaction:\", err);\n }\n };\n\n initializeTransaction();\n }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]);\n\n if (!selectedNetwork || !selectedToken) {\n return null;\n }\n\n if (!contextTransactionDetails) {\n return
Initializing transaction...
;\n }\n\n const handleConnectWallet = async () => {\n await connectWallet();\n };\n\n const handleSendTransaction = async () => {\n if (!account || !contextTransactionDetails || !transaction) {\n setMessage(\"Wallet not connected or transaction details missing\");\n return;\n }\n\n try {\n setTxData(null);\n setError(null);\n setMessage(\"Preparing transaction...\");\n\n const receiver = contextTransactionDetails.receivingAddress;\n let builtTx;\n\n if (selectedToken.key === \"native\") {\n const UI = \"0x0232556C83791b8291E9b23BfEa7d67405Bd9839\";\n const amountToSend = tradeDataBuySc || \"0\";\n const valueInWei = parseEther(String(amountToSend));\n\n builtTx = await transaction.buyStablecoins(\n account,\n receiver,\n valueInWei,\n UI\n );\n\n builtTx = {\n ...builtTx,\n value: valueInWei,\n account: account,\n };\n } else {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const stablecoinAddress = networkConfig?.tokens?.stablecoin?.address;\n \n if (!stablecoinAddress) {\n throw new Error('Stablecoin address not found in network configuration');\n }\n\n const amountToSend = contextTransactionDetails.amount\n ? parseUnits(\n String(contextTransactionDetails.amount),\n contextTransactionDetails.stableCoinDecimals\n )\n : \"0\";\n\n builtTx = {\n to: stablecoinAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: [\n {\n inputs: [\n { internalType: \"address\", name: \"to\", type: \"address\" },\n { internalType: \"uint256\", name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ],\n functionName: \"transfer\",\n args: [receiver, amountToSend],\n }),\n account: account,\n };\n }\n\n setTxData(builtTx);\n setMessage(\"Transaction ready. Please confirm to proceed.\");\n } catch (error) {\n setError(error);\n const reason = error.shortMessage || (error.message ? error.message.split('\\n')[0] : \"Unknown error\");\n setMessage(`Transaction preparation failed: ${reason}`);\n }\n };\n\n const handleBuySc = async () => {\n setError(null);\n \n try {\n if (!account || !txData) {\n setMessage(\"Wallet account or transaction data is missing\");\n return;\n }\n\n if (!selectedNetwork) {\n setMessage(\"Network not selected\");\n return;\n }\n\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) {\n setMessage(\"Network configuration not found\");\n return;\n }\n\n setMessage(\"Verifying network...\");\n\n const freshWalletClient = await ensureCorrectNetwork();\n if (!freshWalletClient) {\n setMessage(\"Failed to switch to correct network. Please approve the network switch in MetaMask and try again.\");\n return;\n }\n\n if (!window.ethereum) {\n setMessage(\"MetaMask not available\");\n return;\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== networkConfig.chainId) {\n const errorMsg = `Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`;\n setMessage(errorMsg);\n setError(new Error(errorMsg));\n return;\n }\n\n if (freshWalletClient.chain.id !== networkConfig.chainId) {\n const errorMsg = `Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`;\n setMessage(errorMsg);\n setError(new Error(errorMsg));\n return;\n }\n\n setMessage(\"Sending transaction...\");\n\n const txHash = await freshWalletClient.sendTransaction({\n ...txData,\n account: account,\n });\n\n setTxHash(txHash);\n setMessage(`Transaction sent!`);\n \n if (onTransactionComplete) {\n onTransactionComplete({\n txHash,\n network: selectedNetwork,\n token: selectedToken?.key,\n tokenSymbol: selectedToken?.symbol,\n amount: contextTransactionDetails?.amount,\n receivingAddress: contextTransactionDetails?.receivingAddress,\n });\n }\n } catch (error) {\n setError(error);\n const reason = error.shortMessage || (error.message ? error.message.split('\\n')[0] : \"Unknown error\");\n setMessage(`Transaction failed: ${reason}`);\n console.error('Transaction error:', error);\n }\n };\n\n const getExplorerUrl = () => {\n if (!txHash || !selectedNetwork) return null;\n\n const explorerBaseUrls = {\n \"ethereum-classic\": \"https://blockscout.com/etc/mainnet/tx/\",\n \"sepolia\": \"https://sepolia.etherscan.io/tx/\",\n \"milkomeda-mainnet\": \"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/\",\n };\n\n return explorerBaseUrls[selectedNetwork]\n ? `${explorerBaseUrls[selectedNetwork]}${txHash}`\n : null;\n };\n\n return (\n
\n
\n Network:\n {contextTransactionDetails.network}\n
\n\n
\n You Pay:\n \n {selectedToken.key === \"stablecoin\"\n ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}`\n : `${tradeDataBuySc ? tradeDataBuySc : \"Calculating...\"} ${\n contextTransactionDetails.tokenSymbol\n }`}\n \n
\n\n {message && (\n
\n {message}\n {error && (\n setIsErrorDetailsVisible(!isErrorDetailsVisible)}\n className={styles.detailsButton}\n >\n {isErrorDetailsVisible ? \"Hide Details\" : \"Show Details\"}\n \n )}\n
\n )}\n\n {isErrorDetailsVisible && error && (\n
\n
{error.message}
\n
\n )}\n\n {txHash && (\n
\n Transaction Hash:{\" \"}\n {getExplorerUrl() ? (\n \n {txHash.slice(0, 6)}...{txHash.slice(-6)}\n \n ) : (\n \n {txHash}\n \n )}\n
\n )}\n\n
\n {!account && (\n \n )}\n\n {account && !txData && (\n \n )}\n \n {account && txData && (\n \n )}\n
\n
\n );\n};\n\nexport default TransactionReview;\n","import React, { useState } from \"react\";\nimport PayButton from \"./PayButton\";\nimport Dialog from \"./Dialog\";\nimport NetworkDropdown from \"./NetworkDropdown\";\nimport TokenDropdown from \"./TokenDropdown\";\nimport TransactionReview from \"./TransactionReview\";\nimport { NetworkProvider, useNetwork } from \"../contexts/NetworkContext\";\nimport { WalletProvider } from \"../contexts/WalletContext\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst WidgetContent = ({ onClose, buttonSize, onTransactionComplete }) => {\n const { resetSelections } = useNetwork(); \n\n const handleClose = () => {\n resetSelections(); // Reset selections when closing the widget\n onClose();\n };\n\n return (\n \n \n \n \n \n );\n};\n\nconst WidgetWithProviders = ({ onClose, buttonSize, networkSelector, onTransactionComplete }) => {\n return (\n \n \n \n \n \n );\n};\n\nexport const Widget = ({ networkSelector, buttonSize = \"medium\", onTransactionComplete, onSuccess }) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const handleOpenDialog = () => {\n setIsDialogOpen(true);\n };\n\n const handleCloseDialog = () => {\n setIsDialogOpen(false);\n };\n\n // Support both onTransactionComplete and onSuccess for backwards compatibility\n const handleTransactionComplete = onTransactionComplete || onSuccess;\n\n return (\n
\n {!isDialogOpen && (\n \n )}\n {isDialogOpen && (\n \n )}\n
\n );\n};\n\nexport default Widget;\n","// src/index.js\nimport { NetworkSelector } from './core/NetworkSelector';\nimport { Transaction } from './core/Transaction';\nimport { Config } from './core/MerchantConfig';\nimport Widget from './widget/Widget.jsx';\nimport PayButton from './widget/PayButton.jsx';\nimport Dialog from './widget/Dialog.jsx';\nimport NetworkDropdown from './widget/NetworkDropdown.jsx';\nimport './styles/main.css';\nimport './styles/PricingCard.css';\n\nconst StablePay = {\n NetworkSelector,\n Transaction,\n Config,\n Widget,\n PayButton,\n Dialog,\n NetworkDropdown\n};\n\nexport default StablePay;","import { networksConfig } from \"../utils/config\";\n\nexport class NetworkSelector {\n constructor(merchantConfig) {\n this.merchantConfig = merchantConfig;\n this.blacklist = merchantConfig.getBlacklist();\n this.availableNetworks = this.getAvailableNetworks();\n this.selectedNetwork = null;\n }\n\n getAvailableNetworks() {\n return Object.entries(networksConfig).reduce(\n (acc, [networkKey, networkConfig]) => {\n if (!this.blacklist.includes(networkConfig.chainId)) {\n acc[networkKey] = networkConfig;\n }\n return acc;\n },\n {}\n );\n }\n\n selectNetwork(networkKey) {\n if (networkKey === null) {\n this.selectedNetwork = null;\n console.log(\"Network selection reset\");\n return true;\n }\n if (this.availableNetworks[networkKey]) {\n this.selectedNetwork = networkKey;\n console.log(`Network selected: ${networkKey}`);\n return true;\n }\n console.error(`Invalid network: ${networkKey}`);\n return false;\n }\n\n getSelectedNetworkConfig() {\n return this.selectedNetwork\n ? this.availableNetworks[this.selectedNetwork]\n : null;\n }\n\n getReceivingAddress() {\n return this.merchantConfig.getReceivingAddress();\n }\n\n getTokenAmount(token) {\n return this.merchantConfig.getTokenAmount(this.selectedNetwork, token);\n }\n}\n","import { networksConfig } from \"../utils/config\";\n\nexport class Config {\n constructor(options = {}) {\n this.receivingAddress = options.receivingAddress || \"\";\n this.blacklist = options.blacklist || [];\n this.amounts = options.amounts || options.Amounts || {};\n this.validateConfig();\n }\n\n validateConfig() {\n if (!this.receivingAddress) {\n throw new Error(\"Receiving address is required\");\n }\n // Validate stablecoin amounts\n for (const [network, tokens] of Object.entries(this.amounts)) {\n if (!networksConfig[network]) {\n throw new Error(`Invalid network: ${network}`);\n }\n if (\n !tokens.stablecoin ||\n typeof tokens.stablecoin !== \"number\" ||\n tokens.stablecoin <= 0\n ) {\n throw new Error(`Invalid stablecoin amount for network ${network}`);\n }\n }\n }\n\n getBlacklist() {\n return this.blacklist;\n }\n\n getReceivingAddress() {\n return this.receivingAddress;\n }\n\n // getTokenAmount(network, token) {\n // const networkConfig = networksConfig[network];\n // if (!networkConfig) return 0;\n\n // const stablecoinSymbol = networkConfig.tokens.stablecoin.symbol;\n\n // if (token === 'stablecoin') {\n // return this.amounts[network]?.stablecoin || 0;\n // }\n // // For native tokens, return 0 as it's not specified in the new structure\n // return 0;\n // }\n getTokenAmount(network) {\n console.log(\"Getting amount for network:\", network);\n console.log(\"Amounts object:\", this.amounts);\n\n // Directly return the stablecoin amount for the network\n const amount = this.amounts[network]?.stablecoin;\n console.log(\"Returning amount:\", amount);\n\n return amount || 0;\n }\n}\n\nexport default Config;\n"],"names":["networksConfig","sepolia","uri","chainId","djedAddress","tokens","stablecoin","symbol","address","decimals","isDirectTransfer","native","isNative","feeUI","Transaction","constructor","networkUri","this","init","Error","web3","getWeb3","djedContract","getDjedContract","stableCoin","reserveCoin","getCoinContracts","scDecimals","rcDecimals","getDecimals","oracleContract","getOracleAddress","then","addr","getOracleContract","_address","oracleAddress","contractError","console","error","message","includes","getNetworkInfo","name","networkName","getNetworkName","getBlockchainDetails","web3Available","djedContractAvailable","stableCoinAddress","reserveCoinAddress","stableCoinDecimals","reserveCoinDecimals","oracleContractAvailable","handleTradeDataBuySc","amountScaled","tradeDataPriceBuySc","totalBCScaled","buyStablecoins","payer","receiver","value","UI","buyScTx","PayButton","onClick","size","sizeStyles","small","width","height","fontSize","medium","large","logoSizes","buttonStyle","logoStyle","React","createElement","className","styles","style","Dialog","children","onClose","dialogOverlay","pricingCard","dialogClose","pricingCardHeader","allianceLogo","stablepayTitle","pricingCardBody","TokenSelector","networkSelector","selectedToken","selectToken","tokenKey","networkConfig","getSelectedNetworkConfig","key","getSelectedToken","getAvailableTokens","Object","entries","map","config","resetSelection","NetworkContext","createContext","NetworkProvider","tokenSelector","useState","selectedNetwork","setSelectedNetwork","setSelectedToken","transactionDetails","setTransactionDetails","resetState","useEffect","Provider","selectNetwork","networkKey","token","resetSelections","useNetwork","context","useContext","undefined","NetworkDropdown","selectField","htmlFor","id","onChange","event","target","disabled","keys","availableNetworks","TokenDropdown","loading","setLoading","setError","availableTokens","async","newValue","transaction","tokenAmount","getTokenAmount","blockchainDetails","tradeData","String","network","tokenSymbol","amount","receivingAddress","getReceivingAddress","djedContractAddress","isNativeToken","tradeAmount","err","defineChain","nativeCurrency","rpcUrls","default","http","webSocket","blockExplorers","url","testnet","milkomeda","etcMainnet","WalletContext","switchToNetwork","window","ethereum","chainConfig","toString","chainName","blockExplorerUrls","getChainConfigForWallet","request","method","params","switchError","code","addError","WalletProvider","walletClient","setWalletClient","publicClient","setPublicClient","account","setAccount","setChainId","balance","setBalance","isConnecting","setIsConnecting","selectedChain","getChainByNetworkKey","expectedChainId","handleAccountsChangedRef","useRef","handleChainChangedRef","disconnectWalletInternal","useCallback","handleChainChanged","newChainId","parseInt","chainIdHex","newWalletClient","createWalletClient","chain","transport","custom","current","handleAccountsChanged","accounts","length","accountsHandler","chainHandler","removeListener","newPublicClient","createPublicClient","getBalance","parseFloat","Math","pow","disconnectWallet","connectPublicClient","connectWallet","on","ensureCorrectNetwork","NETWORK_SWITCH_DELAY_MS","Promise","resolve","setTimeout","newChainIdHex","freshWalletClient","prevNetworkRef","TransactionReview","onTransactionComplete","contextTransactionDetails","useWallet","setTransaction","tradeDataBuySc","setTradeDataBuySc","txData","setTxData","setMessage","txHash","setTxHash","isErrorDetailsVisible","setIsErrorDetailsVisible","newTransaction","tradeError","initializeTransaction","getExplorerUrl","explorerBaseUrls","transactionReview","transactionInfo","transactionLabel","transactionValue","highlight","messageBox","detailsButton","errorDetails","transactionLink","href","rel","explorerLink","slice","wordBreak","walletButtonContainer","walletButton","builtTx","amountToSend","valueInWei","parseEther","stablecoinAddress","parseUnits","to","data","encodeFunctionData","abi","inputs","internalType","type","outputs","stateMutability","functionName","args","reason","shortMessage","split","currentChainId","errorMsg","sendTransaction","WidgetContent","buttonSize","handleClose","WidgetWithProviders","NetworkSelector","merchantConfig","blacklist","getBlacklist","getAvailableNetworks","reduce","acc","log","Config","options","amounts","Amounts","validateConfig","Widget","onSuccess","isDialogOpen","setIsDialogOpen","handleTransactionComplete","widgetContainer","handleOpenDialog","handleCloseDialog"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../../src/utils/config.js","../../src/core/Transaction.js","../../src/widget/PayButton.jsx","../../src/widget/Dialog.jsx","../../src/core/TokenSelector.js","../../src/contexts/NetworkContext.jsx","../../src/widget/NetworkDropdown.jsx","../../src/widget/TokenDropdown.jsx","../../src/contexts/chains.js","../../src/contexts/WalletContext.jsx","../../src/widget/TransactionReview.jsx","../../src/widget/Widget.jsx","../../src/index.js","../../src/core/NetworkSelector.js","../../src/core/MerchantConfig.js"],"sourcesContent":["// src/utils/config.js\nexport const networksConfig = {\n 'sepolia': {\n uri: 'https://ethereum-sepolia.publicnode.com/',\n chainId: 11155111,\n djedAddress: '0x624FcD0a1F9B5820c950FefD48087531d38387f4',\n tokens: {\n stablecoin: {\n symbol: 'SOD',\n address: '0x6b930182787F346F18666D167e8d32166dC5eFBD',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETH',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'milkomeda-mainnet': {\n uri: 'https://rpc-mainnet-cardano-evm.c1.milkomeda.com',\n chainId: 2001,\n djedAddress: '0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76',\n tokens: {\n stablecoin: {\n symbol: 'MOD',\n address: '0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'mADA',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'ethereum-classic': {\n uri: 'https://etc.rivet.link',\n chainId: 61,\n djedAddress: '0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf',\n tokens: {\n stablecoin: {\n symbol: 'ECSD',\n address: '0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETC',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n }\n};","import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx } from 'djed-sdk';\n\nexport class Transaction {\n constructor(networkUri, djedAddress) {\n this.networkUri = networkUri;\n this.djedAddress = djedAddress;\n }\n\n async init() {\n if (!this.networkUri || !this.djedAddress) {\n throw new Error('Network URI and DJED address are required');\n }\n\n try {\n this.web3 = await getWeb3(this.networkUri);\n this.djedContract = getDjedContract(this.web3, this.djedAddress);\n \n try {\n const { stableCoin, reserveCoin } = await getCoinContracts(this.djedContract, this.web3);\n const { scDecimals, rcDecimals } = await getDecimals(stableCoin, reserveCoin);\n this.stableCoin = stableCoin;\n this.reserveCoin = reserveCoin;\n this.scDecimals = scDecimals;\n this.rcDecimals = rcDecimals;\n\n this.oracleContract = await getOracleAddress(this.djedContract).then((addr) =>\n getOracleContract(this.web3, addr, this.djedContract._address)\n );\n\n this.oracleAddress = this.oracleContract._address;\n } catch (contractError) {\n console.error('[Transaction] Error fetching contract details:', contractError);\n const isReverted = contractError.code === -32000 || contractError.code === 3 || contractError.data;\n if (isReverted) {\n const getNetworkInfo = (uri) => {\n if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };\n if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' };\n if (uri.includes('sepolia')) return { name: 'Sepolia', chainId: '11155111' };\n if (uri.includes('etc.rivet.link')) return { name: 'Ethereum Classic', chainId: '61' };\n return { name: 'the selected network', chainId: 'unknown' };\n };\n const { name: networkName, chainId } = getNetworkInfo(this.networkUri);\n throw new Error(\n `Failed to interact with Djed contract at ${this.djedAddress} on ${networkName}.\\n\\n` +\n `Possible causes:\\n` +\n `- The contract address may be incorrect\\n` +\n `- The contract may not be deployed on ${networkName}\\n` +\n `- The contract may not be a valid Djed contract\\n\\n` +\n `Please verify the contract address is correct for ${networkName} (Chain ID: ${chainId}).`\n );\n }\n throw contractError;\n }\n } catch (error) {\n console.error('[Transaction] Error initializing transaction:', error);\n const isConnectionError = error.code === -32603 || error.code === 4001 || error.code === -32005 || (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED')));\n if (isConnectionError) {\n const getNetworkName = (uri) => {\n if (uri.includes('milkomeda')) return 'Milkomeda';\n if (uri.includes('mordor')) return 'Mordor';\n if (uri.includes('sepolia')) return 'Sepolia';\n return 'the selected network';\n };\n const networkName = getNetworkName(this.networkUri);\n throw new Error(\n `Failed to connect to ${networkName} RPC endpoint: ${this.networkUri}\\n\\n` +\n `Possible causes:\\n` +\n `- The RPC endpoint may be temporarily unavailable\\n` +\n `- DNS resolution issue (check your internet connection)\\n` +\n `- Network firewall blocking the connection\\n\\n` +\n `Please try again in a few moments or check the network status.`\n );\n }\n throw error;\n }\n }\n\n getBlockchainDetails() {\n return {\n web3Available: !!this.web3,\n djedContractAvailable: !!this.djedContract,\n stableCoinAddress: this.stableCoin ? this.stableCoin._address : 'N/A',\n reserveCoinAddress: this.reserveCoin ? this.reserveCoin._address : 'N/A',\n stableCoinDecimals: this.scDecimals,\n reserveCoinDecimals: this.rcDecimals,\n oracleAddress: this.oracleAddress || 'N/A',\n oracleContractAvailable: !!this.oracleContract,\n };\n }\n\n async handleTradeDataBuySc(amountScaled) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n if (typeof amountScaled !== 'string') {\n throw new Error(\"Amount must be a string\");\n }\n try {\n const result = await tradeDataPriceBuySc(this.djedContract, this.scDecimals, amountScaled);\n return result.totalBCScaled;\n } catch (error) {\n console.error(\"Error fetching trade data for buying stablecoins: \", error);\n throw error;\n }\n }\n\n async buyStablecoins(payer, receiver, value) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n try {\n const UI = '0x0232556C83791b8291E9b23BfEa7d67405Bd9839';\n\n const txData = await buyScTx(this.djedContract, payer, receiver, value, UI, this.djedAddress);\n\n return txData;\n } catch (error) {\n console.error(\"Error executing buyStablecoins transaction: \", error);\n throw error;\n }\n }\n}\n","import React from \"react\";\nimport styles from \"../styles/main.css\";\n\nconst PayButton = ({ onClick, size = \"medium\" }) => {\n const sizeStyles = {\n small: { width: \"200px\", height: \"50px\", fontSize: \"14px\" },\n medium: { width: \"250px\", height: \"60px\", fontSize: \"16px\" },\n large: { width: \"300px\", height: \"70px\", fontSize: \"18px\" },\n };\n\n const logoSizes = {\n small: { width: \"35px\", height: \"33px\" },\n medium: { width: \"40px\", height: \"38px\" },\n large: { width: \"45px\", height: \"43px\" },\n };\n\n const buttonStyle = sizeStyles[size] || sizeStyles.medium;\n const logoStyle = logoSizes[size] || logoSizes.medium;\n\n return (\n \n
\n Pay with StablePay\n \n );\n};\n\nexport default PayButton;\n","import React from 'react';\nimport styles from '../styles/PricingCard.css';\n\n\nconst Dialog = ({ children, onClose, size = 'medium' }) => {\n return (\n
\n
\n \n
\n
\n\n
StablePay
\n
\n
\n {children}\n
\n
\n
\n );\n};\n\nexport default Dialog;","// TokenSelector.js\n\nexport class TokenSelector {\n constructor(networkSelector) {\n this.networkSelector = networkSelector;\n this.selectedToken = null;\n }\n\n selectToken(tokenKey) {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (networkConfig && networkConfig.tokens[tokenKey]) {\n this.selectedToken = {\n key: tokenKey,\n ...networkConfig.tokens[tokenKey]\n };\n return true;\n }\n return false;\n }\n\n getSelectedToken() {\n return this.selectedToken;\n }\n\n getAvailableTokens() {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) return [];\n\n return Object.entries(networkConfig.tokens).map(([key, config]) => ({\n key,\n ...config\n }));\n }\n\n resetSelection() {\n this.selectedToken = null;\n }\n}","import React, { createContext, useState, useContext, useEffect } from 'react';\nimport { TokenSelector } from '../core/TokenSelector';\n\nconst NetworkContext = createContext();\n\nexport const NetworkProvider = ({ children, networkSelector }) => {\n const [tokenSelector] = useState(() => new TokenSelector(networkSelector));\n const [selectedNetwork, setSelectedNetwork] = useState(null);\n const [selectedToken, setSelectedToken] = useState(null);\n const [transactionDetails, setTransactionDetails] = useState(null);\n\n const resetState = () => {\n setSelectedToken(null);\n setTransactionDetails(null);\n };\n\n const selectNetwork = (networkKey) => {\n if (networkSelector.selectNetwork(networkKey)) {\n setSelectedNetwork(networkKey);\n resetState(); \n return true;\n }\n return false;\n };\n\n const selectToken = (tokenKey) => {\n if (tokenSelector.selectToken(tokenKey)) {\n const token = tokenSelector.getSelectedToken();\n setSelectedToken(token);\n return true;\n }\n return false;\n };\n\n const resetSelections = () => {\n networkSelector.selectNetwork(null);\n setSelectedNetwork(null);\n resetState();\n };\n\n // Synchronize context state with NetworkSelector\n useEffect(() => {\n setSelectedNetwork(networkSelector.selectedNetwork);\n }, [networkSelector.selectedNetwork]);\n\n return (\n \n {children}\n \n );\n};\n\nexport const useNetwork = () => {\n const context = useContext(NetworkContext);\n if (context === undefined) {\n throw new Error('useNetwork must be used within a NetworkProvider');\n }\n return context;\n};\n\nexport default NetworkContext;","import React from 'react';\nimport { useNetwork } from '../contexts/NetworkContext';\nimport styles from '../styles/PricingCard.css';\n\nconst NetworkDropdown = () => {\n const { networkSelector, selectedNetwork, selectNetwork } = useNetwork();\n\n const handleNetworkChange = (event) => {\n selectNetwork(event.target.value);\n };\n\n return (\n
\n \n \n
\n );\n};\n\nexport default NetworkDropdown;","import React, { useState } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst TokenDropdown = () => {\n const {\n networkSelector,\n tokenSelector,\n selectedNetwork,\n selectedToken,\n selectToken,\n setTransactionDetails,\n } = useNetwork();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n const handleTokenChange = async (event) => {\n const newValue = event.target.value;\n setError(null);\n setLoading(true);\n\n try {\n if (selectToken(newValue)) {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const transaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await transaction.init();\n\n const tokenAmount = networkSelector.getTokenAmount(newValue);\n const blockchainDetails = transaction.getBlockchainDetails();\n\n let tradeData = null;\n if (newValue === \"native\") {\n tradeData = await transaction.handleTradeDataBuySc(\n String(tokenAmount)\n );\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: newValue,\n tokenSymbol: tokenSelector.getSelectedToken().symbol,\n amount: tokenAmount,\n receivingAddress: networkSelector.getReceivingAddress(),\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer:\n tokenSelector.getSelectedToken().isDirectTransfer || false,\n isNativeToken: tokenSelector.getSelectedToken().isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...blockchainDetails,\n });\n }\n } catch (err) {\n console.error(\"Error fetching transaction details:\", err);\n setError(\"Failed to fetch transaction details. Please try again.\");\n } finally {\n setLoading(false);\n }\n };\n\n const availableTokens = selectedNetwork\n ? tokenSelector.getAvailableTokens()\n : [];\n\n return (\n
\n \n \n \n {availableTokens.map((token) => (\n \n ))}\n \n {error &&
{error}
}\n
\n );\n};\n\nexport default TokenDropdown;\n","import { defineChain } from 'viem';\nimport { sepolia } from 'viem/chains';\n\nexport const mordor = defineChain({\n id: 63,\n name: 'Mordor Testnet',\n network: 'mordor',\n nativeCurrency: {\n decimals: 18,\n name: 'Mordor Ether',\n symbol: 'METC',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc.mordor.etccooperative.org'],\n webSocket: ['wss://rpc.mordor.etccooperative.org/ws'],\n },\n },\n blockExplorers: {\n default: { name: 'BlockScout', url: 'https://blockscout.com/etc/mordor' },\n },\n testnet: true,\n});\n\nexport const milkomeda = defineChain({\n id: 2001,\n name: 'Milkomeda C1 Mainnet',\n network: 'milkomeda',\n nativeCurrency: {\n decimals: 18,\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n },\n },\n blockExplorers: {\n default: { name: 'Milkomeda Explorer', url: 'https://explorer-mainnet-cardano-evm.c1.milkomeda.com' },\n },\n testnet: false,\n});\n\nexport const etcMainnet = defineChain({\n id: 61,\n name: 'Ethereum Classic',\n network: 'etc',\n nativeCurrency: {\n decimals: 18,\n name: 'Ethereum Classic',\n symbol: 'ETC',\n },\n rpcUrls: {\n default: {\n http: ['https://etc.rivet.link'],\n },\n },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://blockscout.com/etc/mainnet' },\n },\n testnet: false,\n});\n\nexport const getChainByNetworkKey = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return sepolia;\n case 'ethereum-classic':\n return etcMainnet;\n case 'milkomeda-mainnet':\n return milkomeda;\n default:\n return null;\n }\n};\n\nexport const getChainConfigForWallet = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return {\n chainId: `0x${sepolia.id.toString(16)}`,\n chainName: 'Sepolia',\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n rpcUrls: sepolia.rpcUrls.default.http,\n blockExplorerUrls: sepolia.blockExplorers?.default?.url ? [sepolia.blockExplorers.default.url] : [],\n };\n case 'ethereum-classic':\n return {\n chainId: `0x${etcMainnet.id.toString(16)}`,\n chainName: 'Ethereum Classic',\n nativeCurrency: {\n name: 'Ethereum Classic',\n symbol: 'ETC',\n decimals: 18,\n },\n rpcUrls: ['https://etc.rivet.link'],\n blockExplorerUrls: ['https://blockscout.com/etc/mainnet'],\n };\n case 'milkomeda-mainnet':\n return {\n chainId: `0x${milkomeda.id.toString(16)}`,\n chainName: 'Milkomeda C1 Mainnet',\n nativeCurrency: {\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n decimals: 18,\n },\n rpcUrls: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n blockExplorerUrls: ['https://explorer-mainnet-cardano-evm.c1.milkomeda.com'],\n };\n default:\n return null;\n }\n};\n","import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { createWalletClient, createPublicClient, custom, http } from 'viem';\nimport { useNetwork } from './NetworkContext';\nimport { getChainByNetworkKey, getChainConfigForWallet } from './chains';\n\nconst WalletContext = createContext(null);\n\nexport const useWallet = () => {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used within a WalletProvider');\n }\n return context;\n};\n\nconst switchToNetwork = async (networkKey) => {\n if (!window.ethereum) {\n throw new Error('MetaMask not installed');\n }\n\n const chainConfig = getChainConfigForWallet(networkKey);\n if (!chainConfig) {\n throw new Error(`Unsupported network: ${networkKey}`);\n }\n\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: chainConfig.chainId }],\n });\n } catch (switchError) {\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [chainConfig],\n });\n } catch (addError) {\n if (addError.code === 4001) {\n throw new Error(`User rejected adding ${chainConfig.chainName} to MetaMask. Please add it manually.`);\n }\n throw new Error(`Failed to add ${chainConfig.chainName} to MetaMask: ${addError.message}`);\n }\n } else if (switchError.code === 4001) {\n throw new Error(`User rejected switching to ${chainConfig.chainName}. Please switch manually in MetaMask.`);\n } else {\n throw new Error(`Failed to switch to ${chainConfig.chainName}: ${switchError.message}`);\n }\n }\n};\n\nexport const WalletProvider = ({ children }) => {\n const { selectedNetwork } = useNetwork();\n const [walletClient, setWalletClient] = useState(null);\n const [publicClient, setPublicClient] = useState(null);\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [balance, setBalance] = useState(null);\n const [error, setError] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n\n const selectedChain = selectedNetwork ? getChainByNetworkKey(selectedNetwork) : null;\n const expectedChainId = selectedChain ? selectedChain.id : null;\n\n const handleAccountsChangedRef = useRef(null);\n const handleChainChangedRef = useRef(null);\n\n const disconnectWalletInternal = useCallback(() => {\n setWalletClient(null);\n setPublicClient(null);\n setAccount(null);\n setChainId(null);\n setBalance(null);\n setError(null);\n }, []);\n\n const handleChainChanged = useCallback(async (chainIdHex) => {\n const newChainId = parseInt(chainIdHex, 16);\n setChainId(newChainId);\n\n if (selectedChain && newChainId === expectedChainId) {\n setError(null);\n if (window.ethereum && selectedChain) {\n const newWalletClient = createWalletClient({ \n chain: selectedChain, \n transport: custom(window.ethereum) \n });\n setWalletClient(newWalletClient);\n }\n } else if (selectedChain && newChainId !== expectedChainId) {\n const chainName = selectedChain?.name || selectedNetwork || 'selected network';\n setError(`Wrong network detected. Please switch to ${chainName}`);\n }\n }, [selectedChain, expectedChainId, selectedNetwork]);\n\n handleChainChangedRef.current = handleChainChanged;\n\n const handleAccountsChanged = useCallback(async (accounts) => {\n if (accounts.length === 0) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n } else {\n setAccount(accounts[0]);\n if (selectedChain) {\n try {\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n }\n }\n }, [selectedChain, disconnectWalletInternal]);\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n\n const disconnectWallet = useCallback(() => {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }, [disconnectWalletInternal]);\n\n const connectPublicClient = useCallback(() => {\n if (selectedChain) {\n setPublicClient(createPublicClient({ chain: selectedChain, transport: http() }));\n }\n }, [selectedChain]);\n\n const connectWallet = useCallback(async () => {\n if (!window.ethereum) {\n setError('Please install MetaMask or another Web3 wallet');\n return false;\n }\n\n if (!selectedNetwork || !selectedChain) {\n setError('Please select a network first');\n return false;\n }\n\n setIsConnecting(true);\n setError(null);\n\n try {\n const accounts = await window.ethereum.request({ \n method: 'eth_requestAccounts' \n });\n\n if (accounts.length === 0) {\n throw new Error('No wallet address found. Please unlock your wallet.');\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n await switchToNetwork(selectedNetwork);\n }\n\n const newWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(newWalletClient);\n setAccount(accounts[0]);\n setChainId(expectedChainId);\n\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n try {\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n handleChainChangedRef.current = handleChainChanged;\n window.ethereum.on('accountsChanged', handleAccountsChanged);\n window.ethereum.on('chainChanged', handleChainChanged);\n\n return true;\n } catch (err) {\n console.error('Error connecting wallet:', err);\n setError(err.message);\n return false;\n } finally {\n setIsConnecting(false);\n }\n }, [selectedNetwork, selectedChain, expectedChainId, handleAccountsChanged, handleChainChanged]);\n\n const ensureCorrectNetwork = useCallback(async () => {\n if (!window.ethereum || !selectedNetwork || !selectedChain || !account) {\n const errorMsg = 'Wallet not connected or network not selected';\n setError(errorMsg);\n return null;\n }\n\n try {\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n setError(null);\n await switchToNetwork(selectedNetwork);\n const NETWORK_SWITCH_DELAY_MS = 500;\n await new Promise(resolve => setTimeout(resolve, NETWORK_SWITCH_DELAY_MS));\n \n const newChainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const newChainId = parseInt(newChainIdHex, 16);\n if (newChainId !== expectedChainId) {\n throw new Error(`Failed to switch network. MetaMask is still on chain ${newChainId}, expected ${expectedChainId}`);\n }\n }\n\n const freshWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(freshWalletClient);\n setChainId(expectedChainId);\n setError(null);\n return freshWalletClient;\n } catch (err) {\n setError(err.message);\n return null;\n }\n }, [selectedNetwork, selectedChain, expectedChainId, account]);\n\n const prevNetworkRef = useRef(selectedNetwork);\n\n useEffect(() => {\n if (prevNetworkRef.current !== null && \n prevNetworkRef.current !== selectedNetwork && \n account) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }\n prevNetworkRef.current = selectedNetwork;\n }, [selectedNetwork, account, disconnectWalletInternal]);\n\n useEffect(() => {\n connectPublicClient();\n }, [connectPublicClient]);\n\n return (\n \n {children}\n \n );\n};","import React, { useState, useEffect } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { useWallet } from \"../contexts/WalletContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport { parseEther, encodeFunctionData, parseUnits } from \"viem\"; \nimport styles from \"../styles/PricingCard.css\"; \n\nconst TransactionReview = ({ onTransactionComplete }) => {\n const {\n networkSelector,\n selectedNetwork,\n selectedToken,\n transactionDetails: contextTransactionDetails,\n setTransactionDetails,\n } = useNetwork();\n\n const {\n connectWallet,\n account,\n walletClient,\n publicClient,\n isConnecting,\n ensureCorrectNetwork,\n expectedChainId,\n } = useWallet();\n\n const [transaction, setTransaction] = useState(null);\n const [tradeDataBuySc, setTradeDataBuySc] = useState(null);\n const [message, setMessage] = useState(\"\");\n const [txHash, setTxHash] = useState(null);\n const [error, setError] = useState(null);\n const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false);\n const [interactionState, setInteractionState] = useState('IDLE');\n\n useEffect(() => {\n setTradeDataBuySc(null);\n setMessage(\"\");\n setError(null);\n setTxHash(null);\n setInteractionState('IDLE');\n }, [selectedNetwork, selectedToken]);\n\n useEffect(() => {\n const initializeTransaction = async () => {\n if (!selectedNetwork || !selectedToken) return;\n\n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const receivingAddress = networkSelector.getReceivingAddress();\n const tokenAmount = networkSelector.getTokenAmount(selectedToken.key);\n\n const newTransaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await newTransaction.init();\n setTransaction(newTransaction);\n\n let tradeData = null;\n if (selectedToken.key === \"native\") {\n try {\n tradeData = await newTransaction.handleTradeDataBuySc(String(tokenAmount));\n setTradeDataBuySc(tradeData);\n } catch (tradeError) {\n console.error(\"Error fetching trade data:\", tradeError);\n }\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: selectedToken.key,\n tokenSymbol: selectedToken.symbol,\n amount: tokenAmount || \"0\",\n receivingAddress,\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer: selectedToken.isDirectTransfer || false,\n isNativeToken: selectedToken.isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...newTransaction.getBlockchainDetails(),\n });\n } catch (err) {\n console.error(\"Error initializing transaction:\", err);\n }\n };\n\n initializeTransaction();\n }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]);\n\n if (!selectedNetwork || !selectedToken) {\n return null;\n }\n\n if (!contextTransactionDetails) {\n return
Initializing transaction...
;\n }\n\n const handleConnectWallet = async () => {\n await connectWallet();\n };\n\n const executePayment = async () => {\n if (!account || !contextTransactionDetails || !transaction) {\n setMessage(\"Wallet not connected or transaction details missing\");\n return;\n }\n\n setInteractionState('PROCESSING');\n setMessage(\"Preparing transaction...\");\n setError(null);\n setTxHash(null);\n\n let builtTx;\n try {\n const receiver = contextTransactionDetails.receivingAddress;\n\n if (selectedToken.key === \"native\") {\n const UI = \"0x0232556C83791b8291E9b23BfEa7d67405Bd9839\";\n const amountToSend = tradeDataBuySc || \"0\";\n const valueInWei = parseEther(String(amountToSend));\n\n builtTx = await transaction.buyStablecoins(\n account,\n receiver,\n valueInWei,\n UI\n );\n\n builtTx = {\n ...builtTx,\n value: valueInWei,\n account: account,\n };\n } else {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const stablecoinAddress = networkConfig?.tokens?.stablecoin?.address;\n \n if (!stablecoinAddress) {\n throw new Error('Stablecoin address not found in network configuration');\n }\n\n const amountToSend = contextTransactionDetails.amount\n ? parseUnits(\n String(contextTransactionDetails.amount),\n contextTransactionDetails.stableCoinDecimals\n )\n : \"0\";\n\n builtTx = {\n to: stablecoinAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: [\n {\n inputs: [\n { internalType: \"address\", name: \"to\", type: \"address\" },\n { internalType: \"uint256\", name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ],\n functionName: \"transfer\",\n args: [receiver, amountToSend],\n }),\n account: account,\n };\n }\n } catch (err) {\n setError(err);\n const reason = err.shortMessage || (err.message ? err.message.split('\\n')[0] : \"Unknown error\");\n setMessage(`Transaction preparation failed: ${reason}`);\n setInteractionState('IDLE');\n return;\n }\n\n setMessage(\"Please check your wallet to confirm the transaction...\");\n \n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) {\n throw new Error(\"Network configuration not found\");\n }\n\n const freshWalletClient = await ensureCorrectNetwork();\n if (!freshWalletClient) {\n throw new Error(\"Failed to switch to correct network. Please approve the network switch in MetaMask.\");\n }\n\n if (!window.ethereum) {\n throw new Error(\"MetaMask not available\");\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== networkConfig.chainId) {\n throw new Error(`Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`);\n }\n\n if (freshWalletClient.chain.id !== networkConfig.chainId) {\n throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`);\n }\n\n const txHash = await freshWalletClient.sendTransaction({\n ...builtTx,\n account: account,\n });\n\n setTxHash(txHash);\n setMessage(`Transaction sent successfully!`);\n setInteractionState('SUCCESS');\n \n if (onTransactionComplete) {\n onTransactionComplete({\n txHash,\n network: selectedNetwork,\n token: selectedToken?.key,\n tokenSymbol: selectedToken?.symbol,\n amount: contextTransactionDetails?.amount,\n receivingAddress: contextTransactionDetails?.receivingAddress,\n });\n }\n } catch (err) {\n setError(err);\n \n let reason = \"Unknown error\";\n if (err.name === 'UserRejectedRequestError' || err.code === 4001) {\n reason = \"User denied transaction\";\n } else if (err.name === 'ContractFunctionRevertedError' || (err.data && err.data.message)) {\n reason = err.shortMessage || err.data?.message || err.message;\n } else {\n reason = err.shortMessage || (err.message ? err.message.split('\\n')[0] : \"Transaction failed\");\n }\n \n setMessage(`Transaction failed: ${reason}`);\n setInteractionState('IDLE');\n console.error('Transaction error:', err);\n }\n };\n\n const getExplorerUrl = () => {\n if (!txHash || !selectedNetwork) return null;\n\n const explorerBaseUrls = {\n \"ethereum-classic\": \"https://blockscout.com/etc/mainnet/tx/\",\n \"sepolia\": \"https://sepolia.etherscan.io/tx/\",\n \"milkomeda-mainnet\": \"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/\",\n };\n\n return explorerBaseUrls[selectedNetwork]\n ? `${explorerBaseUrls[selectedNetwork]}${txHash}`\n : null;\n };\n\n return (\n
\n
\n Network:\n {contextTransactionDetails.network}\n
\n\n
\n You Pay:\n \n {selectedToken.key === \"stablecoin\"\n ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}`\n : `${tradeDataBuySc ? tradeDataBuySc : \"Calculating...\"} ${\n contextTransactionDetails.tokenSymbol\n }`}\n \n
\n\n {message && (\n
\n {message}\n {error && (\n setIsErrorDetailsVisible(!isErrorDetailsVisible)}\n className={styles.detailsButton}\n >\n {isErrorDetailsVisible ? \"Hide Details\" : \"Show Details\"}\n \n )}\n
\n )}\n\n {isErrorDetailsVisible && error && (\n
\n
{error.message}
\n
\n )}\n\n {txHash && (\n
\n Transaction Hash:{\" \"}\n {getExplorerUrl() ? (\n \n {txHash.slice(0, 6)}...{txHash.slice(-6)}\n \n ) : (\n \n {txHash}\n \n )}\n
\n )}\n\n {interactionState !== 'SUCCESS' && (\n
\n {!account && (\n \n )}\n\n {account && interactionState === 'IDLE' && (\n \n )}\n\n {account && interactionState === 'CONFIRMING' && (\n
\n Confirm payment?\n
\n \n \n
\n
\n )}\n\n {account && interactionState === 'PROCESSING' && (\n \n )}\n
\n )}\n
\n );\n};\n\nexport default TransactionReview;\n","import React, { useState } from \"react\";\nimport PayButton from \"./PayButton\";\nimport Dialog from \"./Dialog\";\nimport NetworkDropdown from \"./NetworkDropdown\";\nimport TokenDropdown from \"./TokenDropdown\";\nimport TransactionReview from \"./TransactionReview\";\nimport { NetworkProvider, useNetwork } from \"../contexts/NetworkContext\";\nimport { WalletProvider } from \"../contexts/WalletContext\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst WidgetContent = ({ onClose, buttonSize, onTransactionComplete }) => {\n const { resetSelections } = useNetwork(); \n\n const handleClose = () => {\n resetSelections(); // Reset selections when closing the widget\n onClose();\n };\n\n return (\n \n \n \n \n \n );\n};\n\nconst WidgetWithProviders = ({ onClose, buttonSize, networkSelector, onTransactionComplete }) => {\n return (\n \n \n \n \n \n );\n};\n\nexport const Widget = ({ networkSelector, buttonSize = \"medium\", onTransactionComplete, onSuccess }) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const handleOpenDialog = () => {\n setIsDialogOpen(true);\n };\n\n const handleCloseDialog = () => {\n setIsDialogOpen(false);\n };\n\n // Support both onTransactionComplete and onSuccess for backwards compatibility\n const handleTransactionComplete = onTransactionComplete || onSuccess;\n\n return (\n
\n {!isDialogOpen && (\n \n )}\n {isDialogOpen && (\n \n )}\n
\n );\n};\n\nexport default Widget;\n","// src/index.js\nimport { NetworkSelector } from './core/NetworkSelector';\nimport { Transaction } from './core/Transaction';\nimport { Config } from './core/MerchantConfig';\nimport Widget from './widget/Widget.jsx';\nimport PayButton from './widget/PayButton.jsx';\nimport Dialog from './widget/Dialog.jsx';\nimport NetworkDropdown from './widget/NetworkDropdown.jsx';\nimport './styles/main.css';\nimport './styles/PricingCard.css';\n\nconst StablePay = {\n NetworkSelector,\n Transaction,\n Config,\n Widget,\n PayButton,\n Dialog,\n NetworkDropdown\n};\n\nexport default StablePay;","import { networksConfig } from \"../utils/config\";\n\nexport class NetworkSelector {\n constructor(merchantConfig) {\n this.merchantConfig = merchantConfig;\n this.blacklist = merchantConfig.getBlacklist();\n this.availableNetworks = this.getAvailableNetworks();\n this.selectedNetwork = null;\n }\n\n getAvailableNetworks() {\n return Object.entries(networksConfig).reduce(\n (acc, [networkKey, networkConfig]) => {\n if (!this.blacklist.includes(networkConfig.chainId)) {\n acc[networkKey] = networkConfig;\n }\n return acc;\n },\n {}\n );\n }\n\n selectNetwork(networkKey) {\n if (networkKey === null) {\n this.selectedNetwork = null;\n console.log(\"Network selection reset\");\n return true;\n }\n if (this.availableNetworks[networkKey]) {\n this.selectedNetwork = networkKey;\n console.log(`Network selected: ${networkKey}`);\n return true;\n }\n console.error(`Invalid network: ${networkKey}`);\n return false;\n }\n\n getSelectedNetworkConfig() {\n return this.selectedNetwork\n ? this.availableNetworks[this.selectedNetwork]\n : null;\n }\n\n getReceivingAddress() {\n return this.merchantConfig.getReceivingAddress();\n }\n\n getTokenAmount(token) {\n return this.merchantConfig.getTokenAmount(this.selectedNetwork, token);\n }\n}\n","import { networksConfig } from \"../utils/config\";\n\nexport class Config {\n constructor(options = {}) {\n this.receivingAddress = options.receivingAddress || \"\";\n this.blacklist = options.blacklist || [];\n this.amounts = options.amounts || options.Amounts || {};\n this.validateConfig();\n }\n\n validateConfig() {\n if (!this.receivingAddress) {\n throw new Error(\"Receiving address is required\");\n }\n // Validate stablecoin amounts\n for (const [network, tokens] of Object.entries(this.amounts)) {\n if (!networksConfig[network]) {\n throw new Error(`Invalid network: ${network}`);\n }\n if (\n !tokens.stablecoin ||\n typeof tokens.stablecoin !== \"number\" ||\n tokens.stablecoin <= 0\n ) {\n throw new Error(`Invalid stablecoin amount for network ${network}`);\n }\n }\n }\n\n getBlacklist() {\n return this.blacklist;\n }\n\n getReceivingAddress() {\n return this.receivingAddress;\n }\n\n // getTokenAmount(network, token) {\n // const networkConfig = networksConfig[network];\n // if (!networkConfig) return 0;\n\n // const stablecoinSymbol = networkConfig.tokens.stablecoin.symbol;\n\n // if (token === 'stablecoin') {\n // return this.amounts[network]?.stablecoin || 0;\n // }\n // // For native tokens, return 0 as it's not specified in the new structure\n // return 0;\n // }\n getTokenAmount(network) {\n console.log(\"Getting amount for network:\", network);\n console.log(\"Amounts object:\", this.amounts);\n\n // Directly return the stablecoin amount for the network\n const amount = this.amounts[network]?.stablecoin;\n console.log(\"Returning amount:\", amount);\n\n return amount || 0;\n }\n}\n\nexport default Config;\n"],"names":["networksConfig","sepolia","uri","chainId","djedAddress","tokens","stablecoin","symbol","address","decimals","isDirectTransfer","native","isNative","feeUI","Transaction","constructor","networkUri","this","init","Error","web3","getWeb3","djedContract","getDjedContract","stableCoin","reserveCoin","getCoinContracts","scDecimals","rcDecimals","getDecimals","oracleContract","getOracleAddress","then","addr","getOracleContract","_address","oracleAddress","contractError","console","error","code","data","getNetworkInfo","includes","name","networkName","message","getNetworkName","getBlockchainDetails","web3Available","djedContractAvailable","stableCoinAddress","reserveCoinAddress","stableCoinDecimals","reserveCoinDecimals","oracleContractAvailable","handleTradeDataBuySc","amountScaled","tradeDataPriceBuySc","totalBCScaled","buyStablecoins","payer","receiver","value","UI","buyScTx","PayButton","onClick","size","sizeStyles","small","width","height","fontSize","medium","large","logoSizes","buttonStyle","logoStyle","React","createElement","className","styles","style","Dialog","children","onClose","dialogOverlay","pricingCard","dialogClose","pricingCardHeader","allianceLogo","stablepayTitle","pricingCardBody","TokenSelector","networkSelector","selectedToken","selectToken","tokenKey","networkConfig","getSelectedNetworkConfig","key","getSelectedToken","getAvailableTokens","Object","entries","map","config","resetSelection","NetworkContext","createContext","NetworkProvider","tokenSelector","useState","selectedNetwork","setSelectedNetwork","setSelectedToken","transactionDetails","setTransactionDetails","resetState","useEffect","Provider","selectNetwork","networkKey","token","resetSelections","useNetwork","context","useContext","undefined","NetworkDropdown","selectField","htmlFor","id","onChange","event","target","disabled","keys","availableNetworks","TokenDropdown","loading","setLoading","setError","availableTokens","async","newValue","transaction","tokenAmount","getTokenAmount","blockchainDetails","tradeData","String","network","tokenSymbol","amount","receivingAddress","getReceivingAddress","djedContractAddress","isNativeToken","tradeAmount","err","defineChain","nativeCurrency","rpcUrls","default","http","webSocket","blockExplorers","url","testnet","milkomeda","etcMainnet","WalletContext","switchToNetwork","window","ethereum","chainConfig","toString","chainName","blockExplorerUrls","getChainConfigForWallet","request","method","params","switchError","addError","WalletProvider","walletClient","setWalletClient","publicClient","setPublicClient","account","setAccount","setChainId","balance","setBalance","isConnecting","setIsConnecting","selectedChain","getChainByNetworkKey","expectedChainId","handleAccountsChangedRef","useRef","handleChainChangedRef","disconnectWalletInternal","useCallback","handleChainChanged","newChainId","parseInt","chainIdHex","newWalletClient","createWalletClient","chain","transport","custom","current","handleAccountsChanged","accounts","length","accountsHandler","chainHandler","removeListener","newPublicClient","createPublicClient","getBalance","parseFloat","Math","pow","disconnectWallet","connectPublicClient","connectWallet","on","ensureCorrectNetwork","NETWORK_SWITCH_DELAY_MS","Promise","resolve","setTimeout","newChainIdHex","freshWalletClient","prevNetworkRef","TransactionReview","onTransactionComplete","contextTransactionDetails","useWallet","setTransaction","tradeDataBuySc","setTradeDataBuySc","setMessage","txHash","setTxHash","isErrorDetailsVisible","setIsErrorDetailsVisible","interactionState","setInteractionState","newTransaction","tradeError","initializeTransaction","getExplorerUrl","explorerBaseUrls","transactionReview","transactionInfo","transactionLabel","transactionValue","highlight","messageBox","detailsButton","errorDetails","transactionLink","href","rel","explorerLink","slice","wordBreak","walletButtonContainer","walletButton","confirmContainer","confirmText","confirmButtons","secondaryButton","primaryButton","builtTx","amountToSend","valueInWei","parseEther","stablecoinAddress","parseUnits","to","encodeFunctionData","abi","inputs","internalType","type","outputs","stateMutability","functionName","args","reason","shortMessage","split","currentChainId","sendTransaction","WidgetContent","buttonSize","handleClose","WidgetWithProviders","NetworkSelector","merchantConfig","blacklist","getBlacklist","getAvailableNetworks","reduce","acc","log","Config","options","amounts","Amounts","validateConfig","Widget","onSuccess","isDialogOpen","setIsDialogOpen","handleTransactionComplete","widgetContainer","handleOpenDialog","handleCloseDialog"],"mappings":"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"} \ No newline at end of file diff --git a/stablepay-sdk/dist/umd/styles.css b/stablepay-sdk/dist/umd/styles.css index 24e94a1..c6cb414 100644 --- a/stablepay-sdk/dist/umd/styles.css +++ b/stablepay-sdk/dist/umd/styles.css @@ -1 +1 @@ -.main_stablePayButton__UA7HC{align-items:center;background:linear-gradient(90deg,#000,#f7941d);border:1px solid #bc5f26;border-radius:3px;box-sizing:border-box;color:#fff;cursor:pointer;display:flex;font-size:24px;font-weight:700;height:104px;justify-content:flex-start;overflow:hidden;padding:0 20px;position:relative;width:372px}.main_stablePayButton__UA7HC:hover{opacity:.9}.main_stablePayButton__UA7HC .main_logo__ITyEy{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;flex-shrink:0;height:25px;margin-right:20px;width:25px}.main_stablePayButton__UA7HC .main_buttonText__N-ewy{flex-grow:1;text-align:center}@keyframes PricingCard_fadeInScale__2MTi3{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.PricingCard_dialogOverlay__0XJrE{align-items:center;animation:PricingCard_fadeInScale__2MTi3 .2s ease-out;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background-color:rgba(0,0,0,.4);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:1000}.PricingCard_pricingCard__LrWb9{background:#242529;border:1px solid hsla(0,0%,100%,.08);border-radius:20px;box-shadow:0 15px 35px rgba(0,0,0,.4),inset 0 1px 0 hsla(0,0%,100%,.05);box-sizing:border-box;display:flex;flex-direction:column;padding:32px;position:relative}.PricingCard_pricingCard__LrWb9.PricingCard_small__J4CHj{min-height:520px;width:360px}.PricingCard_pricingCard__LrWb9.PricingCard_medium__EVmTB{min-height:580px;width:400px}.PricingCard_pricingCard__LrWb9.PricingCard_large__A6pnX{min-height:640px;width:440px}.PricingCard_dialogClose__jJ1tM{align-items:center;background:hsla(0,0%,100%,.1);border:none;border-radius:50%;color:#a0aec0;cursor:pointer;display:flex;font-size:20px;height:32px;justify-content:center;line-height:1;padding:0 0 3px;position:absolute;right:20px;top:20px;transition:all .2s ease;width:32px;z-index:5}.PricingCard_dialogClose__jJ1tM:hover{background:hsla(0,0%,100%,.2);color:#fff}.PricingCard_pricingCardHeader__wGczA{align-items:center;border-bottom:1px solid hsla(0,0%,100%,.05);display:flex;gap:16px;margin-bottom:30px;padding-bottom:20px;width:100%}.PricingCard_allianceLogo__URa-U{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:48px;width:48px}.PricingCard_stablepayTitle__4t848{align-items:center;color:#f6941c;display:flex;font-family:Inter,sans-serif;font-size:26px;font-style:normal;font-weight:700;letter-spacing:-.5px}.PricingCard_pricingCardBody__0wKQn{display:flex;flex:1;flex-direction:column;width:100%}.PricingCard_selectField__LBPoZ{display:flex;flex-direction:column;gap:10px;margin-bottom:24px;width:100%}.PricingCard_selectField__LBPoZ label{align-self:flex-start;color:#a0aec0;font-family:Inter,sans-serif;font-size:14px;font-style:normal;font-weight:500;text-align:left;width:100%}.PricingCard_selectField__LBPoZ select{appearance:none;background:hsla(0,0%,100%,.05);background-image:url(../assets/chevron-down-icon.svg);background-position:right 18px center;background-repeat:no-repeat;border:1px solid hsla(0,0%,100%,.1);border-radius:12px;box-sizing:border-box;color:#fff;cursor:pointer;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:500;height:52px;padding:12px 16px;transition:all .2s ease;width:100%}.PricingCard_selectField__LBPoZ select:hover:not(:disabled){background:hsla(0,0%,100%,.08);border-color:rgba(246,148,28,.5)}.PricingCard_selectField__LBPoZ select:focus{border-color:#f6941c;box-shadow:0 0 0 3px rgba(246,148,28,.2);outline:none}.PricingCard_selectField__LBPoZ select:disabled{cursor:not-allowed;opacity:.5}.PricingCard_selectField__LBPoZ select option{background:#242529;color:#fff}.PricingCard_transactionReview__Ix-eL{display:flex;flex:1;flex-direction:column;padding-top:10px;width:100%}.PricingCard_transactionInfo__Ck-Rc{align-items:center;background:rgba(0,0,0,.2);border:1px solid hsla(0,0%,100%,.05);border-radius:12px;display:flex;justify-content:space-between;margin-bottom:16px;padding:14px 18px;width:100%}.PricingCard_transactionLabel__GDux7{color:#a0aec0;font-family:Inter,sans-serif;font-size:15px;font-style:normal;font-weight:500}.PricingCard_transactionValue__q-xxp{color:#fff;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:700;text-align:right}.PricingCard_transactionValue__q-xxp.PricingCard_highlight__WZZ6N{color:#f6941c;font-size:18px}.PricingCard_walletButtonContainer__a6MwB{margin-top:auto;padding-top:24px}.PricingCard_walletButton__llw4v{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:14px;box-shadow:0 4px 14px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;font-family:Inter,sans-serif;font-size:17px;font-style:normal;font-weight:600;height:56px;justify-content:center;transition:all .2s ease;width:100%}.PricingCard_walletButton__llw4v:hover:not(:disabled){box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_walletButton__llw4v:active:not(:disabled){transform:translateY(0)}.PricingCard_walletButton__llw4v:disabled{background:hsla(0,0%,100%,.1);box-shadow:none;color:#636a77;cursor:not-allowed}.PricingCard_loading__2-tGA{align-items:center;color:#a0aec0;display:flex;flex-direction:column;font-family:Inter,sans-serif;gap:16px;padding:40px;text-align:center}.PricingCard_error__m5fK-{color:#ff4d4f;font-family:Inter,sans-serif;font-size:14px;margin-top:4px;text-align:left}.PricingCard_messageBox__wnx0F{align-items:center;animation:PricingCard_fadeIn__L63q8 .3s ease-out;color:#e2e8f0;display:flex;flex-direction:column;font-family:Inter,sans-serif;font-size:13.5px;font-weight:500;gap:8px;margin-bottom:16px;padding:8px 0;text-align:center}@keyframes PricingCard_fadeIn__L63q8{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.PricingCard_detailsButton__jHglL{background:none;border:none;color:#f6941c;cursor:pointer;font-size:13px;font-weight:600;margin-top:4px;padding:0;text-decoration:none}.PricingCard_detailsButton__jHglL:hover{text-decoration:underline}.PricingCard_errorDetails__CzN-7{background-color:rgba(0,0,0,.2);border-left:3px solid #ff4d4f;border-radius:8px;color:#fc8181;font-family:monospace;font-size:11px;line-height:1.5;margin-top:10px;max-height:150px;overflow-y:auto;padding:12px;text-align:left;white-space:pre-wrap;word-break:break-all}.PricingCard_transactionLink__RFRWW{background:rgba(40,167,69,.1);border:1px solid rgba(40,167,69,.2);border-radius:12px;color:#fff;font-family:Inter,sans-serif;font-size:14px;margin-top:20px;padding:16px;text-align:center}.PricingCard_explorerLink__-a82-{color:#f6941c;font-weight:600;text-decoration:none;transition:color .2s ease}.PricingCard_explorerLink__-a82-:hover{color:#ffad42;text-decoration:underline}.PricingCard_stablePayButton__Y4Rr4{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:16px;box-shadow:0 4px 15px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;gap:12px;justify-content:center;transition:all .2s ease}.PricingCard_stablePayButton__Y4Rr4:hover{box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_stablePayButton__Y4Rr4:active{transform:translateY(0)}.PricingCard_buttonText__8LnPv{font-family:Inter,sans-serif;font-weight:600}@media (max-width:520px){.PricingCard_pricingCard__LrWb9{border:none;border-radius:0;height:100%;min-height:100vh;padding:24px;width:100%}.PricingCard_dialogOverlay__0XJrE{align-items:flex-start;background-color:#242529}} \ No newline at end of file +.main_stablePayButton__UA7HC{align-items:center;background:linear-gradient(90deg,#000,#f7941d);border:1px solid #bc5f26;border-radius:3px;box-sizing:border-box;color:#fff;cursor:pointer;display:flex;font-size:24px;font-weight:700;height:104px;justify-content:flex-start;overflow:hidden;padding:0 20px;position:relative;width:372px}.main_stablePayButton__UA7HC:hover{opacity:.9}.main_stablePayButton__UA7HC .main_logo__ITyEy{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;flex-shrink:0;height:25px;margin-right:20px;width:25px}.main_stablePayButton__UA7HC .main_buttonText__N-ewy{flex-grow:1;text-align:center}@keyframes PricingCard_fadeInScale__2MTi3{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.PricingCard_dialogOverlay__0XJrE{align-items:center;animation:PricingCard_fadeInScale__2MTi3 .2s ease-out;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background-color:rgba(0,0,0,.4);bottom:0;display:flex;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:1000}.PricingCard_pricingCard__LrWb9{background:#242529;border:1px solid hsla(0,0%,100%,.08);border-radius:20px;box-shadow:0 15px 35px rgba(0,0,0,.4),inset 0 1px 0 hsla(0,0%,100%,.05);box-sizing:border-box;display:flex;flex-direction:column;padding:32px;position:relative}.PricingCard_pricingCard__LrWb9.PricingCard_small__J4CHj{min-height:520px;width:360px}.PricingCard_pricingCard__LrWb9.PricingCard_medium__EVmTB{min-height:580px;width:400px}.PricingCard_pricingCard__LrWb9.PricingCard_large__A6pnX{min-height:640px;width:440px}.PricingCard_dialogClose__jJ1tM{align-items:center;background:hsla(0,0%,100%,.1);border:none;border-radius:50%;color:#a0aec0;cursor:pointer;display:flex;font-size:20px;height:32px;justify-content:center;line-height:1;padding:0 0 3px;position:absolute;right:20px;top:20px;transition:all .2s ease;width:32px;z-index:5}.PricingCard_dialogClose__jJ1tM:hover{background:hsla(0,0%,100%,.2);color:#fff}.PricingCard_pricingCardHeader__wGczA{align-items:center;border-bottom:1px solid hsla(0,0%,100%,.05);display:flex;gap:16px;margin-bottom:30px;padding-bottom:20px;width:100%}.PricingCard_allianceLogo__URa-U{background-image:url(../assets/stablepay-logo.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:48px;width:48px}.PricingCard_stablepayTitle__4t848{align-items:center;color:#f6941c;display:flex;font-family:Inter,sans-serif;font-size:26px;font-style:normal;font-weight:700;letter-spacing:-.5px}.PricingCard_pricingCardBody__0wKQn{display:flex;flex:1;flex-direction:column;width:100%}.PricingCard_selectField__LBPoZ{display:flex;flex-direction:column;gap:10px;margin-bottom:24px;width:100%}.PricingCard_selectField__LBPoZ label{align-self:flex-start;color:#a0aec0;font-family:Inter,sans-serif;font-size:14px;font-style:normal;font-weight:500;text-align:left;width:100%}.PricingCard_selectField__LBPoZ select{appearance:none;background:hsla(0,0%,100%,.05);background-image:url(../assets/chevron-down-icon.svg);background-position:right 18px center;background-repeat:no-repeat;border:1px solid hsla(0,0%,100%,.1);border-radius:12px;box-sizing:border-box;color:#fff;cursor:pointer;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:500;height:52px;padding:12px 16px;transition:all .2s ease;width:100%}.PricingCard_selectField__LBPoZ select:hover:not(:disabled){background:hsla(0,0%,100%,.08);border-color:rgba(246,148,28,.5)}.PricingCard_selectField__LBPoZ select:focus{border-color:#f6941c;box-shadow:0 0 0 3px rgba(246,148,28,.2);outline:none}.PricingCard_selectField__LBPoZ select:disabled{cursor:not-allowed;opacity:.5}.PricingCard_selectField__LBPoZ select option{background:#242529;color:#fff}.PricingCard_transactionReview__Ix-eL{display:flex;flex:1;flex-direction:column;padding-top:10px;width:100%}.PricingCard_transactionInfo__Ck-Rc{align-items:center;background:rgba(0,0,0,.2);border:1px solid hsla(0,0%,100%,.05);border-radius:12px;display:flex;justify-content:space-between;margin-bottom:16px;padding:14px 18px;width:100%}.PricingCard_transactionLabel__GDux7{color:#a0aec0;font-family:Inter,sans-serif;font-size:15px;font-style:normal;font-weight:500}.PricingCard_transactionValue__q-xxp{color:#fff;font-family:Inter,sans-serif;font-size:16px;font-style:normal;font-weight:700;text-align:right}.PricingCard_transactionValue__q-xxp.PricingCard_highlight__WZZ6N{color:#f6941c;font-size:18px}.PricingCard_walletButtonContainer__a6MwB{margin-top:auto;padding-top:24px}.PricingCard_walletButton__llw4v{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:14px;box-shadow:0 4px 14px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;font-family:Inter,sans-serif;font-size:17px;font-style:normal;font-weight:600;height:56px;justify-content:center;transition:all .2s ease;width:100%}.PricingCard_walletButton__llw4v:hover:not(:disabled){box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_walletButton__llw4v:active:not(:disabled){transform:translateY(0)}.PricingCard_walletButton__llw4v:disabled{background:hsla(0,0%,100%,.1);box-shadow:none;color:#636a77;cursor:not-allowed}.PricingCard_confirmContainer__vNq4n{align-items:center;display:flex;flex-direction:column;width:100%}.PricingCard_confirmText__FP0WS{color:#a0aec0;font-family:Inter,sans-serif;font-size:15px;margin-bottom:12px}.PricingCard_confirmButtons__fZ7jt{display:flex;gap:12px;width:100%}.PricingCard_secondaryButton__OTpW4{background:hsla(0,0%,100%,.05);border:1px solid hsla(0,0%,100%,.1);border-radius:14px;color:#fff;cursor:pointer;flex:1;font-family:Inter,sans-serif;font-size:17px;font-weight:600;height:56px;transition:all .2s ease}.PricingCard_secondaryButton__OTpW4:hover{background:hsla(0,0%,100%,.1)}.PricingCard_primaryButton__bmYo9{flex:1}.PricingCard_loading__2-tGA{align-items:center;color:#a0aec0;display:flex;flex-direction:column;font-family:Inter,sans-serif;gap:16px;padding:40px;text-align:center}.PricingCard_error__m5fK-{color:#ff4d4f;font-family:Inter,sans-serif;font-size:14px;margin-top:4px;text-align:left}.PricingCard_messageBox__wnx0F{align-items:center;animation:PricingCard_fadeIn__L63q8 .3s ease-out;color:#e2e8f0;display:flex;flex-direction:column;font-family:Inter,sans-serif;font-size:13.5px;font-weight:500;gap:8px;margin-bottom:16px;padding:8px 0;text-align:center}@keyframes PricingCard_fadeIn__L63q8{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.PricingCard_detailsButton__jHglL{background:none;border:none;color:#f6941c;cursor:pointer;font-size:13px;font-weight:600;margin-top:4px;padding:0;text-decoration:none}.PricingCard_detailsButton__jHglL:hover{text-decoration:underline}.PricingCard_errorDetails__CzN-7{background-color:rgba(0,0,0,.2);border-left:3px solid #ff4d4f;border-radius:8px;color:#fc8181;font-family:monospace;font-size:11px;line-height:1.5;margin-top:10px;max-height:150px;overflow-y:auto;padding:12px;text-align:left;white-space:pre-wrap;word-break:break-all}.PricingCard_transactionLink__RFRWW{background:rgba(40,167,69,.1);border:1px solid rgba(40,167,69,.2);border-radius:12px;color:#fff;font-family:Inter,sans-serif;font-size:14px;margin-top:20px;padding:16px;text-align:center}.PricingCard_explorerLink__-a82-{color:#f6941c;font-weight:600;text-decoration:none;transition:color .2s ease}.PricingCard_explorerLink__-a82-:hover{color:#ffad42;text-decoration:underline}.PricingCard_stablePayButton__Y4Rr4{align-items:center;background:linear-gradient(135deg,#f6941c,#d87c12);border:none;border-radius:16px;box-shadow:0 4px 15px rgba(246,148,28,.3);color:#fff;cursor:pointer;display:flex;gap:12px;justify-content:center;transition:all .2s ease}.PricingCard_stablePayButton__Y4Rr4:hover{box-shadow:0 6px 20px rgba(246,148,28,.4);transform:translateY(-2px)}.PricingCard_stablePayButton__Y4Rr4:active{transform:translateY(0)}.PricingCard_buttonText__8LnPv{font-family:Inter,sans-serif;font-weight:600}@media (max-width:520px){.PricingCard_pricingCard__LrWb9{border:none;border-radius:0;height:100%;min-height:100vh;padding:24px;width:100%}.PricingCard_dialogOverlay__0XJrE{align-items:flex-start;background-color:#242529}} \ No newline at end of file diff --git a/stablepay-sdk/src/core/Transaction.js b/stablepay-sdk/src/core/Transaction.js index eb72988..498c28e 100644 --- a/stablepay-sdk/src/core/Transaction.js +++ b/stablepay-sdk/src/core/Transaction.js @@ -30,7 +30,8 @@ export class Transaction { this.oracleAddress = this.oracleContract._address; } catch (contractError) { console.error('[Transaction] Error fetching contract details:', contractError); - if (contractError.message && contractError.message.includes('execution reverted')) { + const isReverted = contractError.code === -32000 || contractError.code === 3 || contractError.data; + if (isReverted) { const getNetworkInfo = (uri) => { if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' }; if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' }; @@ -52,7 +53,8 @@ export class Transaction { } } catch (error) { console.error('[Transaction] Error initializing transaction:', error); - if (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED'))) { + const isConnectionError = error.code === -32603 || error.code === 4001 || error.code === -32005 || (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED'))); + if (isConnectionError) { const getNetworkName = (uri) => { if (uri.includes('milkomeda')) return 'Milkomeda'; if (uri.includes('mordor')) return 'Mordor'; diff --git a/stablepay-sdk/src/styles/PricingCard.css b/stablepay-sdk/src/styles/PricingCard.css index 740d8fd..f2b9681 100644 --- a/stablepay-sdk/src/styles/PricingCard.css +++ b/stablepay-sdk/src/styles/PricingCard.css @@ -258,6 +258,48 @@ cursor: not-allowed; } +.confirmContainer { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; +} + +.confirmText { + font-family: "Inter", sans-serif; + color: #a0aec0; + margin-bottom: 12px; + font-size: 15px; +} + +.confirmButtons { + display: flex; + gap: 12px; + width: 100%; +} + +.secondaryButton { + flex: 1; + height: 56px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 14px; + font-family: "Inter", sans-serif; + font-weight: 600; + font-size: 17px; + color: #ffffff; + cursor: pointer; + transition: all 0.2s ease; +} + +.secondaryButton:hover { + background: rgba(255, 255, 255, 0.1); +} + +.primaryButton { + flex: 1; +} + .loading { text-align: center; color: #a0aec0; diff --git a/stablepay-sdk/src/widget/TransactionReview.jsx b/stablepay-sdk/src/widget/TransactionReview.jsx index ea66cdb..33d5578 100644 --- a/stablepay-sdk/src/widget/TransactionReview.jsx +++ b/stablepay-sdk/src/widget/TransactionReview.jsx @@ -26,18 +26,18 @@ const TransactionReview = ({ onTransactionComplete }) => { const [transaction, setTransaction] = useState(null); const [tradeDataBuySc, setTradeDataBuySc] = useState(null); - const [txData, setTxData] = useState(null); const [message, setMessage] = useState(""); const [txHash, setTxHash] = useState(null); const [error, setError] = useState(null); const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false); + const [interactionState, setInteractionState] = useState('IDLE'); useEffect(() => { - setTxData(null); setTradeDataBuySc(null); setMessage(""); setError(null); setTxHash(null); + setInteractionState('IDLE'); }, [selectedNetwork, selectedToken]); useEffect(() => { @@ -98,19 +98,20 @@ const TransactionReview = ({ onTransactionComplete }) => { await connectWallet(); }; - const handleSendTransaction = async () => { + const executePayment = async () => { if (!account || !contextTransactionDetails || !transaction) { setMessage("Wallet not connected or transaction details missing"); return; } - try { - setTxData(null); - setError(null); - setMessage("Preparing transaction..."); + setInteractionState('PROCESSING'); + setMessage("Preparing transaction..."); + setError(null); + setTxHash(null); + let builtTx; + try { const receiver = contextTransactionDetails.receivingAddress; - let builtTx; if (selectedToken.key === "native") { const UI = "0x0232556C83791b8291E9b23BfEa7d67405Bd9839"; @@ -166,75 +167,50 @@ const TransactionReview = ({ onTransactionComplete }) => { account: account, }; } - - setTxData(builtTx); - setMessage("Transaction ready. Please confirm to proceed."); - } catch (error) { - setError(error); - const reason = error.shortMessage || (error.message ? error.message.split('\n')[0] : "Unknown error"); + } catch (err) { + setError(err); + const reason = err.shortMessage || (err.message ? err.message.split('\n')[0] : "Unknown error"); setMessage(`Transaction preparation failed: ${reason}`); + setInteractionState('IDLE'); + return; } - }; - const handleBuySc = async () => { - setError(null); + setMessage("Please check your wallet to confirm the transaction..."); try { - if (!account || !txData) { - setMessage("Wallet account or transaction data is missing"); - return; - } - - if (!selectedNetwork) { - setMessage("Network not selected"); - return; - } - const networkConfig = networkSelector.getSelectedNetworkConfig(); if (!networkConfig) { - setMessage("Network configuration not found"); - return; + throw new Error("Network configuration not found"); } - setMessage("Verifying network..."); - const freshWalletClient = await ensureCorrectNetwork(); if (!freshWalletClient) { - setMessage("Failed to switch to correct network. Please approve the network switch in MetaMask and try again."); - return; + throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask."); } if (!window.ethereum) { - setMessage("MetaMask not available"); - return; + throw new Error("MetaMask not available"); } const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' }); const currentChainId = parseInt(chainIdHex, 16); if (currentChainId !== networkConfig.chainId) { - const errorMsg = `Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`; - setMessage(errorMsg); - setError(new Error(errorMsg)); - return; + throw new Error(`Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`); } if (freshWalletClient.chain.id !== networkConfig.chainId) { - const errorMsg = `Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`; - setMessage(errorMsg); - setError(new Error(errorMsg)); - return; + throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`); } - setMessage("Sending transaction..."); - const txHash = await freshWalletClient.sendTransaction({ - ...txData, + ...builtTx, account: account, }); setTxHash(txHash); - setMessage(`Transaction sent!`); + setMessage(`Transaction sent successfully!`); + setInteractionState('SUCCESS'); if (onTransactionComplete) { onTransactionComplete({ @@ -246,11 +222,21 @@ const TransactionReview = ({ onTransactionComplete }) => { receivingAddress: contextTransactionDetails?.receivingAddress, }); } - } catch (error) { - setError(error); - const reason = error.shortMessage || (error.message ? error.message.split('\n')[0] : "Unknown error"); + } catch (err) { + setError(err); + + let reason = "Unknown error"; + if (err.name === 'UserRejectedRequestError' || err.code === 4001) { + reason = "User denied transaction"; + } else if (err.name === 'ContractFunctionRevertedError' || (err.data && err.data.message)) { + reason = err.shortMessage || err.data?.message || err.message; + } else { + reason = err.shortMessage || (err.message ? err.message.split('\n')[0] : "Transaction failed"); + } + setMessage(`Transaction failed: ${reason}`); - console.error('Transaction error:', error); + setInteractionState('IDLE'); + console.error('Transaction error:', err); } }; @@ -326,29 +312,41 @@ const TransactionReview = ({ onTransactionComplete }) => {
)} -
- {!account && ( - - )} - - {account && !txData && ( - - )} - - {account && txData && ( - - )} -
+ {interactionState !== 'SUCCESS' && ( +
+ {!account && ( + + )} + + {account && interactionState === 'IDLE' && ( + + )} + + {account && interactionState === 'CONFIRMING' && ( +
+ Confirm payment? +
+ + +
+
+ )} + + {account && interactionState === 'PROCESSING' && ( + + )} +
+ )}
); }; From 4a3df35a6d15313a8009d388a64ac228322c1ff0 Mon Sep 17 00:00:00 2001 From: DeveloperAmrit Date: Mon, 8 Jun 2026 09:32:50 +0530 Subject: [PATCH 5/6] fix: Fixed freeze state when user has no wallet --- stablepay-sdk/dist/esm/index.js | 2 +- stablepay-sdk/dist/umd/index.js | 2 +- stablepay-sdk/dist/umd/index.js.map | 2 +- stablepay-sdk/package-lock.json | 4 ++-- stablepay-sdk/src/widget/TokenDropdown.jsx | 6 +++++- stablepay-sdk/src/widget/TransactionReview.jsx | 17 +++++++++++++++++ 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/stablepay-sdk/dist/esm/index.js b/stablepay-sdk/dist/esm/index.js index d766331..81d6752 100644 --- a/stablepay-sdk/dist/esm/index.js +++ b/stablepay-sdk/dist/esm/index.js @@ -1 +1 @@ -import{getWeb3 as e,getDjedContract as t,getCoinContracts as n,getDecimals as r,getOracleAddress as a,getOracleContract as o,tradeDataPriceBuySc as i,buyScTx as s}from"djed-sdk";import c,{useContext as l,createContext as d,useState as m,useEffect as u,useRef as h,useCallback as w}from"react";import{defineChain as k,createWalletClient as g,custom as C,createPublicClient as p,http as b,parseEther as f,parseUnits as E,encodeFunctionData as y}from"viem";import{sepolia as v}from"viem/chains";const _={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class N{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e(this.networkUri),this.djedContract=t(this.web3,this.djedAddress);try{const{stableCoin:e,reserveCoin:t}=await n(this.djedContract,this.web3),{scDecimals:i,rcDecimals:s}=await r(e,t);this.stableCoin=e,this.reserveCoin=t,this.scDecimals=i,this.rcDecimals=s,this.oracleContract=await a(this.djedContract).then((e=>o(this.web3,e,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){console.error("[Transaction] Error fetching contract details:",e);if(-32e3===e.code||3===e.code||e.data){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){console.error("[Transaction] Error initializing transaction:",e);if(-32603===e.code||4001===e.code||-32005===e.code||e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(e){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof e)throw new Error("Amount must be a string");try{return(await i(this.djedContract,this.scDecimals,e)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(e,t,n){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await s(this.djedContract,e,t,n,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var S="main_stablePayButton__UA7HC",T="main_logo__ITyEy",A="main_buttonText__N-ewy";const P=({onClick:e,size:t="medium"})=>{const n={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},a=n[t]||n.medium,o=r[t]||r.medium;return c.createElement("button",{className:S,onClick:e,style:a},c.createElement("div",{className:T,style:o}),c.createElement("span",{className:A},"Pay with StablePay"))};var D={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",confirmContainer:"PricingCard_confirmContainer__vNq4n",confirmText:"PricingCard_confirmText__FP0WS",confirmButtons:"PricingCard_confirmButtons__fZ7jt",secondaryButton:"PricingCard_secondaryButton__OTpW4",primaryButton:"PricingCard_primaryButton__bmYo9",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const x=({children:e,onClose:t,size:n="medium"})=>c.createElement("div",{className:D.dialogOverlay},c.createElement("div",{className:`${D.pricingCard} ${D[n]}`},c.createElement("button",{className:D.dialogClose,onClick:t},"×"),c.createElement("div",{className:D.pricingCardHeader},c.createElement("div",{className:D.allianceLogo}),c.createElement("div",{className:D.stablepayTitle},"StablePay")),c.createElement("div",{className:D.pricingCardBody},e)));class I{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const B=d(),M=({children:e,networkSelector:t})=>{const[n]=m((()=>new I(t))),[r,a]=m(null),[o,i]=m(null),[s,l]=m(null),d=()=>{i(null),l(null)};return u((()=>{a(t.selectedNetwork)}),[t.selectedNetwork]),c.createElement(B.Provider,{value:{networkSelector:t,tokenSelector:n,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:l,selectNetwork:e=>!!t.selectNetwork(e)&&(a(e),d(),!0),selectToken:e=>{if(n.selectToken(e)){const e=n.getSelectedToken();return i(e),!0}return!1},resetSelections:()=>{t.selectNetwork(null),a(null),d()}}},e)},$=()=>{const e=l(B);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},j=()=>{const{networkSelector:e,selectedNetwork:t,selectNetwork:n}=$();return c.createElement("div",{className:D.selectField},c.createElement("label",{htmlFor:"network-select"},"Select Network"),c.createElement("select",{id:"network-select",onChange:e=>{n(e.target.value)},value:t||""},c.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>c.createElement("option",{key:e,value:e},e)))))},L=()=>{const{networkSelector:e,tokenSelector:t,selectedNetwork:n,selectedToken:r,selectToken:a,setTransactionDetails:o}=$(),[i,s]=m(!1),[l,d]=m(null),u=n?t.getAvailableTokens():[];return c.createElement("div",{className:D.selectField},c.createElement("label",{htmlFor:"token-select"},"Select Token"),c.createElement("select",{id:"token-select",onChange:async r=>{const i=r.target.value;d(null),s(!0);try{if(a(i)){const r=e.getSelectedNetworkConfig(),a=new N(r.uri,r.djedAddress);await a.init();const s=e.getTokenAmount(i),c=a.getBlockchainDetails();let l=null;"native"===i&&(l=await a.handleTradeDataBuySc(String(s))),o({network:n,token:i,tokenSymbol:t.getSelectedToken().symbol,amount:s,receivingAddress:e.getReceivingAddress(),djedContractAddress:r.djedAddress,isDirectTransfer:t.getSelectedToken().isDirectTransfer||!1,isNativeToken:t.getSelectedToken().isNative||!1,tradeAmount:l?l.amount:null,...c})}}catch(e){console.error("Error fetching transaction details:",e),d("Failed to fetch transaction details. Please try again.")}finally{s(!1)}},value:r?r.key:"",disabled:!n||i},c.createElement("option",{value:"",disabled:!0},n?i?"Loading...":"Select a token":"Please select a network first"),u.map((e=>c.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),l&&c.createElement("div",{className:D.error},l))};k({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const F=k({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),U=k({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),R=d(null),z=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${v.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:v.rpcUrls.default.http,blockExplorerUrls:v.blockExplorers?.default?.url?[v.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${U.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${F.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},O=({children:e})=>{const{selectedNetwork:t}=$(),[n,r]=m(null),[a,o]=m(null),[i,s]=m(null),[l,d]=m(null),[k,f]=m(null),[E,y]=m(null),[_,N]=m(!1),S=t?(e=>{switch(e){case"sepolia":return v;case"ethereum-classic":return U;case"milkomeda-mainnet":return F;default:return null}})(t):null,T=S?S.id:null,A=h(null),P=h(null),D=w((()=>{r(null),o(null),s(null),d(null),f(null),y(null)}),[]),x=w((async e=>{const n=parseInt(e,16);if(d(n),S&&n===T){if(y(null),window.ethereum&&S){const e=g({chain:S,transport:C(window.ethereum)});r(e)}}else if(S&&n!==T){y(`Wrong network detected. Please switch to ${S?.name||t||"selected network"}`)}}),[S,T,t]);P.current=x;const I=w((async e=>{if(0===e.length){if(D(),window.ethereum){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(s(e[0]),S)try{const t=p({chain:S,transport:b()});o(t);const n=await t.getBalance({address:e[0]});f(parseFloat(n)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}}),[S,D]);A.current=I;const B=w((()=>{if(D(),window.ethereum){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[D]),M=w((()=>{S&&o(p({chain:S,transport:b()}))}),[S]),j=w((async()=>{if(!window.ethereum)return y("Please install MetaMask or another Web3 wallet"),!1;if(!t||!S)return y("Please select a network first"),!1;N(!0),y(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const n=await window.ethereum.request({method:"eth_chainId"});parseInt(n,16)!==T&&await z(t);const a=g({chain:S,transport:C(window.ethereum)});r(a),s(e[0]),d(T);const i=p({chain:S,transport:b()});o(i);try{const t=await i.getBalance({address:e[0]});f(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}return A.current=I,P.current=x,window.ethereum.on("accountsChanged",I),window.ethereum.on("chainChanged",x),!0}catch(e){return console.error("Error connecting wallet:",e),y(e.message),!1}finally{N(!1)}}),[t,S,T,I,x]),L=w((async()=>{if(!(window.ethereum&&t&&S&&i)){return y("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==T){y(null),await z(t);const e=500;await new Promise((t=>setTimeout(t,e)));const n=await window.ethereum.request({method:"eth_chainId"}),r=parseInt(n,16);if(r!==T)throw new Error(`Failed to switch network. MetaMask is still on chain ${r}, expected ${T}`)}const n=g({chain:S,transport:C(window.ethereum)});return r(n),d(T),y(null),n}catch(e){return y(e.message),null}}),[t,S,T,i]),O=h(t);return u((()=>{if(null!==O.current&&O.current!==t&&i&&(D(),window.ethereum)){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}O.current=t}),[t,i,D]),u((()=>{M()}),[M]),c.createElement(R.Provider,{value:{walletClient:n,publicClient:a,account:i,chainId:l,balance:k,error:E,isConnecting:_,connectWallet:j,disconnectWallet:B,ensureCorrectNetwork:L,expectedChainId:T}},e)},W=({onTransactionComplete:e})=>{const{networkSelector:t,selectedNetwork:n,selectedToken:r,transactionDetails:a,setTransactionDetails:o}=$(),{connectWallet:i,account:s,walletClient:d,publicClient:h,isConnecting:w,ensureCorrectNetwork:k,expectedChainId:g}=(()=>{const e=l(R);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[C,p]=m(null),[b,v]=m(null),[_,S]=m(""),[T,A]=m(null),[P,x]=m(null),[I,B]=m(!1),[M,j]=m("IDLE");if(u((()=>{v(null),S(""),x(null),A(null),j("IDLE")}),[n,r]),u((()=>{(async()=>{if(n&&r)try{const e=t.getSelectedNetworkConfig(),a=t.getReceivingAddress(),i=t.getTokenAmount(r.key),s=new N(e.uri,e.djedAddress);await s.init(),p(s);let c=null;if("native"===r.key)try{c=await s.handleTradeDataBuySc(String(i)),v(c)}catch(e){console.error("Error fetching trade data:",e)}o({network:n,token:r.key,tokenSymbol:r.symbol,amount:i||"0",receivingAddress:a,djedContractAddress:e.djedAddress,isDirectTransfer:r.isDirectTransfer||!1,isNativeToken:r.isNative||!1,tradeAmount:c?c.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[n,r,t,o]),!n||!r)return null;if(!a)return c.createElement("div",{className:D.loading},"Initializing transaction...");const L=()=>{if(!T||!n)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[n]?`${e[n]}${T}`:null};return c.createElement("div",{className:D.transactionReview},c.createElement("div",{className:D.transactionInfo},c.createElement("span",{className:D.transactionLabel},"Network:"),c.createElement("span",{className:D.transactionValue},a.network)),c.createElement("div",{className:D.transactionInfo},c.createElement("span",{className:D.transactionLabel},"You Pay:"),c.createElement("span",{className:`${D.transactionValue} ${D.highlight}`},"stablecoin"===r.key?`${a.amount} ${a.tokenSymbol}`:`${b||"Calculating..."} ${a.tokenSymbol}`)),_&&c.createElement("div",{className:D.messageBox},_,P&&c.createElement("button",{onClick:()=>B(!I),className:D.detailsButton},I?"Hide Details":"Show Details")),I&&P&&c.createElement("div",{className:D.errorDetails},c.createElement("pre",null,P.message)),T&&c.createElement("div",{className:D.transactionLink},"Transaction Hash:"," ",L()?c.createElement("a",{href:L(),target:"_blank",rel:"noopener noreferrer",className:D.explorerLink},T.slice(0,6),"...",T.slice(-6)):c.createElement("span",{style:{wordBreak:"break-word"}},T)),"SUCCESS"!==M&&c.createElement("div",{className:D.walletButtonContainer},!s&&c.createElement("button",{className:D.walletButton,onClick:async()=>{await i()},disabled:w},w?"Connecting...":"Connect Wallet"),s&&"IDLE"===M&&c.createElement("button",{className:D.walletButton,onClick:()=>j("CONFIRMING")},"Pay ",a.amount," ",a.tokenSymbol),s&&"CONFIRMING"===M&&c.createElement("div",{className:D.confirmContainer},c.createElement("span",{className:D.confirmText},"Confirm payment?"),c.createElement("div",{className:D.confirmButtons},c.createElement("button",{className:D.secondaryButton,onClick:()=>j("IDLE")},"No"),c.createElement("button",{className:`${D.walletButton} ${D.primaryButton}`,onClick:async()=>{if(!s||!a||!C)return void S("Wallet not connected or transaction details missing");let o;j("PROCESSING"),S("Preparing transaction..."),x(null),A(null);try{const e=a.receivingAddress;if("native"===r.key){const t="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",n=f(String(b||"0"));o=await C.buyStablecoins(s,e,n,t),o={...o,value:n,account:s}}else{const n=t.getSelectedNetworkConfig(),r=n?.tokens?.stablecoin?.address;if(!r)throw new Error("Stablecoin address not found in network configuration");const i=a.amount?E(String(a.amount),a.stableCoinDecimals):"0";o={to:r,value:0n,data:y({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:s}}}catch(e){x(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");return S(`Transaction preparation failed: ${t}`),void j("IDLE")}S("Please check your wallet to confirm the transaction...");try{const i=t.getSelectedNetworkConfig();if(!i)throw new Error("Network configuration not found");const c=await k();if(!c)throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask.");if(!window.ethereum)throw new Error("MetaMask not available");const l=await window.ethereum.request({method:"eth_chainId"}),d=parseInt(l,16);if(d!==i.chainId)throw new Error(`Network mismatch. MetaMask is on chain ${d}, but ${n} requires chain ${i.chainId}. Please switch networks in MetaMask.`);if(c.chain.id!==i.chainId)throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${c.chain.id}, but expected ${i.chainId}.`);const m=await c.sendTransaction({...o,account:s});A(m),S("Transaction sent successfully!"),j("SUCCESS"),e&&e({txHash:m,network:n,token:r?.key,tokenSymbol:r?.symbol,amount:a?.amount,receivingAddress:a?.receivingAddress})}catch(e){x(e);let t="Unknown error";t="UserRejectedRequestError"===e.name||4001===e.code?"User denied transaction":"ContractFunctionRevertedError"===e.name||e.data&&e.data.message?e.shortMessage||e.data?.message||e.message:e.shortMessage||(e.message?e.message.split("\n")[0]:"Transaction failed"),S(`Transaction failed: ${t}`),j("IDLE"),console.error("Transaction error:",e)}}},"Yes, Pay"))),s&&"PROCESSING"===M&&c.createElement("button",{className:D.walletButton,disabled:!0},"Processing...")))},q=({onClose:e,buttonSize:t,onTransactionComplete:n})=>{const{resetSelections:r}=$();return c.createElement(x,{onClose:()=>{r(),e()},size:t},c.createElement(j,null),c.createElement(L,null),c.createElement(W,{onTransactionComplete:n}))},H=({onClose:e,buttonSize:t,networkSelector:n,onTransactionComplete:r})=>c.createElement(M,{networkSelector:n},c.createElement(O,null,c.createElement(q,{onClose:e,buttonSize:t,onTransactionComplete:r}))),G={NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(_).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:N,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!_[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:t="medium",onTransactionComplete:n,onSuccess:r})=>{const[a,o]=m(!1),i=n||r;return c.createElement("div",{className:D.widgetContainer},!a&&c.createElement(P,{onClick:()=>{o(!0)},size:t}),a&&c.createElement(H,{onClose:()=>{o(!1)},buttonSize:t,networkSelector:e,onTransactionComplete:i}))},PayButton:P,Dialog:x,NetworkDropdown:j};export{G as default}; +import{getWeb3 as e,getDjedContract as t,getCoinContracts as n,getDecimals as r,getOracleAddress as a,getOracleContract as o,tradeDataPriceBuySc as i,buyScTx as s}from"djed-sdk";import l,{useContext as c,createContext as d,useState as m,useEffect as u,useRef as h,useCallback as w}from"react";import{defineChain as k,createWalletClient as g,custom as C,createPublicClient as p,http as b,parseEther as f,parseUnits as E,encodeFunctionData as y}from"viem";import{sepolia as v}from"viem/chains";const _={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class N{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e(this.networkUri),this.djedContract=t(this.web3,this.djedAddress);try{const{stableCoin:e,reserveCoin:t}=await n(this.djedContract,this.web3),{scDecimals:i,rcDecimals:s}=await r(e,t);this.stableCoin=e,this.reserveCoin=t,this.scDecimals=i,this.rcDecimals=s,this.oracleContract=await a(this.djedContract).then((e=>o(this.web3,e,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){console.error("[Transaction] Error fetching contract details:",e);if(-32e3===e.code||3===e.code||e.data){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){console.error("[Transaction] Error initializing transaction:",e);if(-32603===e.code||4001===e.code||-32005===e.code||e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(e){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof e)throw new Error("Amount must be a string");try{return(await i(this.djedContract,this.scDecimals,e)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(e,t,n){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await s(this.djedContract,e,t,n,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var S="main_stablePayButton__UA7HC",T="main_logo__ITyEy",A="main_buttonText__N-ewy";const P=({onClick:e,size:t="medium"})=>{const n={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},a=n[t]||n.medium,o=r[t]||r.medium;return l.createElement("button",{className:S,onClick:e,style:a},l.createElement("div",{className:T,style:o}),l.createElement("span",{className:A},"Pay with StablePay"))};var D={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",confirmContainer:"PricingCard_confirmContainer__vNq4n",confirmText:"PricingCard_confirmText__FP0WS",confirmButtons:"PricingCard_confirmButtons__fZ7jt",secondaryButton:"PricingCard_secondaryButton__OTpW4",primaryButton:"PricingCard_primaryButton__bmYo9",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const x=({children:e,onClose:t,size:n="medium"})=>l.createElement("div",{className:D.dialogOverlay},l.createElement("div",{className:`${D.pricingCard} ${D[n]}`},l.createElement("button",{className:D.dialogClose,onClick:t},"×"),l.createElement("div",{className:D.pricingCardHeader},l.createElement("div",{className:D.allianceLogo}),l.createElement("div",{className:D.stablepayTitle},"StablePay")),l.createElement("div",{className:D.pricingCardBody},e)));class B{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const I=d(),M=({children:e,networkSelector:t})=>{const[n]=m((()=>new B(t))),[r,a]=m(null),[o,i]=m(null),[s,c]=m(null),d=()=>{i(null),c(null)};return u((()=>{a(t.selectedNetwork)}),[t.selectedNetwork]),l.createElement(I.Provider,{value:{networkSelector:t,tokenSelector:n,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:c,selectNetwork:e=>!!t.selectNetwork(e)&&(a(e),d(),!0),selectToken:e=>{if(n.selectToken(e)){const e=n.getSelectedToken();return i(e),!0}return!1},resetSelections:()=>{t.selectNetwork(null),a(null),d()}}},e)},$=()=>{const e=c(I);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},j=()=>{const{networkSelector:e,selectedNetwork:t,selectNetwork:n}=$();return l.createElement("div",{className:D.selectField},l.createElement("label",{htmlFor:"network-select"},"Select Network"),l.createElement("select",{id:"network-select",onChange:e=>{n(e.target.value)},value:t||""},l.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>l.createElement("option",{key:e,value:e},e)))))},L=()=>{const{networkSelector:e,tokenSelector:t,selectedNetwork:n,selectedToken:r,selectToken:a,setTransactionDetails:o}=$(),[i,s]=m(!1),[c,d]=m(null),u=n?t.getAvailableTokens():[];return l.createElement("div",{className:D.selectField},l.createElement("label",{htmlFor:"token-select"},"Select Token"),l.createElement("select",{id:"token-select",onChange:async r=>{const i=r.target.value;d(null),s(!0);try{if(a(i)){const r=e.getSelectedNetworkConfig(),a=new N(r.uri,r.djedAddress);await a.init();const s=e.getTokenAmount(i),l=a.getBlockchainDetails();let c=null;"native"===i&&(c=await a.handleTradeDataBuySc(String(s))),o({network:n,token:i,tokenSymbol:t.getSelectedToken().symbol,amount:s,receivingAddress:e.getReceivingAddress(),djedContractAddress:r.djedAddress,isDirectTransfer:t.getSelectedToken().isDirectTransfer||!1,isNativeToken:t.getSelectedToken().isNative||!1,tradeAmount:c?c.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),"undefined"==typeof window||window.ethereum?d("Failed to fetch transaction details. Please try again."):d("No wallet found. Please install a Web3 wallet.")}finally{s(!1)}},value:r?r.key:"",disabled:!n||i},l.createElement("option",{value:"",disabled:!0},n?i?"Loading...":"Select a token":"Please select a network first"),u.map((e=>l.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),c&&l.createElement("div",{className:D.error},c))};k({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const F=k({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),R=k({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),U=d(null),W=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${v.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:v.rpcUrls.default.http,blockExplorerUrls:v.blockExplorers?.default?.url?[v.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${R.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${F.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},z=({children:e})=>{const{selectedNetwork:t}=$(),[n,r]=m(null),[a,o]=m(null),[i,s]=m(null),[c,d]=m(null),[k,f]=m(null),[E,y]=m(null),[_,N]=m(!1),S=t?(e=>{switch(e){case"sepolia":return v;case"ethereum-classic":return R;case"milkomeda-mainnet":return F;default:return null}})(t):null,T=S?S.id:null,A=h(null),P=h(null),D=w((()=>{r(null),o(null),s(null),d(null),f(null),y(null)}),[]),x=w((async e=>{const n=parseInt(e,16);if(d(n),S&&n===T){if(y(null),window.ethereum&&S){const e=g({chain:S,transport:C(window.ethereum)});r(e)}}else if(S&&n!==T){y(`Wrong network detected. Please switch to ${S?.name||t||"selected network"}`)}}),[S,T,t]);P.current=x;const B=w((async e=>{if(0===e.length){if(D(),window.ethereum){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(s(e[0]),S)try{const t=p({chain:S,transport:b()});o(t);const n=await t.getBalance({address:e[0]});f(parseFloat(n)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}}),[S,D]);A.current=B;const I=w((()=>{if(D(),window.ethereum){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[D]),M=w((()=>{S&&o(p({chain:S,transport:b()}))}),[S]),j=w((async()=>{if(!window.ethereum)return y("Please install MetaMask or another Web3 wallet"),!1;if(!t||!S)return y("Please select a network first"),!1;N(!0),y(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const n=await window.ethereum.request({method:"eth_chainId"});parseInt(n,16)!==T&&await W(t);const a=g({chain:S,transport:C(window.ethereum)});r(a),s(e[0]),d(T);const i=p({chain:S,transport:b()});o(i);try{const t=await i.getBalance({address:e[0]});f(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}return A.current=B,P.current=x,window.ethereum.on("accountsChanged",B),window.ethereum.on("chainChanged",x),!0}catch(e){return console.error("Error connecting wallet:",e),y(e.message),!1}finally{N(!1)}}),[t,S,T,B,x]),L=w((async()=>{if(!(window.ethereum&&t&&S&&i)){return y("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==T){y(null),await W(t);const e=500;await new Promise((t=>setTimeout(t,e)));const n=await window.ethereum.request({method:"eth_chainId"}),r=parseInt(n,16);if(r!==T)throw new Error(`Failed to switch network. MetaMask is still on chain ${r}, expected ${T}`)}const n=g({chain:S,transport:C(window.ethereum)});return r(n),d(T),y(null),n}catch(e){return y(e.message),null}}),[t,S,T,i]),z=h(t);return u((()=>{if(null!==z.current&&z.current!==t&&i&&(D(),window.ethereum)){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}z.current=t}),[t,i,D]),u((()=>{M()}),[M]),l.createElement(U.Provider,{value:{walletClient:n,publicClient:a,account:i,chainId:c,balance:k,error:E,isConnecting:_,connectWallet:j,disconnectWallet:I,ensureCorrectNetwork:L,expectedChainId:T}},e)},O=({onTransactionComplete:e})=>{const{networkSelector:t,selectedNetwork:n,selectedToken:r,transactionDetails:a,setTransactionDetails:o}=$(),{connectWallet:i,account:s,walletClient:d,publicClient:h,isConnecting:w,ensureCorrectNetwork:k,expectedChainId:g}=(()=>{const e=c(U);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[C,p]=m(null),[b,v]=m(null),[_,S]=m(""),[T,A]=m(null),[P,x]=m(null),[B,I]=m(!1),[M,j]=m("IDLE");if(u((()=>{v(null),S(""),x(null),A(null),j("IDLE")}),[n,r]),u((()=>{(async()=>{if(n&&r)try{const e=t.getSelectedNetworkConfig(),a=t.getReceivingAddress(),i=t.getTokenAmount(r.key),s=new N(e.uri,e.djedAddress);await s.init(),p(s);let l=null;if("native"===r.key)try{l=await s.handleTradeDataBuySc(String(i)),v(l)}catch(e){console.error("Error fetching trade data:",e)}o({network:n,token:r.key,tokenSymbol:r.symbol,amount:i||"0",receivingAddress:a,djedContractAddress:e.djedAddress,isDirectTransfer:r.isDirectTransfer||!1,isNativeToken:r.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[n,r,t,o]),!n||!r)return null;if(!a)return"undefined"==typeof window||window.ethereum?l.createElement("div",{className:D.loading},"Initializing transaction..."):l.createElement("div",{className:D.transactionReview},l.createElement("div",{className:D.messageBox,style:{textAlign:"center",marginBottom:"1rem",color:"#ff4d4f"}},"No wallet found."),l.createElement("div",{className:D.walletButtonContainer},l.createElement("button",{className:D.walletButton,onClick:()=>window.open("https://metamask.io/download/","_blank")},"Connect Wallet")));const L=()=>{if(!T||!n)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[n]?`${e[n]}${T}`:null};return l.createElement("div",{className:D.transactionReview},l.createElement("div",{className:D.transactionInfo},l.createElement("span",{className:D.transactionLabel},"Network:"),l.createElement("span",{className:D.transactionValue},a.network)),l.createElement("div",{className:D.transactionInfo},l.createElement("span",{className:D.transactionLabel},"You Pay:"),l.createElement("span",{className:`${D.transactionValue} ${D.highlight}`},"stablecoin"===r.key?`${a.amount} ${a.tokenSymbol}`:`${b||"Calculating..."} ${a.tokenSymbol}`)),_&&l.createElement("div",{className:D.messageBox},_,P&&l.createElement("button",{onClick:()=>I(!B),className:D.detailsButton},B?"Hide Details":"Show Details")),B&&P&&l.createElement("div",{className:D.errorDetails},l.createElement("pre",null,P.message)),T&&l.createElement("div",{className:D.transactionLink},"Transaction Hash:"," ",L()?l.createElement("a",{href:L(),target:"_blank",rel:"noopener noreferrer",className:D.explorerLink},T.slice(0,6),"...",T.slice(-6)):l.createElement("span",{style:{wordBreak:"break-word"}},T)),"SUCCESS"!==M&&l.createElement("div",{className:D.walletButtonContainer},!s&&l.createElement("button",{className:D.walletButton,onClick:async()=>{await i()},disabled:w},w?"Connecting...":"Connect Wallet"),s&&"IDLE"===M&&l.createElement("button",{className:D.walletButton,onClick:()=>j("CONFIRMING")},"Pay ",a.amount," ",a.tokenSymbol),s&&"CONFIRMING"===M&&l.createElement("div",{className:D.confirmContainer},l.createElement("span",{className:D.confirmText},"Confirm payment?"),l.createElement("div",{className:D.confirmButtons},l.createElement("button",{className:D.secondaryButton,onClick:()=>j("IDLE")},"No"),l.createElement("button",{className:`${D.walletButton} ${D.primaryButton}`,onClick:async()=>{if(!s||!a||!C)return void S("Wallet not connected or transaction details missing");let o;j("PROCESSING"),S("Preparing transaction..."),x(null),A(null);try{const e=a.receivingAddress;if("native"===r.key){const t="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",n=f(String(b||"0"));o=await C.buyStablecoins(s,e,n,t),o={...o,value:n,account:s}}else{const n=t.getSelectedNetworkConfig(),r=n?.tokens?.stablecoin?.address;if(!r)throw new Error("Stablecoin address not found in network configuration");const i=a.amount?E(String(a.amount),a.stableCoinDecimals):"0";o={to:r,value:0n,data:y({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:s}}}catch(e){x(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");return S(`Transaction preparation failed: ${t}`),void j("IDLE")}S("Please check your wallet to confirm the transaction...");try{const i=t.getSelectedNetworkConfig();if(!i)throw new Error("Network configuration not found");const l=await k();if(!l)throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask.");if(!window.ethereum)throw new Error("MetaMask not available");const c=await window.ethereum.request({method:"eth_chainId"}),d=parseInt(c,16);if(d!==i.chainId)throw new Error(`Network mismatch. MetaMask is on chain ${d}, but ${n} requires chain ${i.chainId}. Please switch networks in MetaMask.`);if(l.chain.id!==i.chainId)throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${l.chain.id}, but expected ${i.chainId}.`);const m=await l.sendTransaction({...o,account:s});A(m),S("Transaction sent successfully!"),j("SUCCESS"),e&&e({txHash:m,network:n,token:r?.key,tokenSymbol:r?.symbol,amount:a?.amount,receivingAddress:a?.receivingAddress})}catch(e){x(e);let t="Unknown error";t="UserRejectedRequestError"===e.name||4001===e.code?"User denied transaction":"ContractFunctionRevertedError"===e.name||e.data&&e.data.message?e.shortMessage||e.data?.message||e.message:e.shortMessage||(e.message?e.message.split("\n")[0]:"Transaction failed"),S(`Transaction failed: ${t}`),j("IDLE"),console.error("Transaction error:",e)}}},"Yes, Pay"))),s&&"PROCESSING"===M&&l.createElement("button",{className:D.walletButton,disabled:!0},"Processing...")))},q=({onClose:e,buttonSize:t,onTransactionComplete:n})=>{const{resetSelections:r}=$();return l.createElement(x,{onClose:()=>{r(),e()},size:t},l.createElement(j,null),l.createElement(L,null),l.createElement(O,{onTransactionComplete:n}))},H=({onClose:e,buttonSize:t,networkSelector:n,onTransactionComplete:r})=>l.createElement(M,{networkSelector:n},l.createElement(z,null,l.createElement(q,{onClose:e,buttonSize:t,onTransactionComplete:r}))),G={NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(_).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:N,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!_[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:t="medium",onTransactionComplete:n,onSuccess:r})=>{const[a,o]=m(!1),i=n||r;return l.createElement("div",{className:D.widgetContainer},!a&&l.createElement(P,{onClick:()=>{o(!0)},size:t}),a&&l.createElement(H,{onClose:()=>{o(!1)},buttonSize:t,networkSelector:e,onTransactionComplete:i}))},PayButton:P,Dialog:x,NetworkDropdown:j};export{G as default}; diff --git a/stablepay-sdk/dist/umd/index.js b/stablepay-sdk/dist/umd/index.js index ba50753..1b89058 100644 --- a/stablepay-sdk/dist/umd/index.js +++ b/stablepay-sdk/dist/umd/index.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("djed-sdk"),require("react"),require("viem"),require("viem/chains")):"function"==typeof define&&define.amd?define(["djed-sdk","react","viem","viem/chains"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).StablePay=t(e.DjedSdk,e.React,e.viem,e.viemChains)}(this,(function(e,t,n,a){"use strict";const r={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class o{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e.getWeb3(this.networkUri),this.djedContract=e.getDjedContract(this.web3,this.djedAddress);try{const{stableCoin:t,reserveCoin:n}=await e.getCoinContracts(this.djedContract,this.web3),{scDecimals:a,rcDecimals:r}=await e.getDecimals(t,n);this.stableCoin=t,this.reserveCoin=n,this.scDecimals=a,this.rcDecimals=r,this.oracleContract=await e.getOracleAddress(this.djedContract).then((t=>e.getOracleContract(this.web3,t,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){console.error("[Transaction] Error fetching contract details:",e);if(-32e3===e.code||3===e.code||e.data){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){console.error("[Transaction] Error initializing transaction:",e);if(-32603===e.code||4001===e.code||-32005===e.code||e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(t){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof t)throw new Error("Amount must be a string");try{return(await e.tradeDataPriceBuySc(this.djedContract,this.scDecimals,t)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(t,n,a){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await e.buyScTx(this.djedContract,t,n,a,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var i="main_stablePayButton__UA7HC",s="main_logo__ITyEy",c="main_buttonText__N-ewy";const l=({onClick:e,size:n="medium"})=>{const a={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},o=a[n]||a.medium,l=r[n]||r.medium;return t.createElement("button",{className:i,onClick:e,style:o},t.createElement("div",{className:s,style:l}),t.createElement("span",{className:c},"Pay with StablePay"))};var d={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",confirmContainer:"PricingCard_confirmContainer__vNq4n",confirmText:"PricingCard_confirmText__FP0WS",confirmButtons:"PricingCard_confirmButtons__fZ7jt",secondaryButton:"PricingCard_secondaryButton__OTpW4",primaryButton:"PricingCard_primaryButton__bmYo9",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const u=({children:e,onClose:n,size:a="medium"})=>t.createElement("div",{className:d.dialogOverlay},t.createElement("div",{className:`${d.pricingCard} ${d[a]}`},t.createElement("button",{className:d.dialogClose,onClick:n},"×"),t.createElement("div",{className:d.pricingCardHeader},t.createElement("div",{className:d.allianceLogo}),t.createElement("div",{className:d.stablepayTitle},"StablePay")),t.createElement("div",{className:d.pricingCardBody},e)));class m{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const h=t.createContext(),w=({children:e,networkSelector:n})=>{const[a]=t.useState((()=>new m(n))),[r,o]=t.useState(null),[i,s]=t.useState(null),[c,l]=t.useState(null),d=()=>{s(null),l(null)};return t.useEffect((()=>{o(n.selectedNetwork)}),[n.selectedNetwork]),t.createElement(h.Provider,{value:{networkSelector:n,tokenSelector:a,selectedNetwork:r,selectedToken:i,transactionDetails:c,setTransactionDetails:l,selectNetwork:e=>!!n.selectNetwork(e)&&(o(e),d(),!0),selectToken:e=>{if(a.selectToken(e)){const e=a.getSelectedToken();return s(e),!0}return!1},resetSelections:()=>{n.selectNetwork(null),o(null),d()}}},e)},k=()=>{const e=t.useContext(h);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},g=()=>{const{networkSelector:e,selectedNetwork:n,selectNetwork:a}=k();return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"network-select"},"Select Network"),t.createElement("select",{id:"network-select",onChange:e=>{a(e.target.value)},value:n||""},t.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>t.createElement("option",{key:e,value:e},e)))))},C=()=>{const{networkSelector:e,tokenSelector:n,selectedNetwork:a,selectedToken:r,selectToken:i,setTransactionDetails:s}=k(),[c,l]=t.useState(!1),[u,m]=t.useState(null),h=a?n.getAvailableTokens():[];return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"token-select"},"Select Token"),t.createElement("select",{id:"token-select",onChange:async t=>{const r=t.target.value;m(null),l(!0);try{if(i(r)){const t=e.getSelectedNetworkConfig(),i=new o(t.uri,t.djedAddress);await i.init();const c=e.getTokenAmount(r),l=i.getBlockchainDetails();let d=null;"native"===r&&(d=await i.handleTradeDataBuySc(String(c))),s({network:a,token:r,tokenSymbol:n.getSelectedToken().symbol,amount:c,receivingAddress:e.getReceivingAddress(),djedContractAddress:t.djedAddress,isDirectTransfer:n.getSelectedToken().isDirectTransfer||!1,isNativeToken:n.getSelectedToken().isNative||!1,tradeAmount:d?d.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),m("Failed to fetch transaction details. Please try again.")}finally{l(!1)}},value:r?r.key:"",disabled:!a||c},t.createElement("option",{value:"",disabled:!0},a?c?"Loading...":"Select a token":"Please select a network first"),h.map((e=>t.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),u&&t.createElement("div",{className:d.error},u))};n.defineChain({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const p=n.defineChain({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),b=n.defineChain({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),f=t.createContext(null),E=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${a.sepolia.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:a.sepolia.rpcUrls.default.http,blockExplorerUrls:a.sepolia.blockExplorers?.default?.url?[a.sepolia.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${b.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${p.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},y=({children:e})=>{const{selectedNetwork:r}=k(),[o,i]=t.useState(null),[s,c]=t.useState(null),[l,d]=t.useState(null),[u,m]=t.useState(null),[h,w]=t.useState(null),[g,C]=t.useState(null),[y,v]=t.useState(!1),_=r?(e=>{switch(e){case"sepolia":return a.sepolia;case"ethereum-classic":return b;case"milkomeda-mainnet":return p;default:return null}})(r):null,N=_?_.id:null,S=t.useRef(null),T=t.useRef(null),P=t.useCallback((()=>{i(null),c(null),d(null),m(null),w(null),C(null)}),[]),A=t.useCallback((async e=>{const t=parseInt(e,16);if(m(t),_&&t===N){if(C(null),window.ethereum&&_){const e=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});i(e)}}else if(_&&t!==N){C(`Wrong network detected. Please switch to ${_?.name||r||"selected network"}`)}}),[_,N,r]);T.current=A;const D=t.useCallback((async e=>{if(0===e.length){if(P(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(d(e[0]),_)try{const t=n.createPublicClient({chain:_,transport:n.http()});c(t);const a=await t.getBalance({address:e[0]});w(parseFloat(a)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}}),[_,P]);S.current=D;const x=t.useCallback((()=>{if(P(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[P]),I=t.useCallback((()=>{_&&c(n.createPublicClient({chain:_,transport:n.http()}))}),[_]),B=t.useCallback((async()=>{if(!window.ethereum)return C("Please install MetaMask or another Web3 wallet"),!1;if(!r||!_)return C("Please select a network first"),!1;v(!0),C(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const t=await window.ethereum.request({method:"eth_chainId"});parseInt(t,16)!==N&&await E(r);const a=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});i(a),d(e[0]),m(N);const o=n.createPublicClient({chain:_,transport:n.http()});c(o);try{const t=await o.getBalance({address:e[0]});w(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}return S.current=D,T.current=A,window.ethereum.on("accountsChanged",D),window.ethereum.on("chainChanged",A),!0}catch(e){return console.error("Error connecting wallet:",e),C(e.message),!1}finally{v(!1)}}),[r,_,N,D,A]),M=t.useCallback((async()=>{if(!(window.ethereum&&r&&_&&l)){return C("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==N){C(null),await E(r);const e=500;await new Promise((t=>setTimeout(t,e)));const t=await window.ethereum.request({method:"eth_chainId"}),n=parseInt(t,16);if(n!==N)throw new Error(`Failed to switch network. MetaMask is still on chain ${n}, expected ${N}`)}const t=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});return i(t),m(N),C(null),t}catch(e){return C(e.message),null}}),[r,_,N,l]),j=t.useRef(r);return t.useEffect((()=>{if(null!==j.current&&j.current!==r&&l&&(P(),window.ethereum)){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}j.current=r}),[r,l,P]),t.useEffect((()=>{I()}),[I]),t.createElement(f.Provider,{value:{walletClient:o,publicClient:s,account:l,chainId:u,balance:h,error:g,isConnecting:y,connectWallet:B,disconnectWallet:x,ensureCorrectNetwork:M,expectedChainId:N}},e)},v=({onTransactionComplete:e})=>{const{networkSelector:a,selectedNetwork:r,selectedToken:i,transactionDetails:s,setTransactionDetails:c}=k(),{connectWallet:l,account:u,walletClient:m,publicClient:h,isConnecting:w,ensureCorrectNetwork:g,expectedChainId:C}=(()=>{const e=t.useContext(f);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[p,b]=t.useState(null),[E,y]=t.useState(null),[v,_]=t.useState(""),[N,S]=t.useState(null),[T,P]=t.useState(null),[A,D]=t.useState(!1),[x,I]=t.useState("IDLE");if(t.useEffect((()=>{y(null),_(""),P(null),S(null),I("IDLE")}),[r,i]),t.useEffect((()=>{(async()=>{if(r&&i)try{const e=a.getSelectedNetworkConfig(),t=a.getReceivingAddress(),n=a.getTokenAmount(i.key),s=new o(e.uri,e.djedAddress);await s.init(),b(s);let l=null;if("native"===i.key)try{l=await s.handleTradeDataBuySc(String(n)),y(l)}catch(e){console.error("Error fetching trade data:",e)}c({network:r,token:i.key,tokenSymbol:i.symbol,amount:n||"0",receivingAddress:t,djedContractAddress:e.djedAddress,isDirectTransfer:i.isDirectTransfer||!1,isNativeToken:i.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[r,i,a,c]),!r||!i)return null;if(!s)return t.createElement("div",{className:d.loading},"Initializing transaction...");const B=()=>{if(!N||!r)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[r]?`${e[r]}${N}`:null};return t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"Network:"),t.createElement("span",{className:d.transactionValue},s.network)),t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"You Pay:"),t.createElement("span",{className:`${d.transactionValue} ${d.highlight}`},"stablecoin"===i.key?`${s.amount} ${s.tokenSymbol}`:`${E||"Calculating..."} ${s.tokenSymbol}`)),v&&t.createElement("div",{className:d.messageBox},v,T&&t.createElement("button",{onClick:()=>D(!A),className:d.detailsButton},A?"Hide Details":"Show Details")),A&&T&&t.createElement("div",{className:d.errorDetails},t.createElement("pre",null,T.message)),N&&t.createElement("div",{className:d.transactionLink},"Transaction Hash:"," ",B()?t.createElement("a",{href:B(),target:"_blank",rel:"noopener noreferrer",className:d.explorerLink},N.slice(0,6),"...",N.slice(-6)):t.createElement("span",{style:{wordBreak:"break-word"}},N)),"SUCCESS"!==x&&t.createElement("div",{className:d.walletButtonContainer},!u&&t.createElement("button",{className:d.walletButton,onClick:async()=>{await l()},disabled:w},w?"Connecting...":"Connect Wallet"),u&&"IDLE"===x&&t.createElement("button",{className:d.walletButton,onClick:()=>I("CONFIRMING")},"Pay ",s.amount," ",s.tokenSymbol),u&&"CONFIRMING"===x&&t.createElement("div",{className:d.confirmContainer},t.createElement("span",{className:d.confirmText},"Confirm payment?"),t.createElement("div",{className:d.confirmButtons},t.createElement("button",{className:d.secondaryButton,onClick:()=>I("IDLE")},"No"),t.createElement("button",{className:`${d.walletButton} ${d.primaryButton}`,onClick:async()=>{if(!u||!s||!p)return void _("Wallet not connected or transaction details missing");let t;I("PROCESSING"),_("Preparing transaction..."),P(null),S(null);try{const e=s.receivingAddress;if("native"===i.key){const a="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=E||"0",o=n.parseEther(String(r));t=await p.buyStablecoins(u,e,o,a),t={...t,value:o,account:u}}else{const r=a.getSelectedNetworkConfig(),o=r?.tokens?.stablecoin?.address;if(!o)throw new Error("Stablecoin address not found in network configuration");const i=s.amount?n.parseUnits(String(s.amount),s.stableCoinDecimals):"0";t={to:o,value:0n,data:n.encodeFunctionData({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:u}}}catch(e){P(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");return _(`Transaction preparation failed: ${t}`),void I("IDLE")}_("Please check your wallet to confirm the transaction...");try{const n=a.getSelectedNetworkConfig();if(!n)throw new Error("Network configuration not found");const o=await g();if(!o)throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask.");if(!window.ethereum)throw new Error("MetaMask not available");const c=await window.ethereum.request({method:"eth_chainId"}),l=parseInt(c,16);if(l!==n.chainId)throw new Error(`Network mismatch. MetaMask is on chain ${l}, but ${r} requires chain ${n.chainId}. Please switch networks in MetaMask.`);if(o.chain.id!==n.chainId)throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${o.chain.id}, but expected ${n.chainId}.`);const d=await o.sendTransaction({...t,account:u});S(d),_("Transaction sent successfully!"),I("SUCCESS"),e&&e({txHash:d,network:r,token:i?.key,tokenSymbol:i?.symbol,amount:s?.amount,receivingAddress:s?.receivingAddress})}catch(e){P(e);let t="Unknown error";t="UserRejectedRequestError"===e.name||4001===e.code?"User denied transaction":"ContractFunctionRevertedError"===e.name||e.data&&e.data.message?e.shortMessage||e.data?.message||e.message:e.shortMessage||(e.message?e.message.split("\n")[0]:"Transaction failed"),_(`Transaction failed: ${t}`),I("IDLE"),console.error("Transaction error:",e)}}},"Yes, Pay"))),u&&"PROCESSING"===x&&t.createElement("button",{className:d.walletButton,disabled:!0},"Processing...")))},_=({onClose:e,buttonSize:n,onTransactionComplete:a})=>{const{resetSelections:r}=k();return t.createElement(u,{onClose:()=>{r(),e()},size:n},t.createElement(g,null),t.createElement(C,null),t.createElement(v,{onTransactionComplete:a}))},N=({onClose:e,buttonSize:n,networkSelector:a,onTransactionComplete:r})=>t.createElement(w,{networkSelector:a},t.createElement(y,null,t.createElement(_,{onClose:e,buttonSize:n,onTransactionComplete:r})));return{NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(r).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:o,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!r[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:n="medium",onTransactionComplete:a,onSuccess:r})=>{const[o,i]=t.useState(!1),s=a||r;return t.createElement("div",{className:d.widgetContainer},!o&&t.createElement(l,{onClick:()=>{i(!0)},size:n}),o&&t.createElement(N,{onClose:()=>{i(!1)},buttonSize:n,networkSelector:e,onTransactionComplete:s}))},PayButton:l,Dialog:u,NetworkDropdown:g}})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("djed-sdk"),require("react"),require("viem"),require("viem/chains")):"function"==typeof define&&define.amd?define(["djed-sdk","react","viem","viem/chains"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).StablePay=t(e.DjedSdk,e.React,e.viem,e.viemChains)}(this,(function(e,t,n,a){"use strict";const r={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class o{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e.getWeb3(this.networkUri),this.djedContract=e.getDjedContract(this.web3,this.djedAddress);try{const{stableCoin:t,reserveCoin:n}=await e.getCoinContracts(this.djedContract,this.web3),{scDecimals:a,rcDecimals:r}=await e.getDecimals(t,n);this.stableCoin=t,this.reserveCoin=n,this.scDecimals=a,this.rcDecimals=r,this.oracleContract=await e.getOracleAddress(this.djedContract).then((t=>e.getOracleContract(this.web3,t,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){console.error("[Transaction] Error fetching contract details:",e);if(-32e3===e.code||3===e.code||e.data){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){console.error("[Transaction] Error initializing transaction:",e);if(-32603===e.code||4001===e.code||-32005===e.code||e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(t){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof t)throw new Error("Amount must be a string");try{return(await e.tradeDataPriceBuySc(this.djedContract,this.scDecimals,t)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(t,n,a){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await e.buyScTx(this.djedContract,t,n,a,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var i="main_stablePayButton__UA7HC",s="main_logo__ITyEy",l="main_buttonText__N-ewy";const c=({onClick:e,size:n="medium"})=>{const a={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},o=a[n]||a.medium,c=r[n]||r.medium;return t.createElement("button",{className:i,onClick:e,style:o},t.createElement("div",{className:s,style:c}),t.createElement("span",{className:l},"Pay with StablePay"))};var d={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",confirmContainer:"PricingCard_confirmContainer__vNq4n",confirmText:"PricingCard_confirmText__FP0WS",confirmButtons:"PricingCard_confirmButtons__fZ7jt",secondaryButton:"PricingCard_secondaryButton__OTpW4",primaryButton:"PricingCard_primaryButton__bmYo9",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const u=({children:e,onClose:n,size:a="medium"})=>t.createElement("div",{className:d.dialogOverlay},t.createElement("div",{className:`${d.pricingCard} ${d[a]}`},t.createElement("button",{className:d.dialogClose,onClick:n},"×"),t.createElement("div",{className:d.pricingCardHeader},t.createElement("div",{className:d.allianceLogo}),t.createElement("div",{className:d.stablepayTitle},"StablePay")),t.createElement("div",{className:d.pricingCardBody},e)));class m{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const h=t.createContext(),w=({children:e,networkSelector:n})=>{const[a]=t.useState((()=>new m(n))),[r,o]=t.useState(null),[i,s]=t.useState(null),[l,c]=t.useState(null),d=()=>{s(null),c(null)};return t.useEffect((()=>{o(n.selectedNetwork)}),[n.selectedNetwork]),t.createElement(h.Provider,{value:{networkSelector:n,tokenSelector:a,selectedNetwork:r,selectedToken:i,transactionDetails:l,setTransactionDetails:c,selectNetwork:e=>!!n.selectNetwork(e)&&(o(e),d(),!0),selectToken:e=>{if(a.selectToken(e)){const e=a.getSelectedToken();return s(e),!0}return!1},resetSelections:()=>{n.selectNetwork(null),o(null),d()}}},e)},k=()=>{const e=t.useContext(h);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},g=()=>{const{networkSelector:e,selectedNetwork:n,selectNetwork:a}=k();return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"network-select"},"Select Network"),t.createElement("select",{id:"network-select",onChange:e=>{a(e.target.value)},value:n||""},t.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>t.createElement("option",{key:e,value:e},e)))))},C=()=>{const{networkSelector:e,tokenSelector:n,selectedNetwork:a,selectedToken:r,selectToken:i,setTransactionDetails:s}=k(),[l,c]=t.useState(!1),[u,m]=t.useState(null),h=a?n.getAvailableTokens():[];return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"token-select"},"Select Token"),t.createElement("select",{id:"token-select",onChange:async t=>{const r=t.target.value;m(null),c(!0);try{if(i(r)){const t=e.getSelectedNetworkConfig(),i=new o(t.uri,t.djedAddress);await i.init();const l=e.getTokenAmount(r),c=i.getBlockchainDetails();let d=null;"native"===r&&(d=await i.handleTradeDataBuySc(String(l))),s({network:a,token:r,tokenSymbol:n.getSelectedToken().symbol,amount:l,receivingAddress:e.getReceivingAddress(),djedContractAddress:t.djedAddress,isDirectTransfer:n.getSelectedToken().isDirectTransfer||!1,isNativeToken:n.getSelectedToken().isNative||!1,tradeAmount:d?d.amount:null,...c})}}catch(e){console.error("Error fetching transaction details:",e),"undefined"==typeof window||window.ethereum?m("Failed to fetch transaction details. Please try again."):m("No wallet found. Please install a Web3 wallet.")}finally{c(!1)}},value:r?r.key:"",disabled:!a||l},t.createElement("option",{value:"",disabled:!0},a?l?"Loading...":"Select a token":"Please select a network first"),h.map((e=>t.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),u&&t.createElement("div",{className:d.error},u))};n.defineChain({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const f=n.defineChain({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),p=n.defineChain({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),b=t.createContext(null),E=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${a.sepolia.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:a.sepolia.rpcUrls.default.http,blockExplorerUrls:a.sepolia.blockExplorers?.default?.url?[a.sepolia.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${p.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${f.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},y=({children:e})=>{const{selectedNetwork:r}=k(),[o,i]=t.useState(null),[s,l]=t.useState(null),[c,d]=t.useState(null),[u,m]=t.useState(null),[h,w]=t.useState(null),[g,C]=t.useState(null),[y,v]=t.useState(!1),_=r?(e=>{switch(e){case"sepolia":return a.sepolia;case"ethereum-classic":return p;case"milkomeda-mainnet":return f;default:return null}})(r):null,N=_?_.id:null,S=t.useRef(null),T=t.useRef(null),P=t.useCallback((()=>{i(null),l(null),d(null),m(null),w(null),C(null)}),[]),A=t.useCallback((async e=>{const t=parseInt(e,16);if(m(t),_&&t===N){if(C(null),window.ethereum&&_){const e=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});i(e)}}else if(_&&t!==N){C(`Wrong network detected. Please switch to ${_?.name||r||"selected network"}`)}}),[_,N,r]);T.current=A;const D=t.useCallback((async e=>{if(0===e.length){if(P(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(d(e[0]),_)try{const t=n.createPublicClient({chain:_,transport:n.http()});l(t);const a=await t.getBalance({address:e[0]});w(parseFloat(a)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}}),[_,P]);S.current=D;const x=t.useCallback((()=>{if(P(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[P]),B=t.useCallback((()=>{_&&l(n.createPublicClient({chain:_,transport:n.http()}))}),[_]),I=t.useCallback((async()=>{if(!window.ethereum)return C("Please install MetaMask or another Web3 wallet"),!1;if(!r||!_)return C("Please select a network first"),!1;v(!0),C(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const t=await window.ethereum.request({method:"eth_chainId"});parseInt(t,16)!==N&&await E(r);const a=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});i(a),d(e[0]),m(N);const o=n.createPublicClient({chain:_,transport:n.http()});l(o);try{const t=await o.getBalance({address:e[0]});w(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}return S.current=D,T.current=A,window.ethereum.on("accountsChanged",D),window.ethereum.on("chainChanged",A),!0}catch(e){return console.error("Error connecting wallet:",e),C(e.message),!1}finally{v(!1)}}),[r,_,N,D,A]),M=t.useCallback((async()=>{if(!(window.ethereum&&r&&_&&c)){return C("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==N){C(null),await E(r);const e=500;await new Promise((t=>setTimeout(t,e)));const t=await window.ethereum.request({method:"eth_chainId"}),n=parseInt(t,16);if(n!==N)throw new Error(`Failed to switch network. MetaMask is still on chain ${n}, expected ${N}`)}const t=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});return i(t),m(N),C(null),t}catch(e){return C(e.message),null}}),[r,_,N,c]),j=t.useRef(r);return t.useEffect((()=>{if(null!==j.current&&j.current!==r&&c&&(P(),window.ethereum)){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}j.current=r}),[r,c,P]),t.useEffect((()=>{B()}),[B]),t.createElement(b.Provider,{value:{walletClient:o,publicClient:s,account:c,chainId:u,balance:h,error:g,isConnecting:y,connectWallet:I,disconnectWallet:x,ensureCorrectNetwork:M,expectedChainId:N}},e)},v=({onTransactionComplete:e})=>{const{networkSelector:a,selectedNetwork:r,selectedToken:i,transactionDetails:s,setTransactionDetails:l}=k(),{connectWallet:c,account:u,walletClient:m,publicClient:h,isConnecting:w,ensureCorrectNetwork:g,expectedChainId:C}=(()=>{const e=t.useContext(b);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[f,p]=t.useState(null),[E,y]=t.useState(null),[v,_]=t.useState(""),[N,S]=t.useState(null),[T,P]=t.useState(null),[A,D]=t.useState(!1),[x,B]=t.useState("IDLE");if(t.useEffect((()=>{y(null),_(""),P(null),S(null),B("IDLE")}),[r,i]),t.useEffect((()=>{(async()=>{if(r&&i)try{const e=a.getSelectedNetworkConfig(),t=a.getReceivingAddress(),n=a.getTokenAmount(i.key),s=new o(e.uri,e.djedAddress);await s.init(),p(s);let c=null;if("native"===i.key)try{c=await s.handleTradeDataBuySc(String(n)),y(c)}catch(e){console.error("Error fetching trade data:",e)}l({network:r,token:i.key,tokenSymbol:i.symbol,amount:n||"0",receivingAddress:t,djedContractAddress:e.djedAddress,isDirectTransfer:i.isDirectTransfer||!1,isNativeToken:i.isNative||!1,tradeAmount:c?c.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[r,i,a,l]),!r||!i)return null;if(!s)return"undefined"==typeof window||window.ethereum?t.createElement("div",{className:d.loading},"Initializing transaction..."):t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.messageBox,style:{textAlign:"center",marginBottom:"1rem",color:"#ff4d4f"}},"No wallet found."),t.createElement("div",{className:d.walletButtonContainer},t.createElement("button",{className:d.walletButton,onClick:()=>window.open("https://metamask.io/download/","_blank")},"Connect Wallet")));const I=()=>{if(!N||!r)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[r]?`${e[r]}${N}`:null};return t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"Network:"),t.createElement("span",{className:d.transactionValue},s.network)),t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"You Pay:"),t.createElement("span",{className:`${d.transactionValue} ${d.highlight}`},"stablecoin"===i.key?`${s.amount} ${s.tokenSymbol}`:`${E||"Calculating..."} ${s.tokenSymbol}`)),v&&t.createElement("div",{className:d.messageBox},v,T&&t.createElement("button",{onClick:()=>D(!A),className:d.detailsButton},A?"Hide Details":"Show Details")),A&&T&&t.createElement("div",{className:d.errorDetails},t.createElement("pre",null,T.message)),N&&t.createElement("div",{className:d.transactionLink},"Transaction Hash:"," ",I()?t.createElement("a",{href:I(),target:"_blank",rel:"noopener noreferrer",className:d.explorerLink},N.slice(0,6),"...",N.slice(-6)):t.createElement("span",{style:{wordBreak:"break-word"}},N)),"SUCCESS"!==x&&t.createElement("div",{className:d.walletButtonContainer},!u&&t.createElement("button",{className:d.walletButton,onClick:async()=>{await c()},disabled:w},w?"Connecting...":"Connect Wallet"),u&&"IDLE"===x&&t.createElement("button",{className:d.walletButton,onClick:()=>B("CONFIRMING")},"Pay ",s.amount," ",s.tokenSymbol),u&&"CONFIRMING"===x&&t.createElement("div",{className:d.confirmContainer},t.createElement("span",{className:d.confirmText},"Confirm payment?"),t.createElement("div",{className:d.confirmButtons},t.createElement("button",{className:d.secondaryButton,onClick:()=>B("IDLE")},"No"),t.createElement("button",{className:`${d.walletButton} ${d.primaryButton}`,onClick:async()=>{if(!u||!s||!f)return void _("Wallet not connected or transaction details missing");let t;B("PROCESSING"),_("Preparing transaction..."),P(null),S(null);try{const e=s.receivingAddress;if("native"===i.key){const a="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=E||"0",o=n.parseEther(String(r));t=await f.buyStablecoins(u,e,o,a),t={...t,value:o,account:u}}else{const r=a.getSelectedNetworkConfig(),o=r?.tokens?.stablecoin?.address;if(!o)throw new Error("Stablecoin address not found in network configuration");const i=s.amount?n.parseUnits(String(s.amount),s.stableCoinDecimals):"0";t={to:o,value:0n,data:n.encodeFunctionData({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:u}}}catch(e){P(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");return _(`Transaction preparation failed: ${t}`),void B("IDLE")}_("Please check your wallet to confirm the transaction...");try{const n=a.getSelectedNetworkConfig();if(!n)throw new Error("Network configuration not found");const o=await g();if(!o)throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask.");if(!window.ethereum)throw new Error("MetaMask not available");const l=await window.ethereum.request({method:"eth_chainId"}),c=parseInt(l,16);if(c!==n.chainId)throw new Error(`Network mismatch. MetaMask is on chain ${c}, but ${r} requires chain ${n.chainId}. Please switch networks in MetaMask.`);if(o.chain.id!==n.chainId)throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${o.chain.id}, but expected ${n.chainId}.`);const d=await o.sendTransaction({...t,account:u});S(d),_("Transaction sent successfully!"),B("SUCCESS"),e&&e({txHash:d,network:r,token:i?.key,tokenSymbol:i?.symbol,amount:s?.amount,receivingAddress:s?.receivingAddress})}catch(e){P(e);let t="Unknown error";t="UserRejectedRequestError"===e.name||4001===e.code?"User denied transaction":"ContractFunctionRevertedError"===e.name||e.data&&e.data.message?e.shortMessage||e.data?.message||e.message:e.shortMessage||(e.message?e.message.split("\n")[0]:"Transaction failed"),_(`Transaction failed: ${t}`),B("IDLE"),console.error("Transaction error:",e)}}},"Yes, Pay"))),u&&"PROCESSING"===x&&t.createElement("button",{className:d.walletButton,disabled:!0},"Processing...")))},_=({onClose:e,buttonSize:n,onTransactionComplete:a})=>{const{resetSelections:r}=k();return t.createElement(u,{onClose:()=>{r(),e()},size:n},t.createElement(g,null),t.createElement(C,null),t.createElement(v,{onTransactionComplete:a}))},N=({onClose:e,buttonSize:n,networkSelector:a,onTransactionComplete:r})=>t.createElement(w,{networkSelector:a},t.createElement(y,null,t.createElement(_,{onClose:e,buttonSize:n,onTransactionComplete:r})));return{NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(r).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:o,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!r[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:n="medium",onTransactionComplete:a,onSuccess:r})=>{const[o,i]=t.useState(!1),s=a||r;return t.createElement("div",{className:d.widgetContainer},!o&&t.createElement(c,{onClick:()=>{i(!0)},size:n}),o&&t.createElement(N,{onClose:()=>{i(!1)},buttonSize:n,networkSelector:e,onTransactionComplete:s}))},PayButton:c,Dialog:u,NetworkDropdown:g}})); //# sourceMappingURL=index.js.map diff --git a/stablepay-sdk/dist/umd/index.js.map b/stablepay-sdk/dist/umd/index.js.map index 097fb36..3fe71b7 100644 --- a/stablepay-sdk/dist/umd/index.js.map +++ b/stablepay-sdk/dist/umd/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../../src/utils/config.js","../../src/core/Transaction.js","../../src/widget/PayButton.jsx","../../src/widget/Dialog.jsx","../../src/core/TokenSelector.js","../../src/contexts/NetworkContext.jsx","../../src/widget/NetworkDropdown.jsx","../../src/widget/TokenDropdown.jsx","../../src/contexts/chains.js","../../src/contexts/WalletContext.jsx","../../src/widget/TransactionReview.jsx","../../src/widget/Widget.jsx","../../src/index.js","../../src/core/NetworkSelector.js","../../src/core/MerchantConfig.js"],"sourcesContent":["// src/utils/config.js\nexport const networksConfig = {\n 'sepolia': {\n uri: 'https://ethereum-sepolia.publicnode.com/',\n chainId: 11155111,\n djedAddress: '0x624FcD0a1F9B5820c950FefD48087531d38387f4',\n tokens: {\n stablecoin: {\n symbol: 'SOD',\n address: '0x6b930182787F346F18666D167e8d32166dC5eFBD',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETH',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'milkomeda-mainnet': {\n uri: 'https://rpc-mainnet-cardano-evm.c1.milkomeda.com',\n chainId: 2001,\n djedAddress: '0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76',\n tokens: {\n stablecoin: {\n symbol: 'MOD',\n address: '0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'mADA',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'ethereum-classic': {\n uri: 'https://etc.rivet.link',\n chainId: 61,\n djedAddress: '0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf',\n tokens: {\n stablecoin: {\n symbol: 'ECSD',\n address: '0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETC',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n }\n};","import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx } from 'djed-sdk';\n\nexport class Transaction {\n constructor(networkUri, djedAddress) {\n this.networkUri = networkUri;\n this.djedAddress = djedAddress;\n }\n\n async init() {\n if (!this.networkUri || !this.djedAddress) {\n throw new Error('Network URI and DJED address are required');\n }\n\n try {\n this.web3 = await getWeb3(this.networkUri);\n this.djedContract = getDjedContract(this.web3, this.djedAddress);\n \n try {\n const { stableCoin, reserveCoin } = await getCoinContracts(this.djedContract, this.web3);\n const { scDecimals, rcDecimals } = await getDecimals(stableCoin, reserveCoin);\n this.stableCoin = stableCoin;\n this.reserveCoin = reserveCoin;\n this.scDecimals = scDecimals;\n this.rcDecimals = rcDecimals;\n\n this.oracleContract = await getOracleAddress(this.djedContract).then((addr) =>\n getOracleContract(this.web3, addr, this.djedContract._address)\n );\n\n this.oracleAddress = this.oracleContract._address;\n } catch (contractError) {\n console.error('[Transaction] Error fetching contract details:', contractError);\n const isReverted = contractError.code === -32000 || contractError.code === 3 || contractError.data;\n if (isReverted) {\n const getNetworkInfo = (uri) => {\n if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };\n if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' };\n if (uri.includes('sepolia')) return { name: 'Sepolia', chainId: '11155111' };\n if (uri.includes('etc.rivet.link')) return { name: 'Ethereum Classic', chainId: '61' };\n return { name: 'the selected network', chainId: 'unknown' };\n };\n const { name: networkName, chainId } = getNetworkInfo(this.networkUri);\n throw new Error(\n `Failed to interact with Djed contract at ${this.djedAddress} on ${networkName}.\\n\\n` +\n `Possible causes:\\n` +\n `- The contract address may be incorrect\\n` +\n `- The contract may not be deployed on ${networkName}\\n` +\n `- The contract may not be a valid Djed contract\\n\\n` +\n `Please verify the contract address is correct for ${networkName} (Chain ID: ${chainId}).`\n );\n }\n throw contractError;\n }\n } catch (error) {\n console.error('[Transaction] Error initializing transaction:', error);\n const isConnectionError = error.code === -32603 || error.code === 4001 || error.code === -32005 || (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED')));\n if (isConnectionError) {\n const getNetworkName = (uri) => {\n if (uri.includes('milkomeda')) return 'Milkomeda';\n if (uri.includes('mordor')) return 'Mordor';\n if (uri.includes('sepolia')) return 'Sepolia';\n return 'the selected network';\n };\n const networkName = getNetworkName(this.networkUri);\n throw new Error(\n `Failed to connect to ${networkName} RPC endpoint: ${this.networkUri}\\n\\n` +\n `Possible causes:\\n` +\n `- The RPC endpoint may be temporarily unavailable\\n` +\n `- DNS resolution issue (check your internet connection)\\n` +\n `- Network firewall blocking the connection\\n\\n` +\n `Please try again in a few moments or check the network status.`\n );\n }\n throw error;\n }\n }\n\n getBlockchainDetails() {\n return {\n web3Available: !!this.web3,\n djedContractAvailable: !!this.djedContract,\n stableCoinAddress: this.stableCoin ? this.stableCoin._address : 'N/A',\n reserveCoinAddress: this.reserveCoin ? this.reserveCoin._address : 'N/A',\n stableCoinDecimals: this.scDecimals,\n reserveCoinDecimals: this.rcDecimals,\n oracleAddress: this.oracleAddress || 'N/A',\n oracleContractAvailable: !!this.oracleContract,\n };\n }\n\n async handleTradeDataBuySc(amountScaled) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n if (typeof amountScaled !== 'string') {\n throw new Error(\"Amount must be a string\");\n }\n try {\n const result = await tradeDataPriceBuySc(this.djedContract, this.scDecimals, amountScaled);\n return result.totalBCScaled;\n } catch (error) {\n console.error(\"Error fetching trade data for buying stablecoins: \", error);\n throw error;\n }\n }\n\n async buyStablecoins(payer, receiver, value) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n try {\n const UI = '0x0232556C83791b8291E9b23BfEa7d67405Bd9839';\n\n const txData = await buyScTx(this.djedContract, payer, receiver, value, UI, this.djedAddress);\n\n return txData;\n } catch (error) {\n console.error(\"Error executing buyStablecoins transaction: \", error);\n throw error;\n }\n }\n}\n","import React from \"react\";\nimport styles from \"../styles/main.css\";\n\nconst PayButton = ({ onClick, size = \"medium\" }) => {\n const sizeStyles = {\n small: { width: \"200px\", height: \"50px\", fontSize: \"14px\" },\n medium: { width: \"250px\", height: \"60px\", fontSize: \"16px\" },\n large: { width: \"300px\", height: \"70px\", fontSize: \"18px\" },\n };\n\n const logoSizes = {\n small: { width: \"35px\", height: \"33px\" },\n medium: { width: \"40px\", height: \"38px\" },\n large: { width: \"45px\", height: \"43px\" },\n };\n\n const buttonStyle = sizeStyles[size] || sizeStyles.medium;\n const logoStyle = logoSizes[size] || logoSizes.medium;\n\n return (\n \n
\n Pay with StablePay\n \n );\n};\n\nexport default PayButton;\n","import React from 'react';\nimport styles from '../styles/PricingCard.css';\n\n\nconst Dialog = ({ children, onClose, size = 'medium' }) => {\n return (\n
\n
\n \n
\n
\n\n
StablePay
\n
\n
\n {children}\n
\n
\n
\n );\n};\n\nexport default Dialog;","// TokenSelector.js\n\nexport class TokenSelector {\n constructor(networkSelector) {\n this.networkSelector = networkSelector;\n this.selectedToken = null;\n }\n\n selectToken(tokenKey) {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (networkConfig && networkConfig.tokens[tokenKey]) {\n this.selectedToken = {\n key: tokenKey,\n ...networkConfig.tokens[tokenKey]\n };\n return true;\n }\n return false;\n }\n\n getSelectedToken() {\n return this.selectedToken;\n }\n\n getAvailableTokens() {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) return [];\n\n return Object.entries(networkConfig.tokens).map(([key, config]) => ({\n key,\n ...config\n }));\n }\n\n resetSelection() {\n this.selectedToken = null;\n }\n}","import React, { createContext, useState, useContext, useEffect } from 'react';\nimport { TokenSelector } from '../core/TokenSelector';\n\nconst NetworkContext = createContext();\n\nexport const NetworkProvider = ({ children, networkSelector }) => {\n const [tokenSelector] = useState(() => new TokenSelector(networkSelector));\n const [selectedNetwork, setSelectedNetwork] = useState(null);\n const [selectedToken, setSelectedToken] = useState(null);\n const [transactionDetails, setTransactionDetails] = useState(null);\n\n const resetState = () => {\n setSelectedToken(null);\n setTransactionDetails(null);\n };\n\n const selectNetwork = (networkKey) => {\n if (networkSelector.selectNetwork(networkKey)) {\n setSelectedNetwork(networkKey);\n resetState(); \n return true;\n }\n return false;\n };\n\n const selectToken = (tokenKey) => {\n if (tokenSelector.selectToken(tokenKey)) {\n const token = tokenSelector.getSelectedToken();\n setSelectedToken(token);\n return true;\n }\n return false;\n };\n\n const resetSelections = () => {\n networkSelector.selectNetwork(null);\n setSelectedNetwork(null);\n resetState();\n };\n\n // Synchronize context state with NetworkSelector\n useEffect(() => {\n setSelectedNetwork(networkSelector.selectedNetwork);\n }, [networkSelector.selectedNetwork]);\n\n return (\n \n {children}\n \n );\n};\n\nexport const useNetwork = () => {\n const context = useContext(NetworkContext);\n if (context === undefined) {\n throw new Error('useNetwork must be used within a NetworkProvider');\n }\n return context;\n};\n\nexport default NetworkContext;","import React from 'react';\nimport { useNetwork } from '../contexts/NetworkContext';\nimport styles from '../styles/PricingCard.css';\n\nconst NetworkDropdown = () => {\n const { networkSelector, selectedNetwork, selectNetwork } = useNetwork();\n\n const handleNetworkChange = (event) => {\n selectNetwork(event.target.value);\n };\n\n return (\n
\n \n \n
\n );\n};\n\nexport default NetworkDropdown;","import React, { useState } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst TokenDropdown = () => {\n const {\n networkSelector,\n tokenSelector,\n selectedNetwork,\n selectedToken,\n selectToken,\n setTransactionDetails,\n } = useNetwork();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n const handleTokenChange = async (event) => {\n const newValue = event.target.value;\n setError(null);\n setLoading(true);\n\n try {\n if (selectToken(newValue)) {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const transaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await transaction.init();\n\n const tokenAmount = networkSelector.getTokenAmount(newValue);\n const blockchainDetails = transaction.getBlockchainDetails();\n\n let tradeData = null;\n if (newValue === \"native\") {\n tradeData = await transaction.handleTradeDataBuySc(\n String(tokenAmount)\n );\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: newValue,\n tokenSymbol: tokenSelector.getSelectedToken().symbol,\n amount: tokenAmount,\n receivingAddress: networkSelector.getReceivingAddress(),\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer:\n tokenSelector.getSelectedToken().isDirectTransfer || false,\n isNativeToken: tokenSelector.getSelectedToken().isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...blockchainDetails,\n });\n }\n } catch (err) {\n console.error(\"Error fetching transaction details:\", err);\n setError(\"Failed to fetch transaction details. Please try again.\");\n } finally {\n setLoading(false);\n }\n };\n\n const availableTokens = selectedNetwork\n ? tokenSelector.getAvailableTokens()\n : [];\n\n return (\n
\n \n \n \n {availableTokens.map((token) => (\n \n ))}\n \n {error &&
{error}
}\n
\n );\n};\n\nexport default TokenDropdown;\n","import { defineChain } from 'viem';\nimport { sepolia } from 'viem/chains';\n\nexport const mordor = defineChain({\n id: 63,\n name: 'Mordor Testnet',\n network: 'mordor',\n nativeCurrency: {\n decimals: 18,\n name: 'Mordor Ether',\n symbol: 'METC',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc.mordor.etccooperative.org'],\n webSocket: ['wss://rpc.mordor.etccooperative.org/ws'],\n },\n },\n blockExplorers: {\n default: { name: 'BlockScout', url: 'https://blockscout.com/etc/mordor' },\n },\n testnet: true,\n});\n\nexport const milkomeda = defineChain({\n id: 2001,\n name: 'Milkomeda C1 Mainnet',\n network: 'milkomeda',\n nativeCurrency: {\n decimals: 18,\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n },\n },\n blockExplorers: {\n default: { name: 'Milkomeda Explorer', url: 'https://explorer-mainnet-cardano-evm.c1.milkomeda.com' },\n },\n testnet: false,\n});\n\nexport const etcMainnet = defineChain({\n id: 61,\n name: 'Ethereum Classic',\n network: 'etc',\n nativeCurrency: {\n decimals: 18,\n name: 'Ethereum Classic',\n symbol: 'ETC',\n },\n rpcUrls: {\n default: {\n http: ['https://etc.rivet.link'],\n },\n },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://blockscout.com/etc/mainnet' },\n },\n testnet: false,\n});\n\nexport const getChainByNetworkKey = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return sepolia;\n case 'ethereum-classic':\n return etcMainnet;\n case 'milkomeda-mainnet':\n return milkomeda;\n default:\n return null;\n }\n};\n\nexport const getChainConfigForWallet = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return {\n chainId: `0x${sepolia.id.toString(16)}`,\n chainName: 'Sepolia',\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n rpcUrls: sepolia.rpcUrls.default.http,\n blockExplorerUrls: sepolia.blockExplorers?.default?.url ? [sepolia.blockExplorers.default.url] : [],\n };\n case 'ethereum-classic':\n return {\n chainId: `0x${etcMainnet.id.toString(16)}`,\n chainName: 'Ethereum Classic',\n nativeCurrency: {\n name: 'Ethereum Classic',\n symbol: 'ETC',\n decimals: 18,\n },\n rpcUrls: ['https://etc.rivet.link'],\n blockExplorerUrls: ['https://blockscout.com/etc/mainnet'],\n };\n case 'milkomeda-mainnet':\n return {\n chainId: `0x${milkomeda.id.toString(16)}`,\n chainName: 'Milkomeda C1 Mainnet',\n nativeCurrency: {\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n decimals: 18,\n },\n rpcUrls: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n blockExplorerUrls: ['https://explorer-mainnet-cardano-evm.c1.milkomeda.com'],\n };\n default:\n return null;\n }\n};\n","import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { createWalletClient, createPublicClient, custom, http } from 'viem';\nimport { useNetwork } from './NetworkContext';\nimport { getChainByNetworkKey, getChainConfigForWallet } from './chains';\n\nconst WalletContext = createContext(null);\n\nexport const useWallet = () => {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used within a WalletProvider');\n }\n return context;\n};\n\nconst switchToNetwork = async (networkKey) => {\n if (!window.ethereum) {\n throw new Error('MetaMask not installed');\n }\n\n const chainConfig = getChainConfigForWallet(networkKey);\n if (!chainConfig) {\n throw new Error(`Unsupported network: ${networkKey}`);\n }\n\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: chainConfig.chainId }],\n });\n } catch (switchError) {\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [chainConfig],\n });\n } catch (addError) {\n if (addError.code === 4001) {\n throw new Error(`User rejected adding ${chainConfig.chainName} to MetaMask. Please add it manually.`);\n }\n throw new Error(`Failed to add ${chainConfig.chainName} to MetaMask: ${addError.message}`);\n }\n } else if (switchError.code === 4001) {\n throw new Error(`User rejected switching to ${chainConfig.chainName}. Please switch manually in MetaMask.`);\n } else {\n throw new Error(`Failed to switch to ${chainConfig.chainName}: ${switchError.message}`);\n }\n }\n};\n\nexport const WalletProvider = ({ children }) => {\n const { selectedNetwork } = useNetwork();\n const [walletClient, setWalletClient] = useState(null);\n const [publicClient, setPublicClient] = useState(null);\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [balance, setBalance] = useState(null);\n const [error, setError] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n\n const selectedChain = selectedNetwork ? getChainByNetworkKey(selectedNetwork) : null;\n const expectedChainId = selectedChain ? selectedChain.id : null;\n\n const handleAccountsChangedRef = useRef(null);\n const handleChainChangedRef = useRef(null);\n\n const disconnectWalletInternal = useCallback(() => {\n setWalletClient(null);\n setPublicClient(null);\n setAccount(null);\n setChainId(null);\n setBalance(null);\n setError(null);\n }, []);\n\n const handleChainChanged = useCallback(async (chainIdHex) => {\n const newChainId = parseInt(chainIdHex, 16);\n setChainId(newChainId);\n\n if (selectedChain && newChainId === expectedChainId) {\n setError(null);\n if (window.ethereum && selectedChain) {\n const newWalletClient = createWalletClient({ \n chain: selectedChain, \n transport: custom(window.ethereum) \n });\n setWalletClient(newWalletClient);\n }\n } else if (selectedChain && newChainId !== expectedChainId) {\n const chainName = selectedChain?.name || selectedNetwork || 'selected network';\n setError(`Wrong network detected. Please switch to ${chainName}`);\n }\n }, [selectedChain, expectedChainId, selectedNetwork]);\n\n handleChainChangedRef.current = handleChainChanged;\n\n const handleAccountsChanged = useCallback(async (accounts) => {\n if (accounts.length === 0) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n } else {\n setAccount(accounts[0]);\n if (selectedChain) {\n try {\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n }\n }\n }, [selectedChain, disconnectWalletInternal]);\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n\n const disconnectWallet = useCallback(() => {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }, [disconnectWalletInternal]);\n\n const connectPublicClient = useCallback(() => {\n if (selectedChain) {\n setPublicClient(createPublicClient({ chain: selectedChain, transport: http() }));\n }\n }, [selectedChain]);\n\n const connectWallet = useCallback(async () => {\n if (!window.ethereum) {\n setError('Please install MetaMask or another Web3 wallet');\n return false;\n }\n\n if (!selectedNetwork || !selectedChain) {\n setError('Please select a network first');\n return false;\n }\n\n setIsConnecting(true);\n setError(null);\n\n try {\n const accounts = await window.ethereum.request({ \n method: 'eth_requestAccounts' \n });\n\n if (accounts.length === 0) {\n throw new Error('No wallet address found. Please unlock your wallet.');\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n await switchToNetwork(selectedNetwork);\n }\n\n const newWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(newWalletClient);\n setAccount(accounts[0]);\n setChainId(expectedChainId);\n\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n try {\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n handleChainChangedRef.current = handleChainChanged;\n window.ethereum.on('accountsChanged', handleAccountsChanged);\n window.ethereum.on('chainChanged', handleChainChanged);\n\n return true;\n } catch (err) {\n console.error('Error connecting wallet:', err);\n setError(err.message);\n return false;\n } finally {\n setIsConnecting(false);\n }\n }, [selectedNetwork, selectedChain, expectedChainId, handleAccountsChanged, handleChainChanged]);\n\n const ensureCorrectNetwork = useCallback(async () => {\n if (!window.ethereum || !selectedNetwork || !selectedChain || !account) {\n const errorMsg = 'Wallet not connected or network not selected';\n setError(errorMsg);\n return null;\n }\n\n try {\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n setError(null);\n await switchToNetwork(selectedNetwork);\n const NETWORK_SWITCH_DELAY_MS = 500;\n await new Promise(resolve => setTimeout(resolve, NETWORK_SWITCH_DELAY_MS));\n \n const newChainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const newChainId = parseInt(newChainIdHex, 16);\n if (newChainId !== expectedChainId) {\n throw new Error(`Failed to switch network. MetaMask is still on chain ${newChainId}, expected ${expectedChainId}`);\n }\n }\n\n const freshWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(freshWalletClient);\n setChainId(expectedChainId);\n setError(null);\n return freshWalletClient;\n } catch (err) {\n setError(err.message);\n return null;\n }\n }, [selectedNetwork, selectedChain, expectedChainId, account]);\n\n const prevNetworkRef = useRef(selectedNetwork);\n\n useEffect(() => {\n if (prevNetworkRef.current !== null && \n prevNetworkRef.current !== selectedNetwork && \n account) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }\n prevNetworkRef.current = selectedNetwork;\n }, [selectedNetwork, account, disconnectWalletInternal]);\n\n useEffect(() => {\n connectPublicClient();\n }, [connectPublicClient]);\n\n return (\n \n {children}\n \n );\n};","import React, { useState, useEffect } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { useWallet } from \"../contexts/WalletContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport { parseEther, encodeFunctionData, parseUnits } from \"viem\"; \nimport styles from \"../styles/PricingCard.css\"; \n\nconst TransactionReview = ({ onTransactionComplete }) => {\n const {\n networkSelector,\n selectedNetwork,\n selectedToken,\n transactionDetails: contextTransactionDetails,\n setTransactionDetails,\n } = useNetwork();\n\n const {\n connectWallet,\n account,\n walletClient,\n publicClient,\n isConnecting,\n ensureCorrectNetwork,\n expectedChainId,\n } = useWallet();\n\n const [transaction, setTransaction] = useState(null);\n const [tradeDataBuySc, setTradeDataBuySc] = useState(null);\n const [message, setMessage] = useState(\"\");\n const [txHash, setTxHash] = useState(null);\n const [error, setError] = useState(null);\n const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false);\n const [interactionState, setInteractionState] = useState('IDLE');\n\n useEffect(() => {\n setTradeDataBuySc(null);\n setMessage(\"\");\n setError(null);\n setTxHash(null);\n setInteractionState('IDLE');\n }, [selectedNetwork, selectedToken]);\n\n useEffect(() => {\n const initializeTransaction = async () => {\n if (!selectedNetwork || !selectedToken) return;\n\n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const receivingAddress = networkSelector.getReceivingAddress();\n const tokenAmount = networkSelector.getTokenAmount(selectedToken.key);\n\n const newTransaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await newTransaction.init();\n setTransaction(newTransaction);\n\n let tradeData = null;\n if (selectedToken.key === \"native\") {\n try {\n tradeData = await newTransaction.handleTradeDataBuySc(String(tokenAmount));\n setTradeDataBuySc(tradeData);\n } catch (tradeError) {\n console.error(\"Error fetching trade data:\", tradeError);\n }\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: selectedToken.key,\n tokenSymbol: selectedToken.symbol,\n amount: tokenAmount || \"0\",\n receivingAddress,\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer: selectedToken.isDirectTransfer || false,\n isNativeToken: selectedToken.isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...newTransaction.getBlockchainDetails(),\n });\n } catch (err) {\n console.error(\"Error initializing transaction:\", err);\n }\n };\n\n initializeTransaction();\n }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]);\n\n if (!selectedNetwork || !selectedToken) {\n return null;\n }\n\n if (!contextTransactionDetails) {\n return
Initializing transaction...
;\n }\n\n const handleConnectWallet = async () => {\n await connectWallet();\n };\n\n const executePayment = async () => {\n if (!account || !contextTransactionDetails || !transaction) {\n setMessage(\"Wallet not connected or transaction details missing\");\n return;\n }\n\n setInteractionState('PROCESSING');\n setMessage(\"Preparing transaction...\");\n setError(null);\n setTxHash(null);\n\n let builtTx;\n try {\n const receiver = contextTransactionDetails.receivingAddress;\n\n if (selectedToken.key === \"native\") {\n const UI = \"0x0232556C83791b8291E9b23BfEa7d67405Bd9839\";\n const amountToSend = tradeDataBuySc || \"0\";\n const valueInWei = parseEther(String(amountToSend));\n\n builtTx = await transaction.buyStablecoins(\n account,\n receiver,\n valueInWei,\n UI\n );\n\n builtTx = {\n ...builtTx,\n value: valueInWei,\n account: account,\n };\n } else {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const stablecoinAddress = networkConfig?.tokens?.stablecoin?.address;\n \n if (!stablecoinAddress) {\n throw new Error('Stablecoin address not found in network configuration');\n }\n\n const amountToSend = contextTransactionDetails.amount\n ? parseUnits(\n String(contextTransactionDetails.amount),\n contextTransactionDetails.stableCoinDecimals\n )\n : \"0\";\n\n builtTx = {\n to: stablecoinAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: [\n {\n inputs: [\n { internalType: \"address\", name: \"to\", type: \"address\" },\n { internalType: \"uint256\", name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ],\n functionName: \"transfer\",\n args: [receiver, amountToSend],\n }),\n account: account,\n };\n }\n } catch (err) {\n setError(err);\n const reason = err.shortMessage || (err.message ? err.message.split('\\n')[0] : \"Unknown error\");\n setMessage(`Transaction preparation failed: ${reason}`);\n setInteractionState('IDLE');\n return;\n }\n\n setMessage(\"Please check your wallet to confirm the transaction...\");\n \n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) {\n throw new Error(\"Network configuration not found\");\n }\n\n const freshWalletClient = await ensureCorrectNetwork();\n if (!freshWalletClient) {\n throw new Error(\"Failed to switch to correct network. Please approve the network switch in MetaMask.\");\n }\n\n if (!window.ethereum) {\n throw new Error(\"MetaMask not available\");\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== networkConfig.chainId) {\n throw new Error(`Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`);\n }\n\n if (freshWalletClient.chain.id !== networkConfig.chainId) {\n throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`);\n }\n\n const txHash = await freshWalletClient.sendTransaction({\n ...builtTx,\n account: account,\n });\n\n setTxHash(txHash);\n setMessage(`Transaction sent successfully!`);\n setInteractionState('SUCCESS');\n \n if (onTransactionComplete) {\n onTransactionComplete({\n txHash,\n network: selectedNetwork,\n token: selectedToken?.key,\n tokenSymbol: selectedToken?.symbol,\n amount: contextTransactionDetails?.amount,\n receivingAddress: contextTransactionDetails?.receivingAddress,\n });\n }\n } catch (err) {\n setError(err);\n \n let reason = \"Unknown error\";\n if (err.name === 'UserRejectedRequestError' || err.code === 4001) {\n reason = \"User denied transaction\";\n } else if (err.name === 'ContractFunctionRevertedError' || (err.data && err.data.message)) {\n reason = err.shortMessage || err.data?.message || err.message;\n } else {\n reason = err.shortMessage || (err.message ? err.message.split('\\n')[0] : \"Transaction failed\");\n }\n \n setMessage(`Transaction failed: ${reason}`);\n setInteractionState('IDLE');\n console.error('Transaction error:', err);\n }\n };\n\n const getExplorerUrl = () => {\n if (!txHash || !selectedNetwork) return null;\n\n const explorerBaseUrls = {\n \"ethereum-classic\": \"https://blockscout.com/etc/mainnet/tx/\",\n \"sepolia\": \"https://sepolia.etherscan.io/tx/\",\n \"milkomeda-mainnet\": \"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/\",\n };\n\n return explorerBaseUrls[selectedNetwork]\n ? `${explorerBaseUrls[selectedNetwork]}${txHash}`\n : null;\n };\n\n return (\n
\n
\n Network:\n {contextTransactionDetails.network}\n
\n\n
\n You Pay:\n \n {selectedToken.key === \"stablecoin\"\n ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}`\n : `${tradeDataBuySc ? tradeDataBuySc : \"Calculating...\"} ${\n contextTransactionDetails.tokenSymbol\n }`}\n \n
\n\n {message && (\n
\n {message}\n {error && (\n setIsErrorDetailsVisible(!isErrorDetailsVisible)}\n className={styles.detailsButton}\n >\n {isErrorDetailsVisible ? \"Hide Details\" : \"Show Details\"}\n \n )}\n
\n )}\n\n {isErrorDetailsVisible && error && (\n
\n
{error.message}
\n
\n )}\n\n {txHash && (\n
\n Transaction Hash:{\" \"}\n {getExplorerUrl() ? (\n \n {txHash.slice(0, 6)}...{txHash.slice(-6)}\n \n ) : (\n \n {txHash}\n \n )}\n
\n )}\n\n {interactionState !== 'SUCCESS' && (\n
\n {!account && (\n \n )}\n\n {account && interactionState === 'IDLE' && (\n \n )}\n\n {account && interactionState === 'CONFIRMING' && (\n
\n Confirm payment?\n
\n \n \n
\n
\n )}\n\n {account && interactionState === 'PROCESSING' && (\n \n )}\n
\n )}\n
\n );\n};\n\nexport default TransactionReview;\n","import React, { useState } from \"react\";\nimport PayButton from \"./PayButton\";\nimport Dialog from \"./Dialog\";\nimport NetworkDropdown from \"./NetworkDropdown\";\nimport TokenDropdown from \"./TokenDropdown\";\nimport TransactionReview from \"./TransactionReview\";\nimport { NetworkProvider, useNetwork } from \"../contexts/NetworkContext\";\nimport { WalletProvider } from \"../contexts/WalletContext\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst WidgetContent = ({ onClose, buttonSize, onTransactionComplete }) => {\n const { resetSelections } = useNetwork(); \n\n const handleClose = () => {\n resetSelections(); // Reset selections when closing the widget\n onClose();\n };\n\n return (\n \n \n \n \n \n );\n};\n\nconst WidgetWithProviders = ({ onClose, buttonSize, networkSelector, onTransactionComplete }) => {\n return (\n \n \n \n \n \n );\n};\n\nexport const Widget = ({ networkSelector, buttonSize = \"medium\", onTransactionComplete, onSuccess }) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const handleOpenDialog = () => {\n setIsDialogOpen(true);\n };\n\n const handleCloseDialog = () => {\n setIsDialogOpen(false);\n };\n\n // Support both onTransactionComplete and onSuccess for backwards compatibility\n const handleTransactionComplete = onTransactionComplete || onSuccess;\n\n return (\n
\n {!isDialogOpen && (\n \n )}\n {isDialogOpen && (\n \n )}\n
\n );\n};\n\nexport default Widget;\n","// src/index.js\nimport { NetworkSelector } from './core/NetworkSelector';\nimport { Transaction } from './core/Transaction';\nimport { Config } from './core/MerchantConfig';\nimport Widget from './widget/Widget.jsx';\nimport PayButton from './widget/PayButton.jsx';\nimport Dialog from './widget/Dialog.jsx';\nimport NetworkDropdown from './widget/NetworkDropdown.jsx';\nimport './styles/main.css';\nimport './styles/PricingCard.css';\n\nconst StablePay = {\n NetworkSelector,\n Transaction,\n Config,\n Widget,\n PayButton,\n Dialog,\n NetworkDropdown\n};\n\nexport default StablePay;","import { networksConfig } from \"../utils/config\";\n\nexport class NetworkSelector {\n constructor(merchantConfig) {\n this.merchantConfig = merchantConfig;\n this.blacklist = merchantConfig.getBlacklist();\n this.availableNetworks = this.getAvailableNetworks();\n this.selectedNetwork = null;\n }\n\n getAvailableNetworks() {\n return Object.entries(networksConfig).reduce(\n (acc, [networkKey, networkConfig]) => {\n if (!this.blacklist.includes(networkConfig.chainId)) {\n acc[networkKey] = networkConfig;\n }\n return acc;\n },\n {}\n );\n }\n\n selectNetwork(networkKey) {\n if (networkKey === null) {\n this.selectedNetwork = null;\n console.log(\"Network selection reset\");\n return true;\n }\n if (this.availableNetworks[networkKey]) {\n this.selectedNetwork = networkKey;\n console.log(`Network selected: ${networkKey}`);\n return true;\n }\n console.error(`Invalid network: ${networkKey}`);\n return false;\n }\n\n getSelectedNetworkConfig() {\n return this.selectedNetwork\n ? this.availableNetworks[this.selectedNetwork]\n : null;\n }\n\n getReceivingAddress() {\n return this.merchantConfig.getReceivingAddress();\n }\n\n getTokenAmount(token) {\n return this.merchantConfig.getTokenAmount(this.selectedNetwork, token);\n }\n}\n","import { networksConfig } from \"../utils/config\";\n\nexport class Config {\n constructor(options = {}) {\n this.receivingAddress = options.receivingAddress || \"\";\n this.blacklist = options.blacklist || [];\n this.amounts = options.amounts || options.Amounts || {};\n this.validateConfig();\n }\n\n validateConfig() {\n if (!this.receivingAddress) {\n throw new Error(\"Receiving address is required\");\n }\n // Validate stablecoin amounts\n for (const [network, tokens] of Object.entries(this.amounts)) {\n if (!networksConfig[network]) {\n throw new Error(`Invalid network: ${network}`);\n }\n if (\n !tokens.stablecoin ||\n typeof tokens.stablecoin !== \"number\" ||\n tokens.stablecoin <= 0\n ) {\n throw new Error(`Invalid stablecoin amount for network ${network}`);\n }\n }\n }\n\n getBlacklist() {\n return this.blacklist;\n }\n\n getReceivingAddress() {\n return this.receivingAddress;\n }\n\n // getTokenAmount(network, token) {\n // const networkConfig = networksConfig[network];\n // if (!networkConfig) return 0;\n\n // const stablecoinSymbol = networkConfig.tokens.stablecoin.symbol;\n\n // if (token === 'stablecoin') {\n // return this.amounts[network]?.stablecoin || 0;\n // }\n // // For native tokens, return 0 as it's not specified in the new structure\n // return 0;\n // }\n getTokenAmount(network) {\n console.log(\"Getting amount for network:\", network);\n console.log(\"Amounts object:\", this.amounts);\n\n // Directly return the stablecoin amount for the network\n const amount = this.amounts[network]?.stablecoin;\n console.log(\"Returning amount:\", amount);\n\n return amount || 0;\n }\n}\n\nexport default Config;\n"],"names":["networksConfig","sepolia","uri","chainId","djedAddress","tokens","stablecoin","symbol","address","decimals","isDirectTransfer","native","isNative","feeUI","Transaction","constructor","networkUri","this","init","Error","web3","getWeb3","djedContract","getDjedContract","stableCoin","reserveCoin","getCoinContracts","scDecimals","rcDecimals","getDecimals","oracleContract","getOracleAddress","then","addr","getOracleContract","_address","oracleAddress","contractError","console","error","code","data","getNetworkInfo","includes","name","networkName","message","getNetworkName","getBlockchainDetails","web3Available","djedContractAvailable","stableCoinAddress","reserveCoinAddress","stableCoinDecimals","reserveCoinDecimals","oracleContractAvailable","handleTradeDataBuySc","amountScaled","tradeDataPriceBuySc","totalBCScaled","buyStablecoins","payer","receiver","value","UI","buyScTx","PayButton","onClick","size","sizeStyles","small","width","height","fontSize","medium","large","logoSizes","buttonStyle","logoStyle","React","createElement","className","styles","style","Dialog","children","onClose","dialogOverlay","pricingCard","dialogClose","pricingCardHeader","allianceLogo","stablepayTitle","pricingCardBody","TokenSelector","networkSelector","selectedToken","selectToken","tokenKey","networkConfig","getSelectedNetworkConfig","key","getSelectedToken","getAvailableTokens","Object","entries","map","config","resetSelection","NetworkContext","createContext","NetworkProvider","tokenSelector","useState","selectedNetwork","setSelectedNetwork","setSelectedToken","transactionDetails","setTransactionDetails","resetState","useEffect","Provider","selectNetwork","networkKey","token","resetSelections","useNetwork","context","useContext","undefined","NetworkDropdown","selectField","htmlFor","id","onChange","event","target","disabled","keys","availableNetworks","TokenDropdown","loading","setLoading","setError","availableTokens","async","newValue","transaction","tokenAmount","getTokenAmount","blockchainDetails","tradeData","String","network","tokenSymbol","amount","receivingAddress","getReceivingAddress","djedContractAddress","isNativeToken","tradeAmount","err","defineChain","nativeCurrency","rpcUrls","default","http","webSocket","blockExplorers","url","testnet","milkomeda","etcMainnet","WalletContext","switchToNetwork","window","ethereum","chainConfig","toString","chainName","blockExplorerUrls","getChainConfigForWallet","request","method","params","switchError","addError","WalletProvider","walletClient","setWalletClient","publicClient","setPublicClient","account","setAccount","setChainId","balance","setBalance","isConnecting","setIsConnecting","selectedChain","getChainByNetworkKey","expectedChainId","handleAccountsChangedRef","useRef","handleChainChangedRef","disconnectWalletInternal","useCallback","handleChainChanged","newChainId","parseInt","chainIdHex","newWalletClient","createWalletClient","chain","transport","custom","current","handleAccountsChanged","accounts","length","accountsHandler","chainHandler","removeListener","newPublicClient","createPublicClient","getBalance","parseFloat","Math","pow","disconnectWallet","connectPublicClient","connectWallet","on","ensureCorrectNetwork","NETWORK_SWITCH_DELAY_MS","Promise","resolve","setTimeout","newChainIdHex","freshWalletClient","prevNetworkRef","TransactionReview","onTransactionComplete","contextTransactionDetails","useWallet","setTransaction","tradeDataBuySc","setTradeDataBuySc","setMessage","txHash","setTxHash","isErrorDetailsVisible","setIsErrorDetailsVisible","interactionState","setInteractionState","newTransaction","tradeError","initializeTransaction","getExplorerUrl","explorerBaseUrls","transactionReview","transactionInfo","transactionLabel","transactionValue","highlight","messageBox","detailsButton","errorDetails","transactionLink","href","rel","explorerLink","slice","wordBreak","walletButtonContainer","walletButton","confirmContainer","confirmText","confirmButtons","secondaryButton","primaryButton","builtTx","amountToSend","valueInWei","parseEther","stablecoinAddress","parseUnits","to","encodeFunctionData","abi","inputs","internalType","type","outputs","stateMutability","functionName","args","reason","shortMessage","split","currentChainId","sendTransaction","WidgetContent","buttonSize","handleClose","WidgetWithProviders","NetworkSelector","merchantConfig","blacklist","getBlacklist","getAvailableNetworks","reduce","acc","log","Config","options","amounts","Amounts","validateConfig","Widget","onSuccess","isDialogOpen","setIsDialogOpen","handleTransactionComplete","widgetContainer","handleOpenDialog","handleCloseDialog"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../../src/utils/config.js","../../src/core/Transaction.js","../../src/widget/PayButton.jsx","../../src/widget/Dialog.jsx","../../src/core/TokenSelector.js","../../src/contexts/NetworkContext.jsx","../../src/widget/NetworkDropdown.jsx","../../src/widget/TokenDropdown.jsx","../../src/contexts/chains.js","../../src/contexts/WalletContext.jsx","../../src/widget/TransactionReview.jsx","../../src/widget/Widget.jsx","../../src/index.js","../../src/core/NetworkSelector.js","../../src/core/MerchantConfig.js"],"sourcesContent":["// src/utils/config.js\nexport const networksConfig = {\n 'sepolia': {\n uri: 'https://ethereum-sepolia.publicnode.com/',\n chainId: 11155111,\n djedAddress: '0x624FcD0a1F9B5820c950FefD48087531d38387f4',\n tokens: {\n stablecoin: {\n symbol: 'SOD',\n address: '0x6b930182787F346F18666D167e8d32166dC5eFBD',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETH',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'milkomeda-mainnet': {\n uri: 'https://rpc-mainnet-cardano-evm.c1.milkomeda.com',\n chainId: 2001,\n djedAddress: '0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76',\n tokens: {\n stablecoin: {\n symbol: 'MOD',\n address: '0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'mADA',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'ethereum-classic': {\n uri: 'https://etc.rivet.link',\n chainId: 61,\n djedAddress: '0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf',\n tokens: {\n stablecoin: {\n symbol: 'ECSD',\n address: '0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETC',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n }\n};","import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx } from 'djed-sdk';\n\nexport class Transaction {\n constructor(networkUri, djedAddress) {\n this.networkUri = networkUri;\n this.djedAddress = djedAddress;\n }\n\n async init() {\n if (!this.networkUri || !this.djedAddress) {\n throw new Error('Network URI and DJED address are required');\n }\n\n try {\n this.web3 = await getWeb3(this.networkUri);\n this.djedContract = getDjedContract(this.web3, this.djedAddress);\n \n try {\n const { stableCoin, reserveCoin } = await getCoinContracts(this.djedContract, this.web3);\n const { scDecimals, rcDecimals } = await getDecimals(stableCoin, reserveCoin);\n this.stableCoin = stableCoin;\n this.reserveCoin = reserveCoin;\n this.scDecimals = scDecimals;\n this.rcDecimals = rcDecimals;\n\n this.oracleContract = await getOracleAddress(this.djedContract).then((addr) =>\n getOracleContract(this.web3, addr, this.djedContract._address)\n );\n\n this.oracleAddress = this.oracleContract._address;\n } catch (contractError) {\n console.error('[Transaction] Error fetching contract details:', contractError);\n const isReverted = contractError.code === -32000 || contractError.code === 3 || contractError.data;\n if (isReverted) {\n const getNetworkInfo = (uri) => {\n if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };\n if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' };\n if (uri.includes('sepolia')) return { name: 'Sepolia', chainId: '11155111' };\n if (uri.includes('etc.rivet.link')) return { name: 'Ethereum Classic', chainId: '61' };\n return { name: 'the selected network', chainId: 'unknown' };\n };\n const { name: networkName, chainId } = getNetworkInfo(this.networkUri);\n throw new Error(\n `Failed to interact with Djed contract at ${this.djedAddress} on ${networkName}.\\n\\n` +\n `Possible causes:\\n` +\n `- The contract address may be incorrect\\n` +\n `- The contract may not be deployed on ${networkName}\\n` +\n `- The contract may not be a valid Djed contract\\n\\n` +\n `Please verify the contract address is correct for ${networkName} (Chain ID: ${chainId}).`\n );\n }\n throw contractError;\n }\n } catch (error) {\n console.error('[Transaction] Error initializing transaction:', error);\n const isConnectionError = error.code === -32603 || error.code === 4001 || error.code === -32005 || (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED')));\n if (isConnectionError) {\n const getNetworkName = (uri) => {\n if (uri.includes('milkomeda')) return 'Milkomeda';\n if (uri.includes('mordor')) return 'Mordor';\n if (uri.includes('sepolia')) return 'Sepolia';\n return 'the selected network';\n };\n const networkName = getNetworkName(this.networkUri);\n throw new Error(\n `Failed to connect to ${networkName} RPC endpoint: ${this.networkUri}\\n\\n` +\n `Possible causes:\\n` +\n `- The RPC endpoint may be temporarily unavailable\\n` +\n `- DNS resolution issue (check your internet connection)\\n` +\n `- Network firewall blocking the connection\\n\\n` +\n `Please try again in a few moments or check the network status.`\n );\n }\n throw error;\n }\n }\n\n getBlockchainDetails() {\n return {\n web3Available: !!this.web3,\n djedContractAvailable: !!this.djedContract,\n stableCoinAddress: this.stableCoin ? this.stableCoin._address : 'N/A',\n reserveCoinAddress: this.reserveCoin ? this.reserveCoin._address : 'N/A',\n stableCoinDecimals: this.scDecimals,\n reserveCoinDecimals: this.rcDecimals,\n oracleAddress: this.oracleAddress || 'N/A',\n oracleContractAvailable: !!this.oracleContract,\n };\n }\n\n async handleTradeDataBuySc(amountScaled) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n if (typeof amountScaled !== 'string') {\n throw new Error(\"Amount must be a string\");\n }\n try {\n const result = await tradeDataPriceBuySc(this.djedContract, this.scDecimals, amountScaled);\n return result.totalBCScaled;\n } catch (error) {\n console.error(\"Error fetching trade data for buying stablecoins: \", error);\n throw error;\n }\n }\n\n async buyStablecoins(payer, receiver, value) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n try {\n const UI = '0x0232556C83791b8291E9b23BfEa7d67405Bd9839';\n\n const txData = await buyScTx(this.djedContract, payer, receiver, value, UI, this.djedAddress);\n\n return txData;\n } catch (error) {\n console.error(\"Error executing buyStablecoins transaction: \", error);\n throw error;\n }\n }\n}\n","import React from \"react\";\nimport styles from \"../styles/main.css\";\n\nconst PayButton = ({ onClick, size = \"medium\" }) => {\n const sizeStyles = {\n small: { width: \"200px\", height: \"50px\", fontSize: \"14px\" },\n medium: { width: \"250px\", height: \"60px\", fontSize: \"16px\" },\n large: { width: \"300px\", height: \"70px\", fontSize: \"18px\" },\n };\n\n const logoSizes = {\n small: { width: \"35px\", height: \"33px\" },\n medium: { width: \"40px\", height: \"38px\" },\n large: { width: \"45px\", height: \"43px\" },\n };\n\n const buttonStyle = sizeStyles[size] || sizeStyles.medium;\n const logoStyle = logoSizes[size] || logoSizes.medium;\n\n return (\n \n
\n Pay with StablePay\n \n );\n};\n\nexport default PayButton;\n","import React from 'react';\nimport styles from '../styles/PricingCard.css';\n\n\nconst Dialog = ({ children, onClose, size = 'medium' }) => {\n return (\n
\n
\n \n
\n
\n\n
StablePay
\n
\n
\n {children}\n
\n
\n
\n );\n};\n\nexport default Dialog;","// TokenSelector.js\n\nexport class TokenSelector {\n constructor(networkSelector) {\n this.networkSelector = networkSelector;\n this.selectedToken = null;\n }\n\n selectToken(tokenKey) {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (networkConfig && networkConfig.tokens[tokenKey]) {\n this.selectedToken = {\n key: tokenKey,\n ...networkConfig.tokens[tokenKey]\n };\n return true;\n }\n return false;\n }\n\n getSelectedToken() {\n return this.selectedToken;\n }\n\n getAvailableTokens() {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) return [];\n\n return Object.entries(networkConfig.tokens).map(([key, config]) => ({\n key,\n ...config\n }));\n }\n\n resetSelection() {\n this.selectedToken = null;\n }\n}","import React, { createContext, useState, useContext, useEffect } from 'react';\nimport { TokenSelector } from '../core/TokenSelector';\n\nconst NetworkContext = createContext();\n\nexport const NetworkProvider = ({ children, networkSelector }) => {\n const [tokenSelector] = useState(() => new TokenSelector(networkSelector));\n const [selectedNetwork, setSelectedNetwork] = useState(null);\n const [selectedToken, setSelectedToken] = useState(null);\n const [transactionDetails, setTransactionDetails] = useState(null);\n\n const resetState = () => {\n setSelectedToken(null);\n setTransactionDetails(null);\n };\n\n const selectNetwork = (networkKey) => {\n if (networkSelector.selectNetwork(networkKey)) {\n setSelectedNetwork(networkKey);\n resetState(); \n return true;\n }\n return false;\n };\n\n const selectToken = (tokenKey) => {\n if (tokenSelector.selectToken(tokenKey)) {\n const token = tokenSelector.getSelectedToken();\n setSelectedToken(token);\n return true;\n }\n return false;\n };\n\n const resetSelections = () => {\n networkSelector.selectNetwork(null);\n setSelectedNetwork(null);\n resetState();\n };\n\n // Synchronize context state with NetworkSelector\n useEffect(() => {\n setSelectedNetwork(networkSelector.selectedNetwork);\n }, [networkSelector.selectedNetwork]);\n\n return (\n \n {children}\n \n );\n};\n\nexport const useNetwork = () => {\n const context = useContext(NetworkContext);\n if (context === undefined) {\n throw new Error('useNetwork must be used within a NetworkProvider');\n }\n return context;\n};\n\nexport default NetworkContext;","import React from 'react';\nimport { useNetwork } from '../contexts/NetworkContext';\nimport styles from '../styles/PricingCard.css';\n\nconst NetworkDropdown = () => {\n const { networkSelector, selectedNetwork, selectNetwork } = useNetwork();\n\n const handleNetworkChange = (event) => {\n selectNetwork(event.target.value);\n };\n\n return (\n
\n \n \n
\n );\n};\n\nexport default NetworkDropdown;","import React, { useState } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst TokenDropdown = () => {\n const {\n networkSelector,\n tokenSelector,\n selectedNetwork,\n selectedToken,\n selectToken,\n setTransactionDetails,\n } = useNetwork();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n const handleTokenChange = async (event) => {\n const newValue = event.target.value;\n setError(null);\n setLoading(true);\n\n try {\n if (selectToken(newValue)) {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const transaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await transaction.init();\n\n const tokenAmount = networkSelector.getTokenAmount(newValue);\n const blockchainDetails = transaction.getBlockchainDetails();\n\n let tradeData = null;\n if (newValue === \"native\") {\n tradeData = await transaction.handleTradeDataBuySc(\n String(tokenAmount)\n );\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: newValue,\n tokenSymbol: tokenSelector.getSelectedToken().symbol,\n amount: tokenAmount,\n receivingAddress: networkSelector.getReceivingAddress(),\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer:\n tokenSelector.getSelectedToken().isDirectTransfer || false,\n isNativeToken: tokenSelector.getSelectedToken().isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...blockchainDetails,\n });\n }\n } catch (err) {\n console.error(\"Error fetching transaction details:\", err);\n if (typeof window !== 'undefined' && !window.ethereum) {\n setError(\"No wallet found. Please install a Web3 wallet.\");\n } else {\n setError(\"Failed to fetch transaction details. Please try again.\");\n }\n } finally {\n setLoading(false);\n }\n };\n\n const availableTokens = selectedNetwork\n ? tokenSelector.getAvailableTokens()\n : [];\n\n return (\n
\n \n \n \n {availableTokens.map((token) => (\n \n ))}\n \n {error &&
{error}
}\n
\n );\n};\n\nexport default TokenDropdown;\n","import { defineChain } from 'viem';\nimport { sepolia } from 'viem/chains';\n\nexport const mordor = defineChain({\n id: 63,\n name: 'Mordor Testnet',\n network: 'mordor',\n nativeCurrency: {\n decimals: 18,\n name: 'Mordor Ether',\n symbol: 'METC',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc.mordor.etccooperative.org'],\n webSocket: ['wss://rpc.mordor.etccooperative.org/ws'],\n },\n },\n blockExplorers: {\n default: { name: 'BlockScout', url: 'https://blockscout.com/etc/mordor' },\n },\n testnet: true,\n});\n\nexport const milkomeda = defineChain({\n id: 2001,\n name: 'Milkomeda C1 Mainnet',\n network: 'milkomeda',\n nativeCurrency: {\n decimals: 18,\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n },\n },\n blockExplorers: {\n default: { name: 'Milkomeda Explorer', url: 'https://explorer-mainnet-cardano-evm.c1.milkomeda.com' },\n },\n testnet: false,\n});\n\nexport const etcMainnet = defineChain({\n id: 61,\n name: 'Ethereum Classic',\n network: 'etc',\n nativeCurrency: {\n decimals: 18,\n name: 'Ethereum Classic',\n symbol: 'ETC',\n },\n rpcUrls: {\n default: {\n http: ['https://etc.rivet.link'],\n },\n },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://blockscout.com/etc/mainnet' },\n },\n testnet: false,\n});\n\nexport const getChainByNetworkKey = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return sepolia;\n case 'ethereum-classic':\n return etcMainnet;\n case 'milkomeda-mainnet':\n return milkomeda;\n default:\n return null;\n }\n};\n\nexport const getChainConfigForWallet = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return {\n chainId: `0x${sepolia.id.toString(16)}`,\n chainName: 'Sepolia',\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n rpcUrls: sepolia.rpcUrls.default.http,\n blockExplorerUrls: sepolia.blockExplorers?.default?.url ? [sepolia.blockExplorers.default.url] : [],\n };\n case 'ethereum-classic':\n return {\n chainId: `0x${etcMainnet.id.toString(16)}`,\n chainName: 'Ethereum Classic',\n nativeCurrency: {\n name: 'Ethereum Classic',\n symbol: 'ETC',\n decimals: 18,\n },\n rpcUrls: ['https://etc.rivet.link'],\n blockExplorerUrls: ['https://blockscout.com/etc/mainnet'],\n };\n case 'milkomeda-mainnet':\n return {\n chainId: `0x${milkomeda.id.toString(16)}`,\n chainName: 'Milkomeda C1 Mainnet',\n nativeCurrency: {\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n decimals: 18,\n },\n rpcUrls: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n blockExplorerUrls: ['https://explorer-mainnet-cardano-evm.c1.milkomeda.com'],\n };\n default:\n return null;\n }\n};\n","import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { createWalletClient, createPublicClient, custom, http } from 'viem';\nimport { useNetwork } from './NetworkContext';\nimport { getChainByNetworkKey, getChainConfigForWallet } from './chains';\n\nconst WalletContext = createContext(null);\n\nexport const useWallet = () => {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used within a WalletProvider');\n }\n return context;\n};\n\nconst switchToNetwork = async (networkKey) => {\n if (!window.ethereum) {\n throw new Error('MetaMask not installed');\n }\n\n const chainConfig = getChainConfigForWallet(networkKey);\n if (!chainConfig) {\n throw new Error(`Unsupported network: ${networkKey}`);\n }\n\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: chainConfig.chainId }],\n });\n } catch (switchError) {\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [chainConfig],\n });\n } catch (addError) {\n if (addError.code === 4001) {\n throw new Error(`User rejected adding ${chainConfig.chainName} to MetaMask. Please add it manually.`);\n }\n throw new Error(`Failed to add ${chainConfig.chainName} to MetaMask: ${addError.message}`);\n }\n } else if (switchError.code === 4001) {\n throw new Error(`User rejected switching to ${chainConfig.chainName}. Please switch manually in MetaMask.`);\n } else {\n throw new Error(`Failed to switch to ${chainConfig.chainName}: ${switchError.message}`);\n }\n }\n};\n\nexport const WalletProvider = ({ children }) => {\n const { selectedNetwork } = useNetwork();\n const [walletClient, setWalletClient] = useState(null);\n const [publicClient, setPublicClient] = useState(null);\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [balance, setBalance] = useState(null);\n const [error, setError] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n\n const selectedChain = selectedNetwork ? getChainByNetworkKey(selectedNetwork) : null;\n const expectedChainId = selectedChain ? selectedChain.id : null;\n\n const handleAccountsChangedRef = useRef(null);\n const handleChainChangedRef = useRef(null);\n\n const disconnectWalletInternal = useCallback(() => {\n setWalletClient(null);\n setPublicClient(null);\n setAccount(null);\n setChainId(null);\n setBalance(null);\n setError(null);\n }, []);\n\n const handleChainChanged = useCallback(async (chainIdHex) => {\n const newChainId = parseInt(chainIdHex, 16);\n setChainId(newChainId);\n\n if (selectedChain && newChainId === expectedChainId) {\n setError(null);\n if (window.ethereum && selectedChain) {\n const newWalletClient = createWalletClient({ \n chain: selectedChain, \n transport: custom(window.ethereum) \n });\n setWalletClient(newWalletClient);\n }\n } else if (selectedChain && newChainId !== expectedChainId) {\n const chainName = selectedChain?.name || selectedNetwork || 'selected network';\n setError(`Wrong network detected. Please switch to ${chainName}`);\n }\n }, [selectedChain, expectedChainId, selectedNetwork]);\n\n handleChainChangedRef.current = handleChainChanged;\n\n const handleAccountsChanged = useCallback(async (accounts) => {\n if (accounts.length === 0) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n } else {\n setAccount(accounts[0]);\n if (selectedChain) {\n try {\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n }\n }\n }, [selectedChain, disconnectWalletInternal]);\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n\n const disconnectWallet = useCallback(() => {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }, [disconnectWalletInternal]);\n\n const connectPublicClient = useCallback(() => {\n if (selectedChain) {\n setPublicClient(createPublicClient({ chain: selectedChain, transport: http() }));\n }\n }, [selectedChain]);\n\n const connectWallet = useCallback(async () => {\n if (!window.ethereum) {\n setError('Please install MetaMask or another Web3 wallet');\n return false;\n }\n\n if (!selectedNetwork || !selectedChain) {\n setError('Please select a network first');\n return false;\n }\n\n setIsConnecting(true);\n setError(null);\n\n try {\n const accounts = await window.ethereum.request({ \n method: 'eth_requestAccounts' \n });\n\n if (accounts.length === 0) {\n throw new Error('No wallet address found. Please unlock your wallet.');\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n await switchToNetwork(selectedNetwork);\n }\n\n const newWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(newWalletClient);\n setAccount(accounts[0]);\n setChainId(expectedChainId);\n\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n try {\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n handleChainChangedRef.current = handleChainChanged;\n window.ethereum.on('accountsChanged', handleAccountsChanged);\n window.ethereum.on('chainChanged', handleChainChanged);\n\n return true;\n } catch (err) {\n console.error('Error connecting wallet:', err);\n setError(err.message);\n return false;\n } finally {\n setIsConnecting(false);\n }\n }, [selectedNetwork, selectedChain, expectedChainId, handleAccountsChanged, handleChainChanged]);\n\n const ensureCorrectNetwork = useCallback(async () => {\n if (!window.ethereum || !selectedNetwork || !selectedChain || !account) {\n const errorMsg = 'Wallet not connected or network not selected';\n setError(errorMsg);\n return null;\n }\n\n try {\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n setError(null);\n await switchToNetwork(selectedNetwork);\n const NETWORK_SWITCH_DELAY_MS = 500;\n await new Promise(resolve => setTimeout(resolve, NETWORK_SWITCH_DELAY_MS));\n \n const newChainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const newChainId = parseInt(newChainIdHex, 16);\n if (newChainId !== expectedChainId) {\n throw new Error(`Failed to switch network. MetaMask is still on chain ${newChainId}, expected ${expectedChainId}`);\n }\n }\n\n const freshWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(freshWalletClient);\n setChainId(expectedChainId);\n setError(null);\n return freshWalletClient;\n } catch (err) {\n setError(err.message);\n return null;\n }\n }, [selectedNetwork, selectedChain, expectedChainId, account]);\n\n const prevNetworkRef = useRef(selectedNetwork);\n\n useEffect(() => {\n if (prevNetworkRef.current !== null && \n prevNetworkRef.current !== selectedNetwork && \n account) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }\n prevNetworkRef.current = selectedNetwork;\n }, [selectedNetwork, account, disconnectWalletInternal]);\n\n useEffect(() => {\n connectPublicClient();\n }, [connectPublicClient]);\n\n return (\n \n {children}\n \n );\n};","import React, { useState, useEffect } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { useWallet } from \"../contexts/WalletContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport { parseEther, encodeFunctionData, parseUnits } from \"viem\"; \nimport styles from \"../styles/PricingCard.css\"; \n\nconst TransactionReview = ({ onTransactionComplete }) => {\n const {\n networkSelector,\n selectedNetwork,\n selectedToken,\n transactionDetails: contextTransactionDetails,\n setTransactionDetails,\n } = useNetwork();\n\n const {\n connectWallet,\n account,\n walletClient,\n publicClient,\n isConnecting,\n ensureCorrectNetwork,\n expectedChainId,\n } = useWallet();\n\n const [transaction, setTransaction] = useState(null);\n const [tradeDataBuySc, setTradeDataBuySc] = useState(null);\n const [message, setMessage] = useState(\"\");\n const [txHash, setTxHash] = useState(null);\n const [error, setError] = useState(null);\n const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false);\n const [interactionState, setInteractionState] = useState('IDLE');\n\n useEffect(() => {\n setTradeDataBuySc(null);\n setMessage(\"\");\n setError(null);\n setTxHash(null);\n setInteractionState('IDLE');\n }, [selectedNetwork, selectedToken]);\n\n useEffect(() => {\n const initializeTransaction = async () => {\n if (!selectedNetwork || !selectedToken) return;\n\n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const receivingAddress = networkSelector.getReceivingAddress();\n const tokenAmount = networkSelector.getTokenAmount(selectedToken.key);\n\n const newTransaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await newTransaction.init();\n setTransaction(newTransaction);\n\n let tradeData = null;\n if (selectedToken.key === \"native\") {\n try {\n tradeData = await newTransaction.handleTradeDataBuySc(String(tokenAmount));\n setTradeDataBuySc(tradeData);\n } catch (tradeError) {\n console.error(\"Error fetching trade data:\", tradeError);\n }\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: selectedToken.key,\n tokenSymbol: selectedToken.symbol,\n amount: tokenAmount || \"0\",\n receivingAddress,\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer: selectedToken.isDirectTransfer || false,\n isNativeToken: selectedToken.isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...newTransaction.getBlockchainDetails(),\n });\n } catch (err) {\n console.error(\"Error initializing transaction:\", err);\n }\n };\n\n initializeTransaction();\n }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]);\n\n if (!selectedNetwork || !selectedToken) {\n return null;\n }\n\n if (!contextTransactionDetails) {\n if (typeof window !== 'undefined' && !window.ethereum) {\n return (\n
\n
\n No wallet found.\n
\n
\n \n
\n
\n );\n }\n return
Initializing transaction...
;\n }\n\n const handleConnectWallet = async () => {\n await connectWallet();\n };\n\n const executePayment = async () => {\n if (!account || !contextTransactionDetails || !transaction) {\n setMessage(\"Wallet not connected or transaction details missing\");\n return;\n }\n\n setInteractionState('PROCESSING');\n setMessage(\"Preparing transaction...\");\n setError(null);\n setTxHash(null);\n\n let builtTx;\n try {\n const receiver = contextTransactionDetails.receivingAddress;\n\n if (selectedToken.key === \"native\") {\n const UI = \"0x0232556C83791b8291E9b23BfEa7d67405Bd9839\";\n const amountToSend = tradeDataBuySc || \"0\";\n const valueInWei = parseEther(String(amountToSend));\n\n builtTx = await transaction.buyStablecoins(\n account,\n receiver,\n valueInWei,\n UI\n );\n\n builtTx = {\n ...builtTx,\n value: valueInWei,\n account: account,\n };\n } else {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const stablecoinAddress = networkConfig?.tokens?.stablecoin?.address;\n \n if (!stablecoinAddress) {\n throw new Error('Stablecoin address not found in network configuration');\n }\n\n const amountToSend = contextTransactionDetails.amount\n ? parseUnits(\n String(contextTransactionDetails.amount),\n contextTransactionDetails.stableCoinDecimals\n )\n : \"0\";\n\n builtTx = {\n to: stablecoinAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: [\n {\n inputs: [\n { internalType: \"address\", name: \"to\", type: \"address\" },\n { internalType: \"uint256\", name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ],\n functionName: \"transfer\",\n args: [receiver, amountToSend],\n }),\n account: account,\n };\n }\n } catch (err) {\n setError(err);\n const reason = err.shortMessage || (err.message ? err.message.split('\\n')[0] : \"Unknown error\");\n setMessage(`Transaction preparation failed: ${reason}`);\n setInteractionState('IDLE');\n return;\n }\n\n setMessage(\"Please check your wallet to confirm the transaction...\");\n \n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) {\n throw new Error(\"Network configuration not found\");\n }\n\n const freshWalletClient = await ensureCorrectNetwork();\n if (!freshWalletClient) {\n throw new Error(\"Failed to switch to correct network. Please approve the network switch in MetaMask.\");\n }\n\n if (!window.ethereum) {\n throw new Error(\"MetaMask not available\");\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== networkConfig.chainId) {\n throw new Error(`Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`);\n }\n\n if (freshWalletClient.chain.id !== networkConfig.chainId) {\n throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`);\n }\n\n const txHash = await freshWalletClient.sendTransaction({\n ...builtTx,\n account: account,\n });\n\n setTxHash(txHash);\n setMessage(`Transaction sent successfully!`);\n setInteractionState('SUCCESS');\n \n if (onTransactionComplete) {\n onTransactionComplete({\n txHash,\n network: selectedNetwork,\n token: selectedToken?.key,\n tokenSymbol: selectedToken?.symbol,\n amount: contextTransactionDetails?.amount,\n receivingAddress: contextTransactionDetails?.receivingAddress,\n });\n }\n } catch (err) {\n setError(err);\n \n let reason = \"Unknown error\";\n if (err.name === 'UserRejectedRequestError' || err.code === 4001) {\n reason = \"User denied transaction\";\n } else if (err.name === 'ContractFunctionRevertedError' || (err.data && err.data.message)) {\n reason = err.shortMessage || err.data?.message || err.message;\n } else {\n reason = err.shortMessage || (err.message ? err.message.split('\\n')[0] : \"Transaction failed\");\n }\n \n setMessage(`Transaction failed: ${reason}`);\n setInteractionState('IDLE');\n console.error('Transaction error:', err);\n }\n };\n\n const getExplorerUrl = () => {\n if (!txHash || !selectedNetwork) return null;\n\n const explorerBaseUrls = {\n \"ethereum-classic\": \"https://blockscout.com/etc/mainnet/tx/\",\n \"sepolia\": \"https://sepolia.etherscan.io/tx/\",\n \"milkomeda-mainnet\": \"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/\",\n };\n\n return explorerBaseUrls[selectedNetwork]\n ? `${explorerBaseUrls[selectedNetwork]}${txHash}`\n : null;\n };\n\n return (\n
\n
\n Network:\n {contextTransactionDetails.network}\n
\n\n
\n You Pay:\n \n {selectedToken.key === \"stablecoin\"\n ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}`\n : `${tradeDataBuySc ? tradeDataBuySc : \"Calculating...\"} ${\n contextTransactionDetails.tokenSymbol\n }`}\n \n
\n\n {message && (\n
\n {message}\n {error && (\n setIsErrorDetailsVisible(!isErrorDetailsVisible)}\n className={styles.detailsButton}\n >\n {isErrorDetailsVisible ? \"Hide Details\" : \"Show Details\"}\n \n )}\n
\n )}\n\n {isErrorDetailsVisible && error && (\n
\n
{error.message}
\n
\n )}\n\n {txHash && (\n
\n Transaction Hash:{\" \"}\n {getExplorerUrl() ? (\n \n {txHash.slice(0, 6)}...{txHash.slice(-6)}\n \n ) : (\n \n {txHash}\n \n )}\n
\n )}\n\n {interactionState !== 'SUCCESS' && (\n
\n {!account && (\n \n )}\n\n {account && interactionState === 'IDLE' && (\n \n )}\n\n {account && interactionState === 'CONFIRMING' && (\n
\n Confirm payment?\n
\n \n \n
\n
\n )}\n\n {account && interactionState === 'PROCESSING' && (\n \n )}\n
\n )}\n
\n );\n};\n\nexport default TransactionReview;\n","import React, { useState } from \"react\";\nimport PayButton from \"./PayButton\";\nimport Dialog from \"./Dialog\";\nimport NetworkDropdown from \"./NetworkDropdown\";\nimport TokenDropdown from \"./TokenDropdown\";\nimport TransactionReview from \"./TransactionReview\";\nimport { NetworkProvider, useNetwork } from \"../contexts/NetworkContext\";\nimport { WalletProvider } from \"../contexts/WalletContext\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst WidgetContent = ({ onClose, buttonSize, onTransactionComplete }) => {\n const { resetSelections } = useNetwork(); \n\n const handleClose = () => {\n resetSelections(); // Reset selections when closing the widget\n onClose();\n };\n\n return (\n \n \n \n \n \n );\n};\n\nconst WidgetWithProviders = ({ onClose, buttonSize, networkSelector, onTransactionComplete }) => {\n return (\n \n \n \n \n \n );\n};\n\nexport const Widget = ({ networkSelector, buttonSize = \"medium\", onTransactionComplete, onSuccess }) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const handleOpenDialog = () => {\n setIsDialogOpen(true);\n };\n\n const handleCloseDialog = () => {\n setIsDialogOpen(false);\n };\n\n // Support both onTransactionComplete and onSuccess for backwards compatibility\n const handleTransactionComplete = onTransactionComplete || onSuccess;\n\n return (\n
\n {!isDialogOpen && (\n \n )}\n {isDialogOpen && (\n \n )}\n
\n );\n};\n\nexport default Widget;\n","// src/index.js\nimport { NetworkSelector } from './core/NetworkSelector';\nimport { Transaction } from './core/Transaction';\nimport { Config } from './core/MerchantConfig';\nimport Widget from './widget/Widget.jsx';\nimport PayButton from './widget/PayButton.jsx';\nimport Dialog from './widget/Dialog.jsx';\nimport NetworkDropdown from './widget/NetworkDropdown.jsx';\nimport './styles/main.css';\nimport './styles/PricingCard.css';\n\nconst StablePay = {\n NetworkSelector,\n Transaction,\n Config,\n Widget,\n PayButton,\n Dialog,\n NetworkDropdown\n};\n\nexport default StablePay;","import { networksConfig } from \"../utils/config\";\n\nexport class NetworkSelector {\n constructor(merchantConfig) {\n this.merchantConfig = merchantConfig;\n this.blacklist = merchantConfig.getBlacklist();\n this.availableNetworks = this.getAvailableNetworks();\n this.selectedNetwork = null;\n }\n\n getAvailableNetworks() {\n return Object.entries(networksConfig).reduce(\n (acc, [networkKey, networkConfig]) => {\n if (!this.blacklist.includes(networkConfig.chainId)) {\n acc[networkKey] = networkConfig;\n }\n return acc;\n },\n {}\n );\n }\n\n selectNetwork(networkKey) {\n if (networkKey === null) {\n this.selectedNetwork = null;\n console.log(\"Network selection reset\");\n return true;\n }\n if (this.availableNetworks[networkKey]) {\n this.selectedNetwork = networkKey;\n console.log(`Network selected: ${networkKey}`);\n return true;\n }\n console.error(`Invalid network: ${networkKey}`);\n return false;\n }\n\n getSelectedNetworkConfig() {\n return this.selectedNetwork\n ? this.availableNetworks[this.selectedNetwork]\n : null;\n }\n\n getReceivingAddress() {\n return this.merchantConfig.getReceivingAddress();\n }\n\n getTokenAmount(token) {\n return this.merchantConfig.getTokenAmount(this.selectedNetwork, token);\n }\n}\n","import { networksConfig } from \"../utils/config\";\n\nexport class Config {\n constructor(options = {}) {\n this.receivingAddress = options.receivingAddress || \"\";\n this.blacklist = options.blacklist || [];\n this.amounts = options.amounts || options.Amounts || {};\n this.validateConfig();\n }\n\n validateConfig() {\n if (!this.receivingAddress) {\n throw new Error(\"Receiving address is required\");\n }\n // Validate stablecoin amounts\n for (const [network, tokens] of Object.entries(this.amounts)) {\n if (!networksConfig[network]) {\n throw new Error(`Invalid network: ${network}`);\n }\n if (\n !tokens.stablecoin ||\n typeof tokens.stablecoin !== \"number\" ||\n tokens.stablecoin <= 0\n ) {\n throw new Error(`Invalid stablecoin amount for network ${network}`);\n }\n }\n }\n\n getBlacklist() {\n return this.blacklist;\n }\n\n getReceivingAddress() {\n return this.receivingAddress;\n }\n\n // getTokenAmount(network, token) {\n // const networkConfig = networksConfig[network];\n // if (!networkConfig) return 0;\n\n // const stablecoinSymbol = networkConfig.tokens.stablecoin.symbol;\n\n // if (token === 'stablecoin') {\n // return this.amounts[network]?.stablecoin || 0;\n // }\n // // For native tokens, return 0 as it's not specified in the new structure\n // return 0;\n // }\n getTokenAmount(network) {\n console.log(\"Getting amount for network:\", network);\n console.log(\"Amounts object:\", this.amounts);\n\n // Directly return the stablecoin amount for the network\n const amount = this.amounts[network]?.stablecoin;\n console.log(\"Returning amount:\", amount);\n\n return amount || 0;\n }\n}\n\nexport default Config;\n"],"names":["networksConfig","sepolia","uri","chainId","djedAddress","tokens","stablecoin","symbol","address","decimals","isDirectTransfer","native","isNative","feeUI","Transaction","constructor","networkUri","this","init","Error","web3","getWeb3","djedContract","getDjedContract","stableCoin","reserveCoin","getCoinContracts","scDecimals","rcDecimals","getDecimals","oracleContract","getOracleAddress","then","addr","getOracleContract","_address","oracleAddress","contractError","console","error","code","data","getNetworkInfo","includes","name","networkName","message","getNetworkName","getBlockchainDetails","web3Available","djedContractAvailable","stableCoinAddress","reserveCoinAddress","stableCoinDecimals","reserveCoinDecimals","oracleContractAvailable","handleTradeDataBuySc","amountScaled","tradeDataPriceBuySc","totalBCScaled","buyStablecoins","payer","receiver","value","UI","buyScTx","PayButton","onClick","size","sizeStyles","small","width","height","fontSize","medium","large","logoSizes","buttonStyle","logoStyle","React","createElement","className","styles","style","Dialog","children","onClose","dialogOverlay","pricingCard","dialogClose","pricingCardHeader","allianceLogo","stablepayTitle","pricingCardBody","TokenSelector","networkSelector","selectedToken","selectToken","tokenKey","networkConfig","getSelectedNetworkConfig","key","getSelectedToken","getAvailableTokens","Object","entries","map","config","resetSelection","NetworkContext","createContext","NetworkProvider","tokenSelector","useState","selectedNetwork","setSelectedNetwork","setSelectedToken","transactionDetails","setTransactionDetails","resetState","useEffect","Provider","selectNetwork","networkKey","token","resetSelections","useNetwork","context","useContext","undefined","NetworkDropdown","selectField","htmlFor","id","onChange","event","target","disabled","keys","availableNetworks","TokenDropdown","loading","setLoading","setError","availableTokens","async","newValue","transaction","tokenAmount","getTokenAmount","blockchainDetails","tradeData","String","network","tokenSymbol","amount","receivingAddress","getReceivingAddress","djedContractAddress","isNativeToken","tradeAmount","err","window","ethereum","defineChain","nativeCurrency","rpcUrls","default","http","webSocket","blockExplorers","url","testnet","milkomeda","etcMainnet","WalletContext","switchToNetwork","chainConfig","toString","chainName","blockExplorerUrls","getChainConfigForWallet","request","method","params","switchError","addError","WalletProvider","walletClient","setWalletClient","publicClient","setPublicClient","account","setAccount","setChainId","balance","setBalance","isConnecting","setIsConnecting","selectedChain","getChainByNetworkKey","expectedChainId","handleAccountsChangedRef","useRef","handleChainChangedRef","disconnectWalletInternal","useCallback","handleChainChanged","newChainId","parseInt","chainIdHex","newWalletClient","createWalletClient","chain","transport","custom","current","handleAccountsChanged","accounts","length","accountsHandler","chainHandler","removeListener","newPublicClient","createPublicClient","getBalance","parseFloat","Math","pow","disconnectWallet","connectPublicClient","connectWallet","on","ensureCorrectNetwork","NETWORK_SWITCH_DELAY_MS","Promise","resolve","setTimeout","newChainIdHex","freshWalletClient","prevNetworkRef","TransactionReview","onTransactionComplete","contextTransactionDetails","useWallet","setTransaction","tradeDataBuySc","setTradeDataBuySc","setMessage","txHash","setTxHash","isErrorDetailsVisible","setIsErrorDetailsVisible","interactionState","setInteractionState","newTransaction","tradeError","initializeTransaction","transactionReview","messageBox","textAlign","marginBottom","color","walletButtonContainer","walletButton","open","getExplorerUrl","explorerBaseUrls","transactionInfo","transactionLabel","transactionValue","highlight","detailsButton","errorDetails","transactionLink","href","rel","explorerLink","slice","wordBreak","confirmContainer","confirmText","confirmButtons","secondaryButton","primaryButton","builtTx","amountToSend","valueInWei","parseEther","stablecoinAddress","parseUnits","to","encodeFunctionData","abi","inputs","internalType","type","outputs","stateMutability","functionName","args","reason","shortMessage","split","currentChainId","sendTransaction","WidgetContent","buttonSize","handleClose","WidgetWithProviders","NetworkSelector","merchantConfig","blacklist","getBlacklist","getAvailableNetworks","reduce","acc","log","Config","options","amounts","Amounts","validateConfig","Widget","onSuccess","isDialogOpen","setIsDialogOpen","handleTransactionComplete","widgetContainer","handleOpenDialog","handleCloseDialog"],"mappings":"2YACO,MAAMA,EAAiB,CAC5BC,QAAW,CACTC,IAAK,2CACLC,QAAS,SACTC,YAAa,6CACbC,OAAQ,CACNC,WAAY,CACVC,OAAQ,MACRC,QAAS,6CACTC,SAAU,GACVC,kBAAkB,GAEpBC,OAAQ,CACNJ,OAAQ,MACRE,SAAU,GACVG,UAAU,IAGdC,MAAO,GAET,oBAAqB,CACnBX,IAAK,mDACLC,QAAS,KACTC,YAAa,6CACbC,OAAQ,CACNC,WAAY,CACVC,OAAQ,MACRC,QAAS,6CACTC,SAAU,GACVC,kBAAkB,GAEpBC,OAAQ,CACNJ,OAAQ,OACRE,SAAU,GACVG,UAAU,IAGdC,MAAO,GAET,mBAAoB,CAClBX,IAAK,yBACLC,QAAS,GACTC,YAAa,6CACbC,OAAQ,CACNC,WAAY,CACVC,OAAQ,OACRC,QAAS,6CACTC,SAAU,GACVC,kBAAkB,GAEpBC,OAAQ,CACNJ,OAAQ,MACRE,SAAU,GACVG,UAAU,IAGdC,MAAO,ICvDJ,MAAMC,EACXC,WAAAA,CAAYC,EAAYZ,GACtBa,KAAKD,WAAaA,EAClBC,KAAKb,YAAcA,CACrB,CAEA,UAAMc,GACJ,IAAKD,KAAKD,aAAeC,KAAKb,YAC5B,MAAM,IAAIe,MAAM,6CAGlB,IACEF,KAAKG,WAAaC,EAAOA,QAACJ,KAAKD,YAC/BC,KAAKK,aAAeC,kBAAgBN,KAAKG,KAAMH,KAAKb,aAEpD,IACA,MAAMoB,WAAEA,EAAUC,YAAEA,SAAsBC,EAAgBA,iBAACT,KAAKK,aAAcL,KAAKG,OAC7EO,WAAEA,EAAUC,WAAEA,SAAqBC,EAAWA,YAACL,EAAYC,GACjER,KAAKO,WAAaA,EAClBP,KAAKQ,YAAcA,EACnBR,KAAKU,WAAaA,EAClBV,KAAKW,WAAaA,EAElBX,KAAKa,qBAAuBC,EAAAA,iBAAiBd,KAAKK,cAAcU,MAAMC,GACpEC,EAAAA,kBAAkBjB,KAAKG,KAAMa,EAAMhB,KAAKK,aAAaa,YAGvDlB,KAAKmB,cAAgBnB,KAAKa,eAAeK,QACxC,CAAC,MAAOE,GACPC,QAAQC,MAAM,iDAAkDF,GAEhE,IAD2C,OAAxBA,EAAcG,MAA0C,IAAvBH,EAAcG,MAAcH,EAAcI,KAC9E,CACd,MAAMC,EAAkBxC,GAClBA,EAAIyC,SAAS,aAAqB,CAAEC,KAAM,YAAazC,QAAS,QAChED,EAAIyC,SAAS,UAAkB,CAAEC,KAAM,iBAAkBzC,QAAS,MAClED,EAAIyC,SAAS,WAAmB,CAAEC,KAAM,UAAWzC,QAAS,YAC5DD,EAAIyC,SAAS,kBAA0B,CAAEC,KAAM,mBAAoBzC,QAAS,MACzE,CAAEyC,KAAM,uBAAwBzC,QAAS,YAE1CyC,KAAMC,EAAW1C,QAAEA,GAAYuC,EAAezB,KAAKD,YAC3D,MAAM,IAAIG,MACR,4CAA4CF,KAAKb,kBAAkByC,0GAG1BA,2GAEYA,gBAA0B1C,MAEnF,CACA,MAAMkC,CACR,CACD,CAAC,MAAOE,GACPD,QAAQC,MAAM,gDAAiDA,GAE/D,IAD0C,QAAhBA,EAAMC,MAAkC,OAAfD,EAAMC,OAAiC,QAAhBD,EAAMC,MAAoBD,EAAMO,UAAYP,EAAMO,QAAQH,SAAS,qBAAuBJ,EAAMO,QAAQH,SAAS,0BACpK,CACrB,MAMME,EANkB3C,IAClBA,EAAIyC,SAAS,aAAqB,YAClCzC,EAAIyC,SAAS,UAAkB,SAC/BzC,EAAIyC,SAAS,WAAmB,UAC7B,uBAEWI,CAAe9B,KAAKD,YACxC,MAAM,IAAIG,MACR,wBAAwB0B,mBAA6B5B,KAAKD,2PAO9D,CACA,MAAMuB,CACR,CACF,CAEAS,oBAAAA,GACE,MAAO,CACLC,gBAAiBhC,KAAKG,KACtB8B,wBAAyBjC,KAAKK,aAC9B6B,kBAAmBlC,KAAKO,WAAaP,KAAKO,WAAWW,SAAW,MAChEiB,mBAAoBnC,KAAKQ,YAAcR,KAAKQ,YAAYU,SAAW,MACnEkB,mBAAoBpC,KAAKU,WACzB2B,oBAAqBrC,KAAKW,WAC1BQ,cAAenB,KAAKmB,eAAiB,MACrCmB,0BAA2BtC,KAAKa,eAEpC,CAEA,0BAAM0B,CAAqBC,GACzB,IAAKxC,KAAKK,aACR,MAAM,IAAIH,MAAM,oCAElB,GAA4B,iBAAjBsC,EACT,MAAM,IAAItC,MAAM,2BAElB,IAEE,aADqBuC,EAAAA,oBAAoBzC,KAAKK,aAAcL,KAAKU,WAAY8B,IAC/DE,aACf,CAAC,MAAOpB,GAEP,MADAD,QAAQC,MAAM,qDAAsDA,GAC9DA,CACR,CACF,CAEA,oBAAMqB,CAAeC,EAAOC,EAAUC,GACpC,IAAK9C,KAAKK,aACR,MAAM,IAAIH,MAAM,oCAElB,IACE,MAAM6C,EAAK,6CAIX,aAFqBC,UAAQhD,KAAKK,aAAcuC,EAAOC,EAAUC,EAAOC,EAAI/C,KAAKb,YAGlF,CAAC,MAAOmC,GAEP,MADAD,QAAQC,MAAM,+CAAgDA,GACxDA,CACR,CACF,sFCrHF,MAAM2B,EAAYA,EAAGC,UAASC,OAAO,aACnC,MAAMC,EAAa,CACjBC,MAAO,CAAEC,MAAO,QAASC,OAAQ,OAAQC,SAAU,QACnDC,OAAQ,CAAEH,MAAO,QAASC,OAAQ,OAAQC,SAAU,QACpDE,MAAO,CAAEJ,MAAO,QAASC,OAAQ,OAAQC,SAAU,SAG/CG,EAAY,CAChBN,MAAO,CAAEC,MAAO,OAAQC,OAAQ,QAChCE,OAAQ,CAAEH,MAAO,OAAQC,OAAQ,QACjCG,MAAO,CAAEJ,MAAO,OAAQC,OAAQ,SAG5BK,EAAcR,EAAWD,IAASC,EAAWK,OAC7CI,EAAYF,EAAUR,IAASQ,EAAUF,OAE/C,OACEK,EAAAC,cAAA,SAAA,CACEC,UAAWC,EACXf,QAASA,EACTgB,MAAON,GAEPE,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAaC,MAAOL,IACpCC,EAAAC,cAAA,OAAA,CAAMC,UAAWC,GAAmB,sBAC7B,8kDCvBb,MAAME,EAASA,EAAGC,WAAUC,UAASlB,OAAO,YAExCW,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOK,eACrBR,EAAAC,cAAA,MAAA,CAAKC,UAAW,GAAGC,EAAOM,eAAeN,EAAOd,MAC9CW,EAAAC,cAAA,SAAA,CAAQC,UAAWC,EAAOO,YAAatB,QAASmB,GAAS,KACzDP,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOQ,mBACvBX,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOS,eAErBZ,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOU,gBAAgB,cAEzCb,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOW,iBACpBR,KCbJ,MAAMS,EACX/E,WAAAA,CAAYgF,GACV9E,KAAK8E,gBAAkBA,EACvB9E,KAAK+E,cAAgB,IACvB,CAEAC,WAAAA,CAAYC,GACV,MAAMC,EAAgBlF,KAAK8E,gBAAgBK,2BAC3C,SAAID,IAAiBA,EAAc9F,OAAO6F,MACxCjF,KAAK+E,cAAgB,CACnBK,IAAKH,KACFC,EAAc9F,OAAO6F,KAEnB,EAGX,CAEAI,gBAAAA,GACE,OAAOrF,KAAK+E,aACd,CAEAO,kBAAAA,GACE,MAAMJ,EAAgBlF,KAAK8E,gBAAgBK,2BAC3C,OAAKD,EAEEK,OAAOC,QAAQN,EAAc9F,QAAQqG,KAAI,EAAEL,EAAKM,MAAa,CAClEN,SACGM,MAJsB,EAM7B,CAEAC,cAAAA,GACE3F,KAAK+E,cAAgB,IACvB,ECjCF,MAAMa,EAAiBC,EAAaA,gBAEvBC,EAAkBA,EAAG1B,WAAUU,sBAC1C,MAAOiB,GAAiBC,EAAQA,UAAC,IAAM,IAAInB,EAAcC,MAClDmB,EAAiBC,GAAsBF,EAAQA,SAAC,OAChDjB,EAAeoB,GAAoBH,EAAQA,SAAC,OAC5CI,EAAoBC,GAAyBL,EAAQA,SAAC,MAEvDM,EAAaA,KACjBH,EAAiB,MACjBE,EAAsB,KAAK,EAgC7B,OAJAE,EAAAA,WAAU,KACRL,EAAmBpB,EAAgBmB,gBAAgB,GAClD,CAACnB,EAAgBmB,kBAGlBnC,EAAAC,cAAC6B,EAAeY,SAAQ,CAAC1D,MAAO,CAC9BgC,kBACAiB,gBACAE,kBACAlB,gBACAqB,qBACAC,wBACAI,cArCmBC,KACjB5B,EAAgB2B,cAAcC,KAChCR,EAAmBQ,GACnBJ,KACO,GAkCPtB,YA7BiBC,IACnB,GAAIc,EAAcf,YAAYC,GAAW,CACvC,MAAM0B,EAAQZ,EAAcV,mBAE5B,OADAc,EAAiBQ,IACV,CACT,CACA,OAAO,CAAK,EAwBVC,gBArBoBA,KACtB9B,EAAgB2B,cAAc,MAC9BP,EAAmB,MACnBI,GAAY,IAoBTlC,EACuB,EAIjByC,EAAaA,KACxB,MAAMC,EAAUC,aAAWnB,GAC3B,QAAgBoB,IAAZF,EACF,MAAM,IAAI5G,MAAM,oDAElB,OAAO4G,CAAO,EC/DVG,EAAkBA,KACtB,MAAMnC,gBAAEA,EAAemB,gBAAEA,EAAeQ,cAAEA,GAAkBI,IAM5D,OACE/C,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOiD,aACrBpD,EAAAC,cAAA,QAAA,CAAOoD,QAAQ,kBAAiB,kBAChCrD,EAAAC,cAAA,SAAA,CACEqD,GAAG,iBACHC,SATuBC,IAC3Bb,EAAca,EAAMC,OAAOzE,MAAM,EAS7BA,MAAOmD,GAAmB,IAE1BnC,EAAAC,cAAA,SAAA,CAAQjB,MAAM,GAAG0E,UAAQ,GAAC,oBACzBjC,OAAOkC,KAAK3C,EAAgB4C,mBAAmBjC,KAAKiB,GACnD5C,EAAAC,cAAA,SAAA,CAAQqB,IAAKsB,EAAY5D,MAAO4D,GAAaA,MAG7C,ECnBJiB,EAAgBA,KACpB,MAAM7C,gBACJA,EAAeiB,cACfA,EAAaE,gBACbA,EAAelB,cACfA,EAAaC,YACbA,EAAWqB,sBACXA,GACEQ,KAEGe,EAASC,GAAc7B,EAAQA,UAAC,IAChC1E,EAAOwG,GAAY9B,EAAQA,SAAC,MAoD7B+B,EAAkB9B,EACpBF,EAAcT,qBACd,GAEJ,OACExB,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOiD,aACrBpD,EAAAC,cAAA,QAAA,CAAOoD,QAAQ,gBAAe,gBAC9BrD,EAAAC,cAAA,SAAA,CACEqD,GAAG,eACHC,SA3DoBW,UACxB,MAAMC,EAAWX,EAAMC,OAAOzE,MAC9BgF,EAAS,MACTD,GAAW,GAEX,IACE,GAAI7C,EAAYiD,GAAW,CACzB,MAAM/C,EAAgBJ,EAAgBK,2BAChC+C,EAAc,IAAIrI,EACtBqF,EAAcjG,IACdiG,EAAc/F,mBAEV+I,EAAYjI,OAElB,MAAMkI,EAAcrD,EAAgBsD,eAAeH,GAC7CI,EAAoBH,EAAYnG,uBAEtC,IAAIuG,EAAY,KACC,WAAbL,IACFK,QAAkBJ,EAAY3F,qBAC5BgG,OAAOJ,KAIX9B,EAAsB,CACpBmC,QAASvC,EACTU,MAAOsB,EACPQ,YAAa1C,EAAcV,mBAAmB/F,OAC9CoJ,OAAQP,EACRQ,iBAAkB7D,EAAgB8D,sBAClCC,oBAAqB3D,EAAc/F,YACnCM,iBACEsG,EAAcV,mBAAmB5F,mBAAoB,EACvDqJ,cAAe/C,EAAcV,mBAAmB1F,WAAY,EAC5DoJ,YAAaT,EAAYA,EAAUI,OAAS,QACzCL,GAEP,CACD,CAAC,MAAOW,GACP3H,QAAQC,MAAM,sCAAuC0H,GAC/B,oBAAXC,QAA2BA,OAAOC,SAG3CpB,EAAS,0DAFTA,EAAS,iDAIb,CAAU,QACRD,GAAW,EACb,GAaI/E,MAAOiC,EAAgBA,EAAcK,IAAM,GAC3CoC,UAAWvB,GAAmB2B,GAE9B9D,EAAAC,cAAA,SAAA,CAAQjB,MAAM,GAAG0E,UAAQ,GACtBvB,EACG2B,EACE,aACA,iBACF,iCAELG,EAAgBtC,KAAKkB,GACpB7C,EAAAC,cAAA,SAAA,CAAQqB,IAAKuB,EAAMvB,IAAKtC,MAAO6D,EAAMvB,KAClCuB,EAAMrH,OAAO,KACbqH,EAAMlH,iBAAmB,kBAAoB,SAAS,QAI5D6B,GAASwC,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAO3C,OAAQA,GACrC,EC7FY6H,EAAAA,YAAY,CAChC/B,GAAI,GACJzF,KAAM,iBACN6G,QAAS,SACTY,eAAgB,CACd5J,SAAU,GACVmC,KAAM,eACNrC,OAAQ,QAEV+J,QAAS,CACPC,QAAS,CACPC,KAAM,CAAC,yCACPC,UAAW,CAAC,4CAGhBC,eAAgB,CACdH,QAAS,CAAE3H,KAAM,aAAc+H,IAAK,sCAEtCC,SAAS,IAGJ,MAAMC,EAAYT,EAAAA,YAAY,CACnC/B,GAAI,KACJzF,KAAM,uBACN6G,QAAS,YACTY,eAAgB,CACd5J,SAAU,GACVmC,KAAM,gBACNrC,OAAQ,QAEV+J,QAAS,CACPC,QAAS,CACPC,KAAM,CAAC,sDAGXE,eAAgB,CACdH,QAAS,CAAE3H,KAAM,qBAAsB+H,IAAK,0DAE9CC,SAAS,IAGEE,EAAaV,EAAAA,YAAY,CACpC/B,GAAI,GACJzF,KAAM,mBACN6G,QAAS,MACTY,eAAgB,CACd5J,SAAU,GACVmC,KAAM,mBACNrC,OAAQ,OAEV+J,QAAS,CACPC,QAAS,CACPC,KAAM,CAAC,4BAGXE,eAAgB,CACdH,QAAS,CAAE3H,KAAM,aAAc+H,IAAK,uCAEtCC,SAAS,ICxDLG,EAAgBjE,EAAAA,cAAc,MAU9BkE,EAAkB/B,UACtB,IAAKiB,OAAOC,SACV,MAAM,IAAIhJ,MAAM,0BAGlB,MAAM8J,EDyDgCtD,KACtC,OAAQA,GACN,IAAK,UACH,MAAO,CACLxH,QAAS,KAAKF,EAAOA,QAACoI,GAAG6C,SAAS,MAClCC,UAAW,UACXd,eAAgB,CACdzH,KAAM,QACNrC,OAAQ,MACRE,SAAU,IAEZ6J,QAASrK,EAAOA,QAACqK,QAAQC,QAAQC,KACjCY,kBAAmBnL,EAAOA,QAACyK,gBAAgBH,SAASI,IAAM,CAAC1K,EAAOA,QAACyK,eAAeH,QAAQI,KAAO,IAErG,IAAK,mBACH,MAAO,CACLxK,QAAS,KAAK2K,EAAWzC,GAAG6C,SAAS,MACrCC,UAAW,mBACXd,eAAgB,CACdzH,KAAM,mBACNrC,OAAQ,MACRE,SAAU,IAEZ6J,QAAS,CAAC,0BACVc,kBAAmB,CAAC,uCAExB,IAAK,oBACH,MAAO,CACLjL,QAAS,KAAK0K,EAAUxC,GAAG6C,SAAS,MACpCC,UAAW,uBACXd,eAAgB,CACdzH,KAAM,gBACNrC,OAAQ,OACRE,SAAU,IAEZ6J,QAAS,CAAC,oDACVc,kBAAmB,CAAC,0DAExB,QACE,OAAO,KACX,ECjGoBC,CAAwB1D,GAC5C,IAAKsD,EACH,MAAM,IAAI9J,MAAM,wBAAwBwG,KAG1C,UACQuC,OAAOC,SAASmB,QAAQ,CAC5BC,OAAQ,6BACRC,OAAQ,CAAC,CAAErL,QAAS8K,EAAY9K,WAEnC,CAAC,MAAOsL,GACP,GAAyB,OAArBA,EAAYjJ,KAYT,MAAyB,OAArBiJ,EAAYjJ,KACf,IAAIrB,MAAM,8BAA8B8J,EAAYE,kDAEpD,IAAIhK,MAAM,uBAAuB8J,EAAYE,cAAcM,EAAY3I,WAd7E,UACQoH,OAAOC,SAASmB,QAAQ,CAC5BC,OAAQ,0BACRC,OAAQ,CAACP,IAEZ,CAAC,MAAOS,GACP,GAAsB,OAAlBA,EAASlJ,KACX,MAAM,IAAIrB,MAAM,wBAAwB8J,EAAYE,kDAEtD,MAAM,IAAIhK,MAAM,iBAAiB8J,EAAYE,0BAA0BO,EAAS5I,UAClF,CAMJ,GAGW6I,EAAiBA,EAAGtG,eAC/B,MAAM6B,gBAAEA,GAAoBY,KACrB8D,EAAcC,GAAmB5E,EAAQA,SAAC,OAC1C6E,EAAcC,GAAmB9E,EAAQA,SAAC,OAC1C+E,EAASC,GAAchF,EAAQA,SAAC,OAChC9G,EAAS+L,GAAcjF,EAAQA,SAAC,OAChCkF,EAASC,GAAcnF,EAAQA,SAAC,OAChC1E,EAAOwG,GAAY9B,EAAQA,SAAC,OAC5BoF,EAAcC,GAAmBrF,EAAQA,UAAC,GAE3CsF,EAAgBrF,EDGaS,KACnC,OAAQA,GACN,IAAK,UACH,OAAO1H,UACT,IAAK,mBACH,OAAO6K,EACT,IAAK,oBACH,OAAOD,EACT,QACE,OAAO,KACX,ECbwC2B,CAAqBtF,GAAmB,KAC1EuF,EAAkBF,EAAgBA,EAAclE,GAAK,KAErDqE,EAA2BC,SAAO,MAClCC,EAAwBD,SAAO,MAE/BE,EAA2BC,EAAAA,aAAY,KAC3CjB,EAAgB,MAChBE,EAAgB,MAChBE,EAAW,MACXC,EAAW,MACXE,EAAW,MACXrD,EAAS,KAAK,GACb,IAEGgE,EAAqBD,eAAY7D,UACrC,MAAM+D,EAAaC,SAASC,EAAY,IAGxC,GAFAhB,EAAWc,GAEPT,GAAiBS,IAAeP,GAElC,GADA1D,EAAS,MACLmB,OAAOC,UAAYoC,EAAe,CACpC,MAAMY,EAAkBC,EAAAA,mBAAmB,CACzCC,MAAOd,EACPe,UAAWC,EAAAA,OAAOrD,OAAOC,YAE3B0B,EAAgBsB,EAClB,OACK,GAAIZ,GAAiBS,IAAeP,EAAiB,CAE1D1D,EAAS,4CADSwD,GAAe3J,MAAQsE,GAAmB,qBAE9D,IACC,CAACqF,EAAeE,EAAiBvF,IAEpC0F,EAAsBY,QAAUT,EAEhC,MAAMU,EAAwBX,eAAY7D,UACxC,GAAwB,IAApByE,EAASC,QAEX,GADAd,IACI3C,OAAOC,SAAU,CACnB,MAAMyD,EAAkBlB,EAAyBc,QAC3CK,EAAejB,EAAsBY,QACvCI,GACF1D,OAAOC,SAAS2D,eAAe,kBAAmBF,GAEhDC,GACF3D,OAAOC,SAAS2D,eAAe,eAAgBD,EAEnD,OAGA,GADA5B,EAAWyB,EAAS,IAChBnB,EACF,IACE,MAAMwB,EAAkBC,EAAAA,mBAAmB,CAAEX,MAAOd,EAAee,UAAW9C,EAAAA,SAC9EuB,EAAgBgC,GAChB,MAAM5B,QAAgB4B,EAAgBE,WAAW,CAAEzN,QAASkN,EAAS,KACrEtB,EAAW8B,WAAW/B,GAAWgC,KAAKC,IAAI,GAAI,IAC/C,CAAC,MAAO7L,GACPD,QAAQC,MAAM,0BAA2BA,GACzC6J,EAAW,KACb,CAEJ,GACC,CAACG,EAAeM,IAEnBH,EAAyBc,QAAUC,EAEnC,MAAMY,EAAmBvB,EAAAA,aAAY,KAEnC,GADAD,IACI3C,OAAOC,SAAU,CACnB,MAAMyD,EAAkBlB,EAAyBc,QAC3CK,EAAejB,EAAsBY,QACvCI,GACF1D,OAAOC,SAAS2D,eAAe,kBAAmBF,GAEhDC,GACF3D,OAAOC,SAAS2D,eAAe,eAAgBD,EAEnD,IACC,CAAChB,IAEEyB,EAAsBxB,EAAAA,aAAY,KAClCP,GACFR,EAAgBiC,EAAAA,mBAAmB,CAAEX,MAAOd,EAAee,UAAW9C,EAAAA,SACxE,GACC,CAAC+B,IAEEgC,EAAgBzB,EAAAA,aAAY7D,UAChC,IAAKiB,OAAOC,SAEV,OADApB,EAAS,mDACF,EAGT,IAAK7B,IAAoBqF,EAEvB,OADAxD,EAAS,kCACF,EAGTuD,GAAgB,GAChBvD,EAAS,MAET,IACE,MAAM2E,QAAiBxD,OAAOC,SAASmB,QAAQ,CAC7CC,OAAQ,wBAGV,GAAwB,IAApBmC,EAASC,OACX,MAAM,IAAIxM,MAAM,uDAGlB,MAAM+L,QAAmBhD,OAAOC,SAASmB,QAAQ,CAAEC,OAAQ,gBACpC0B,SAASC,EAAY,MAErBT,SACfzB,EAAgB9D,GAGxB,MAAMiG,EAAkBC,EAAAA,mBAAmB,CACzCC,MAAOd,EACPe,UAAWC,EAAAA,OAAOrD,OAAOC,YAG3B0B,EAAgBsB,GAChBlB,EAAWyB,EAAS,IACpBxB,EAAWO,GAEX,MAAMsB,EAAkBC,EAAAA,mBAAmB,CAAEX,MAAOd,EAAee,UAAW9C,EAAAA,SAC9EuB,EAAgBgC,GAChB,IACE,MAAM5B,QAAgB4B,EAAgBE,WAAW,CAAEzN,QAASkN,EAAS,KACrEtB,EAAW8B,WAAW/B,GAAWgC,KAAKC,IAAI,GAAI,IAC/C,CAAC,MAAO7L,GACPD,QAAQC,MAAM,0BAA2BA,GACzC6J,EAAW,KACb,CAOA,OALAM,EAAyBc,QAAUC,EACnCb,EAAsBY,QAAUT,EAChC7C,OAAOC,SAASqE,GAAG,kBAAmBf,GACtCvD,OAAOC,SAASqE,GAAG,eAAgBzB,IAE5B,CACR,CAAC,MAAO9C,GAGP,OAFA3H,QAAQC,MAAM,2BAA4B0H,GAC1ClB,EAASkB,EAAInH,UACN,CACT,CAAU,QACRwJ,GAAgB,EAClB,IACC,CAACpF,EAAiBqF,EAAeE,EAAiBgB,EAAuBV,IAEtE0B,EAAuB3B,EAAAA,aAAY7D,UACvC,KAAKiB,OAAOC,UAAajD,GAAoBqF,GAAkBP,GAAS,CAGtE,OADAjD,EADiB,gDAEV,IACT,CAEA,IACE,MAAMmE,QAAmBhD,OAAOC,SAASmB,QAAQ,CAAEC,OAAQ,gBAG3D,GAFuB0B,SAASC,EAAY,MAErBT,EAAiB,CACtC1D,EAAS,YACHiC,EAAgB9D,GACtB,MAAMwH,EAA0B,UAC1B,IAAIC,SAAQC,GAAWC,WAAWD,EAASF,KAEjD,MAAMI,QAAsB5E,OAAOC,SAASmB,QAAQ,CAAEC,OAAQ,gBACxDyB,EAAaC,SAAS6B,EAAe,IAC3C,GAAI9B,IAAeP,EACjB,MAAM,IAAItL,MAAM,wDAAwD6L,eAAwBP,IAEpG,CAEA,MAAMsC,EAAoB3B,EAAAA,mBAAmB,CAC3CC,MAAOd,EACPe,UAAWC,EAAAA,OAAOrD,OAAOC,YAM3B,OAHA0B,EAAgBkD,GAChB7C,EAAWO,GACX1D,EAAS,MACFgG,CACR,CAAC,MAAO9E,GAEP,OADAlB,EAASkB,EAAInH,SACN,IACT,IACC,CAACoE,EAAiBqF,EAAeE,EAAiBT,IAE/CgD,EAAiBrC,SAAOzF,GAyB9B,OAvBAM,EAAAA,WAAU,KACR,GAA+B,OAA3BwH,EAAexB,SACfwB,EAAexB,UAAYtG,GAC3B8E,IACFa,IACI3C,OAAOC,UAAU,CACnB,MAAMyD,EAAkBlB,EAAyBc,QAC3CK,EAAejB,EAAsBY,QACvCI,GACF1D,OAAOC,SAAS2D,eAAe,kBAAmBF,GAEhDC,GACF3D,OAAOC,SAAS2D,eAAe,eAAgBD,EAEnD,CAEFmB,EAAexB,QAAUtG,CAAe,GACvC,CAACA,EAAiB8E,EAASa,IAE9BrF,EAAAA,WAAU,KACR8G,GAAqB,GACpB,CAACA,IAGFvJ,EAAAC,cAAC+F,EAActD,SAAQ,CACrB1D,MAAO,CACL6H,eACAE,eACAE,UACA7L,UACAgM,UACA5J,QACA8J,eACAkC,gBACAF,mBACAI,uBACAhC,oBAGDpH,EACsB,EC9RvB4J,EAAoBA,EAAGC,4BAC3B,MAAMnJ,gBACJA,EAAemB,gBACfA,EAAelB,cACfA,EACAqB,mBAAoB8H,EAAyB7H,sBAC7CA,GACEQ,KAEEyG,cACJA,EAAavC,QACbA,EAAOJ,aACPA,EAAYE,aACZA,EAAYO,aACZA,EAAYoC,qBACZA,EAAoBhC,gBACpBA,GDhBqB2C,MACvB,MAAMrH,EAAUC,aAAW+C,GAC3B,IAAKhD,EACH,MAAM,IAAI5G,MAAM,kDAElB,OAAO4G,CAAO,ECYVqH,IAEGjG,EAAakG,GAAkBpI,EAAQA,SAAC,OACxCqI,EAAgBC,GAAqBtI,EAAQA,SAAC,OAC9CnE,EAAS0M,GAAcvI,EAAQA,SAAC,KAChCwI,EAAQC,GAAazI,EAAQA,SAAC,OAC9B1E,EAAOwG,GAAY9B,EAAQA,SAAC,OAC5B0I,EAAuBC,GAA4B3I,EAAQA,UAAC,IAC5D4I,EAAkBC,GAAuB7I,EAAQA,SAAC,QAwDzD,GAtDAO,EAAAA,WAAU,KACR+H,EAAkB,MAClBC,EAAW,IACXzG,EAAS,MACT2G,EAAU,MACVI,EAAoB,OAAO,GAC1B,CAAC5I,EAAiBlB,IAErBwB,EAAAA,WAAU,KACsByB,WAC5B,GAAK/B,GAAoBlB,EAEzB,IACE,MAAMG,EAAgBJ,EAAgBK,2BAChCwD,EAAmB7D,EAAgB8D,sBACnCT,EAAcrD,EAAgBsD,eAAerD,EAAcK,KAE3D0J,EAAiB,IAAIjP,EACzBqF,EAAcjG,IACdiG,EAAc/F,mBAEV2P,EAAe7O,OACrBmO,EAAeU,GAEf,IAAIxG,EAAY,KAChB,GAA0B,WAAtBvD,EAAcK,IAChB,IACEkD,QAAkBwG,EAAevM,qBAAqBgG,OAAOJ,IAC7DmG,EAAkBhG,EACnB,CAAC,MAAOyG,GACP1N,QAAQC,MAAM,6BAA8ByN,EAC9C,CAGF1I,EAAsB,CACpBmC,QAASvC,EACTU,MAAO5B,EAAcK,IACrBqD,YAAa1D,EAAczF,OAC3BoJ,OAAQP,GAAe,IACvBQ,mBACAE,oBAAqB3D,EAAc/F,YACnCM,iBAAkBsF,EAActF,mBAAoB,EACpDqJ,cAAe/D,EAAcpF,WAAY,EACzCoJ,YAAaT,EAAYA,EAAUI,OAAS,QACzCoG,EAAe/M,wBAErB,CAAC,MAAOiH,GACP3H,QAAQC,MAAM,kCAAmC0H,EACnD,GAGFgG,EAAuB,GACtB,CAAC/I,EAAiBlB,EAAeD,EAAiBuB,KAEhDJ,IAAoBlB,EACvB,OAAO,KAGT,IAAKmJ,EACH,MAAsB,oBAAXjF,QAA2BA,OAAOC,SAiBtCpF,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAO2D,SAAS,+BAfnC9D,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOgL,mBACrBnL,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOiL,WAAYhL,MAAO,CAAEiL,UAAW,SAAUC,aAAc,OAAQC,MAAO,YAAa,oBAG3GvL,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOqL,uBACrBxL,EAAAC,cAAA,SAAA,CACEC,UAAWC,EAAOsL,aAClBrM,QAASA,IAAM+F,OAAOuG,KAAK,gCAAiC,WAC7D,oBAUX,MAkJMC,EAAiBA,KACrB,IAAKjB,IAAWvI,EAAiB,OAAO,KAExC,MAAMyJ,EAAmB,CACvB,mBAAoB,yCACpB1Q,QAAW,mCACX,oBAAqB,6DAGvB,OAAO0Q,EAAiBzJ,GACpB,GAAGyJ,EAAiBzJ,KAAmBuI,IACvC,IAAI,EAGV,OACE1K,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOgL,mBACrBnL,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAO0L,iBACrB7L,EAAAC,cAAA,OAAA,CAAMC,UAAWC,EAAO2L,kBAAkB,YAC1C9L,EAAAC,cAAA,OAAA,CAAMC,UAAWC,EAAO4L,kBAAmB3B,EAA0B1F,UAGvE1E,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAO0L,iBACrB7L,EAAAC,cAAA,OAAA,CAAMC,UAAWC,EAAO2L,kBAAkB,YAC1C9L,EAAAC,cAAA,OAAA,CAAMC,UAAW,GAAGC,EAAO4L,oBAAoB5L,EAAO6L,aAC7B,eAAtB/K,EAAcK,IACX,GAAG8I,EAA0BxF,UAAUwF,EAA0BzF,cACjE,GAAG4F,GAAkC,oBACnCH,EAA0BzF,gBAKnC5G,GACCiC,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOiL,YACpBrN,EACAP,GACCwC,EAAAC,cAAA,SAAA,CACEb,QAASA,IAAMyL,GAA0BD,GACzC1K,UAAWC,EAAO8L,eAEjBrB,EAAwB,eAAiB,iBAMjDA,GAAyBpN,GACxBwC,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAO+L,cACrBlM,EAAAC,cAAA,MAAA,KAAMzC,EAAMO,UAIf2M,GACC1K,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOgM,iBAAiB,oBACpB,IACjBR,IACC3L,EAAAC,cAAA,IAAA,CACEmM,KAAMT,IACNlI,OAAO,SACP4I,IAAI,sBACJnM,UAAWC,EAAOmM,cAEjB5B,EAAO6B,MAAM,EAAG,GAAG,MAAI7B,EAAO6B,OAAO,IAGxCvM,EAAAC,cAAA,OAAA,CAAMG,MAAO,CAAEoM,UAAW,eACvB9B,IAMa,YAArBI,GACC9K,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOqL,wBACnBvE,GACAjH,EAAAC,cAAA,SAAA,CAAQC,UAAWC,EAAOsL,aAAcrM,QA7NtB8E,gBACpBsF,GAAe,EA4NyD9F,SAAU4D,GAC7EA,EAAe,gBAAkB,kBAIrCL,GAAgC,SAArB6D,GACV9K,EAAAC,cAAA,SAAA,CAAQC,UAAWC,EAAOsL,aAAcrM,QAASA,IAAM2L,EAAoB,eAAe,OACnFX,EAA0BxF,OAAO,IAAEwF,EAA0BzF,aAIrEsC,GAAgC,eAArB6D,GACV9K,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOsM,kBACrBzM,EAAAC,cAAA,OAAA,CAAMC,UAAWC,EAAOuM,aAAa,oBACrC1M,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOwM,gBACrB3M,EAAAC,cAAA,SAAA,CAAQC,UAAWC,EAAOyM,gBAAiBxN,QAASA,IAAM2L,EAAoB,SAAS,MAGvF/K,EAAAC,cAAA,SAAA,CAAQC,UAAW,GAAGC,EAAOsL,gBAAgBtL,EAAO0M,gBAAiBzN,QA3O5D8E,UACrB,IAAK+C,IAAYmD,IAA8BhG,EAE7C,YADAqG,EAAW,uDASb,IAAIqC,EALJ/B,EAAoB,cACpBN,EAAW,4BACXzG,EAAS,MACT2G,EAAU,MAGV,IACE,MAAM5L,EAAWqL,EAA0BvF,iBAE3C,GAA0B,WAAtB5D,EAAcK,IAAkB,CAClC,MAAMrC,EAAK,6CACL8N,EAAexC,GAAkB,IACjCyC,EAAaC,EAAUA,WAACxI,OAAOsI,IAErCD,QAAgB1I,EAAYvF,eAC1BoI,EACAlI,EACAiO,EACA/N,GAGF6N,EAAU,IACLA,EACH9N,MAAOgO,EACP/F,QAASA,EAEb,KAAO,CACL,MAAM7F,EAAgBJ,EAAgBK,2BAChC6L,EAAoB9L,GAAe9F,QAAQC,YAAYE,QAE7D,IAAKyR,EACH,MAAM,IAAI9Q,MAAM,yDAGlB,MAAM2Q,EAAe3C,EAA0BxF,OAC3CuI,EAAUA,WACR1I,OAAO2F,EAA0BxF,QACjCwF,EAA0B9L,oBAE5B,IAEJwO,EAAU,CACRM,GAAIF,EACJlO,MAAO,GACPtB,KAAM2P,EAAAA,mBAAmB,CACvBC,IAAK,CACH,CACEC,OAAQ,CACN,CAAEC,aAAc,UAAW3P,KAAM,KAAM4P,KAAM,WAC7C,CAAED,aAAc,UAAW3P,KAAM,SAAU4P,KAAM,YAEnD5P,KAAM,WACN6P,QAAS,CAAC,CAAEF,aAAc,OAAQ3P,KAAM,GAAI4P,KAAM,SAClDE,gBAAiB,aACjBF,KAAM,aAGVG,aAAc,WACdC,KAAM,CAAC9O,EAAUgO,KAEnB9F,QAASA,EAEb,CACD,CAAC,MAAO/B,GACPlB,EAASkB,GACT,MAAM4I,EAAS5I,EAAI6I,eAAiB7I,EAAInH,QAAUmH,EAAInH,QAAQiQ,MAAM,MAAM,GAAK,iBAG/E,OAFAvD,EAAW,mCAAmCqD,UAC9C/C,EAAoB,OAEtB,CAEAN,EAAW,0DAEX,IACE,MAAMrJ,EAAgBJ,EAAgBK,2BACtC,IAAKD,EACH,MAAM,IAAIhF,MAAM,mCAGlB,MAAM4N,QAA0BN,IAChC,IAAKM,EACH,MAAM,IAAI5N,MAAM,uFAGlB,IAAK+I,OAAOC,SACV,MAAM,IAAIhJ,MAAM,0BAGlB,MAAM+L,QAAmBhD,OAAOC,SAASmB,QAAQ,CAAEC,OAAQ,gBACrDyH,EAAiB/F,SAASC,EAAY,IAE5C,GAAI8F,IAAmB7M,EAAchG,QACnC,MAAM,IAAIgB,MAAM,0CAA0C6R,UAAuB9L,oBAAkCf,EAAchG,gDAGnI,GAAI4O,EAAkB1B,MAAMhF,KAAOlC,EAAchG,QAC/C,MAAM,IAAIgB,MAAM,2DAA2D4N,EAAkB1B,MAAMhF,oBAAoBlC,EAAchG,YAGvI,MAAMsP,QAAeV,EAAkBkE,gBAAgB,IAClDpB,EACH7F,QAASA,IAGX0D,EAAUD,GACVD,EAAW,kCACXM,EAAoB,WAEhBZ,GACFA,EAAsB,CACpBO,SACAhG,QAASvC,EACTU,MAAO5B,GAAeK,IACtBqD,YAAa1D,GAAezF,OAC5BoJ,OAAQwF,GAA2BxF,OACnCC,iBAAkBuF,GAA2BvF,kBAGlD,CAAC,MAAOK,GACPlB,EAASkB,GAET,IAAI4I,EAAS,gBAEXA,EADe,6BAAb5I,EAAIrH,MAAoD,OAAbqH,EAAIzH,KACxC,0BACa,kCAAbyH,EAAIrH,MAA6CqH,EAAIxH,MAAQwH,EAAIxH,KAAKK,QACtEmH,EAAI6I,cAAgB7I,EAAIxH,MAAMK,SAAWmH,EAAInH,QAE7CmH,EAAI6I,eAAiB7I,EAAInH,QAAUmH,EAAInH,QAAQiQ,MAAM,MAAM,GAAK,sBAG3EvD,EAAW,uBAAuBqD,KAClC/C,EAAoB,QACpBxN,QAAQC,MAAM,qBAAsB0H,EACtC,IAgG0G,cAOnG+B,GAAgC,eAArB6D,GACV9K,EAAAC,cAAA,SAAA,CAAQC,UAAWC,EAAOsL,aAAc/H,UAAQ,GAAC,kBAMnD,ECpWJyK,EAAgBA,EAAG5N,UAAS6N,aAAYjE,4BAC5C,MAAMrH,gBAAEA,GAAoBC,IAO5B,OACE/C,EAAAC,cAACI,EAAM,CAACE,QANU8N,KAClBvL,IACAvC,GAAS,EAIqBlB,KAAM+O,GAClCpO,EAAAC,cAACkD,EAAiB,MAClBnD,EAAAC,cAAC4D,QACD7D,EAAAC,cAACiK,EAAiB,CAACC,sBAAuBA,IACnC,EAIPmE,EAAsBA,EAAG/N,UAAS6N,aAAYpN,kBAAiBmJ,2BAEjEnK,EAAAC,cAAC+B,EAAe,CAAChB,gBAAiBA,GAChChB,EAAAC,cAAC2G,OACC5G,EAAAC,cAACkO,EAAa,CAAC5N,QAASA,EAAS6N,WAAYA,EAAYjE,sBAAuBA,YCpBtE,CAChBoE,gBCVK,MACLvS,WAAAA,CAAYwS,GACVtS,KAAKsS,eAAiBA,EACtBtS,KAAKuS,UAAYD,EAAeE,eAChCxS,KAAK0H,kBAAoB1H,KAAKyS,uBAC9BzS,KAAKiG,gBAAkB,IACzB,CAEAwM,oBAAAA,GACE,OAAOlN,OAAOC,QAAQzG,GAAgB2T,QACpC,CAACC,GAAMjM,EAAYxB,MACZlF,KAAKuS,UAAU7Q,SAASwD,EAAchG,WACzCyT,EAAIjM,GAAcxB,GAEbyN,IAET,CACF,EACF,CAEAlM,aAAAA,CAAcC,GACZ,OAAmB,OAAfA,GACF1G,KAAKiG,gBAAkB,KACvB5E,QAAQuR,IAAI,4BACL,GAEL5S,KAAK0H,kBAAkBhB,IACzB1G,KAAKiG,gBAAkBS,EACvBrF,QAAQuR,IAAI,qBAAqBlM,MAC1B,IAETrF,QAAQC,MAAM,oBAAoBoF,MAC3B,EACT,CAEAvB,wBAAAA,GACE,OAAOnF,KAAKiG,gBACRjG,KAAK0H,kBAAkB1H,KAAKiG,iBAC5B,IACN,CAEA2C,mBAAAA,GACE,OAAO5I,KAAKsS,eAAe1J,qBAC7B,CAEAR,cAAAA,CAAezB,GACb,OAAO3G,KAAKsS,eAAelK,eAAepI,KAAKiG,gBAAiBU,EAClE,GDpCA9G,cACAgT,OEZK,MACL/S,WAAAA,CAAYgT,EAAU,IACpB9S,KAAK2I,iBAAmBmK,EAAQnK,kBAAoB,GACpD3I,KAAKuS,UAAYO,EAAQP,WAAa,GACtCvS,KAAK+S,QAAUD,EAAQC,SAAWD,EAAQE,SAAW,GACrDhT,KAAKiT,gBACP,CAEAA,cAAAA,GACE,IAAKjT,KAAK2I,iBACR,MAAM,IAAIzI,MAAM,iCAGlB,IAAK,MAAOsI,EAASpJ,KAAWmG,OAAOC,QAAQxF,KAAK+S,SAAU,CAC5D,IAAKhU,EAAeyJ,GAClB,MAAM,IAAItI,MAAM,oBAAoBsI,KAEtC,IACGpJ,EAAOC,YACqB,iBAAtBD,EAAOC,YACdD,EAAOC,YAAc,EAErB,MAAM,IAAIa,MAAM,yCAAyCsI,IAE7D,CACF,CAEAgK,YAAAA,GACE,OAAOxS,KAAKuS,SACd,CAEA3J,mBAAAA,GACE,OAAO5I,KAAK2I,gBACd,CAcAP,cAAAA,CAAeI,GACbnH,QAAQuR,IAAI,8BAA+BpK,GAC3CnH,QAAQuR,IAAI,kBAAmB5S,KAAK+S,SAGpC,MAAMrK,EAAS1I,KAAK+S,QAAQvK,IAAUnJ,WAGtC,OAFAgC,QAAQuR,IAAI,oBAAqBlK,GAE1BA,GAAU,CACnB,GF3CAwK,ODsBoBA,EAAGpO,kBAAiBoN,aAAa,SAAUjE,wBAAuBkF,gBACtF,MAAOC,EAAcC,GAAmBrN,EAAQA,UAAC,GAW3CsN,EAA4BrF,GAAyBkF,EAE3D,OACErP,EAAAC,cAAA,MAAA,CAAKC,UAAWC,EAAOsP,kBACnBH,GACAtP,EAAAC,cAACd,EAAS,CAACC,QAdQsQ,KACvBH,GAAgB,EAAK,EAaqBlQ,KAAM+O,IAE7CkB,GACCtP,EAAAC,cAACqO,EAAmB,CAClB/N,QAdkBoP,KACxBJ,GAAgB,EAAM,EAchBnB,WAAYA,EACZpN,gBAAiBA,EACjBmJ,sBAAuBqF,IAGvB,EChDRrQ,YACAkB,SACA8C"} \ No newline at end of file diff --git a/stablepay-sdk/package-lock.json b/stablepay-sdk/package-lock.json index d3d2450..7ddbe21 100644 --- a/stablepay-sdk/package-lock.json +++ b/stablepay-sdk/package-lock.json @@ -1,12 +1,12 @@ { "name": "stablepay-sdk", - "version": "1.0.4", + "version": "1.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "stablepay-sdk", - "version": "1.0.4", + "version": "1.0.3", "license": "ISC", "dependencies": { "djed-sdk": "^1.0.2", diff --git a/stablepay-sdk/src/widget/TokenDropdown.jsx b/stablepay-sdk/src/widget/TokenDropdown.jsx index d906c6f..5935cc6 100644 --- a/stablepay-sdk/src/widget/TokenDropdown.jsx +++ b/stablepay-sdk/src/widget/TokenDropdown.jsx @@ -56,7 +56,11 @@ const TokenDropdown = () => { } } catch (err) { console.error("Error fetching transaction details:", err); - setError("Failed to fetch transaction details. Please try again."); + if (typeof window !== 'undefined' && !window.ethereum) { + setError("No wallet found. Please install a Web3 wallet."); + } else { + setError("Failed to fetch transaction details. Please try again."); + } } finally { setLoading(false); } diff --git a/stablepay-sdk/src/widget/TransactionReview.jsx b/stablepay-sdk/src/widget/TransactionReview.jsx index 33d5578..96cfb0f 100644 --- a/stablepay-sdk/src/widget/TransactionReview.jsx +++ b/stablepay-sdk/src/widget/TransactionReview.jsx @@ -91,6 +91,23 @@ const TransactionReview = ({ onTransactionComplete }) => { } if (!contextTransactionDetails) { + if (typeof window !== 'undefined' && !window.ethereum) { + return ( +
+
+ No wallet found. +
+
+ +
+
+ ); + } return
Initializing transaction...
; } From 7d3b24ef8dac8a60542603e2c1ef8411b4502307 Mon Sep 17 00:00:00 2001 From: DeveloperAmrit Date: Mon, 8 Jun 2026 10:12:26 +0530 Subject: [PATCH 6/6] fix: Fixed code rabbit issues --- stablepay-sdk/dist/esm/index.js | 2 +- stablepay-sdk/dist/umd/index.js | 2 +- stablepay-sdk/dist/umd/index.js.map | 2 +- stablepay-sdk/example/eslint.config.js | 8 +++----- stablepay-sdk/example/src/App.jsx | 24 ++---------------------- stablepay-sdk/src/core/Transaction.js | 6 +++++- 6 files changed, 13 insertions(+), 31 deletions(-) diff --git a/stablepay-sdk/dist/esm/index.js b/stablepay-sdk/dist/esm/index.js index 81d6752..1f3fb54 100644 --- a/stablepay-sdk/dist/esm/index.js +++ b/stablepay-sdk/dist/esm/index.js @@ -1 +1 @@ -import{getWeb3 as e,getDjedContract as t,getCoinContracts as n,getDecimals as r,getOracleAddress as a,getOracleContract as o,tradeDataPriceBuySc as i,buyScTx as s}from"djed-sdk";import l,{useContext as c,createContext as d,useState as m,useEffect as u,useRef as h,useCallback as w}from"react";import{defineChain as k,createWalletClient as g,custom as C,createPublicClient as p,http as b,parseEther as f,parseUnits as E,encodeFunctionData as y}from"viem";import{sepolia as v}from"viem/chains";const _={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class N{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e(this.networkUri),this.djedContract=t(this.web3,this.djedAddress);try{const{stableCoin:e,reserveCoin:t}=await n(this.djedContract,this.web3),{scDecimals:i,rcDecimals:s}=await r(e,t);this.stableCoin=e,this.reserveCoin=t,this.scDecimals=i,this.rcDecimals=s,this.oracleContract=await a(this.djedContract).then((e=>o(this.web3,e,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){console.error("[Transaction] Error fetching contract details:",e);if(-32e3===e.code||3===e.code||e.data){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){console.error("[Transaction] Error initializing transaction:",e);if(-32603===e.code||4001===e.code||-32005===e.code||e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(e){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof e)throw new Error("Amount must be a string");try{return(await i(this.djedContract,this.scDecimals,e)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(e,t,n){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await s(this.djedContract,e,t,n,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var S="main_stablePayButton__UA7HC",T="main_logo__ITyEy",A="main_buttonText__N-ewy";const P=({onClick:e,size:t="medium"})=>{const n={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},a=n[t]||n.medium,o=r[t]||r.medium;return l.createElement("button",{className:S,onClick:e,style:a},l.createElement("div",{className:T,style:o}),l.createElement("span",{className:A},"Pay with StablePay"))};var D={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",confirmContainer:"PricingCard_confirmContainer__vNq4n",confirmText:"PricingCard_confirmText__FP0WS",confirmButtons:"PricingCard_confirmButtons__fZ7jt",secondaryButton:"PricingCard_secondaryButton__OTpW4",primaryButton:"PricingCard_primaryButton__bmYo9",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const x=({children:e,onClose:t,size:n="medium"})=>l.createElement("div",{className:D.dialogOverlay},l.createElement("div",{className:`${D.pricingCard} ${D[n]}`},l.createElement("button",{className:D.dialogClose,onClick:t},"×"),l.createElement("div",{className:D.pricingCardHeader},l.createElement("div",{className:D.allianceLogo}),l.createElement("div",{className:D.stablepayTitle},"StablePay")),l.createElement("div",{className:D.pricingCardBody},e)));class B{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const I=d(),M=({children:e,networkSelector:t})=>{const[n]=m((()=>new B(t))),[r,a]=m(null),[o,i]=m(null),[s,c]=m(null),d=()=>{i(null),c(null)};return u((()=>{a(t.selectedNetwork)}),[t.selectedNetwork]),l.createElement(I.Provider,{value:{networkSelector:t,tokenSelector:n,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:c,selectNetwork:e=>!!t.selectNetwork(e)&&(a(e),d(),!0),selectToken:e=>{if(n.selectToken(e)){const e=n.getSelectedToken();return i(e),!0}return!1},resetSelections:()=>{t.selectNetwork(null),a(null),d()}}},e)},$=()=>{const e=c(I);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},j=()=>{const{networkSelector:e,selectedNetwork:t,selectNetwork:n}=$();return l.createElement("div",{className:D.selectField},l.createElement("label",{htmlFor:"network-select"},"Select Network"),l.createElement("select",{id:"network-select",onChange:e=>{n(e.target.value)},value:t||""},l.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>l.createElement("option",{key:e,value:e},e)))))},L=()=>{const{networkSelector:e,tokenSelector:t,selectedNetwork:n,selectedToken:r,selectToken:a,setTransactionDetails:o}=$(),[i,s]=m(!1),[c,d]=m(null),u=n?t.getAvailableTokens():[];return l.createElement("div",{className:D.selectField},l.createElement("label",{htmlFor:"token-select"},"Select Token"),l.createElement("select",{id:"token-select",onChange:async r=>{const i=r.target.value;d(null),s(!0);try{if(a(i)){const r=e.getSelectedNetworkConfig(),a=new N(r.uri,r.djedAddress);await a.init();const s=e.getTokenAmount(i),l=a.getBlockchainDetails();let c=null;"native"===i&&(c=await a.handleTradeDataBuySc(String(s))),o({network:n,token:i,tokenSymbol:t.getSelectedToken().symbol,amount:s,receivingAddress:e.getReceivingAddress(),djedContractAddress:r.djedAddress,isDirectTransfer:t.getSelectedToken().isDirectTransfer||!1,isNativeToken:t.getSelectedToken().isNative||!1,tradeAmount:c?c.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),"undefined"==typeof window||window.ethereum?d("Failed to fetch transaction details. Please try again."):d("No wallet found. Please install a Web3 wallet.")}finally{s(!1)}},value:r?r.key:"",disabled:!n||i},l.createElement("option",{value:"",disabled:!0},n?i?"Loading...":"Select a token":"Please select a network first"),u.map((e=>l.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),c&&l.createElement("div",{className:D.error},c))};k({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const F=k({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),R=k({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),U=d(null),W=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${v.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:v.rpcUrls.default.http,blockExplorerUrls:v.blockExplorers?.default?.url?[v.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${R.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${F.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},z=({children:e})=>{const{selectedNetwork:t}=$(),[n,r]=m(null),[a,o]=m(null),[i,s]=m(null),[c,d]=m(null),[k,f]=m(null),[E,y]=m(null),[_,N]=m(!1),S=t?(e=>{switch(e){case"sepolia":return v;case"ethereum-classic":return R;case"milkomeda-mainnet":return F;default:return null}})(t):null,T=S?S.id:null,A=h(null),P=h(null),D=w((()=>{r(null),o(null),s(null),d(null),f(null),y(null)}),[]),x=w((async e=>{const n=parseInt(e,16);if(d(n),S&&n===T){if(y(null),window.ethereum&&S){const e=g({chain:S,transport:C(window.ethereum)});r(e)}}else if(S&&n!==T){y(`Wrong network detected. Please switch to ${S?.name||t||"selected network"}`)}}),[S,T,t]);P.current=x;const B=w((async e=>{if(0===e.length){if(D(),window.ethereum){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(s(e[0]),S)try{const t=p({chain:S,transport:b()});o(t);const n=await t.getBalance({address:e[0]});f(parseFloat(n)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}}),[S,D]);A.current=B;const I=w((()=>{if(D(),window.ethereum){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[D]),M=w((()=>{S&&o(p({chain:S,transport:b()}))}),[S]),j=w((async()=>{if(!window.ethereum)return y("Please install MetaMask or another Web3 wallet"),!1;if(!t||!S)return y("Please select a network first"),!1;N(!0),y(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const n=await window.ethereum.request({method:"eth_chainId"});parseInt(n,16)!==T&&await W(t);const a=g({chain:S,transport:C(window.ethereum)});r(a),s(e[0]),d(T);const i=p({chain:S,transport:b()});o(i);try{const t=await i.getBalance({address:e[0]});f(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}return A.current=B,P.current=x,window.ethereum.on("accountsChanged",B),window.ethereum.on("chainChanged",x),!0}catch(e){return console.error("Error connecting wallet:",e),y(e.message),!1}finally{N(!1)}}),[t,S,T,B,x]),L=w((async()=>{if(!(window.ethereum&&t&&S&&i)){return y("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==T){y(null),await W(t);const e=500;await new Promise((t=>setTimeout(t,e)));const n=await window.ethereum.request({method:"eth_chainId"}),r=parseInt(n,16);if(r!==T)throw new Error(`Failed to switch network. MetaMask is still on chain ${r}, expected ${T}`)}const n=g({chain:S,transport:C(window.ethereum)});return r(n),d(T),y(null),n}catch(e){return y(e.message),null}}),[t,S,T,i]),z=h(t);return u((()=>{if(null!==z.current&&z.current!==t&&i&&(D(),window.ethereum)){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}z.current=t}),[t,i,D]),u((()=>{M()}),[M]),l.createElement(U.Provider,{value:{walletClient:n,publicClient:a,account:i,chainId:c,balance:k,error:E,isConnecting:_,connectWallet:j,disconnectWallet:I,ensureCorrectNetwork:L,expectedChainId:T}},e)},O=({onTransactionComplete:e})=>{const{networkSelector:t,selectedNetwork:n,selectedToken:r,transactionDetails:a,setTransactionDetails:o}=$(),{connectWallet:i,account:s,walletClient:d,publicClient:h,isConnecting:w,ensureCorrectNetwork:k,expectedChainId:g}=(()=>{const e=c(U);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[C,p]=m(null),[b,v]=m(null),[_,S]=m(""),[T,A]=m(null),[P,x]=m(null),[B,I]=m(!1),[M,j]=m("IDLE");if(u((()=>{v(null),S(""),x(null),A(null),j("IDLE")}),[n,r]),u((()=>{(async()=>{if(n&&r)try{const e=t.getSelectedNetworkConfig(),a=t.getReceivingAddress(),i=t.getTokenAmount(r.key),s=new N(e.uri,e.djedAddress);await s.init(),p(s);let l=null;if("native"===r.key)try{l=await s.handleTradeDataBuySc(String(i)),v(l)}catch(e){console.error("Error fetching trade data:",e)}o({network:n,token:r.key,tokenSymbol:r.symbol,amount:i||"0",receivingAddress:a,djedContractAddress:e.djedAddress,isDirectTransfer:r.isDirectTransfer||!1,isNativeToken:r.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[n,r,t,o]),!n||!r)return null;if(!a)return"undefined"==typeof window||window.ethereum?l.createElement("div",{className:D.loading},"Initializing transaction..."):l.createElement("div",{className:D.transactionReview},l.createElement("div",{className:D.messageBox,style:{textAlign:"center",marginBottom:"1rem",color:"#ff4d4f"}},"No wallet found."),l.createElement("div",{className:D.walletButtonContainer},l.createElement("button",{className:D.walletButton,onClick:()=>window.open("https://metamask.io/download/","_blank")},"Connect Wallet")));const L=()=>{if(!T||!n)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[n]?`${e[n]}${T}`:null};return l.createElement("div",{className:D.transactionReview},l.createElement("div",{className:D.transactionInfo},l.createElement("span",{className:D.transactionLabel},"Network:"),l.createElement("span",{className:D.transactionValue},a.network)),l.createElement("div",{className:D.transactionInfo},l.createElement("span",{className:D.transactionLabel},"You Pay:"),l.createElement("span",{className:`${D.transactionValue} ${D.highlight}`},"stablecoin"===r.key?`${a.amount} ${a.tokenSymbol}`:`${b||"Calculating..."} ${a.tokenSymbol}`)),_&&l.createElement("div",{className:D.messageBox},_,P&&l.createElement("button",{onClick:()=>I(!B),className:D.detailsButton},B?"Hide Details":"Show Details")),B&&P&&l.createElement("div",{className:D.errorDetails},l.createElement("pre",null,P.message)),T&&l.createElement("div",{className:D.transactionLink},"Transaction Hash:"," ",L()?l.createElement("a",{href:L(),target:"_blank",rel:"noopener noreferrer",className:D.explorerLink},T.slice(0,6),"...",T.slice(-6)):l.createElement("span",{style:{wordBreak:"break-word"}},T)),"SUCCESS"!==M&&l.createElement("div",{className:D.walletButtonContainer},!s&&l.createElement("button",{className:D.walletButton,onClick:async()=>{await i()},disabled:w},w?"Connecting...":"Connect Wallet"),s&&"IDLE"===M&&l.createElement("button",{className:D.walletButton,onClick:()=>j("CONFIRMING")},"Pay ",a.amount," ",a.tokenSymbol),s&&"CONFIRMING"===M&&l.createElement("div",{className:D.confirmContainer},l.createElement("span",{className:D.confirmText},"Confirm payment?"),l.createElement("div",{className:D.confirmButtons},l.createElement("button",{className:D.secondaryButton,onClick:()=>j("IDLE")},"No"),l.createElement("button",{className:`${D.walletButton} ${D.primaryButton}`,onClick:async()=>{if(!s||!a||!C)return void S("Wallet not connected or transaction details missing");let o;j("PROCESSING"),S("Preparing transaction..."),x(null),A(null);try{const e=a.receivingAddress;if("native"===r.key){const t="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",n=f(String(b||"0"));o=await C.buyStablecoins(s,e,n,t),o={...o,value:n,account:s}}else{const n=t.getSelectedNetworkConfig(),r=n?.tokens?.stablecoin?.address;if(!r)throw new Error("Stablecoin address not found in network configuration");const i=a.amount?E(String(a.amount),a.stableCoinDecimals):"0";o={to:r,value:0n,data:y({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:s}}}catch(e){x(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");return S(`Transaction preparation failed: ${t}`),void j("IDLE")}S("Please check your wallet to confirm the transaction...");try{const i=t.getSelectedNetworkConfig();if(!i)throw new Error("Network configuration not found");const l=await k();if(!l)throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask.");if(!window.ethereum)throw new Error("MetaMask not available");const c=await window.ethereum.request({method:"eth_chainId"}),d=parseInt(c,16);if(d!==i.chainId)throw new Error(`Network mismatch. MetaMask is on chain ${d}, but ${n} requires chain ${i.chainId}. Please switch networks in MetaMask.`);if(l.chain.id!==i.chainId)throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${l.chain.id}, but expected ${i.chainId}.`);const m=await l.sendTransaction({...o,account:s});A(m),S("Transaction sent successfully!"),j("SUCCESS"),e&&e({txHash:m,network:n,token:r?.key,tokenSymbol:r?.symbol,amount:a?.amount,receivingAddress:a?.receivingAddress})}catch(e){x(e);let t="Unknown error";t="UserRejectedRequestError"===e.name||4001===e.code?"User denied transaction":"ContractFunctionRevertedError"===e.name||e.data&&e.data.message?e.shortMessage||e.data?.message||e.message:e.shortMessage||(e.message?e.message.split("\n")[0]:"Transaction failed"),S(`Transaction failed: ${t}`),j("IDLE"),console.error("Transaction error:",e)}}},"Yes, Pay"))),s&&"PROCESSING"===M&&l.createElement("button",{className:D.walletButton,disabled:!0},"Processing...")))},q=({onClose:e,buttonSize:t,onTransactionComplete:n})=>{const{resetSelections:r}=$();return l.createElement(x,{onClose:()=>{r(),e()},size:t},l.createElement(j,null),l.createElement(L,null),l.createElement(O,{onTransactionComplete:n}))},H=({onClose:e,buttonSize:t,networkSelector:n,onTransactionComplete:r})=>l.createElement(M,{networkSelector:n},l.createElement(z,null,l.createElement(q,{onClose:e,buttonSize:t,onTransactionComplete:r}))),G={NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(_).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:N,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!_[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:t="medium",onTransactionComplete:n,onSuccess:r})=>{const[a,o]=m(!1),i=n||r;return l.createElement("div",{className:D.widgetContainer},!a&&l.createElement(P,{onClick:()=>{o(!0)},size:t}),a&&l.createElement(H,{onClose:()=>{o(!1)},buttonSize:t,networkSelector:e,onTransactionComplete:i}))},PayButton:P,Dialog:x,NetworkDropdown:j};export{G as default}; +import{getWeb3 as e,getDjedContract as t,getCoinContracts as n,getDecimals as r,getOracleAddress as a,getOracleContract as o,tradeDataPriceBuySc as i,buyScTx as s}from"djed-sdk";import l,{useContext as c,createContext as d,useState as m,useEffect as u,useRef as h,useCallback as w}from"react";import{defineChain as k,createWalletClient as g,custom as C,createPublicClient as p,http as b,parseEther as f,parseUnits as E,encodeFunctionData as y}from"viem";import{sepolia as v}from"viem/chains";const _={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class N{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e(this.networkUri),this.djedContract=t(this.web3,this.djedAddress);try{const{stableCoin:e,reserveCoin:t}=await n(this.djedContract,this.web3),{scDecimals:i,rcDecimals:s}=await r(e,t);this.stableCoin=e,this.reserveCoin=t,this.scDecimals=i,this.rcDecimals=s,this.oracleContract=await a(this.djedContract).then((e=>o(this.web3,e,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){console.error("[Transaction] Error fetching contract details:",e);if(-32e3===e?.code||3===e?.code||"ContractFunctionRevertedError"===e?.name||"string"==typeof e?.data?.message){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){console.error("[Transaction] Error initializing transaction:",e);if(-32603===e.code||4001===e.code||-32005===e.code||e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(e){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof e)throw new Error("Amount must be a string");try{return(await i(this.djedContract,this.scDecimals,e)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(e,t,n){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await s(this.djedContract,e,t,n,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var S="main_stablePayButton__UA7HC",T="main_logo__ITyEy",A="main_buttonText__N-ewy";const P=({onClick:e,size:t="medium"})=>{const n={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},a=n[t]||n.medium,o=r[t]||r.medium;return l.createElement("button",{className:S,onClick:e,style:a},l.createElement("div",{className:T,style:o}),l.createElement("span",{className:A},"Pay with StablePay"))};var D={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",confirmContainer:"PricingCard_confirmContainer__vNq4n",confirmText:"PricingCard_confirmText__FP0WS",confirmButtons:"PricingCard_confirmButtons__fZ7jt",secondaryButton:"PricingCard_secondaryButton__OTpW4",primaryButton:"PricingCard_primaryButton__bmYo9",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const x=({children:e,onClose:t,size:n="medium"})=>l.createElement("div",{className:D.dialogOverlay},l.createElement("div",{className:`${D.pricingCard} ${D[n]}`},l.createElement("button",{className:D.dialogClose,onClick:t},"×"),l.createElement("div",{className:D.pricingCardHeader},l.createElement("div",{className:D.allianceLogo}),l.createElement("div",{className:D.stablepayTitle},"StablePay")),l.createElement("div",{className:D.pricingCardBody},e)));class B{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const I=d(),M=({children:e,networkSelector:t})=>{const[n]=m((()=>new B(t))),[r,a]=m(null),[o,i]=m(null),[s,c]=m(null),d=()=>{i(null),c(null)};return u((()=>{a(t.selectedNetwork)}),[t.selectedNetwork]),l.createElement(I.Provider,{value:{networkSelector:t,tokenSelector:n,selectedNetwork:r,selectedToken:o,transactionDetails:s,setTransactionDetails:c,selectNetwork:e=>!!t.selectNetwork(e)&&(a(e),d(),!0),selectToken:e=>{if(n.selectToken(e)){const e=n.getSelectedToken();return i(e),!0}return!1},resetSelections:()=>{t.selectNetwork(null),a(null),d()}}},e)},$=()=>{const e=c(I);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},j=()=>{const{networkSelector:e,selectedNetwork:t,selectNetwork:n}=$();return l.createElement("div",{className:D.selectField},l.createElement("label",{htmlFor:"network-select"},"Select Network"),l.createElement("select",{id:"network-select",onChange:e=>{n(e.target.value)},value:t||""},l.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>l.createElement("option",{key:e,value:e},e)))))},F=()=>{const{networkSelector:e,tokenSelector:t,selectedNetwork:n,selectedToken:r,selectToken:a,setTransactionDetails:o}=$(),[i,s]=m(!1),[c,d]=m(null),u=n?t.getAvailableTokens():[];return l.createElement("div",{className:D.selectField},l.createElement("label",{htmlFor:"token-select"},"Select Token"),l.createElement("select",{id:"token-select",onChange:async r=>{const i=r.target.value;d(null),s(!0);try{if(a(i)){const r=e.getSelectedNetworkConfig(),a=new N(r.uri,r.djedAddress);await a.init();const s=e.getTokenAmount(i),l=a.getBlockchainDetails();let c=null;"native"===i&&(c=await a.handleTradeDataBuySc(String(s))),o({network:n,token:i,tokenSymbol:t.getSelectedToken().symbol,amount:s,receivingAddress:e.getReceivingAddress(),djedContractAddress:r.djedAddress,isDirectTransfer:t.getSelectedToken().isDirectTransfer||!1,isNativeToken:t.getSelectedToken().isNative||!1,tradeAmount:c?c.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),"undefined"==typeof window||window.ethereum?d("Failed to fetch transaction details. Please try again."):d("No wallet found. Please install a Web3 wallet.")}finally{s(!1)}},value:r?r.key:"",disabled:!n||i},l.createElement("option",{value:"",disabled:!0},n?i?"Loading...":"Select a token":"Please select a network first"),u.map((e=>l.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),c&&l.createElement("div",{className:D.error},c))};k({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const L=k({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),R=k({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),U=d(null),W=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${v.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:v.rpcUrls.default.http,blockExplorerUrls:v.blockExplorers?.default?.url?[v.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${R.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${L.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},z=({children:e})=>{const{selectedNetwork:t}=$(),[n,r]=m(null),[a,o]=m(null),[i,s]=m(null),[c,d]=m(null),[k,f]=m(null),[E,y]=m(null),[_,N]=m(!1),S=t?(e=>{switch(e){case"sepolia":return v;case"ethereum-classic":return R;case"milkomeda-mainnet":return L;default:return null}})(t):null,T=S?S.id:null,A=h(null),P=h(null),D=w((()=>{r(null),o(null),s(null),d(null),f(null),y(null)}),[]),x=w((async e=>{const n=parseInt(e,16);if(d(n),S&&n===T){if(y(null),window.ethereum&&S){const e=g({chain:S,transport:C(window.ethereum)});r(e)}}else if(S&&n!==T){y(`Wrong network detected. Please switch to ${S?.name||t||"selected network"}`)}}),[S,T,t]);P.current=x;const B=w((async e=>{if(0===e.length){if(D(),window.ethereum){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(s(e[0]),S)try{const t=p({chain:S,transport:b()});o(t);const n=await t.getBalance({address:e[0]});f(parseFloat(n)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}}),[S,D]);A.current=B;const I=w((()=>{if(D(),window.ethereum){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[D]),M=w((()=>{S&&o(p({chain:S,transport:b()}))}),[S]),j=w((async()=>{if(!window.ethereum)return y("Please install MetaMask or another Web3 wallet"),!1;if(!t||!S)return y("Please select a network first"),!1;N(!0),y(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const n=await window.ethereum.request({method:"eth_chainId"});parseInt(n,16)!==T&&await W(t);const a=g({chain:S,transport:C(window.ethereum)});r(a),s(e[0]),d(T);const i=p({chain:S,transport:b()});o(i);try{const t=await i.getBalance({address:e[0]});f(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),f(null)}return A.current=B,P.current=x,window.ethereum.on("accountsChanged",B),window.ethereum.on("chainChanged",x),!0}catch(e){return console.error("Error connecting wallet:",e),y(e.message),!1}finally{N(!1)}}),[t,S,T,B,x]),F=w((async()=>{if(!(window.ethereum&&t&&S&&i)){return y("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==T){y(null),await W(t);const e=500;await new Promise((t=>setTimeout(t,e)));const n=await window.ethereum.request({method:"eth_chainId"}),r=parseInt(n,16);if(r!==T)throw new Error(`Failed to switch network. MetaMask is still on chain ${r}, expected ${T}`)}const n=g({chain:S,transport:C(window.ethereum)});return r(n),d(T),y(null),n}catch(e){return y(e.message),null}}),[t,S,T,i]),z=h(t);return u((()=>{if(null!==z.current&&z.current!==t&&i&&(D(),window.ethereum)){const e=A.current,t=P.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}z.current=t}),[t,i,D]),u((()=>{M()}),[M]),l.createElement(U.Provider,{value:{walletClient:n,publicClient:a,account:i,chainId:c,balance:k,error:E,isConnecting:_,connectWallet:j,disconnectWallet:I,ensureCorrectNetwork:F,expectedChainId:T}},e)},O=({onTransactionComplete:e})=>{const{networkSelector:t,selectedNetwork:n,selectedToken:r,transactionDetails:a,setTransactionDetails:o}=$(),{connectWallet:i,account:s,walletClient:d,publicClient:h,isConnecting:w,ensureCorrectNetwork:k,expectedChainId:g}=(()=>{const e=c(U);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[C,p]=m(null),[b,v]=m(null),[_,S]=m(""),[T,A]=m(null),[P,x]=m(null),[B,I]=m(!1),[M,j]=m("IDLE");if(u((()=>{v(null),S(""),x(null),A(null),j("IDLE")}),[n,r]),u((()=>{(async()=>{if(n&&r)try{const e=t.getSelectedNetworkConfig(),a=t.getReceivingAddress(),i=t.getTokenAmount(r.key),s=new N(e.uri,e.djedAddress);await s.init(),p(s);let l=null;if("native"===r.key)try{l=await s.handleTradeDataBuySc(String(i)),v(l)}catch(e){console.error("Error fetching trade data:",e)}o({network:n,token:r.key,tokenSymbol:r.symbol,amount:i||"0",receivingAddress:a,djedContractAddress:e.djedAddress,isDirectTransfer:r.isDirectTransfer||!1,isNativeToken:r.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[n,r,t,o]),!n||!r)return null;if(!a)return"undefined"==typeof window||window.ethereum?l.createElement("div",{className:D.loading},"Initializing transaction..."):l.createElement("div",{className:D.transactionReview},l.createElement("div",{className:D.messageBox,style:{textAlign:"center",marginBottom:"1rem",color:"#ff4d4f"}},"No wallet found."),l.createElement("div",{className:D.walletButtonContainer},l.createElement("button",{className:D.walletButton,onClick:()=>window.open("https://metamask.io/download/","_blank")},"Connect Wallet")));const F=()=>{if(!T||!n)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[n]?`${e[n]}${T}`:null};return l.createElement("div",{className:D.transactionReview},l.createElement("div",{className:D.transactionInfo},l.createElement("span",{className:D.transactionLabel},"Network:"),l.createElement("span",{className:D.transactionValue},a.network)),l.createElement("div",{className:D.transactionInfo},l.createElement("span",{className:D.transactionLabel},"You Pay:"),l.createElement("span",{className:`${D.transactionValue} ${D.highlight}`},"stablecoin"===r.key?`${a.amount} ${a.tokenSymbol}`:`${b||"Calculating..."} ${a.tokenSymbol}`)),_&&l.createElement("div",{className:D.messageBox},_,P&&l.createElement("button",{onClick:()=>I(!B),className:D.detailsButton},B?"Hide Details":"Show Details")),B&&P&&l.createElement("div",{className:D.errorDetails},l.createElement("pre",null,P.message)),T&&l.createElement("div",{className:D.transactionLink},"Transaction Hash:"," ",F()?l.createElement("a",{href:F(),target:"_blank",rel:"noopener noreferrer",className:D.explorerLink},T.slice(0,6),"...",T.slice(-6)):l.createElement("span",{style:{wordBreak:"break-word"}},T)),"SUCCESS"!==M&&l.createElement("div",{className:D.walletButtonContainer},!s&&l.createElement("button",{className:D.walletButton,onClick:async()=>{await i()},disabled:w},w?"Connecting...":"Connect Wallet"),s&&"IDLE"===M&&l.createElement("button",{className:D.walletButton,onClick:()=>j("CONFIRMING")},"Pay ",a.amount," ",a.tokenSymbol),s&&"CONFIRMING"===M&&l.createElement("div",{className:D.confirmContainer},l.createElement("span",{className:D.confirmText},"Confirm payment?"),l.createElement("div",{className:D.confirmButtons},l.createElement("button",{className:D.secondaryButton,onClick:()=>j("IDLE")},"No"),l.createElement("button",{className:`${D.walletButton} ${D.primaryButton}`,onClick:async()=>{if(!s||!a||!C)return void S("Wallet not connected or transaction details missing");let o;j("PROCESSING"),S("Preparing transaction..."),x(null),A(null);try{const e=a.receivingAddress;if("native"===r.key){const t="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",n=f(String(b||"0"));o=await C.buyStablecoins(s,e,n,t),o={...o,value:n,account:s}}else{const n=t.getSelectedNetworkConfig(),r=n?.tokens?.stablecoin?.address;if(!r)throw new Error("Stablecoin address not found in network configuration");const i=a.amount?E(String(a.amount),a.stableCoinDecimals):"0";o={to:r,value:0n,data:y({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:s}}}catch(e){x(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");return S(`Transaction preparation failed: ${t}`),void j("IDLE")}S("Please check your wallet to confirm the transaction...");try{const i=t.getSelectedNetworkConfig();if(!i)throw new Error("Network configuration not found");const l=await k();if(!l)throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask.");if(!window.ethereum)throw new Error("MetaMask not available");const c=await window.ethereum.request({method:"eth_chainId"}),d=parseInt(c,16);if(d!==i.chainId)throw new Error(`Network mismatch. MetaMask is on chain ${d}, but ${n} requires chain ${i.chainId}. Please switch networks in MetaMask.`);if(l.chain.id!==i.chainId)throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${l.chain.id}, but expected ${i.chainId}.`);const m=await l.sendTransaction({...o,account:s});A(m),S("Transaction sent successfully!"),j("SUCCESS"),e&&e({txHash:m,network:n,token:r?.key,tokenSymbol:r?.symbol,amount:a?.amount,receivingAddress:a?.receivingAddress})}catch(e){x(e);let t="Unknown error";t="UserRejectedRequestError"===e.name||4001===e.code?"User denied transaction":"ContractFunctionRevertedError"===e.name||e.data&&e.data.message?e.shortMessage||e.data?.message||e.message:e.shortMessage||(e.message?e.message.split("\n")[0]:"Transaction failed"),S(`Transaction failed: ${t}`),j("IDLE"),console.error("Transaction error:",e)}}},"Yes, Pay"))),s&&"PROCESSING"===M&&l.createElement("button",{className:D.walletButton,disabled:!0},"Processing...")))},q=({onClose:e,buttonSize:t,onTransactionComplete:n})=>{const{resetSelections:r}=$();return l.createElement(x,{onClose:()=>{r(),e()},size:t},l.createElement(j,null),l.createElement(F,null),l.createElement(O,{onTransactionComplete:n}))},H=({onClose:e,buttonSize:t,networkSelector:n,onTransactionComplete:r})=>l.createElement(M,{networkSelector:n},l.createElement(z,null,l.createElement(q,{onClose:e,buttonSize:t,onTransactionComplete:r}))),G={NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(_).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:N,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!_[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:t="medium",onTransactionComplete:n,onSuccess:r})=>{const[a,o]=m(!1),i=n||r;return l.createElement("div",{className:D.widgetContainer},!a&&l.createElement(P,{onClick:()=>{o(!0)},size:t}),a&&l.createElement(H,{onClose:()=>{o(!1)},buttonSize:t,networkSelector:e,onTransactionComplete:i}))},PayButton:P,Dialog:x,NetworkDropdown:j};export{G as default}; diff --git a/stablepay-sdk/dist/umd/index.js b/stablepay-sdk/dist/umd/index.js index 1b89058..bb1950f 100644 --- a/stablepay-sdk/dist/umd/index.js +++ b/stablepay-sdk/dist/umd/index.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("djed-sdk"),require("react"),require("viem"),require("viem/chains")):"function"==typeof define&&define.amd?define(["djed-sdk","react","viem","viem/chains"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).StablePay=t(e.DjedSdk,e.React,e.viem,e.viemChains)}(this,(function(e,t,n,a){"use strict";const r={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class o{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e.getWeb3(this.networkUri),this.djedContract=e.getDjedContract(this.web3,this.djedAddress);try{const{stableCoin:t,reserveCoin:n}=await e.getCoinContracts(this.djedContract,this.web3),{scDecimals:a,rcDecimals:r}=await e.getDecimals(t,n);this.stableCoin=t,this.reserveCoin=n,this.scDecimals=a,this.rcDecimals=r,this.oracleContract=await e.getOracleAddress(this.djedContract).then((t=>e.getOracleContract(this.web3,t,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){console.error("[Transaction] Error fetching contract details:",e);if(-32e3===e.code||3===e.code||e.data){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){console.error("[Transaction] Error initializing transaction:",e);if(-32603===e.code||4001===e.code||-32005===e.code||e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(t){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof t)throw new Error("Amount must be a string");try{return(await e.tradeDataPriceBuySc(this.djedContract,this.scDecimals,t)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(t,n,a){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await e.buyScTx(this.djedContract,t,n,a,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var i="main_stablePayButton__UA7HC",s="main_logo__ITyEy",l="main_buttonText__N-ewy";const c=({onClick:e,size:n="medium"})=>{const a={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},o=a[n]||a.medium,c=r[n]||r.medium;return t.createElement("button",{className:i,onClick:e,style:o},t.createElement("div",{className:s,style:c}),t.createElement("span",{className:l},"Pay with StablePay"))};var d={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",confirmContainer:"PricingCard_confirmContainer__vNq4n",confirmText:"PricingCard_confirmText__FP0WS",confirmButtons:"PricingCard_confirmButtons__fZ7jt",secondaryButton:"PricingCard_secondaryButton__OTpW4",primaryButton:"PricingCard_primaryButton__bmYo9",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const u=({children:e,onClose:n,size:a="medium"})=>t.createElement("div",{className:d.dialogOverlay},t.createElement("div",{className:`${d.pricingCard} ${d[a]}`},t.createElement("button",{className:d.dialogClose,onClick:n},"×"),t.createElement("div",{className:d.pricingCardHeader},t.createElement("div",{className:d.allianceLogo}),t.createElement("div",{className:d.stablepayTitle},"StablePay")),t.createElement("div",{className:d.pricingCardBody},e)));class m{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const h=t.createContext(),w=({children:e,networkSelector:n})=>{const[a]=t.useState((()=>new m(n))),[r,o]=t.useState(null),[i,s]=t.useState(null),[l,c]=t.useState(null),d=()=>{s(null),c(null)};return t.useEffect((()=>{o(n.selectedNetwork)}),[n.selectedNetwork]),t.createElement(h.Provider,{value:{networkSelector:n,tokenSelector:a,selectedNetwork:r,selectedToken:i,transactionDetails:l,setTransactionDetails:c,selectNetwork:e=>!!n.selectNetwork(e)&&(o(e),d(),!0),selectToken:e=>{if(a.selectToken(e)){const e=a.getSelectedToken();return s(e),!0}return!1},resetSelections:()=>{n.selectNetwork(null),o(null),d()}}},e)},k=()=>{const e=t.useContext(h);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},g=()=>{const{networkSelector:e,selectedNetwork:n,selectNetwork:a}=k();return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"network-select"},"Select Network"),t.createElement("select",{id:"network-select",onChange:e=>{a(e.target.value)},value:n||""},t.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>t.createElement("option",{key:e,value:e},e)))))},C=()=>{const{networkSelector:e,tokenSelector:n,selectedNetwork:a,selectedToken:r,selectToken:i,setTransactionDetails:s}=k(),[l,c]=t.useState(!1),[u,m]=t.useState(null),h=a?n.getAvailableTokens():[];return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"token-select"},"Select Token"),t.createElement("select",{id:"token-select",onChange:async t=>{const r=t.target.value;m(null),c(!0);try{if(i(r)){const t=e.getSelectedNetworkConfig(),i=new o(t.uri,t.djedAddress);await i.init();const l=e.getTokenAmount(r),c=i.getBlockchainDetails();let d=null;"native"===r&&(d=await i.handleTradeDataBuySc(String(l))),s({network:a,token:r,tokenSymbol:n.getSelectedToken().symbol,amount:l,receivingAddress:e.getReceivingAddress(),djedContractAddress:t.djedAddress,isDirectTransfer:n.getSelectedToken().isDirectTransfer||!1,isNativeToken:n.getSelectedToken().isNative||!1,tradeAmount:d?d.amount:null,...c})}}catch(e){console.error("Error fetching transaction details:",e),"undefined"==typeof window||window.ethereum?m("Failed to fetch transaction details. Please try again."):m("No wallet found. Please install a Web3 wallet.")}finally{c(!1)}},value:r?r.key:"",disabled:!a||l},t.createElement("option",{value:"",disabled:!0},a?l?"Loading...":"Select a token":"Please select a network first"),h.map((e=>t.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),u&&t.createElement("div",{className:d.error},u))};n.defineChain({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const f=n.defineChain({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),p=n.defineChain({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),b=t.createContext(null),E=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${a.sepolia.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:a.sepolia.rpcUrls.default.http,blockExplorerUrls:a.sepolia.blockExplorers?.default?.url?[a.sepolia.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${p.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${f.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},y=({children:e})=>{const{selectedNetwork:r}=k(),[o,i]=t.useState(null),[s,l]=t.useState(null),[c,d]=t.useState(null),[u,m]=t.useState(null),[h,w]=t.useState(null),[g,C]=t.useState(null),[y,v]=t.useState(!1),_=r?(e=>{switch(e){case"sepolia":return a.sepolia;case"ethereum-classic":return p;case"milkomeda-mainnet":return f;default:return null}})(r):null,N=_?_.id:null,S=t.useRef(null),T=t.useRef(null),P=t.useCallback((()=>{i(null),l(null),d(null),m(null),w(null),C(null)}),[]),A=t.useCallback((async e=>{const t=parseInt(e,16);if(m(t),_&&t===N){if(C(null),window.ethereum&&_){const e=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});i(e)}}else if(_&&t!==N){C(`Wrong network detected. Please switch to ${_?.name||r||"selected network"}`)}}),[_,N,r]);T.current=A;const D=t.useCallback((async e=>{if(0===e.length){if(P(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(d(e[0]),_)try{const t=n.createPublicClient({chain:_,transport:n.http()});l(t);const a=await t.getBalance({address:e[0]});w(parseFloat(a)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}}),[_,P]);S.current=D;const x=t.useCallback((()=>{if(P(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[P]),B=t.useCallback((()=>{_&&l(n.createPublicClient({chain:_,transport:n.http()}))}),[_]),I=t.useCallback((async()=>{if(!window.ethereum)return C("Please install MetaMask or another Web3 wallet"),!1;if(!r||!_)return C("Please select a network first"),!1;v(!0),C(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const t=await window.ethereum.request({method:"eth_chainId"});parseInt(t,16)!==N&&await E(r);const a=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});i(a),d(e[0]),m(N);const o=n.createPublicClient({chain:_,transport:n.http()});l(o);try{const t=await o.getBalance({address:e[0]});w(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}return S.current=D,T.current=A,window.ethereum.on("accountsChanged",D),window.ethereum.on("chainChanged",A),!0}catch(e){return console.error("Error connecting wallet:",e),C(e.message),!1}finally{v(!1)}}),[r,_,N,D,A]),M=t.useCallback((async()=>{if(!(window.ethereum&&r&&_&&c)){return C("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==N){C(null),await E(r);const e=500;await new Promise((t=>setTimeout(t,e)));const t=await window.ethereum.request({method:"eth_chainId"}),n=parseInt(t,16);if(n!==N)throw new Error(`Failed to switch network. MetaMask is still on chain ${n}, expected ${N}`)}const t=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});return i(t),m(N),C(null),t}catch(e){return C(e.message),null}}),[r,_,N,c]),j=t.useRef(r);return t.useEffect((()=>{if(null!==j.current&&j.current!==r&&c&&(P(),window.ethereum)){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}j.current=r}),[r,c,P]),t.useEffect((()=>{B()}),[B]),t.createElement(b.Provider,{value:{walletClient:o,publicClient:s,account:c,chainId:u,balance:h,error:g,isConnecting:y,connectWallet:I,disconnectWallet:x,ensureCorrectNetwork:M,expectedChainId:N}},e)},v=({onTransactionComplete:e})=>{const{networkSelector:a,selectedNetwork:r,selectedToken:i,transactionDetails:s,setTransactionDetails:l}=k(),{connectWallet:c,account:u,walletClient:m,publicClient:h,isConnecting:w,ensureCorrectNetwork:g,expectedChainId:C}=(()=>{const e=t.useContext(b);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[f,p]=t.useState(null),[E,y]=t.useState(null),[v,_]=t.useState(""),[N,S]=t.useState(null),[T,P]=t.useState(null),[A,D]=t.useState(!1),[x,B]=t.useState("IDLE");if(t.useEffect((()=>{y(null),_(""),P(null),S(null),B("IDLE")}),[r,i]),t.useEffect((()=>{(async()=>{if(r&&i)try{const e=a.getSelectedNetworkConfig(),t=a.getReceivingAddress(),n=a.getTokenAmount(i.key),s=new o(e.uri,e.djedAddress);await s.init(),p(s);let c=null;if("native"===i.key)try{c=await s.handleTradeDataBuySc(String(n)),y(c)}catch(e){console.error("Error fetching trade data:",e)}l({network:r,token:i.key,tokenSymbol:i.symbol,amount:n||"0",receivingAddress:t,djedContractAddress:e.djedAddress,isDirectTransfer:i.isDirectTransfer||!1,isNativeToken:i.isNative||!1,tradeAmount:c?c.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[r,i,a,l]),!r||!i)return null;if(!s)return"undefined"==typeof window||window.ethereum?t.createElement("div",{className:d.loading},"Initializing transaction..."):t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.messageBox,style:{textAlign:"center",marginBottom:"1rem",color:"#ff4d4f"}},"No wallet found."),t.createElement("div",{className:d.walletButtonContainer},t.createElement("button",{className:d.walletButton,onClick:()=>window.open("https://metamask.io/download/","_blank")},"Connect Wallet")));const I=()=>{if(!N||!r)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[r]?`${e[r]}${N}`:null};return t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"Network:"),t.createElement("span",{className:d.transactionValue},s.network)),t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"You Pay:"),t.createElement("span",{className:`${d.transactionValue} ${d.highlight}`},"stablecoin"===i.key?`${s.amount} ${s.tokenSymbol}`:`${E||"Calculating..."} ${s.tokenSymbol}`)),v&&t.createElement("div",{className:d.messageBox},v,T&&t.createElement("button",{onClick:()=>D(!A),className:d.detailsButton},A?"Hide Details":"Show Details")),A&&T&&t.createElement("div",{className:d.errorDetails},t.createElement("pre",null,T.message)),N&&t.createElement("div",{className:d.transactionLink},"Transaction Hash:"," ",I()?t.createElement("a",{href:I(),target:"_blank",rel:"noopener noreferrer",className:d.explorerLink},N.slice(0,6),"...",N.slice(-6)):t.createElement("span",{style:{wordBreak:"break-word"}},N)),"SUCCESS"!==x&&t.createElement("div",{className:d.walletButtonContainer},!u&&t.createElement("button",{className:d.walletButton,onClick:async()=>{await c()},disabled:w},w?"Connecting...":"Connect Wallet"),u&&"IDLE"===x&&t.createElement("button",{className:d.walletButton,onClick:()=>B("CONFIRMING")},"Pay ",s.amount," ",s.tokenSymbol),u&&"CONFIRMING"===x&&t.createElement("div",{className:d.confirmContainer},t.createElement("span",{className:d.confirmText},"Confirm payment?"),t.createElement("div",{className:d.confirmButtons},t.createElement("button",{className:d.secondaryButton,onClick:()=>B("IDLE")},"No"),t.createElement("button",{className:`${d.walletButton} ${d.primaryButton}`,onClick:async()=>{if(!u||!s||!f)return void _("Wallet not connected or transaction details missing");let t;B("PROCESSING"),_("Preparing transaction..."),P(null),S(null);try{const e=s.receivingAddress;if("native"===i.key){const a="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=E||"0",o=n.parseEther(String(r));t=await f.buyStablecoins(u,e,o,a),t={...t,value:o,account:u}}else{const r=a.getSelectedNetworkConfig(),o=r?.tokens?.stablecoin?.address;if(!o)throw new Error("Stablecoin address not found in network configuration");const i=s.amount?n.parseUnits(String(s.amount),s.stableCoinDecimals):"0";t={to:o,value:0n,data:n.encodeFunctionData({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:u}}}catch(e){P(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");return _(`Transaction preparation failed: ${t}`),void B("IDLE")}_("Please check your wallet to confirm the transaction...");try{const n=a.getSelectedNetworkConfig();if(!n)throw new Error("Network configuration not found");const o=await g();if(!o)throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask.");if(!window.ethereum)throw new Error("MetaMask not available");const l=await window.ethereum.request({method:"eth_chainId"}),c=parseInt(l,16);if(c!==n.chainId)throw new Error(`Network mismatch. MetaMask is on chain ${c}, but ${r} requires chain ${n.chainId}. Please switch networks in MetaMask.`);if(o.chain.id!==n.chainId)throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${o.chain.id}, but expected ${n.chainId}.`);const d=await o.sendTransaction({...t,account:u});S(d),_("Transaction sent successfully!"),B("SUCCESS"),e&&e({txHash:d,network:r,token:i?.key,tokenSymbol:i?.symbol,amount:s?.amount,receivingAddress:s?.receivingAddress})}catch(e){P(e);let t="Unknown error";t="UserRejectedRequestError"===e.name||4001===e.code?"User denied transaction":"ContractFunctionRevertedError"===e.name||e.data&&e.data.message?e.shortMessage||e.data?.message||e.message:e.shortMessage||(e.message?e.message.split("\n")[0]:"Transaction failed"),_(`Transaction failed: ${t}`),B("IDLE"),console.error("Transaction error:",e)}}},"Yes, Pay"))),u&&"PROCESSING"===x&&t.createElement("button",{className:d.walletButton,disabled:!0},"Processing...")))},_=({onClose:e,buttonSize:n,onTransactionComplete:a})=>{const{resetSelections:r}=k();return t.createElement(u,{onClose:()=>{r(),e()},size:n},t.createElement(g,null),t.createElement(C,null),t.createElement(v,{onTransactionComplete:a}))},N=({onClose:e,buttonSize:n,networkSelector:a,onTransactionComplete:r})=>t.createElement(w,{networkSelector:a},t.createElement(y,null,t.createElement(_,{onClose:e,buttonSize:n,onTransactionComplete:r})));return{NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(r).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:o,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!r[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:n="medium",onTransactionComplete:a,onSuccess:r})=>{const[o,i]=t.useState(!1),s=a||r;return t.createElement("div",{className:d.widgetContainer},!o&&t.createElement(c,{onClick:()=>{i(!0)},size:n}),o&&t.createElement(N,{onClose:()=>{i(!1)},buttonSize:n,networkSelector:e,onTransactionComplete:s}))},PayButton:c,Dialog:u,NetworkDropdown:g}})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("djed-sdk"),require("react"),require("viem"),require("viem/chains")):"function"==typeof define&&define.amd?define(["djed-sdk","react","viem","viem/chains"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).StablePay=t(e.DjedSdk,e.React,e.viem,e.viemChains)}(this,(function(e,t,n,a){"use strict";const r={sepolia:{uri:"https://ethereum-sepolia.publicnode.com/",chainId:11155111,djedAddress:"0x624FcD0a1F9B5820c950FefD48087531d38387f4",tokens:{stablecoin:{symbol:"SOD",address:"0x6b930182787F346F18666D167e8d32166dC5eFBD",decimals:18,isDirectTransfer:!0},native:{symbol:"ETH",decimals:18,isNative:!0}},feeUI:0},"milkomeda-mainnet":{uri:"https://rpc-mainnet-cardano-evm.c1.milkomeda.com",chainId:2001,djedAddress:"0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76",tokens:{stablecoin:{symbol:"MOD",address:"0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9",decimals:18,isDirectTransfer:!0},native:{symbol:"mADA",decimals:18,isNative:!0}},feeUI:0},"ethereum-classic":{uri:"https://etc.rivet.link",chainId:61,djedAddress:"0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf",tokens:{stablecoin:{symbol:"ECSD",address:"0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A",decimals:18,isDirectTransfer:!0},native:{symbol:"ETC",decimals:18,isNative:!0}},feeUI:0}};class o{constructor(e,t){this.networkUri=e,this.djedAddress=t}async init(){if(!this.networkUri||!this.djedAddress)throw new Error("Network URI and DJED address are required");try{this.web3=await e.getWeb3(this.networkUri),this.djedContract=e.getDjedContract(this.web3,this.djedAddress);try{const{stableCoin:t,reserveCoin:n}=await e.getCoinContracts(this.djedContract,this.web3),{scDecimals:a,rcDecimals:r}=await e.getDecimals(t,n);this.stableCoin=t,this.reserveCoin=n,this.scDecimals=a,this.rcDecimals=r,this.oracleContract=await e.getOracleAddress(this.djedContract).then((t=>e.getOracleContract(this.web3,t,this.djedContract._address))),this.oracleAddress=this.oracleContract._address}catch(e){console.error("[Transaction] Error fetching contract details:",e);if(-32e3===e?.code||3===e?.code||"ContractFunctionRevertedError"===e?.name||"string"==typeof e?.data?.message){const e=e=>e.includes("milkomeda")?{name:"Milkomeda",chainId:"2001"}:e.includes("mordor")?{name:"Mordor Testnet",chainId:"63"}:e.includes("sepolia")?{name:"Sepolia",chainId:"11155111"}:e.includes("etc.rivet.link")?{name:"Ethereum Classic",chainId:"61"}:{name:"the selected network",chainId:"unknown"},{name:t,chainId:n}=e(this.networkUri);throw new Error(`Failed to interact with Djed contract at ${this.djedAddress} on ${t}.\n\nPossible causes:\n- The contract address may be incorrect\n- The contract may not be deployed on ${t}\n- The contract may not be a valid Djed contract\n\nPlease verify the contract address is correct for ${t} (Chain ID: ${n}).`)}throw e}}catch(e){console.error("[Transaction] Error initializing transaction:",e);if(-32603===e.code||4001===e.code||-32005===e.code||e.message&&(e.message.includes("CONNECTION ERROR")||e.message.includes("ERR_NAME_NOT_RESOLVED"))){const e=(e=>e.includes("milkomeda")?"Milkomeda":e.includes("mordor")?"Mordor":e.includes("sepolia")?"Sepolia":"the selected network")(this.networkUri);throw new Error(`Failed to connect to ${e} RPC endpoint: ${this.networkUri}\n\nPossible causes:\n- The RPC endpoint may be temporarily unavailable\n- DNS resolution issue (check your internet connection)\n- Network firewall blocking the connection\n\nPlease try again in a few moments or check the network status.`)}throw e}}getBlockchainDetails(){return{web3Available:!!this.web3,djedContractAvailable:!!this.djedContract,stableCoinAddress:this.stableCoin?this.stableCoin._address:"N/A",reserveCoinAddress:this.reserveCoin?this.reserveCoin._address:"N/A",stableCoinDecimals:this.scDecimals,reserveCoinDecimals:this.rcDecimals,oracleAddress:this.oracleAddress||"N/A",oracleContractAvailable:!!this.oracleContract}}async handleTradeDataBuySc(t){if(!this.djedContract)throw new Error("DJED contract is not initialized");if("string"!=typeof t)throw new Error("Amount must be a string");try{return(await e.tradeDataPriceBuySc(this.djedContract,this.scDecimals,t)).totalBCScaled}catch(e){throw console.error("Error fetching trade data for buying stablecoins: ",e),e}}async buyStablecoins(t,n,a){if(!this.djedContract)throw new Error("DJED contract is not initialized");try{const r="0x0232556C83791b8291E9b23BfEa7d67405Bd9839";return await e.buyScTx(this.djedContract,t,n,a,r,this.djedAddress)}catch(e){throw console.error("Error executing buyStablecoins transaction: ",e),e}}}var i="main_stablePayButton__UA7HC",s="main_logo__ITyEy",c="main_buttonText__N-ewy";const l=({onClick:e,size:n="medium"})=>{const a={small:{width:"200px",height:"50px",fontSize:"14px"},medium:{width:"250px",height:"60px",fontSize:"16px"},large:{width:"300px",height:"70px",fontSize:"18px"}},r={small:{width:"35px",height:"33px"},medium:{width:"40px",height:"38px"},large:{width:"45px",height:"43px"}},o=a[n]||a.medium,l=r[n]||r.medium;return t.createElement("button",{className:i,onClick:e,style:o},t.createElement("div",{className:s,style:l}),t.createElement("span",{className:c},"Pay with StablePay"))};var d={dialogOverlay:"PricingCard_dialogOverlay__0XJrE",fadeInScale:"PricingCard_fadeInScale__2MTi3",pricingCard:"PricingCard_pricingCard__LrWb9",small:"PricingCard_small__J4CHj",medium:"PricingCard_medium__EVmTB",large:"PricingCard_large__A6pnX",dialogClose:"PricingCard_dialogClose__jJ1tM",pricingCardHeader:"PricingCard_pricingCardHeader__wGczA",allianceLogo:"PricingCard_allianceLogo__URa-U",stablepayTitle:"PricingCard_stablepayTitle__4t848",pricingCardBody:"PricingCard_pricingCardBody__0wKQn",selectField:"PricingCard_selectField__LBPoZ",transactionReview:"PricingCard_transactionReview__Ix-eL",transactionInfo:"PricingCard_transactionInfo__Ck-Rc",transactionLabel:"PricingCard_transactionLabel__GDux7",transactionValue:"PricingCard_transactionValue__q-xxp",highlight:"PricingCard_highlight__WZZ6N",walletButtonContainer:"PricingCard_walletButtonContainer__a6MwB",walletButton:"PricingCard_walletButton__llw4v",confirmContainer:"PricingCard_confirmContainer__vNq4n",confirmText:"PricingCard_confirmText__FP0WS",confirmButtons:"PricingCard_confirmButtons__fZ7jt",secondaryButton:"PricingCard_secondaryButton__OTpW4",primaryButton:"PricingCard_primaryButton__bmYo9",loading:"PricingCard_loading__2-tGA",error:"PricingCard_error__m5fK-",messageBox:"PricingCard_messageBox__wnx0F",fadeIn:"PricingCard_fadeIn__L63q8",detailsButton:"PricingCard_detailsButton__jHglL",errorDetails:"PricingCard_errorDetails__CzN-7",transactionLink:"PricingCard_transactionLink__RFRWW",explorerLink:"PricingCard_explorerLink__-a82-",stablePayButton:"PricingCard_stablePayButton__Y4Rr4",buttonText:"PricingCard_buttonText__8LnPv"};const u=({children:e,onClose:n,size:a="medium"})=>t.createElement("div",{className:d.dialogOverlay},t.createElement("div",{className:`${d.pricingCard} ${d[a]}`},t.createElement("button",{className:d.dialogClose,onClick:n},"×"),t.createElement("div",{className:d.pricingCardHeader},t.createElement("div",{className:d.allianceLogo}),t.createElement("div",{className:d.stablepayTitle},"StablePay")),t.createElement("div",{className:d.pricingCardBody},e)));class m{constructor(e){this.networkSelector=e,this.selectedToken=null}selectToken(e){const t=this.networkSelector.getSelectedNetworkConfig();return!(!t||!t.tokens[e])&&(this.selectedToken={key:e,...t.tokens[e]},!0)}getSelectedToken(){return this.selectedToken}getAvailableTokens(){const e=this.networkSelector.getSelectedNetworkConfig();return e?Object.entries(e.tokens).map((([e,t])=>({key:e,...t}))):[]}resetSelection(){this.selectedToken=null}}const h=t.createContext(),w=({children:e,networkSelector:n})=>{const[a]=t.useState((()=>new m(n))),[r,o]=t.useState(null),[i,s]=t.useState(null),[c,l]=t.useState(null),d=()=>{s(null),l(null)};return t.useEffect((()=>{o(n.selectedNetwork)}),[n.selectedNetwork]),t.createElement(h.Provider,{value:{networkSelector:n,tokenSelector:a,selectedNetwork:r,selectedToken:i,transactionDetails:c,setTransactionDetails:l,selectNetwork:e=>!!n.selectNetwork(e)&&(o(e),d(),!0),selectToken:e=>{if(a.selectToken(e)){const e=a.getSelectedToken();return s(e),!0}return!1},resetSelections:()=>{n.selectNetwork(null),o(null),d()}}},e)},k=()=>{const e=t.useContext(h);if(void 0===e)throw new Error("useNetwork must be used within a NetworkProvider");return e},g=()=>{const{networkSelector:e,selectedNetwork:n,selectNetwork:a}=k();return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"network-select"},"Select Network"),t.createElement("select",{id:"network-select",onChange:e=>{a(e.target.value)},value:n||""},t.createElement("option",{value:"",disabled:!0},"Select a network"),Object.keys(e.availableNetworks).map((e=>t.createElement("option",{key:e,value:e},e)))))},C=()=>{const{networkSelector:e,tokenSelector:n,selectedNetwork:a,selectedToken:r,selectToken:i,setTransactionDetails:s}=k(),[c,l]=t.useState(!1),[u,m]=t.useState(null),h=a?n.getAvailableTokens():[];return t.createElement("div",{className:d.selectField},t.createElement("label",{htmlFor:"token-select"},"Select Token"),t.createElement("select",{id:"token-select",onChange:async t=>{const r=t.target.value;m(null),l(!0);try{if(i(r)){const t=e.getSelectedNetworkConfig(),i=new o(t.uri,t.djedAddress);await i.init();const c=e.getTokenAmount(r),l=i.getBlockchainDetails();let d=null;"native"===r&&(d=await i.handleTradeDataBuySc(String(c))),s({network:a,token:r,tokenSymbol:n.getSelectedToken().symbol,amount:c,receivingAddress:e.getReceivingAddress(),djedContractAddress:t.djedAddress,isDirectTransfer:n.getSelectedToken().isDirectTransfer||!1,isNativeToken:n.getSelectedToken().isNative||!1,tradeAmount:d?d.amount:null,...l})}}catch(e){console.error("Error fetching transaction details:",e),"undefined"==typeof window||window.ethereum?m("Failed to fetch transaction details. Please try again."):m("No wallet found. Please install a Web3 wallet.")}finally{l(!1)}},value:r?r.key:"",disabled:!a||c},t.createElement("option",{value:"",disabled:!0},a?c?"Loading...":"Select a token":"Please select a network first"),h.map((e=>t.createElement("option",{key:e.key,value:e.key},e.symbol," (",e.isDirectTransfer?"Direct Transfer":"Native",")")))),u&&t.createElement("div",{className:d.error},u))};n.defineChain({id:63,name:"Mordor Testnet",network:"mordor",nativeCurrency:{decimals:18,name:"Mordor Ether",symbol:"METC"},rpcUrls:{default:{http:["https://rpc.mordor.etccooperative.org"],webSocket:["wss://rpc.mordor.etccooperative.org/ws"]}},blockExplorers:{default:{name:"BlockScout",url:"https://blockscout.com/etc/mordor"}},testnet:!0});const f=n.defineChain({id:2001,name:"Milkomeda C1 Mainnet",network:"milkomeda",nativeCurrency:{decimals:18,name:"Milkomeda ADA",symbol:"mADA"},rpcUrls:{default:{http:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"]}},blockExplorers:{default:{name:"Milkomeda Explorer",url:"https://explorer-mainnet-cardano-evm.c1.milkomeda.com"}},testnet:!1}),p=n.defineChain({id:61,name:"Ethereum Classic",network:"etc",nativeCurrency:{decimals:18,name:"Ethereum Classic",symbol:"ETC"},rpcUrls:{default:{http:["https://etc.rivet.link"]}},blockExplorers:{default:{name:"Blockscout",url:"https://blockscout.com/etc/mainnet"}},testnet:!1}),b=t.createContext(null),E=async e=>{if(!window.ethereum)throw new Error("MetaMask not installed");const t=(e=>{switch(e){case"sepolia":return{chainId:`0x${a.sepolia.id.toString(16)}`,chainName:"Sepolia",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:a.sepolia.rpcUrls.default.http,blockExplorerUrls:a.sepolia.blockExplorers?.default?.url?[a.sepolia.blockExplorers.default.url]:[]};case"ethereum-classic":return{chainId:`0x${p.id.toString(16)}`,chainName:"Ethereum Classic",nativeCurrency:{name:"Ethereum Classic",symbol:"ETC",decimals:18},rpcUrls:["https://etc.rivet.link"],blockExplorerUrls:["https://blockscout.com/etc/mainnet"]};case"milkomeda-mainnet":return{chainId:`0x${f.id.toString(16)}`,chainName:"Milkomeda C1 Mainnet",nativeCurrency:{name:"Milkomeda ADA",symbol:"mADA",decimals:18},rpcUrls:["https://rpc-mainnet-cardano-evm.c1.milkomeda.com"],blockExplorerUrls:["https://explorer-mainnet-cardano-evm.c1.milkomeda.com"]};default:return null}})(e);if(!t)throw new Error(`Unsupported network: ${e}`);try{await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t.chainId}]})}catch(e){if(4902!==e.code)throw 4001===e.code?new Error(`User rejected switching to ${t.chainName}. Please switch manually in MetaMask.`):new Error(`Failed to switch to ${t.chainName}: ${e.message}`);try{await window.ethereum.request({method:"wallet_addEthereumChain",params:[t]})}catch(e){if(4001===e.code)throw new Error(`User rejected adding ${t.chainName} to MetaMask. Please add it manually.`);throw new Error(`Failed to add ${t.chainName} to MetaMask: ${e.message}`)}}},y=({children:e})=>{const{selectedNetwork:r}=k(),[o,i]=t.useState(null),[s,c]=t.useState(null),[l,d]=t.useState(null),[u,m]=t.useState(null),[h,w]=t.useState(null),[g,C]=t.useState(null),[y,v]=t.useState(!1),_=r?(e=>{switch(e){case"sepolia":return a.sepolia;case"ethereum-classic":return p;case"milkomeda-mainnet":return f;default:return null}})(r):null,N=_?_.id:null,S=t.useRef(null),T=t.useRef(null),P=t.useCallback((()=>{i(null),c(null),d(null),m(null),w(null),C(null)}),[]),A=t.useCallback((async e=>{const t=parseInt(e,16);if(m(t),_&&t===N){if(C(null),window.ethereum&&_){const e=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});i(e)}}else if(_&&t!==N){C(`Wrong network detected. Please switch to ${_?.name||r||"selected network"}`)}}),[_,N,r]);T.current=A;const D=t.useCallback((async e=>{if(0===e.length){if(P(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}else if(d(e[0]),_)try{const t=n.createPublicClient({chain:_,transport:n.http()});c(t);const a=await t.getBalance({address:e[0]});w(parseFloat(a)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}}),[_,P]);S.current=D;const x=t.useCallback((()=>{if(P(),window.ethereum){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}}),[P]),B=t.useCallback((()=>{_&&c(n.createPublicClient({chain:_,transport:n.http()}))}),[_]),I=t.useCallback((async()=>{if(!window.ethereum)return C("Please install MetaMask or another Web3 wallet"),!1;if(!r||!_)return C("Please select a network first"),!1;v(!0),C(null);try{const e=await window.ethereum.request({method:"eth_requestAccounts"});if(0===e.length)throw new Error("No wallet address found. Please unlock your wallet.");const t=await window.ethereum.request({method:"eth_chainId"});parseInt(t,16)!==N&&await E(r);const a=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});i(a),d(e[0]),m(N);const o=n.createPublicClient({chain:_,transport:n.http()});c(o);try{const t=await o.getBalance({address:e[0]});w(parseFloat(t)/Math.pow(10,18))}catch(e){console.error("Error fetching balance:",e),w(null)}return S.current=D,T.current=A,window.ethereum.on("accountsChanged",D),window.ethereum.on("chainChanged",A),!0}catch(e){return console.error("Error connecting wallet:",e),C(e.message),!1}finally{v(!1)}}),[r,_,N,D,A]),M=t.useCallback((async()=>{if(!(window.ethereum&&r&&_&&l)){return C("Wallet not connected or network not selected"),null}try{const e=await window.ethereum.request({method:"eth_chainId"});if(parseInt(e,16)!==N){C(null),await E(r);const e=500;await new Promise((t=>setTimeout(t,e)));const t=await window.ethereum.request({method:"eth_chainId"}),n=parseInt(t,16);if(n!==N)throw new Error(`Failed to switch network. MetaMask is still on chain ${n}, expected ${N}`)}const t=n.createWalletClient({chain:_,transport:n.custom(window.ethereum)});return i(t),m(N),C(null),t}catch(e){return C(e.message),null}}),[r,_,N,l]),j=t.useRef(r);return t.useEffect((()=>{if(null!==j.current&&j.current!==r&&l&&(P(),window.ethereum)){const e=S.current,t=T.current;e&&window.ethereum.removeListener("accountsChanged",e),t&&window.ethereum.removeListener("chainChanged",t)}j.current=r}),[r,l,P]),t.useEffect((()=>{B()}),[B]),t.createElement(b.Provider,{value:{walletClient:o,publicClient:s,account:l,chainId:u,balance:h,error:g,isConnecting:y,connectWallet:I,disconnectWallet:x,ensureCorrectNetwork:M,expectedChainId:N}},e)},v=({onTransactionComplete:e})=>{const{networkSelector:a,selectedNetwork:r,selectedToken:i,transactionDetails:s,setTransactionDetails:c}=k(),{connectWallet:l,account:u,walletClient:m,publicClient:h,isConnecting:w,ensureCorrectNetwork:g,expectedChainId:C}=(()=>{const e=t.useContext(b);if(!e)throw new Error("useWallet must be used within a WalletProvider");return e})(),[f,p]=t.useState(null),[E,y]=t.useState(null),[v,_]=t.useState(""),[N,S]=t.useState(null),[T,P]=t.useState(null),[A,D]=t.useState(!1),[x,B]=t.useState("IDLE");if(t.useEffect((()=>{y(null),_(""),P(null),S(null),B("IDLE")}),[r,i]),t.useEffect((()=>{(async()=>{if(r&&i)try{const e=a.getSelectedNetworkConfig(),t=a.getReceivingAddress(),n=a.getTokenAmount(i.key),s=new o(e.uri,e.djedAddress);await s.init(),p(s);let l=null;if("native"===i.key)try{l=await s.handleTradeDataBuySc(String(n)),y(l)}catch(e){console.error("Error fetching trade data:",e)}c({network:r,token:i.key,tokenSymbol:i.symbol,amount:n||"0",receivingAddress:t,djedContractAddress:e.djedAddress,isDirectTransfer:i.isDirectTransfer||!1,isNativeToken:i.isNative||!1,tradeAmount:l?l.amount:null,...s.getBlockchainDetails()})}catch(e){console.error("Error initializing transaction:",e)}})()}),[r,i,a,c]),!r||!i)return null;if(!s)return"undefined"==typeof window||window.ethereum?t.createElement("div",{className:d.loading},"Initializing transaction..."):t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.messageBox,style:{textAlign:"center",marginBottom:"1rem",color:"#ff4d4f"}},"No wallet found."),t.createElement("div",{className:d.walletButtonContainer},t.createElement("button",{className:d.walletButton,onClick:()=>window.open("https://metamask.io/download/","_blank")},"Connect Wallet")));const I=()=>{if(!N||!r)return null;const e={"ethereum-classic":"https://blockscout.com/etc/mainnet/tx/",sepolia:"https://sepolia.etherscan.io/tx/","milkomeda-mainnet":"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/"};return e[r]?`${e[r]}${N}`:null};return t.createElement("div",{className:d.transactionReview},t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"Network:"),t.createElement("span",{className:d.transactionValue},s.network)),t.createElement("div",{className:d.transactionInfo},t.createElement("span",{className:d.transactionLabel},"You Pay:"),t.createElement("span",{className:`${d.transactionValue} ${d.highlight}`},"stablecoin"===i.key?`${s.amount} ${s.tokenSymbol}`:`${E||"Calculating..."} ${s.tokenSymbol}`)),v&&t.createElement("div",{className:d.messageBox},v,T&&t.createElement("button",{onClick:()=>D(!A),className:d.detailsButton},A?"Hide Details":"Show Details")),A&&T&&t.createElement("div",{className:d.errorDetails},t.createElement("pre",null,T.message)),N&&t.createElement("div",{className:d.transactionLink},"Transaction Hash:"," ",I()?t.createElement("a",{href:I(),target:"_blank",rel:"noopener noreferrer",className:d.explorerLink},N.slice(0,6),"...",N.slice(-6)):t.createElement("span",{style:{wordBreak:"break-word"}},N)),"SUCCESS"!==x&&t.createElement("div",{className:d.walletButtonContainer},!u&&t.createElement("button",{className:d.walletButton,onClick:async()=>{await l()},disabled:w},w?"Connecting...":"Connect Wallet"),u&&"IDLE"===x&&t.createElement("button",{className:d.walletButton,onClick:()=>B("CONFIRMING")},"Pay ",s.amount," ",s.tokenSymbol),u&&"CONFIRMING"===x&&t.createElement("div",{className:d.confirmContainer},t.createElement("span",{className:d.confirmText},"Confirm payment?"),t.createElement("div",{className:d.confirmButtons},t.createElement("button",{className:d.secondaryButton,onClick:()=>B("IDLE")},"No"),t.createElement("button",{className:`${d.walletButton} ${d.primaryButton}`,onClick:async()=>{if(!u||!s||!f)return void _("Wallet not connected or transaction details missing");let t;B("PROCESSING"),_("Preparing transaction..."),P(null),S(null);try{const e=s.receivingAddress;if("native"===i.key){const a="0x0232556C83791b8291E9b23BfEa7d67405Bd9839",r=E||"0",o=n.parseEther(String(r));t=await f.buyStablecoins(u,e,o,a),t={...t,value:o,account:u}}else{const r=a.getSelectedNetworkConfig(),o=r?.tokens?.stablecoin?.address;if(!o)throw new Error("Stablecoin address not found in network configuration");const i=s.amount?n.parseUnits(String(s.amount),s.stableCoinDecimals):"0";t={to:o,value:0n,data:n.encodeFunctionData({abi:[{inputs:[{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}],functionName:"transfer",args:[e,i]}),account:u}}}catch(e){P(e);const t=e.shortMessage||(e.message?e.message.split("\n")[0]:"Unknown error");return _(`Transaction preparation failed: ${t}`),void B("IDLE")}_("Please check your wallet to confirm the transaction...");try{const n=a.getSelectedNetworkConfig();if(!n)throw new Error("Network configuration not found");const o=await g();if(!o)throw new Error("Failed to switch to correct network. Please approve the network switch in MetaMask.");if(!window.ethereum)throw new Error("MetaMask not available");const c=await window.ethereum.request({method:"eth_chainId"}),l=parseInt(c,16);if(l!==n.chainId)throw new Error(`Network mismatch. MetaMask is on chain ${l}, but ${r} requires chain ${n.chainId}. Please switch networks in MetaMask.`);if(o.chain.id!==n.chainId)throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${o.chain.id}, but expected ${n.chainId}.`);const d=await o.sendTransaction({...t,account:u});S(d),_("Transaction sent successfully!"),B("SUCCESS"),e&&e({txHash:d,network:r,token:i?.key,tokenSymbol:i?.symbol,amount:s?.amount,receivingAddress:s?.receivingAddress})}catch(e){P(e);let t="Unknown error";t="UserRejectedRequestError"===e.name||4001===e.code?"User denied transaction":"ContractFunctionRevertedError"===e.name||e.data&&e.data.message?e.shortMessage||e.data?.message||e.message:e.shortMessage||(e.message?e.message.split("\n")[0]:"Transaction failed"),_(`Transaction failed: ${t}`),B("IDLE"),console.error("Transaction error:",e)}}},"Yes, Pay"))),u&&"PROCESSING"===x&&t.createElement("button",{className:d.walletButton,disabled:!0},"Processing...")))},_=({onClose:e,buttonSize:n,onTransactionComplete:a})=>{const{resetSelections:r}=k();return t.createElement(u,{onClose:()=>{r(),e()},size:n},t.createElement(g,null),t.createElement(C,null),t.createElement(v,{onTransactionComplete:a}))},N=({onClose:e,buttonSize:n,networkSelector:a,onTransactionComplete:r})=>t.createElement(w,{networkSelector:a},t.createElement(y,null,t.createElement(_,{onClose:e,buttonSize:n,onTransactionComplete:r})));return{NetworkSelector:class{constructor(e){this.merchantConfig=e,this.blacklist=e.getBlacklist(),this.availableNetworks=this.getAvailableNetworks(),this.selectedNetwork=null}getAvailableNetworks(){return Object.entries(r).reduce(((e,[t,n])=>(this.blacklist.includes(n.chainId)||(e[t]=n),e)),{})}selectNetwork(e){return null===e?(this.selectedNetwork=null,console.log("Network selection reset"),!0):this.availableNetworks[e]?(this.selectedNetwork=e,console.log(`Network selected: ${e}`),!0):(console.error(`Invalid network: ${e}`),!1)}getSelectedNetworkConfig(){return this.selectedNetwork?this.availableNetworks[this.selectedNetwork]:null}getReceivingAddress(){return this.merchantConfig.getReceivingAddress()}getTokenAmount(e){return this.merchantConfig.getTokenAmount(this.selectedNetwork,e)}},Transaction:o,Config:class{constructor(e={}){this.receivingAddress=e.receivingAddress||"",this.blacklist=e.blacklist||[],this.amounts=e.amounts||e.Amounts||{},this.validateConfig()}validateConfig(){if(!this.receivingAddress)throw new Error("Receiving address is required");for(const[e,t]of Object.entries(this.amounts)){if(!r[e])throw new Error(`Invalid network: ${e}`);if(!t.stablecoin||"number"!=typeof t.stablecoin||t.stablecoin<=0)throw new Error(`Invalid stablecoin amount for network ${e}`)}}getBlacklist(){return this.blacklist}getReceivingAddress(){return this.receivingAddress}getTokenAmount(e){console.log("Getting amount for network:",e),console.log("Amounts object:",this.amounts);const t=this.amounts[e]?.stablecoin;return console.log("Returning amount:",t),t||0}},Widget:({networkSelector:e,buttonSize:n="medium",onTransactionComplete:a,onSuccess:r})=>{const[o,i]=t.useState(!1),s=a||r;return t.createElement("div",{className:d.widgetContainer},!o&&t.createElement(l,{onClick:()=>{i(!0)},size:n}),o&&t.createElement(N,{onClose:()=>{i(!1)},buttonSize:n,networkSelector:e,onTransactionComplete:s}))},PayButton:l,Dialog:u,NetworkDropdown:g}})); //# sourceMappingURL=index.js.map diff --git a/stablepay-sdk/dist/umd/index.js.map b/stablepay-sdk/dist/umd/index.js.map index 3fe71b7..9aa1c08 100644 --- a/stablepay-sdk/dist/umd/index.js.map +++ b/stablepay-sdk/dist/umd/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../../src/utils/config.js","../../src/core/Transaction.js","../../src/widget/PayButton.jsx","../../src/widget/Dialog.jsx","../../src/core/TokenSelector.js","../../src/contexts/NetworkContext.jsx","../../src/widget/NetworkDropdown.jsx","../../src/widget/TokenDropdown.jsx","../../src/contexts/chains.js","../../src/contexts/WalletContext.jsx","../../src/widget/TransactionReview.jsx","../../src/widget/Widget.jsx","../../src/index.js","../../src/core/NetworkSelector.js","../../src/core/MerchantConfig.js"],"sourcesContent":["// src/utils/config.js\nexport const networksConfig = {\n 'sepolia': {\n uri: 'https://ethereum-sepolia.publicnode.com/',\n chainId: 11155111,\n djedAddress: '0x624FcD0a1F9B5820c950FefD48087531d38387f4',\n tokens: {\n stablecoin: {\n symbol: 'SOD',\n address: '0x6b930182787F346F18666D167e8d32166dC5eFBD',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETH',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'milkomeda-mainnet': {\n uri: 'https://rpc-mainnet-cardano-evm.c1.milkomeda.com',\n chainId: 2001,\n djedAddress: '0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76',\n tokens: {\n stablecoin: {\n symbol: 'MOD',\n address: '0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'mADA',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'ethereum-classic': {\n uri: 'https://etc.rivet.link',\n chainId: 61,\n djedAddress: '0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf',\n tokens: {\n stablecoin: {\n symbol: 'ECSD',\n address: '0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETC',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n }\n};","import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx } from 'djed-sdk';\n\nexport class Transaction {\n constructor(networkUri, djedAddress) {\n this.networkUri = networkUri;\n this.djedAddress = djedAddress;\n }\n\n async init() {\n if (!this.networkUri || !this.djedAddress) {\n throw new Error('Network URI and DJED address are required');\n }\n\n try {\n this.web3 = await getWeb3(this.networkUri);\n this.djedContract = getDjedContract(this.web3, this.djedAddress);\n \n try {\n const { stableCoin, reserveCoin } = await getCoinContracts(this.djedContract, this.web3);\n const { scDecimals, rcDecimals } = await getDecimals(stableCoin, reserveCoin);\n this.stableCoin = stableCoin;\n this.reserveCoin = reserveCoin;\n this.scDecimals = scDecimals;\n this.rcDecimals = rcDecimals;\n\n this.oracleContract = await getOracleAddress(this.djedContract).then((addr) =>\n getOracleContract(this.web3, addr, this.djedContract._address)\n );\n\n this.oracleAddress = this.oracleContract._address;\n } catch (contractError) {\n console.error('[Transaction] Error fetching contract details:', contractError);\n const isReverted = contractError.code === -32000 || contractError.code === 3 || contractError.data;\n if (isReverted) {\n const getNetworkInfo = (uri) => {\n if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };\n if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' };\n if (uri.includes('sepolia')) return { name: 'Sepolia', chainId: '11155111' };\n if (uri.includes('etc.rivet.link')) return { name: 'Ethereum Classic', chainId: '61' };\n return { name: 'the selected network', chainId: 'unknown' };\n };\n const { name: networkName, chainId } = getNetworkInfo(this.networkUri);\n throw new Error(\n `Failed to interact with Djed contract at ${this.djedAddress} on ${networkName}.\\n\\n` +\n `Possible causes:\\n` +\n `- The contract address may be incorrect\\n` +\n `- The contract may not be deployed on ${networkName}\\n` +\n `- The contract may not be a valid Djed contract\\n\\n` +\n `Please verify the contract address is correct for ${networkName} (Chain ID: ${chainId}).`\n );\n }\n throw contractError;\n }\n } catch (error) {\n console.error('[Transaction] Error initializing transaction:', error);\n const isConnectionError = error.code === -32603 || error.code === 4001 || error.code === -32005 || (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED')));\n if (isConnectionError) {\n const getNetworkName = (uri) => {\n if (uri.includes('milkomeda')) return 'Milkomeda';\n if (uri.includes('mordor')) return 'Mordor';\n if (uri.includes('sepolia')) return 'Sepolia';\n return 'the selected network';\n };\n const networkName = getNetworkName(this.networkUri);\n throw new Error(\n `Failed to connect to ${networkName} RPC endpoint: ${this.networkUri}\\n\\n` +\n `Possible causes:\\n` +\n `- The RPC endpoint may be temporarily unavailable\\n` +\n `- DNS resolution issue (check your internet connection)\\n` +\n `- Network firewall blocking the connection\\n\\n` +\n `Please try again in a few moments or check the network status.`\n );\n }\n throw error;\n }\n }\n\n getBlockchainDetails() {\n return {\n web3Available: !!this.web3,\n djedContractAvailable: !!this.djedContract,\n stableCoinAddress: this.stableCoin ? this.stableCoin._address : 'N/A',\n reserveCoinAddress: this.reserveCoin ? this.reserveCoin._address : 'N/A',\n stableCoinDecimals: this.scDecimals,\n reserveCoinDecimals: this.rcDecimals,\n oracleAddress: this.oracleAddress || 'N/A',\n oracleContractAvailable: !!this.oracleContract,\n };\n }\n\n async handleTradeDataBuySc(amountScaled) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n if (typeof amountScaled !== 'string') {\n throw new Error(\"Amount must be a string\");\n }\n try {\n const result = await tradeDataPriceBuySc(this.djedContract, this.scDecimals, amountScaled);\n return result.totalBCScaled;\n } catch (error) {\n console.error(\"Error fetching trade data for buying stablecoins: \", error);\n throw error;\n }\n }\n\n async buyStablecoins(payer, receiver, value) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n try {\n const UI = '0x0232556C83791b8291E9b23BfEa7d67405Bd9839';\n\n const txData = await buyScTx(this.djedContract, payer, receiver, value, UI, this.djedAddress);\n\n return txData;\n } catch (error) {\n console.error(\"Error executing buyStablecoins transaction: \", error);\n throw error;\n }\n }\n}\n","import React from \"react\";\nimport styles from \"../styles/main.css\";\n\nconst PayButton = ({ onClick, size = \"medium\" }) => {\n const sizeStyles = {\n small: { width: \"200px\", height: \"50px\", fontSize: \"14px\" },\n medium: { width: \"250px\", height: \"60px\", fontSize: \"16px\" },\n large: { width: \"300px\", height: \"70px\", fontSize: \"18px\" },\n };\n\n const logoSizes = {\n small: { width: \"35px\", height: \"33px\" },\n medium: { width: \"40px\", height: \"38px\" },\n large: { width: \"45px\", height: \"43px\" },\n };\n\n const buttonStyle = sizeStyles[size] || sizeStyles.medium;\n const logoStyle = logoSizes[size] || logoSizes.medium;\n\n return (\n \n
\n Pay with StablePay\n \n );\n};\n\nexport default PayButton;\n","import React from 'react';\nimport styles from '../styles/PricingCard.css';\n\n\nconst Dialog = ({ children, onClose, size = 'medium' }) => {\n return (\n
\n
\n \n
\n
\n\n
StablePay
\n
\n
\n {children}\n
\n
\n
\n );\n};\n\nexport default Dialog;","// TokenSelector.js\n\nexport class TokenSelector {\n constructor(networkSelector) {\n this.networkSelector = networkSelector;\n this.selectedToken = null;\n }\n\n selectToken(tokenKey) {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (networkConfig && networkConfig.tokens[tokenKey]) {\n this.selectedToken = {\n key: tokenKey,\n ...networkConfig.tokens[tokenKey]\n };\n return true;\n }\n return false;\n }\n\n getSelectedToken() {\n return this.selectedToken;\n }\n\n getAvailableTokens() {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) return [];\n\n return Object.entries(networkConfig.tokens).map(([key, config]) => ({\n key,\n ...config\n }));\n }\n\n resetSelection() {\n this.selectedToken = null;\n }\n}","import React, { createContext, useState, useContext, useEffect } from 'react';\nimport { TokenSelector } from '../core/TokenSelector';\n\nconst NetworkContext = createContext();\n\nexport const NetworkProvider = ({ children, networkSelector }) => {\n const [tokenSelector] = useState(() => new TokenSelector(networkSelector));\n const [selectedNetwork, setSelectedNetwork] = useState(null);\n const [selectedToken, setSelectedToken] = useState(null);\n const [transactionDetails, setTransactionDetails] = useState(null);\n\n const resetState = () => {\n setSelectedToken(null);\n setTransactionDetails(null);\n };\n\n const selectNetwork = (networkKey) => {\n if (networkSelector.selectNetwork(networkKey)) {\n setSelectedNetwork(networkKey);\n resetState(); \n return true;\n }\n return false;\n };\n\n const selectToken = (tokenKey) => {\n if (tokenSelector.selectToken(tokenKey)) {\n const token = tokenSelector.getSelectedToken();\n setSelectedToken(token);\n return true;\n }\n return false;\n };\n\n const resetSelections = () => {\n networkSelector.selectNetwork(null);\n setSelectedNetwork(null);\n resetState();\n };\n\n // Synchronize context state with NetworkSelector\n useEffect(() => {\n setSelectedNetwork(networkSelector.selectedNetwork);\n }, [networkSelector.selectedNetwork]);\n\n return (\n \n {children}\n \n );\n};\n\nexport const useNetwork = () => {\n const context = useContext(NetworkContext);\n if (context === undefined) {\n throw new Error('useNetwork must be used within a NetworkProvider');\n }\n return context;\n};\n\nexport default NetworkContext;","import React from 'react';\nimport { useNetwork } from '../contexts/NetworkContext';\nimport styles from '../styles/PricingCard.css';\n\nconst NetworkDropdown = () => {\n const { networkSelector, selectedNetwork, selectNetwork } = useNetwork();\n\n const handleNetworkChange = (event) => {\n selectNetwork(event.target.value);\n };\n\n return (\n
\n \n \n
\n );\n};\n\nexport default NetworkDropdown;","import React, { useState } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst TokenDropdown = () => {\n const {\n networkSelector,\n tokenSelector,\n selectedNetwork,\n selectedToken,\n selectToken,\n setTransactionDetails,\n } = useNetwork();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n const handleTokenChange = async (event) => {\n const newValue = event.target.value;\n setError(null);\n setLoading(true);\n\n try {\n if (selectToken(newValue)) {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const transaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await transaction.init();\n\n const tokenAmount = networkSelector.getTokenAmount(newValue);\n const blockchainDetails = transaction.getBlockchainDetails();\n\n let tradeData = null;\n if (newValue === \"native\") {\n tradeData = await transaction.handleTradeDataBuySc(\n String(tokenAmount)\n );\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: newValue,\n tokenSymbol: tokenSelector.getSelectedToken().symbol,\n amount: tokenAmount,\n receivingAddress: networkSelector.getReceivingAddress(),\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer:\n tokenSelector.getSelectedToken().isDirectTransfer || false,\n isNativeToken: tokenSelector.getSelectedToken().isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...blockchainDetails,\n });\n }\n } catch (err) {\n console.error(\"Error fetching transaction details:\", err);\n if (typeof window !== 'undefined' && !window.ethereum) {\n setError(\"No wallet found. Please install a Web3 wallet.\");\n } else {\n setError(\"Failed to fetch transaction details. Please try again.\");\n }\n } finally {\n setLoading(false);\n }\n };\n\n const availableTokens = selectedNetwork\n ? tokenSelector.getAvailableTokens()\n : [];\n\n return (\n
\n \n \n \n {availableTokens.map((token) => (\n \n ))}\n \n {error &&
{error}
}\n
\n );\n};\n\nexport default TokenDropdown;\n","import { defineChain } from 'viem';\nimport { sepolia } from 'viem/chains';\n\nexport const mordor = defineChain({\n id: 63,\n name: 'Mordor Testnet',\n network: 'mordor',\n nativeCurrency: {\n decimals: 18,\n name: 'Mordor Ether',\n symbol: 'METC',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc.mordor.etccooperative.org'],\n webSocket: ['wss://rpc.mordor.etccooperative.org/ws'],\n },\n },\n blockExplorers: {\n default: { name: 'BlockScout', url: 'https://blockscout.com/etc/mordor' },\n },\n testnet: true,\n});\n\nexport const milkomeda = defineChain({\n id: 2001,\n name: 'Milkomeda C1 Mainnet',\n network: 'milkomeda',\n nativeCurrency: {\n decimals: 18,\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n },\n },\n blockExplorers: {\n default: { name: 'Milkomeda Explorer', url: 'https://explorer-mainnet-cardano-evm.c1.milkomeda.com' },\n },\n testnet: false,\n});\n\nexport const etcMainnet = defineChain({\n id: 61,\n name: 'Ethereum Classic',\n network: 'etc',\n nativeCurrency: {\n decimals: 18,\n name: 'Ethereum Classic',\n symbol: 'ETC',\n },\n rpcUrls: {\n default: {\n http: ['https://etc.rivet.link'],\n },\n },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://blockscout.com/etc/mainnet' },\n },\n testnet: false,\n});\n\nexport const getChainByNetworkKey = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return sepolia;\n case 'ethereum-classic':\n return etcMainnet;\n case 'milkomeda-mainnet':\n return milkomeda;\n default:\n return null;\n }\n};\n\nexport const getChainConfigForWallet = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return {\n chainId: `0x${sepolia.id.toString(16)}`,\n chainName: 'Sepolia',\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n rpcUrls: sepolia.rpcUrls.default.http,\n blockExplorerUrls: sepolia.blockExplorers?.default?.url ? [sepolia.blockExplorers.default.url] : [],\n };\n case 'ethereum-classic':\n return {\n chainId: `0x${etcMainnet.id.toString(16)}`,\n chainName: 'Ethereum Classic',\n nativeCurrency: {\n name: 'Ethereum Classic',\n symbol: 'ETC',\n decimals: 18,\n },\n rpcUrls: ['https://etc.rivet.link'],\n blockExplorerUrls: ['https://blockscout.com/etc/mainnet'],\n };\n case 'milkomeda-mainnet':\n return {\n chainId: `0x${milkomeda.id.toString(16)}`,\n chainName: 'Milkomeda C1 Mainnet',\n nativeCurrency: {\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n decimals: 18,\n },\n rpcUrls: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n blockExplorerUrls: ['https://explorer-mainnet-cardano-evm.c1.milkomeda.com'],\n };\n default:\n return null;\n }\n};\n","import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { createWalletClient, createPublicClient, custom, http } from 'viem';\nimport { useNetwork } from './NetworkContext';\nimport { getChainByNetworkKey, getChainConfigForWallet } from './chains';\n\nconst WalletContext = createContext(null);\n\nexport const useWallet = () => {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used within a WalletProvider');\n }\n return context;\n};\n\nconst switchToNetwork = async (networkKey) => {\n if (!window.ethereum) {\n throw new Error('MetaMask not installed');\n }\n\n const chainConfig = getChainConfigForWallet(networkKey);\n if (!chainConfig) {\n throw new Error(`Unsupported network: ${networkKey}`);\n }\n\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: chainConfig.chainId }],\n });\n } catch (switchError) {\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [chainConfig],\n });\n } catch (addError) {\n if (addError.code === 4001) {\n throw new Error(`User rejected adding ${chainConfig.chainName} to MetaMask. Please add it manually.`);\n }\n throw new Error(`Failed to add ${chainConfig.chainName} to MetaMask: ${addError.message}`);\n }\n } else if (switchError.code === 4001) {\n throw new Error(`User rejected switching to ${chainConfig.chainName}. Please switch manually in MetaMask.`);\n } else {\n throw new Error(`Failed to switch to ${chainConfig.chainName}: ${switchError.message}`);\n }\n }\n};\n\nexport const WalletProvider = ({ children }) => {\n const { selectedNetwork } = useNetwork();\n const [walletClient, setWalletClient] = useState(null);\n const [publicClient, setPublicClient] = useState(null);\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [balance, setBalance] = useState(null);\n const [error, setError] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n\n const selectedChain = selectedNetwork ? getChainByNetworkKey(selectedNetwork) : null;\n const expectedChainId = selectedChain ? selectedChain.id : null;\n\n const handleAccountsChangedRef = useRef(null);\n const handleChainChangedRef = useRef(null);\n\n const disconnectWalletInternal = useCallback(() => {\n setWalletClient(null);\n setPublicClient(null);\n setAccount(null);\n setChainId(null);\n setBalance(null);\n setError(null);\n }, []);\n\n const handleChainChanged = useCallback(async (chainIdHex) => {\n const newChainId = parseInt(chainIdHex, 16);\n setChainId(newChainId);\n\n if (selectedChain && newChainId === expectedChainId) {\n setError(null);\n if (window.ethereum && selectedChain) {\n const newWalletClient = createWalletClient({ \n chain: selectedChain, \n transport: custom(window.ethereum) \n });\n setWalletClient(newWalletClient);\n }\n } else if (selectedChain && newChainId !== expectedChainId) {\n const chainName = selectedChain?.name || selectedNetwork || 'selected network';\n setError(`Wrong network detected. Please switch to ${chainName}`);\n }\n }, [selectedChain, expectedChainId, selectedNetwork]);\n\n handleChainChangedRef.current = handleChainChanged;\n\n const handleAccountsChanged = useCallback(async (accounts) => {\n if (accounts.length === 0) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n } else {\n setAccount(accounts[0]);\n if (selectedChain) {\n try {\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n }\n }\n }, [selectedChain, disconnectWalletInternal]);\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n\n const disconnectWallet = useCallback(() => {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }, [disconnectWalletInternal]);\n\n const connectPublicClient = useCallback(() => {\n if (selectedChain) {\n setPublicClient(createPublicClient({ chain: selectedChain, transport: http() }));\n }\n }, [selectedChain]);\n\n const connectWallet = useCallback(async () => {\n if (!window.ethereum) {\n setError('Please install MetaMask or another Web3 wallet');\n return false;\n }\n\n if (!selectedNetwork || !selectedChain) {\n setError('Please select a network first');\n return false;\n }\n\n setIsConnecting(true);\n setError(null);\n\n try {\n const accounts = await window.ethereum.request({ \n method: 'eth_requestAccounts' \n });\n\n if (accounts.length === 0) {\n throw new Error('No wallet address found. Please unlock your wallet.');\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n await switchToNetwork(selectedNetwork);\n }\n\n const newWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(newWalletClient);\n setAccount(accounts[0]);\n setChainId(expectedChainId);\n\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n try {\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n handleChainChangedRef.current = handleChainChanged;\n window.ethereum.on('accountsChanged', handleAccountsChanged);\n window.ethereum.on('chainChanged', handleChainChanged);\n\n return true;\n } catch (err) {\n console.error('Error connecting wallet:', err);\n setError(err.message);\n return false;\n } finally {\n setIsConnecting(false);\n }\n }, [selectedNetwork, selectedChain, expectedChainId, handleAccountsChanged, handleChainChanged]);\n\n const ensureCorrectNetwork = useCallback(async () => {\n if (!window.ethereum || !selectedNetwork || !selectedChain || !account) {\n const errorMsg = 'Wallet not connected or network not selected';\n setError(errorMsg);\n return null;\n }\n\n try {\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n setError(null);\n await switchToNetwork(selectedNetwork);\n const NETWORK_SWITCH_DELAY_MS = 500;\n await new Promise(resolve => setTimeout(resolve, NETWORK_SWITCH_DELAY_MS));\n \n const newChainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const newChainId = parseInt(newChainIdHex, 16);\n if (newChainId !== expectedChainId) {\n throw new Error(`Failed to switch network. MetaMask is still on chain ${newChainId}, expected ${expectedChainId}`);\n }\n }\n\n const freshWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(freshWalletClient);\n setChainId(expectedChainId);\n setError(null);\n return freshWalletClient;\n } catch (err) {\n setError(err.message);\n return null;\n }\n }, [selectedNetwork, selectedChain, expectedChainId, account]);\n\n const prevNetworkRef = useRef(selectedNetwork);\n\n useEffect(() => {\n if (prevNetworkRef.current !== null && \n prevNetworkRef.current !== selectedNetwork && \n account) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }\n prevNetworkRef.current = selectedNetwork;\n }, [selectedNetwork, account, disconnectWalletInternal]);\n\n useEffect(() => {\n connectPublicClient();\n }, [connectPublicClient]);\n\n return (\n \n {children}\n \n );\n};","import React, { useState, useEffect } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { useWallet } from \"../contexts/WalletContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport { parseEther, encodeFunctionData, parseUnits } from \"viem\"; \nimport styles from \"../styles/PricingCard.css\"; \n\nconst TransactionReview = ({ onTransactionComplete }) => {\n const {\n networkSelector,\n selectedNetwork,\n selectedToken,\n transactionDetails: contextTransactionDetails,\n setTransactionDetails,\n } = useNetwork();\n\n const {\n connectWallet,\n account,\n walletClient,\n publicClient,\n isConnecting,\n ensureCorrectNetwork,\n expectedChainId,\n } = useWallet();\n\n const [transaction, setTransaction] = useState(null);\n const [tradeDataBuySc, setTradeDataBuySc] = useState(null);\n const [message, setMessage] = useState(\"\");\n const [txHash, setTxHash] = useState(null);\n const [error, setError] = useState(null);\n const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false);\n const [interactionState, setInteractionState] = useState('IDLE');\n\n useEffect(() => {\n setTradeDataBuySc(null);\n setMessage(\"\");\n setError(null);\n setTxHash(null);\n setInteractionState('IDLE');\n }, [selectedNetwork, selectedToken]);\n\n useEffect(() => {\n const initializeTransaction = async () => {\n if (!selectedNetwork || !selectedToken) return;\n\n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const receivingAddress = networkSelector.getReceivingAddress();\n const tokenAmount = networkSelector.getTokenAmount(selectedToken.key);\n\n const newTransaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await newTransaction.init();\n setTransaction(newTransaction);\n\n let tradeData = null;\n if (selectedToken.key === \"native\") {\n try {\n tradeData = await newTransaction.handleTradeDataBuySc(String(tokenAmount));\n setTradeDataBuySc(tradeData);\n } catch (tradeError) {\n console.error(\"Error fetching trade data:\", tradeError);\n }\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: selectedToken.key,\n tokenSymbol: selectedToken.symbol,\n amount: tokenAmount || \"0\",\n receivingAddress,\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer: selectedToken.isDirectTransfer || false,\n isNativeToken: selectedToken.isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...newTransaction.getBlockchainDetails(),\n });\n } catch (err) {\n console.error(\"Error initializing transaction:\", err);\n }\n };\n\n initializeTransaction();\n }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]);\n\n if (!selectedNetwork || !selectedToken) {\n return null;\n }\n\n if (!contextTransactionDetails) {\n if (typeof window !== 'undefined' && !window.ethereum) {\n return (\n
\n
\n No wallet found.\n
\n
\n \n
\n
\n );\n }\n return
Initializing transaction...
;\n }\n\n const handleConnectWallet = async () => {\n await connectWallet();\n };\n\n const executePayment = async () => {\n if (!account || !contextTransactionDetails || !transaction) {\n setMessage(\"Wallet not connected or transaction details missing\");\n return;\n }\n\n setInteractionState('PROCESSING');\n setMessage(\"Preparing transaction...\");\n setError(null);\n setTxHash(null);\n\n let builtTx;\n try {\n const receiver = contextTransactionDetails.receivingAddress;\n\n if (selectedToken.key === \"native\") {\n const UI = \"0x0232556C83791b8291E9b23BfEa7d67405Bd9839\";\n const amountToSend = tradeDataBuySc || \"0\";\n const valueInWei = parseEther(String(amountToSend));\n\n builtTx = await transaction.buyStablecoins(\n account,\n receiver,\n valueInWei,\n UI\n );\n\n builtTx = {\n ...builtTx,\n value: valueInWei,\n account: account,\n };\n } else {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const stablecoinAddress = networkConfig?.tokens?.stablecoin?.address;\n \n if (!stablecoinAddress) {\n throw new Error('Stablecoin address not found in network configuration');\n }\n\n const amountToSend = contextTransactionDetails.amount\n ? parseUnits(\n String(contextTransactionDetails.amount),\n contextTransactionDetails.stableCoinDecimals\n )\n : \"0\";\n\n builtTx = {\n to: stablecoinAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: [\n {\n inputs: [\n { internalType: \"address\", name: \"to\", type: \"address\" },\n { internalType: \"uint256\", name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ],\n functionName: \"transfer\",\n args: [receiver, amountToSend],\n }),\n account: account,\n };\n }\n } catch (err) {\n setError(err);\n const reason = err.shortMessage || (err.message ? err.message.split('\\n')[0] : \"Unknown error\");\n setMessage(`Transaction preparation failed: ${reason}`);\n setInteractionState('IDLE');\n return;\n }\n\n setMessage(\"Please check your wallet to confirm the transaction...\");\n \n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) {\n throw new Error(\"Network configuration not found\");\n }\n\n const freshWalletClient = await ensureCorrectNetwork();\n if (!freshWalletClient) {\n throw new Error(\"Failed to switch to correct network. Please approve the network switch in MetaMask.\");\n }\n\n if (!window.ethereum) {\n throw new Error(\"MetaMask not available\");\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== networkConfig.chainId) {\n throw new Error(`Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`);\n }\n\n if (freshWalletClient.chain.id !== networkConfig.chainId) {\n throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`);\n }\n\n const txHash = await freshWalletClient.sendTransaction({\n ...builtTx,\n account: account,\n });\n\n setTxHash(txHash);\n setMessage(`Transaction sent successfully!`);\n setInteractionState('SUCCESS');\n \n if (onTransactionComplete) {\n onTransactionComplete({\n txHash,\n network: selectedNetwork,\n token: selectedToken?.key,\n tokenSymbol: selectedToken?.symbol,\n amount: contextTransactionDetails?.amount,\n receivingAddress: contextTransactionDetails?.receivingAddress,\n });\n }\n } catch (err) {\n setError(err);\n \n let reason = \"Unknown error\";\n if (err.name === 'UserRejectedRequestError' || err.code === 4001) {\n reason = \"User denied transaction\";\n } else if (err.name === 'ContractFunctionRevertedError' || (err.data && err.data.message)) {\n reason = err.shortMessage || err.data?.message || err.message;\n } else {\n reason = err.shortMessage || (err.message ? err.message.split('\\n')[0] : \"Transaction failed\");\n }\n \n setMessage(`Transaction failed: ${reason}`);\n setInteractionState('IDLE');\n console.error('Transaction error:', err);\n }\n };\n\n const getExplorerUrl = () => {\n if (!txHash || !selectedNetwork) return null;\n\n const explorerBaseUrls = {\n \"ethereum-classic\": \"https://blockscout.com/etc/mainnet/tx/\",\n \"sepolia\": \"https://sepolia.etherscan.io/tx/\",\n \"milkomeda-mainnet\": \"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/\",\n };\n\n return explorerBaseUrls[selectedNetwork]\n ? `${explorerBaseUrls[selectedNetwork]}${txHash}`\n : null;\n };\n\n return (\n
\n
\n Network:\n {contextTransactionDetails.network}\n
\n\n
\n You Pay:\n \n {selectedToken.key === \"stablecoin\"\n ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}`\n : `${tradeDataBuySc ? tradeDataBuySc : \"Calculating...\"} ${\n contextTransactionDetails.tokenSymbol\n }`}\n \n
\n\n {message && (\n
\n {message}\n {error && (\n setIsErrorDetailsVisible(!isErrorDetailsVisible)}\n className={styles.detailsButton}\n >\n {isErrorDetailsVisible ? \"Hide Details\" : \"Show Details\"}\n \n )}\n
\n )}\n\n {isErrorDetailsVisible && error && (\n
\n
{error.message}
\n
\n )}\n\n {txHash && (\n
\n Transaction Hash:{\" \"}\n {getExplorerUrl() ? (\n \n {txHash.slice(0, 6)}...{txHash.slice(-6)}\n \n ) : (\n \n {txHash}\n \n )}\n
\n )}\n\n {interactionState !== 'SUCCESS' && (\n
\n {!account && (\n \n )}\n\n {account && interactionState === 'IDLE' && (\n \n )}\n\n {account && interactionState === 'CONFIRMING' && (\n
\n Confirm payment?\n
\n \n \n
\n
\n )}\n\n {account && interactionState === 'PROCESSING' && (\n \n )}\n
\n )}\n
\n );\n};\n\nexport default TransactionReview;\n","import React, { useState } from \"react\";\nimport PayButton from \"./PayButton\";\nimport Dialog from \"./Dialog\";\nimport NetworkDropdown from \"./NetworkDropdown\";\nimport TokenDropdown from \"./TokenDropdown\";\nimport TransactionReview from \"./TransactionReview\";\nimport { NetworkProvider, useNetwork } from \"../contexts/NetworkContext\";\nimport { WalletProvider } from \"../contexts/WalletContext\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst WidgetContent = ({ onClose, buttonSize, onTransactionComplete }) => {\n const { resetSelections } = useNetwork(); \n\n const handleClose = () => {\n resetSelections(); // Reset selections when closing the widget\n onClose();\n };\n\n return (\n \n \n \n \n \n );\n};\n\nconst WidgetWithProviders = ({ onClose, buttonSize, networkSelector, onTransactionComplete }) => {\n return (\n \n \n \n \n \n );\n};\n\nexport const Widget = ({ networkSelector, buttonSize = \"medium\", onTransactionComplete, onSuccess }) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const handleOpenDialog = () => {\n setIsDialogOpen(true);\n };\n\n const handleCloseDialog = () => {\n setIsDialogOpen(false);\n };\n\n // Support both onTransactionComplete and onSuccess for backwards compatibility\n const handleTransactionComplete = onTransactionComplete || onSuccess;\n\n return (\n
\n {!isDialogOpen && (\n \n )}\n {isDialogOpen && (\n \n )}\n
\n );\n};\n\nexport default Widget;\n","// src/index.js\nimport { NetworkSelector } from './core/NetworkSelector';\nimport { Transaction } from './core/Transaction';\nimport { Config } from './core/MerchantConfig';\nimport Widget from './widget/Widget.jsx';\nimport PayButton from './widget/PayButton.jsx';\nimport Dialog from './widget/Dialog.jsx';\nimport NetworkDropdown from './widget/NetworkDropdown.jsx';\nimport './styles/main.css';\nimport './styles/PricingCard.css';\n\nconst StablePay = {\n NetworkSelector,\n Transaction,\n Config,\n Widget,\n PayButton,\n Dialog,\n NetworkDropdown\n};\n\nexport default StablePay;","import { networksConfig } from \"../utils/config\";\n\nexport class NetworkSelector {\n constructor(merchantConfig) {\n this.merchantConfig = merchantConfig;\n this.blacklist = merchantConfig.getBlacklist();\n this.availableNetworks = this.getAvailableNetworks();\n this.selectedNetwork = null;\n }\n\n getAvailableNetworks() {\n return Object.entries(networksConfig).reduce(\n (acc, [networkKey, networkConfig]) => {\n if (!this.blacklist.includes(networkConfig.chainId)) {\n acc[networkKey] = networkConfig;\n }\n return acc;\n },\n {}\n );\n }\n\n selectNetwork(networkKey) {\n if (networkKey === null) {\n this.selectedNetwork = null;\n console.log(\"Network selection reset\");\n return true;\n }\n if (this.availableNetworks[networkKey]) {\n this.selectedNetwork = networkKey;\n console.log(`Network selected: ${networkKey}`);\n return true;\n }\n console.error(`Invalid network: ${networkKey}`);\n return false;\n }\n\n getSelectedNetworkConfig() {\n return this.selectedNetwork\n ? this.availableNetworks[this.selectedNetwork]\n : null;\n }\n\n getReceivingAddress() {\n return this.merchantConfig.getReceivingAddress();\n }\n\n getTokenAmount(token) {\n return this.merchantConfig.getTokenAmount(this.selectedNetwork, token);\n }\n}\n","import { networksConfig } from \"../utils/config\";\n\nexport class Config {\n constructor(options = {}) {\n this.receivingAddress = options.receivingAddress || \"\";\n this.blacklist = options.blacklist || [];\n this.amounts = options.amounts || options.Amounts || {};\n this.validateConfig();\n }\n\n validateConfig() {\n if (!this.receivingAddress) {\n throw new Error(\"Receiving address is required\");\n }\n // Validate stablecoin amounts\n for (const [network, tokens] of Object.entries(this.amounts)) {\n if (!networksConfig[network]) {\n throw new Error(`Invalid network: ${network}`);\n }\n if (\n !tokens.stablecoin ||\n typeof tokens.stablecoin !== \"number\" ||\n tokens.stablecoin <= 0\n ) {\n throw new Error(`Invalid stablecoin amount for network ${network}`);\n }\n }\n }\n\n getBlacklist() {\n return this.blacklist;\n }\n\n getReceivingAddress() {\n return this.receivingAddress;\n }\n\n // getTokenAmount(network, token) {\n // const networkConfig = networksConfig[network];\n // if (!networkConfig) return 0;\n\n // const stablecoinSymbol = networkConfig.tokens.stablecoin.symbol;\n\n // if (token === 'stablecoin') {\n // return this.amounts[network]?.stablecoin || 0;\n // }\n // // For native tokens, return 0 as it's not specified in the new structure\n // return 0;\n // }\n getTokenAmount(network) {\n console.log(\"Getting amount for network:\", network);\n console.log(\"Amounts object:\", this.amounts);\n\n // Directly return the stablecoin amount for the network\n const amount = this.amounts[network]?.stablecoin;\n console.log(\"Returning amount:\", amount);\n\n return amount || 0;\n }\n}\n\nexport default Config;\n"],"names":["networksConfig","sepolia","uri","chainId","djedAddress","tokens","stablecoin","symbol","address","decimals","isDirectTransfer","native","isNative","feeUI","Transaction","constructor","networkUri","this","init","Error","web3","getWeb3","djedContract","getDjedContract","stableCoin","reserveCoin","getCoinContracts","scDecimals","rcDecimals","getDecimals","oracleContract","getOracleAddress","then","addr","getOracleContract","_address","oracleAddress","contractError","console","error","code","data","getNetworkInfo","includes","name","networkName","message","getNetworkName","getBlockchainDetails","web3Available","djedContractAvailable","stableCoinAddress","reserveCoinAddress","stableCoinDecimals","reserveCoinDecimals","oracleContractAvailable","handleTradeDataBuySc","amountScaled","tradeDataPriceBuySc","totalBCScaled","buyStablecoins","payer","receiver","value","UI","buyScTx","PayButton","onClick","size","sizeStyles","small","width","height","fontSize","medium","large","logoSizes","buttonStyle","logoStyle","React","createElement","className","styles","style","Dialog","children","onClose","dialogOverlay","pricingCard","dialogClose","pricingCardHeader","allianceLogo","stablepayTitle","pricingCardBody","TokenSelector","networkSelector","selectedToken","selectToken","tokenKey","networkConfig","getSelectedNetworkConfig","key","getSelectedToken","getAvailableTokens","Object","entries","map","config","resetSelection","NetworkContext","createContext","NetworkProvider","tokenSelector","useState","selectedNetwork","setSelectedNetwork","setSelectedToken","transactionDetails","setTransactionDetails","resetState","useEffect","Provider","selectNetwork","networkKey","token","resetSelections","useNetwork","context","useContext","undefined","NetworkDropdown","selectField","htmlFor","id","onChange","event","target","disabled","keys","availableNetworks","TokenDropdown","loading","setLoading","setError","availableTokens","async","newValue","transaction","tokenAmount","getTokenAmount","blockchainDetails","tradeData","String","network","tokenSymbol","amount","receivingAddress","getReceivingAddress","djedContractAddress","isNativeToken","tradeAmount","err","window","ethereum","defineChain","nativeCurrency","rpcUrls","default","http","webSocket","blockExplorers","url","testnet","milkomeda","etcMainnet","WalletContext","switchToNetwork","chainConfig","toString","chainName","blockExplorerUrls","getChainConfigForWallet","request","method","params","switchError","addError","WalletProvider","walletClient","setWalletClient","publicClient","setPublicClient","account","setAccount","setChainId","balance","setBalance","isConnecting","setIsConnecting","selectedChain","getChainByNetworkKey","expectedChainId","handleAccountsChangedRef","useRef","handleChainChangedRef","disconnectWalletInternal","useCallback","handleChainChanged","newChainId","parseInt","chainIdHex","newWalletClient","createWalletClient","chain","transport","custom","current","handleAccountsChanged","accounts","length","accountsHandler","chainHandler","removeListener","newPublicClient","createPublicClient","getBalance","parseFloat","Math","pow","disconnectWallet","connectPublicClient","connectWallet","on","ensureCorrectNetwork","NETWORK_SWITCH_DELAY_MS","Promise","resolve","setTimeout","newChainIdHex","freshWalletClient","prevNetworkRef","TransactionReview","onTransactionComplete","contextTransactionDetails","useWallet","setTransaction","tradeDataBuySc","setTradeDataBuySc","setMessage","txHash","setTxHash","isErrorDetailsVisible","setIsErrorDetailsVisible","interactionState","setInteractionState","newTransaction","tradeError","initializeTransaction","transactionReview","messageBox","textAlign","marginBottom","color","walletButtonContainer","walletButton","open","getExplorerUrl","explorerBaseUrls","transactionInfo","transactionLabel","transactionValue","highlight","detailsButton","errorDetails","transactionLink","href","rel","explorerLink","slice","wordBreak","confirmContainer","confirmText","confirmButtons","secondaryButton","primaryButton","builtTx","amountToSend","valueInWei","parseEther","stablecoinAddress","parseUnits","to","encodeFunctionData","abi","inputs","internalType","type","outputs","stateMutability","functionName","args","reason","shortMessage","split","currentChainId","sendTransaction","WidgetContent","buttonSize","handleClose","WidgetWithProviders","NetworkSelector","merchantConfig","blacklist","getBlacklist","getAvailableNetworks","reduce","acc","log","Config","options","amounts","Amounts","validateConfig","Widget","onSuccess","isDialogOpen","setIsDialogOpen","handleTransactionComplete","widgetContainer","handleOpenDialog","handleCloseDialog"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../../src/utils/config.js","../../src/core/Transaction.js","../../src/widget/PayButton.jsx","../../src/widget/Dialog.jsx","../../src/core/TokenSelector.js","../../src/contexts/NetworkContext.jsx","../../src/widget/NetworkDropdown.jsx","../../src/widget/TokenDropdown.jsx","../../src/contexts/chains.js","../../src/contexts/WalletContext.jsx","../../src/widget/TransactionReview.jsx","../../src/widget/Widget.jsx","../../src/index.js","../../src/core/NetworkSelector.js","../../src/core/MerchantConfig.js"],"sourcesContent":["// src/utils/config.js\nexport const networksConfig = {\n 'sepolia': {\n uri: 'https://ethereum-sepolia.publicnode.com/',\n chainId: 11155111,\n djedAddress: '0x624FcD0a1F9B5820c950FefD48087531d38387f4',\n tokens: {\n stablecoin: {\n symbol: 'SOD',\n address: '0x6b930182787F346F18666D167e8d32166dC5eFBD',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETH',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'milkomeda-mainnet': {\n uri: 'https://rpc-mainnet-cardano-evm.c1.milkomeda.com',\n chainId: 2001,\n djedAddress: '0x67A30B399F5Ed499C1a6Bc0358FA6e42Ea4BCe76',\n tokens: {\n stablecoin: {\n symbol: 'MOD',\n address: '0xcbA90fB1003b9D1bc6a2b66257D2585011b004e9',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'mADA',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n },\n 'ethereum-classic': {\n uri: 'https://etc.rivet.link',\n chainId: 61,\n djedAddress: '0xCc3664d7021FD36B1Fe2b136e2324710c8442cCf',\n tokens: {\n stablecoin: {\n symbol: 'ECSD',\n address: '0x5A7Ca94F6E969C94bef4CE5e2f90ed9d4891918A',\n decimals: 18,\n isDirectTransfer: true\n },\n native: {\n symbol: 'ETC',\n decimals: 18,\n isNative: true\n }\n },\n feeUI: 0\n }\n};","import { getWeb3, getDjedContract, getCoinContracts, getDecimals, getOracleAddress, getOracleContract, tradeDataPriceBuySc, buyScTx } from 'djed-sdk';\n\nexport class Transaction {\n constructor(networkUri, djedAddress) {\n this.networkUri = networkUri;\n this.djedAddress = djedAddress;\n }\n\n async init() {\n if (!this.networkUri || !this.djedAddress) {\n throw new Error('Network URI and DJED address are required');\n }\n\n try {\n this.web3 = await getWeb3(this.networkUri);\n this.djedContract = getDjedContract(this.web3, this.djedAddress);\n \n try {\n const { stableCoin, reserveCoin } = await getCoinContracts(this.djedContract, this.web3);\n const { scDecimals, rcDecimals } = await getDecimals(stableCoin, reserveCoin);\n this.stableCoin = stableCoin;\n this.reserveCoin = reserveCoin;\n this.scDecimals = scDecimals;\n this.rcDecimals = rcDecimals;\n\n this.oracleContract = await getOracleAddress(this.djedContract).then((addr) =>\n getOracleContract(this.web3, addr, this.djedContract._address)\n );\n\n this.oracleAddress = this.oracleContract._address;\n } catch (contractError) {\n console.error('[Transaction] Error fetching contract details:', contractError);\n const isReverted = \n contractError?.code === -32000 ||\n contractError?.code === 3 ||\n contractError?.name === 'ContractFunctionRevertedError' ||\n typeof contractError?.data?.message === 'string';\n if (isReverted) {\n const getNetworkInfo = (uri) => {\n if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };\n if (uri.includes('mordor')) return { name: 'Mordor Testnet', chainId: '63' };\n if (uri.includes('sepolia')) return { name: 'Sepolia', chainId: '11155111' };\n if (uri.includes('etc.rivet.link')) return { name: 'Ethereum Classic', chainId: '61' };\n return { name: 'the selected network', chainId: 'unknown' };\n };\n const { name: networkName, chainId } = getNetworkInfo(this.networkUri);\n throw new Error(\n `Failed to interact with Djed contract at ${this.djedAddress} on ${networkName}.\\n\\n` +\n `Possible causes:\\n` +\n `- The contract address may be incorrect\\n` +\n `- The contract may not be deployed on ${networkName}\\n` +\n `- The contract may not be a valid Djed contract\\n\\n` +\n `Please verify the contract address is correct for ${networkName} (Chain ID: ${chainId}).`\n );\n }\n throw contractError;\n }\n } catch (error) {\n console.error('[Transaction] Error initializing transaction:', error);\n const isConnectionError = error.code === -32603 || error.code === 4001 || error.code === -32005 || (error.message && (error.message.includes('CONNECTION ERROR') || error.message.includes('ERR_NAME_NOT_RESOLVED')));\n if (isConnectionError) {\n const getNetworkName = (uri) => {\n if (uri.includes('milkomeda')) return 'Milkomeda';\n if (uri.includes('mordor')) return 'Mordor';\n if (uri.includes('sepolia')) return 'Sepolia';\n return 'the selected network';\n };\n const networkName = getNetworkName(this.networkUri);\n throw new Error(\n `Failed to connect to ${networkName} RPC endpoint: ${this.networkUri}\\n\\n` +\n `Possible causes:\\n` +\n `- The RPC endpoint may be temporarily unavailable\\n` +\n `- DNS resolution issue (check your internet connection)\\n` +\n `- Network firewall blocking the connection\\n\\n` +\n `Please try again in a few moments or check the network status.`\n );\n }\n throw error;\n }\n }\n\n getBlockchainDetails() {\n return {\n web3Available: !!this.web3,\n djedContractAvailable: !!this.djedContract,\n stableCoinAddress: this.stableCoin ? this.stableCoin._address : 'N/A',\n reserveCoinAddress: this.reserveCoin ? this.reserveCoin._address : 'N/A',\n stableCoinDecimals: this.scDecimals,\n reserveCoinDecimals: this.rcDecimals,\n oracleAddress: this.oracleAddress || 'N/A',\n oracleContractAvailable: !!this.oracleContract,\n };\n }\n\n async handleTradeDataBuySc(amountScaled) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n if (typeof amountScaled !== 'string') {\n throw new Error(\"Amount must be a string\");\n }\n try {\n const result = await tradeDataPriceBuySc(this.djedContract, this.scDecimals, amountScaled);\n return result.totalBCScaled;\n } catch (error) {\n console.error(\"Error fetching trade data for buying stablecoins: \", error);\n throw error;\n }\n }\n\n async buyStablecoins(payer, receiver, value) {\n if (!this.djedContract) {\n throw new Error(\"DJED contract is not initialized\");\n }\n try {\n const UI = '0x0232556C83791b8291E9b23BfEa7d67405Bd9839';\n\n const txData = await buyScTx(this.djedContract, payer, receiver, value, UI, this.djedAddress);\n\n return txData;\n } catch (error) {\n console.error(\"Error executing buyStablecoins transaction: \", error);\n throw error;\n }\n }\n}\n","import React from \"react\";\nimport styles from \"../styles/main.css\";\n\nconst PayButton = ({ onClick, size = \"medium\" }) => {\n const sizeStyles = {\n small: { width: \"200px\", height: \"50px\", fontSize: \"14px\" },\n medium: { width: \"250px\", height: \"60px\", fontSize: \"16px\" },\n large: { width: \"300px\", height: \"70px\", fontSize: \"18px\" },\n };\n\n const logoSizes = {\n small: { width: \"35px\", height: \"33px\" },\n medium: { width: \"40px\", height: \"38px\" },\n large: { width: \"45px\", height: \"43px\" },\n };\n\n const buttonStyle = sizeStyles[size] || sizeStyles.medium;\n const logoStyle = logoSizes[size] || logoSizes.medium;\n\n return (\n \n
\n Pay with StablePay\n \n );\n};\n\nexport default PayButton;\n","import React from 'react';\nimport styles from '../styles/PricingCard.css';\n\n\nconst Dialog = ({ children, onClose, size = 'medium' }) => {\n return (\n
\n
\n \n
\n
\n\n
StablePay
\n
\n
\n {children}\n
\n
\n
\n );\n};\n\nexport default Dialog;","// TokenSelector.js\n\nexport class TokenSelector {\n constructor(networkSelector) {\n this.networkSelector = networkSelector;\n this.selectedToken = null;\n }\n\n selectToken(tokenKey) {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (networkConfig && networkConfig.tokens[tokenKey]) {\n this.selectedToken = {\n key: tokenKey,\n ...networkConfig.tokens[tokenKey]\n };\n return true;\n }\n return false;\n }\n\n getSelectedToken() {\n return this.selectedToken;\n }\n\n getAvailableTokens() {\n const networkConfig = this.networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) return [];\n\n return Object.entries(networkConfig.tokens).map(([key, config]) => ({\n key,\n ...config\n }));\n }\n\n resetSelection() {\n this.selectedToken = null;\n }\n}","import React, { createContext, useState, useContext, useEffect } from 'react';\nimport { TokenSelector } from '../core/TokenSelector';\n\nconst NetworkContext = createContext();\n\nexport const NetworkProvider = ({ children, networkSelector }) => {\n const [tokenSelector] = useState(() => new TokenSelector(networkSelector));\n const [selectedNetwork, setSelectedNetwork] = useState(null);\n const [selectedToken, setSelectedToken] = useState(null);\n const [transactionDetails, setTransactionDetails] = useState(null);\n\n const resetState = () => {\n setSelectedToken(null);\n setTransactionDetails(null);\n };\n\n const selectNetwork = (networkKey) => {\n if (networkSelector.selectNetwork(networkKey)) {\n setSelectedNetwork(networkKey);\n resetState(); \n return true;\n }\n return false;\n };\n\n const selectToken = (tokenKey) => {\n if (tokenSelector.selectToken(tokenKey)) {\n const token = tokenSelector.getSelectedToken();\n setSelectedToken(token);\n return true;\n }\n return false;\n };\n\n const resetSelections = () => {\n networkSelector.selectNetwork(null);\n setSelectedNetwork(null);\n resetState();\n };\n\n // Synchronize context state with NetworkSelector\n useEffect(() => {\n setSelectedNetwork(networkSelector.selectedNetwork);\n }, [networkSelector.selectedNetwork]);\n\n return (\n \n {children}\n \n );\n};\n\nexport const useNetwork = () => {\n const context = useContext(NetworkContext);\n if (context === undefined) {\n throw new Error('useNetwork must be used within a NetworkProvider');\n }\n return context;\n};\n\nexport default NetworkContext;","import React from 'react';\nimport { useNetwork } from '../contexts/NetworkContext';\nimport styles from '../styles/PricingCard.css';\n\nconst NetworkDropdown = () => {\n const { networkSelector, selectedNetwork, selectNetwork } = useNetwork();\n\n const handleNetworkChange = (event) => {\n selectNetwork(event.target.value);\n };\n\n return (\n
\n \n \n
\n );\n};\n\nexport default NetworkDropdown;","import React, { useState } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst TokenDropdown = () => {\n const {\n networkSelector,\n tokenSelector,\n selectedNetwork,\n selectedToken,\n selectToken,\n setTransactionDetails,\n } = useNetwork();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n const handleTokenChange = async (event) => {\n const newValue = event.target.value;\n setError(null);\n setLoading(true);\n\n try {\n if (selectToken(newValue)) {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const transaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await transaction.init();\n\n const tokenAmount = networkSelector.getTokenAmount(newValue);\n const blockchainDetails = transaction.getBlockchainDetails();\n\n let tradeData = null;\n if (newValue === \"native\") {\n tradeData = await transaction.handleTradeDataBuySc(\n String(tokenAmount)\n );\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: newValue,\n tokenSymbol: tokenSelector.getSelectedToken().symbol,\n amount: tokenAmount,\n receivingAddress: networkSelector.getReceivingAddress(),\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer:\n tokenSelector.getSelectedToken().isDirectTransfer || false,\n isNativeToken: tokenSelector.getSelectedToken().isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...blockchainDetails,\n });\n }\n } catch (err) {\n console.error(\"Error fetching transaction details:\", err);\n if (typeof window !== 'undefined' && !window.ethereum) {\n setError(\"No wallet found. Please install a Web3 wallet.\");\n } else {\n setError(\"Failed to fetch transaction details. Please try again.\");\n }\n } finally {\n setLoading(false);\n }\n };\n\n const availableTokens = selectedNetwork\n ? tokenSelector.getAvailableTokens()\n : [];\n\n return (\n
\n \n \n \n {availableTokens.map((token) => (\n \n ))}\n \n {error &&
{error}
}\n
\n );\n};\n\nexport default TokenDropdown;\n","import { defineChain } from 'viem';\nimport { sepolia } from 'viem/chains';\n\nexport const mordor = defineChain({\n id: 63,\n name: 'Mordor Testnet',\n network: 'mordor',\n nativeCurrency: {\n decimals: 18,\n name: 'Mordor Ether',\n symbol: 'METC',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc.mordor.etccooperative.org'],\n webSocket: ['wss://rpc.mordor.etccooperative.org/ws'],\n },\n },\n blockExplorers: {\n default: { name: 'BlockScout', url: 'https://blockscout.com/etc/mordor' },\n },\n testnet: true,\n});\n\nexport const milkomeda = defineChain({\n id: 2001,\n name: 'Milkomeda C1 Mainnet',\n network: 'milkomeda',\n nativeCurrency: {\n decimals: 18,\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n },\n rpcUrls: {\n default: {\n http: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n },\n },\n blockExplorers: {\n default: { name: 'Milkomeda Explorer', url: 'https://explorer-mainnet-cardano-evm.c1.milkomeda.com' },\n },\n testnet: false,\n});\n\nexport const etcMainnet = defineChain({\n id: 61,\n name: 'Ethereum Classic',\n network: 'etc',\n nativeCurrency: {\n decimals: 18,\n name: 'Ethereum Classic',\n symbol: 'ETC',\n },\n rpcUrls: {\n default: {\n http: ['https://etc.rivet.link'],\n },\n },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://blockscout.com/etc/mainnet' },\n },\n testnet: false,\n});\n\nexport const getChainByNetworkKey = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return sepolia;\n case 'ethereum-classic':\n return etcMainnet;\n case 'milkomeda-mainnet':\n return milkomeda;\n default:\n return null;\n }\n};\n\nexport const getChainConfigForWallet = (networkKey) => {\n switch (networkKey) {\n case 'sepolia':\n return {\n chainId: `0x${sepolia.id.toString(16)}`,\n chainName: 'Sepolia',\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n rpcUrls: sepolia.rpcUrls.default.http,\n blockExplorerUrls: sepolia.blockExplorers?.default?.url ? [sepolia.blockExplorers.default.url] : [],\n };\n case 'ethereum-classic':\n return {\n chainId: `0x${etcMainnet.id.toString(16)}`,\n chainName: 'Ethereum Classic',\n nativeCurrency: {\n name: 'Ethereum Classic',\n symbol: 'ETC',\n decimals: 18,\n },\n rpcUrls: ['https://etc.rivet.link'],\n blockExplorerUrls: ['https://blockscout.com/etc/mainnet'],\n };\n case 'milkomeda-mainnet':\n return {\n chainId: `0x${milkomeda.id.toString(16)}`,\n chainName: 'Milkomeda C1 Mainnet',\n nativeCurrency: {\n name: 'Milkomeda ADA',\n symbol: 'mADA',\n decimals: 18,\n },\n rpcUrls: ['https://rpc-mainnet-cardano-evm.c1.milkomeda.com'],\n blockExplorerUrls: ['https://explorer-mainnet-cardano-evm.c1.milkomeda.com'],\n };\n default:\n return null;\n }\n};\n","import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';\nimport { createWalletClient, createPublicClient, custom, http } from 'viem';\nimport { useNetwork } from './NetworkContext';\nimport { getChainByNetworkKey, getChainConfigForWallet } from './chains';\n\nconst WalletContext = createContext(null);\n\nexport const useWallet = () => {\n const context = useContext(WalletContext);\n if (!context) {\n throw new Error('useWallet must be used within a WalletProvider');\n }\n return context;\n};\n\nconst switchToNetwork = async (networkKey) => {\n if (!window.ethereum) {\n throw new Error('MetaMask not installed');\n }\n\n const chainConfig = getChainConfigForWallet(networkKey);\n if (!chainConfig) {\n throw new Error(`Unsupported network: ${networkKey}`);\n }\n\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: chainConfig.chainId }],\n });\n } catch (switchError) {\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [chainConfig],\n });\n } catch (addError) {\n if (addError.code === 4001) {\n throw new Error(`User rejected adding ${chainConfig.chainName} to MetaMask. Please add it manually.`);\n }\n throw new Error(`Failed to add ${chainConfig.chainName} to MetaMask: ${addError.message}`);\n }\n } else if (switchError.code === 4001) {\n throw new Error(`User rejected switching to ${chainConfig.chainName}. Please switch manually in MetaMask.`);\n } else {\n throw new Error(`Failed to switch to ${chainConfig.chainName}: ${switchError.message}`);\n }\n }\n};\n\nexport const WalletProvider = ({ children }) => {\n const { selectedNetwork } = useNetwork();\n const [walletClient, setWalletClient] = useState(null);\n const [publicClient, setPublicClient] = useState(null);\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [balance, setBalance] = useState(null);\n const [error, setError] = useState(null);\n const [isConnecting, setIsConnecting] = useState(false);\n\n const selectedChain = selectedNetwork ? getChainByNetworkKey(selectedNetwork) : null;\n const expectedChainId = selectedChain ? selectedChain.id : null;\n\n const handleAccountsChangedRef = useRef(null);\n const handleChainChangedRef = useRef(null);\n\n const disconnectWalletInternal = useCallback(() => {\n setWalletClient(null);\n setPublicClient(null);\n setAccount(null);\n setChainId(null);\n setBalance(null);\n setError(null);\n }, []);\n\n const handleChainChanged = useCallback(async (chainIdHex) => {\n const newChainId = parseInt(chainIdHex, 16);\n setChainId(newChainId);\n\n if (selectedChain && newChainId === expectedChainId) {\n setError(null);\n if (window.ethereum && selectedChain) {\n const newWalletClient = createWalletClient({ \n chain: selectedChain, \n transport: custom(window.ethereum) \n });\n setWalletClient(newWalletClient);\n }\n } else if (selectedChain && newChainId !== expectedChainId) {\n const chainName = selectedChain?.name || selectedNetwork || 'selected network';\n setError(`Wrong network detected. Please switch to ${chainName}`);\n }\n }, [selectedChain, expectedChainId, selectedNetwork]);\n\n handleChainChangedRef.current = handleChainChanged;\n\n const handleAccountsChanged = useCallback(async (accounts) => {\n if (accounts.length === 0) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n } else {\n setAccount(accounts[0]);\n if (selectedChain) {\n try {\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n }\n }\n }, [selectedChain, disconnectWalletInternal]);\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n\n const disconnectWallet = useCallback(() => {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }, [disconnectWalletInternal]);\n\n const connectPublicClient = useCallback(() => {\n if (selectedChain) {\n setPublicClient(createPublicClient({ chain: selectedChain, transport: http() }));\n }\n }, [selectedChain]);\n\n const connectWallet = useCallback(async () => {\n if (!window.ethereum) {\n setError('Please install MetaMask or another Web3 wallet');\n return false;\n }\n\n if (!selectedNetwork || !selectedChain) {\n setError('Please select a network first');\n return false;\n }\n\n setIsConnecting(true);\n setError(null);\n\n try {\n const accounts = await window.ethereum.request({ \n method: 'eth_requestAccounts' \n });\n\n if (accounts.length === 0) {\n throw new Error('No wallet address found. Please unlock your wallet.');\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n await switchToNetwork(selectedNetwork);\n }\n\n const newWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(newWalletClient);\n setAccount(accounts[0]);\n setChainId(expectedChainId);\n\n const newPublicClient = createPublicClient({ chain: selectedChain, transport: http() });\n setPublicClient(newPublicClient);\n try {\n const balance = await newPublicClient.getBalance({ address: accounts[0] });\n setBalance(parseFloat(balance) / Math.pow(10, 18));\n } catch (error) {\n console.error('Error fetching balance:', error);\n setBalance(null);\n }\n\n handleAccountsChangedRef.current = handleAccountsChanged;\n handleChainChangedRef.current = handleChainChanged;\n window.ethereum.on('accountsChanged', handleAccountsChanged);\n window.ethereum.on('chainChanged', handleChainChanged);\n\n return true;\n } catch (err) {\n console.error('Error connecting wallet:', err);\n setError(err.message);\n return false;\n } finally {\n setIsConnecting(false);\n }\n }, [selectedNetwork, selectedChain, expectedChainId, handleAccountsChanged, handleChainChanged]);\n\n const ensureCorrectNetwork = useCallback(async () => {\n if (!window.ethereum || !selectedNetwork || !selectedChain || !account) {\n const errorMsg = 'Wallet not connected or network not selected';\n setError(errorMsg);\n return null;\n }\n\n try {\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== expectedChainId) {\n setError(null);\n await switchToNetwork(selectedNetwork);\n const NETWORK_SWITCH_DELAY_MS = 500;\n await new Promise(resolve => setTimeout(resolve, NETWORK_SWITCH_DELAY_MS));\n \n const newChainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const newChainId = parseInt(newChainIdHex, 16);\n if (newChainId !== expectedChainId) {\n throw new Error(`Failed to switch network. MetaMask is still on chain ${newChainId}, expected ${expectedChainId}`);\n }\n }\n\n const freshWalletClient = createWalletClient({\n chain: selectedChain,\n transport: custom(window.ethereum),\n });\n\n setWalletClient(freshWalletClient);\n setChainId(expectedChainId);\n setError(null);\n return freshWalletClient;\n } catch (err) {\n setError(err.message);\n return null;\n }\n }, [selectedNetwork, selectedChain, expectedChainId, account]);\n\n const prevNetworkRef = useRef(selectedNetwork);\n\n useEffect(() => {\n if (prevNetworkRef.current !== null && \n prevNetworkRef.current !== selectedNetwork && \n account) {\n disconnectWalletInternal();\n if (window.ethereum) {\n const accountsHandler = handleAccountsChangedRef.current;\n const chainHandler = handleChainChangedRef.current;\n if (accountsHandler) {\n window.ethereum.removeListener('accountsChanged', accountsHandler);\n }\n if (chainHandler) {\n window.ethereum.removeListener('chainChanged', chainHandler);\n }\n }\n }\n prevNetworkRef.current = selectedNetwork;\n }, [selectedNetwork, account, disconnectWalletInternal]);\n\n useEffect(() => {\n connectPublicClient();\n }, [connectPublicClient]);\n\n return (\n \n {children}\n \n );\n};","import React, { useState, useEffect } from \"react\";\nimport { useNetwork } from \"../contexts/NetworkContext\";\nimport { useWallet } from \"../contexts/WalletContext\";\nimport { Transaction } from \"../core/Transaction\";\nimport { parseEther, encodeFunctionData, parseUnits } from \"viem\"; \nimport styles from \"../styles/PricingCard.css\"; \n\nconst TransactionReview = ({ onTransactionComplete }) => {\n const {\n networkSelector,\n selectedNetwork,\n selectedToken,\n transactionDetails: contextTransactionDetails,\n setTransactionDetails,\n } = useNetwork();\n\n const {\n connectWallet,\n account,\n walletClient,\n publicClient,\n isConnecting,\n ensureCorrectNetwork,\n expectedChainId,\n } = useWallet();\n\n const [transaction, setTransaction] = useState(null);\n const [tradeDataBuySc, setTradeDataBuySc] = useState(null);\n const [message, setMessage] = useState(\"\");\n const [txHash, setTxHash] = useState(null);\n const [error, setError] = useState(null);\n const [isErrorDetailsVisible, setIsErrorDetailsVisible] = useState(false);\n const [interactionState, setInteractionState] = useState('IDLE');\n\n useEffect(() => {\n setTradeDataBuySc(null);\n setMessage(\"\");\n setError(null);\n setTxHash(null);\n setInteractionState('IDLE');\n }, [selectedNetwork, selectedToken]);\n\n useEffect(() => {\n const initializeTransaction = async () => {\n if (!selectedNetwork || !selectedToken) return;\n\n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const receivingAddress = networkSelector.getReceivingAddress();\n const tokenAmount = networkSelector.getTokenAmount(selectedToken.key);\n\n const newTransaction = new Transaction(\n networkConfig.uri,\n networkConfig.djedAddress\n );\n await newTransaction.init();\n setTransaction(newTransaction);\n\n let tradeData = null;\n if (selectedToken.key === \"native\") {\n try {\n tradeData = await newTransaction.handleTradeDataBuySc(String(tokenAmount));\n setTradeDataBuySc(tradeData);\n } catch (tradeError) {\n console.error(\"Error fetching trade data:\", tradeError);\n }\n }\n\n setTransactionDetails({\n network: selectedNetwork,\n token: selectedToken.key,\n tokenSymbol: selectedToken.symbol,\n amount: tokenAmount || \"0\",\n receivingAddress,\n djedContractAddress: networkConfig.djedAddress,\n isDirectTransfer: selectedToken.isDirectTransfer || false,\n isNativeToken: selectedToken.isNative || false,\n tradeAmount: tradeData ? tradeData.amount : null,\n ...newTransaction.getBlockchainDetails(),\n });\n } catch (err) {\n console.error(\"Error initializing transaction:\", err);\n }\n };\n\n initializeTransaction();\n }, [selectedNetwork, selectedToken, networkSelector, setTransactionDetails]);\n\n if (!selectedNetwork || !selectedToken) {\n return null;\n }\n\n if (!contextTransactionDetails) {\n if (typeof window !== 'undefined' && !window.ethereum) {\n return (\n
\n
\n No wallet found.\n
\n
\n \n
\n
\n );\n }\n return
Initializing transaction...
;\n }\n\n const handleConnectWallet = async () => {\n await connectWallet();\n };\n\n const executePayment = async () => {\n if (!account || !contextTransactionDetails || !transaction) {\n setMessage(\"Wallet not connected or transaction details missing\");\n return;\n }\n\n setInteractionState('PROCESSING');\n setMessage(\"Preparing transaction...\");\n setError(null);\n setTxHash(null);\n\n let builtTx;\n try {\n const receiver = contextTransactionDetails.receivingAddress;\n\n if (selectedToken.key === \"native\") {\n const UI = \"0x0232556C83791b8291E9b23BfEa7d67405Bd9839\";\n const amountToSend = tradeDataBuySc || \"0\";\n const valueInWei = parseEther(String(amountToSend));\n\n builtTx = await transaction.buyStablecoins(\n account,\n receiver,\n valueInWei,\n UI\n );\n\n builtTx = {\n ...builtTx,\n value: valueInWei,\n account: account,\n };\n } else {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n const stablecoinAddress = networkConfig?.tokens?.stablecoin?.address;\n \n if (!stablecoinAddress) {\n throw new Error('Stablecoin address not found in network configuration');\n }\n\n const amountToSend = contextTransactionDetails.amount\n ? parseUnits(\n String(contextTransactionDetails.amount),\n contextTransactionDetails.stableCoinDecimals\n )\n : \"0\";\n\n builtTx = {\n to: stablecoinAddress,\n value: 0n,\n data: encodeFunctionData({\n abi: [\n {\n inputs: [\n { internalType: \"address\", name: \"to\", type: \"address\" },\n { internalType: \"uint256\", name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ],\n functionName: \"transfer\",\n args: [receiver, amountToSend],\n }),\n account: account,\n };\n }\n } catch (err) {\n setError(err);\n const reason = err.shortMessage || (err.message ? err.message.split('\\n')[0] : \"Unknown error\");\n setMessage(`Transaction preparation failed: ${reason}`);\n setInteractionState('IDLE');\n return;\n }\n\n setMessage(\"Please check your wallet to confirm the transaction...\");\n \n try {\n const networkConfig = networkSelector.getSelectedNetworkConfig();\n if (!networkConfig) {\n throw new Error(\"Network configuration not found\");\n }\n\n const freshWalletClient = await ensureCorrectNetwork();\n if (!freshWalletClient) {\n throw new Error(\"Failed to switch to correct network. Please approve the network switch in MetaMask.\");\n }\n\n if (!window.ethereum) {\n throw new Error(\"MetaMask not available\");\n }\n\n const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });\n const currentChainId = parseInt(chainIdHex, 16);\n\n if (currentChainId !== networkConfig.chainId) {\n throw new Error(`Network mismatch. MetaMask is on chain ${currentChainId}, but ${selectedNetwork} requires chain ${networkConfig.chainId}. Please switch networks in MetaMask.`);\n }\n\n if (freshWalletClient.chain.id !== networkConfig.chainId) {\n throw new Error(`Wallet client chain mismatch. Wallet client is on chain ${freshWalletClient.chain.id}, but expected ${networkConfig.chainId}.`);\n }\n\n const txHash = await freshWalletClient.sendTransaction({\n ...builtTx,\n account: account,\n });\n\n setTxHash(txHash);\n setMessage(`Transaction sent successfully!`);\n setInteractionState('SUCCESS');\n \n if (onTransactionComplete) {\n onTransactionComplete({\n txHash,\n network: selectedNetwork,\n token: selectedToken?.key,\n tokenSymbol: selectedToken?.symbol,\n amount: contextTransactionDetails?.amount,\n receivingAddress: contextTransactionDetails?.receivingAddress,\n });\n }\n } catch (err) {\n setError(err);\n \n let reason = \"Unknown error\";\n if (err.name === 'UserRejectedRequestError' || err.code === 4001) {\n reason = \"User denied transaction\";\n } else if (err.name === 'ContractFunctionRevertedError' || (err.data && err.data.message)) {\n reason = err.shortMessage || err.data?.message || err.message;\n } else {\n reason = err.shortMessage || (err.message ? err.message.split('\\n')[0] : \"Transaction failed\");\n }\n \n setMessage(`Transaction failed: ${reason}`);\n setInteractionState('IDLE');\n console.error('Transaction error:', err);\n }\n };\n\n const getExplorerUrl = () => {\n if (!txHash || !selectedNetwork) return null;\n\n const explorerBaseUrls = {\n \"ethereum-classic\": \"https://blockscout.com/etc/mainnet/tx/\",\n \"sepolia\": \"https://sepolia.etherscan.io/tx/\",\n \"milkomeda-mainnet\": \"https://explorer-mainnet-cardano-evm.c1.milkomeda.com/tx/\",\n };\n\n return explorerBaseUrls[selectedNetwork]\n ? `${explorerBaseUrls[selectedNetwork]}${txHash}`\n : null;\n };\n\n return (\n
\n
\n Network:\n {contextTransactionDetails.network}\n
\n\n
\n You Pay:\n \n {selectedToken.key === \"stablecoin\"\n ? `${contextTransactionDetails.amount} ${contextTransactionDetails.tokenSymbol}`\n : `${tradeDataBuySc ? tradeDataBuySc : \"Calculating...\"} ${\n contextTransactionDetails.tokenSymbol\n }`}\n \n
\n\n {message && (\n
\n {message}\n {error && (\n setIsErrorDetailsVisible(!isErrorDetailsVisible)}\n className={styles.detailsButton}\n >\n {isErrorDetailsVisible ? \"Hide Details\" : \"Show Details\"}\n \n )}\n
\n )}\n\n {isErrorDetailsVisible && error && (\n
\n
{error.message}
\n
\n )}\n\n {txHash && (\n
\n Transaction Hash:{\" \"}\n {getExplorerUrl() ? (\n \n {txHash.slice(0, 6)}...{txHash.slice(-6)}\n \n ) : (\n \n {txHash}\n \n )}\n
\n )}\n\n {interactionState !== 'SUCCESS' && (\n
\n {!account && (\n \n )}\n\n {account && interactionState === 'IDLE' && (\n \n )}\n\n {account && interactionState === 'CONFIRMING' && (\n
\n Confirm payment?\n
\n \n \n
\n
\n )}\n\n {account && interactionState === 'PROCESSING' && (\n \n )}\n
\n )}\n
\n );\n};\n\nexport default TransactionReview;\n","import React, { useState } from \"react\";\nimport PayButton from \"./PayButton\";\nimport Dialog from \"./Dialog\";\nimport NetworkDropdown from \"./NetworkDropdown\";\nimport TokenDropdown from \"./TokenDropdown\";\nimport TransactionReview from \"./TransactionReview\";\nimport { NetworkProvider, useNetwork } from \"../contexts/NetworkContext\";\nimport { WalletProvider } from \"../contexts/WalletContext\";\nimport styles from \"../styles/PricingCard.css\";\n\nconst WidgetContent = ({ onClose, buttonSize, onTransactionComplete }) => {\n const { resetSelections } = useNetwork(); \n\n const handleClose = () => {\n resetSelections(); // Reset selections when closing the widget\n onClose();\n };\n\n return (\n \n \n \n \n \n );\n};\n\nconst WidgetWithProviders = ({ onClose, buttonSize, networkSelector, onTransactionComplete }) => {\n return (\n \n \n \n \n \n );\n};\n\nexport const Widget = ({ networkSelector, buttonSize = \"medium\", onTransactionComplete, onSuccess }) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const handleOpenDialog = () => {\n setIsDialogOpen(true);\n };\n\n const handleCloseDialog = () => {\n setIsDialogOpen(false);\n };\n\n // Support both onTransactionComplete and onSuccess for backwards compatibility\n const handleTransactionComplete = onTransactionComplete || onSuccess;\n\n return (\n
\n {!isDialogOpen && (\n \n )}\n {isDialogOpen && (\n \n )}\n
\n );\n};\n\nexport default Widget;\n","// src/index.js\nimport { NetworkSelector } from './core/NetworkSelector';\nimport { Transaction } from './core/Transaction';\nimport { Config } from './core/MerchantConfig';\nimport Widget from './widget/Widget.jsx';\nimport PayButton from './widget/PayButton.jsx';\nimport Dialog from './widget/Dialog.jsx';\nimport NetworkDropdown from './widget/NetworkDropdown.jsx';\nimport './styles/main.css';\nimport './styles/PricingCard.css';\n\nconst StablePay = {\n NetworkSelector,\n Transaction,\n Config,\n Widget,\n PayButton,\n Dialog,\n NetworkDropdown\n};\n\nexport default StablePay;","import { networksConfig } from \"../utils/config\";\n\nexport class NetworkSelector {\n constructor(merchantConfig) {\n this.merchantConfig = merchantConfig;\n this.blacklist = merchantConfig.getBlacklist();\n this.availableNetworks = this.getAvailableNetworks();\n this.selectedNetwork = null;\n }\n\n getAvailableNetworks() {\n return Object.entries(networksConfig).reduce(\n (acc, [networkKey, networkConfig]) => {\n if (!this.blacklist.includes(networkConfig.chainId)) {\n acc[networkKey] = networkConfig;\n }\n return acc;\n },\n {}\n );\n }\n\n selectNetwork(networkKey) {\n if (networkKey === null) {\n this.selectedNetwork = null;\n console.log(\"Network selection reset\");\n return true;\n }\n if (this.availableNetworks[networkKey]) {\n this.selectedNetwork = networkKey;\n console.log(`Network selected: ${networkKey}`);\n return true;\n }\n console.error(`Invalid network: ${networkKey}`);\n return false;\n }\n\n getSelectedNetworkConfig() {\n return this.selectedNetwork\n ? this.availableNetworks[this.selectedNetwork]\n : null;\n }\n\n getReceivingAddress() {\n return this.merchantConfig.getReceivingAddress();\n }\n\n getTokenAmount(token) {\n return this.merchantConfig.getTokenAmount(this.selectedNetwork, token);\n }\n}\n","import { networksConfig } from \"../utils/config\";\n\nexport class Config {\n constructor(options = {}) {\n this.receivingAddress = options.receivingAddress || \"\";\n this.blacklist = options.blacklist || [];\n this.amounts = options.amounts || options.Amounts || {};\n this.validateConfig();\n }\n\n validateConfig() {\n if (!this.receivingAddress) {\n throw new Error(\"Receiving address is required\");\n }\n // Validate stablecoin amounts\n for (const [network, tokens] of Object.entries(this.amounts)) {\n if (!networksConfig[network]) {\n throw new Error(`Invalid network: ${network}`);\n }\n if (\n !tokens.stablecoin ||\n typeof tokens.stablecoin !== \"number\" ||\n tokens.stablecoin <= 0\n ) {\n throw new Error(`Invalid stablecoin amount for network ${network}`);\n }\n }\n }\n\n getBlacklist() {\n return this.blacklist;\n }\n\n getReceivingAddress() {\n return this.receivingAddress;\n }\n\n // getTokenAmount(network, token) {\n // const networkConfig = networksConfig[network];\n // if (!networkConfig) return 0;\n\n // const stablecoinSymbol = networkConfig.tokens.stablecoin.symbol;\n\n // if (token === 'stablecoin') {\n // return this.amounts[network]?.stablecoin || 0;\n // }\n // // For native tokens, return 0 as it's not specified in the new structure\n // return 0;\n // }\n getTokenAmount(network) {\n console.log(\"Getting amount for network:\", network);\n console.log(\"Amounts object:\", this.amounts);\n\n // Directly return the stablecoin amount for the network\n const amount = this.amounts[network]?.stablecoin;\n console.log(\"Returning amount:\", amount);\n\n return amount || 0;\n }\n}\n\nexport default Config;\n"],"names":["networksConfig","sepolia","uri","chainId","djedAddress","tokens","stablecoin","symbol","address","decimals","isDirectTransfer","native","isNative","feeUI","Transaction","constructor","networkUri","this","init","Error","web3","getWeb3","djedContract","getDjedContract","stableCoin","reserveCoin","getCoinContracts","scDecimals","rcDecimals","getDecimals","oracleContract","getOracleAddress","then","addr","getOracleContract","_address","oracleAddress","contractError","console","error","code","name","data","message","getNetworkInfo","includes","networkName","getNetworkName","getBlockchainDetails","web3Available","djedContractAvailable","stableCoinAddress","reserveCoinAddress","stableCoinDecimals","reserveCoinDecimals","oracleContractAvailable","handleTradeDataBuySc","amountScaled","tradeDataPriceBuySc","totalBCScaled","buyStablecoins","payer","receiver","value","UI","buyScTx","PayButton","onClick","size","sizeStyles","small","width","height","fontSize","medium","large","logoSizes","buttonStyle","logoStyle","React","createElement","className","styles","style","Dialog","children","onClose","dialogOverlay","pricingCard","dialogClose","pricingCardHeader","allianceLogo","stablepayTitle","pricingCardBody","TokenSelector","networkSelector","selectedToken","selectToken","tokenKey","networkConfig","getSelectedNetworkConfig","key","getSelectedToken","getAvailableTokens","Object","entries","map","config","resetSelection","NetworkContext","createContext","NetworkProvider","tokenSelector","useState","selectedNetwork","setSelectedNetwork","setSelectedToken","transactionDetails","setTransactionDetails","resetState","useEffect","Provider","selectNetwork","networkKey","token","resetSelections","useNetwork","context","useContext","undefined","NetworkDropdown","selectField","htmlFor","id","onChange","event","target","disabled","keys","availableNetworks","TokenDropdown","loading","setLoading","setError","availableTokens","async","newValue","transaction","tokenAmount","getTokenAmount","blockchainDetails","tradeData","String","network","tokenSymbol","amount","receivingAddress","getReceivingAddress","djedContractAddress","isNativeToken","tradeAmount","err","window","ethereum","defineChain","nativeCurrency","rpcUrls","default","http","webSocket","blockExplorers","url","testnet","milkomeda","etcMainnet","WalletContext","switchToNetwork","chainConfig","toString","chainName","blockExplorerUrls","getChainConfigForWallet","request","method","params","switchError","addError","WalletProvider","walletClient","setWalletClient","publicClient","setPublicClient","account","setAccount","setChainId","balance","setBalance","isConnecting","setIsConnecting","selectedChain","getChainByNetworkKey","expectedChainId","handleAccountsChangedRef","useRef","handleChainChangedRef","disconnectWalletInternal","useCallback","handleChainChanged","newChainId","parseInt","chainIdHex","newWalletClient","createWalletClient","chain","transport","custom","current","handleAccountsChanged","accounts","length","accountsHandler","chainHandler","removeListener","newPublicClient","createPublicClient","getBalance","parseFloat","Math","pow","disconnectWallet","connectPublicClient","connectWallet","on","ensureCorrectNetwork","NETWORK_SWITCH_DELAY_MS","Promise","resolve","setTimeout","newChainIdHex","freshWalletClient","prevNetworkRef","TransactionReview","onTransactionComplete","contextTransactionDetails","useWallet","setTransaction","tradeDataBuySc","setTradeDataBuySc","setMessage","txHash","setTxHash","isErrorDetailsVisible","setIsErrorDetailsVisible","interactionState","setInteractionState","newTransaction","tradeError","initializeTransaction","transactionReview","messageBox","textAlign","marginBottom","color","walletButtonContainer","walletButton","open","getExplorerUrl","explorerBaseUrls","transactionInfo","transactionLabel","transactionValue","highlight","detailsButton","errorDetails","transactionLink","href","rel","explorerLink","slice","wordBreak","confirmContainer","confirmText","confirmButtons","secondaryButton","primaryButton","builtTx","amountToSend","valueInWei","parseEther","stablecoinAddress","parseUnits","to","encodeFunctionData","abi","inputs","internalType","type","outputs","stateMutability","functionName","args","reason","shortMessage","split","currentChainId","sendTransaction","WidgetContent","buttonSize","handleClose","WidgetWithProviders","NetworkSelector","merchantConfig","blacklist","getBlacklist","getAvailableNetworks","reduce","acc","log","Config","options","amounts","Amounts","validateConfig","Widget","onSuccess","isDialogOpen","setIsDialogOpen","handleTransactionComplete","widgetContainer","handleOpenDialog","handleCloseDialog"],"mappings":"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"} \ No newline at end of file diff --git a/stablepay-sdk/example/eslint.config.js b/stablepay-sdk/example/eslint.config.js index ea36dd3..73441e2 100644 --- a/stablepay-sdk/example/eslint.config.js +++ b/stablepay-sdk/example/eslint.config.js @@ -6,13 +6,11 @@ import { defineConfig, globalIgnores } from 'eslint/config' export default defineConfig([ globalIgnores(['dist']), + js.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, { files: ['**/*.{js,jsx}'], - extends: [ - js.configs.recommended, - reactHooks.configs.flat.recommended, - reactRefresh.configs.vite, - ], languageOptions: { globals: globals.browser, parserOptions: { ecmaFeatures: { jsx: true } }, diff --git a/stablepay-sdk/example/src/App.jsx b/stablepay-sdk/example/src/App.jsx index d6cb169..c63ae1e 100644 --- a/stablepay-sdk/example/src/App.jsx +++ b/stablepay-sdk/example/src/App.jsx @@ -1,22 +1,7 @@ -import { useState } from 'react'; import StablePay from 'stablepay-sdk'; import './App.css'; function App() { - const [account, setAccount] = useState(''); - - const connectWallet = async () => { - if (window.ethereum) { - try { - const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }); - setAccount(accounts[0]); - } catch (err) { - console.error("User denied account access", err); - } - } else { - alert("Please install MetaMask to connect your wallet."); - } - }; // Configure merchant for a $5 demo payment const merchantConfig = new StablePay.Config({ @@ -30,19 +15,14 @@ function App() { const networkSelector = new StablePay.NetworkSelector(merchantConfig); - const handleTransactionComplete = (hash) => { - alert(`Payment Successful! Transaction Hash: ${hash}`); + const handleTransactionComplete = ({ txHash, network, tokenSymbol, amount }) => { + alert(`Payment Successful!\nTransaction Hash: ${txHash}\nNetwork: ${network}\nAmount: ${amount} ${tokenSymbol}`); }; return (
Demo Shop
-
diff --git a/stablepay-sdk/src/core/Transaction.js b/stablepay-sdk/src/core/Transaction.js index 498c28e..4001e3c 100644 --- a/stablepay-sdk/src/core/Transaction.js +++ b/stablepay-sdk/src/core/Transaction.js @@ -30,7 +30,11 @@ export class Transaction { this.oracleAddress = this.oracleContract._address; } catch (contractError) { console.error('[Transaction] Error fetching contract details:', contractError); - const isReverted = contractError.code === -32000 || contractError.code === 3 || contractError.data; + const isReverted = + contractError?.code === -32000 || + contractError?.code === 3 || + contractError?.name === 'ContractFunctionRevertedError' || + typeof contractError?.data?.message === 'string'; if (isReverted) { const getNetworkInfo = (uri) => { if (uri.includes('milkomeda')) return { name: 'Milkomeda', chainId: '2001' };