@idosgames/wallet 0.6.2 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- 'use strict';var appkitAdapterSolana=require('@reown/appkit-adapter-solana'),react=require('@reown/appkit/react'),core=require('@idosgames/core'),viem=require('viem'),react$1=require('react'),jsxRuntime=require('react/jsx-runtime'),web3_js=require('@solana/web3.js'),buffer=require('buffer');var j={id:"5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",name:"Solana",network:"solana-mainnet",nativeCurrency:{name:"Solana",symbol:"SOL",decimals:9},rpcUrls:{default:{http:["https://api.mainnet-beta.solana.com"]}},blockExplorers:{default:{name:"Solscan",url:"https://solscan.io"}},testnet:false,chainNamespace:"solana",caipNetworkId:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"},re={id:"EtWTRABZaYq6iMfeYKouRu166VU2xqa1",name:"Solana Devnet",network:"solana-devnet",nativeCurrency:{name:"Solana",symbol:"SOL",decimals:9},rpcUrls:{default:{http:["https://api.devnet.solana.com"]}},blockExplorers:{default:{name:"Solscan",url:"https://solscan.io"}},testnet:true,chainNamespace:"solana",caipNetworkId:"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"};var he=null;function Se(e){he=e;}function U(){return he}var ke=new Map;function oe(e){let{walletConnectProjectId:t,appName:r,appUrl:o,appIcon:l,wallets:n}=e,p=ke.get(t);if(p)return p;let s=e.networks??[j],a=o??(typeof window<"u"?window.location.origin:""),i={name:r??"iDosGames",description:r??"iDosGames game",url:a,icons:l?[l]:[]},c=new appkitAdapterSolana.SolanaAdapter(n?{wallets:n}:{});return Se(react.createAppKit({adapters:[c],networks:s,projectId:t,metadata:i,features:{analytics:false,email:false,socials:false}})),ke.set(t,c),c}function M(e){return e instanceof viem.BaseError?e.shortMessage:e instanceof Error?e.message:String(e)}function h(e,t,r){return {ok:false,stage:e,error:t,...r}}function C(e,t){return {ok:false,stage:e,error:t}}var be="WALLET_USE_SITE_PANEL",Le=/^[a-z0-9]{8}-preview\.idos\.games$/;function Oe(e=typeof window>"u"?"":window.location.hostname){let t=e.toLowerCase();return Le.test(t)?true:t!=="localhost"&&t!=="127.0.0.1"?false:globalThis.__IDOS_PREVIEW__!=null}function F(){if(typeof window>"u"||Oe())return false;try{return window.self!==window.top}catch{return true}}function ae(e){return h(e,be)}function ie(e){return C(e,be)}async function Y(e){let{client:t,adapter:r,network:o,mint:l,amountRaw:n,titleID:p,category:s}=e;if(F())return ae("deposit-onchain");let a=t.auth.context?.userID;if(!a)return h("deposit-onchain","Not logged in.");if(n<=0n)return h("deposit-onchain","Amount must be positive.");let i;try{i=await r.depositSpl({mint:l,amountRaw:n,userID:a,titleID:p,category:core.normalizeBlockchainCategory(s)});}catch(u){return h("deposit-onchain",M(u))}let c=await t.blockchain.depositToken(o.NetworkID??"",i);return c.ok?{ok:true,onChainTxHash:i,data:c.data}:h("report",c.error,{onChainTxHash:i})}async function z(e){let{client:t,adapter:r,currencyID:o,networkID:l,walletAddress:n,amount:p,category:s}=e;if(F())return ae("request");let a=await t.blockchain.requestTokenWithdrawal(o,l,n,p,s);if(!a.ok)return h("request",a.error);let i=a.data.SolanaSignature,c=a.data.TitleTransactionID??void 0;if(!i)return h("request","Withdrawal response carried no Solana signature.",{titleTransactionID:c});let u;try{u=await r.submitWithdrawal(i);}catch(T){return h("withdraw-onchain",M(T),{titleTransactionID:c})}if(!c)return h("confirm","Missing TitleTransactionID.",{onChainTxHash:u});let f=await t.blockchain.confirmWithdrawal(c,u);return f.ok?{ok:true,onChainTxHash:u,data:a.data}:h("confirm",f.error,{onChainTxHash:u,titleTransactionID:c})}async function $(e){let{client:t,networkID:r,walletAddress:o,signMessage:l}=e;if(F())return ie("challenge");let n=await t.auth.requestWalletChallenge(o,r);if(!n.ok)return C("challenge",n.error);let p;try{let a=await l(new TextEncoder().encode(n.data.Message));p=Pe(a);}catch(a){return C("sign",M(a))}let s=await t.auth.loginWithWallet(o,r,p);return s.ok?{ok:true,data:s.data}:C("login",s.error)}async function se(e){let{client:t,networkID:r,walletAddress:o,signMessage:l}=e;if(F())return ie("challenge");let n=await t.auth.linkWallet(o,r);if(!n.ok)return C("challenge",n.error);if(!n.data.Challenge)return C("challenge","No challenge was issued.");let p;try{let a=await l(new TextEncoder().encode(n.data.Challenge));p=Pe(a);}catch(a){return C("sign",M(a))}let s=await t.auth.linkWallet(o,r,p);return s.ok?{ok:true,data:s.data}:C("login",s.error)}function Pe(e){let t="0x";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}var Te="Wallet not connected.";function Me(e,t,r){let{address:o}=react.useAppKitAccount(),{walletProvider:l}=react.useAppKitProvider("solana"),n=o??null,p=l?.signMessage?.bind(l);return {connected:!!n,account:n,loginWithWallet:(s,a)=>{let i=a??n;return i?p?$({client:e,networkID:s,walletAddress:i,signMessage:p}):Promise.resolve(C("sign","The connected wallet does not support message signing.")):Promise.resolve(C("challenge",Te))},depositToken:s=>Y({client:e,adapter:r,titleID:t,...s}),withdrawToken:s=>{let a=s.walletAddress??n;return a?z({client:e,adapter:r,...s,walletAddress:a}):Promise.resolve(h("request",Te))}}}function le(e,t){switch(e){case null:case void 0:case "":return t;case "PLAY_ACCESS_WALLET_USED_BY_ANOTHER_ACCOUNT":return "This wallet already plays with another account.";case "WALLET_UNLINK_COOLDOWN":return "This wallet was unlinked from another account less than 7 days ago. Try again after the 7 days.";case "WALLET_CHANGES_TOO_FREQUENT":return "Too many wallets were changed this week. Try again in a few days.";case "PLAY_ACCESS_WALLET_LOGIN_ONLY":return "This game is played with a wallet login only.";case "INVALID_WALLET_SIGNATURE":return "The signature does not match the wallet. Please try again.";case "WALLET_CHALLENGE_EXPIRED":return "The request expired. Please try again.";default:return e}}var He=18e4,Ie=9e4;function qe(e){try{let r=e?.session?.peer?.metadata?.redirect,o=r?.native||r?.universal;return !o||typeof window>"u"?!1:(window.location.href=o,!0)}catch{return false}}function Ce(e,t){return new Promise((r,o)=>{let l=setTimeout(()=>o(new Error("The wallet request timed out.")),t);e.then(n=>{clearTimeout(l),r(n);},n=>{clearTimeout(l),o(n instanceof Error?n:new Error(String(n)));});})}function Ve(e){let t="Wallet sign-in failed. Please try again.";return e instanceof Error?/user (rejected|denied|cancelled|canceled)|rejected the request/i.test(e.message)?"Request declined in the wallet.":/timed? ?out/i.test(e.message)?"The wallet did not respond. Open your wallet and try again.":t:t}function je(e){let{client:t,networkID:r,onAuthenticated:o,disabled:l,label:n,style:p,autoStart:s,mode:a="login",onLinked:i}=e,{address:c,isConnected:u}=react.useAppKitAccount(),{walletProvider:f}=react.useAppKitProvider("solana"),[T,w]=react$1.useState(false),[g,m]=react$1.useState(null),[I,W]=react$1.useState(false),[x,R]=react$1.useState(false),D=react$1.useRef(null),Z=react$1.useRef(0),E=react$1.useCallback(()=>{D.current&&clearTimeout(D.current),D.current=null;},[]);react$1.useEffect(()=>E,[E]);let O=react$1.useRef(false),d=react$1.useCallback(async()=>{let B=++Z.current,_=()=>Z.current===B,ne=f?.signMessage?.bind(f);if(!c||!ne){m("The connected wallet cannot sign messages."),w(false);return}w(true),m(null);try{if(R(!0),a==="link"){let J=await Ce(se({client:t,networkID:r,walletAddress:c,signMessage:ne}),Ie);if(!_())return;if(J.ok){i?.(J.data.PlayAccess??null);return}m(J.stage==="sign"?"Signature declined.":le(J.error,"Could not link the wallet."));return}let K=await Ce($({client:t,networkID:r,walletAddress:c,signMessage:ne}),Ie);if(!_())return;if(K.ok){o();return}m(K.stage==="sign"?"Signature declined.":le(K.error,"Wallet sign-in failed."));}catch(K){if(!_())return;console.error("[idosgames/wallet] solana sign-in failed:",K),m(Ve(K));}finally{_()&&(w(false),R(false));}},[c,f,t,r,o,a,i]),S=react$1.useCallback(()=>{qe(f)||U()?.open();},[f]);react$1.useEffect(()=>{!I||!u||!c||!f||(W(false),E(),d());},[I,u,c,f,d,E]);let v=()=>{if(x){S();return}if(m(null),O.current=true,u&&c&&f){d();return}let B=U();if(!B){m("Wallet sign-in is not configured for this title.");return}w(true),W(true),E(),D.current=setTimeout(()=>{W(false),w(false),m("No wallet was connected.");},He),B.open();};return react$1.useEffect(()=>{!s||O.current||(O.current=true,v());},[s]),jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("button",{type:"button",onClick:v,disabled:l,style:{...Ye,...l?{opacity:.6,cursor:"default"}:null,...p},children:x?"Waiting for signature \u2014 tap to open wallet":T?"Check your wallet\u2026":u?n??(a==="link"?"Link wallet":"Sign in with wallet"):"Connect wallet"}),g&&jsxRuntime.jsx("span",{role:"alert",style:ze,children:g})]})}var Ye={padding:"11px 16px",borderRadius:"8px",border:"none",background:"#4c3fa8",color:"#fff",font:"inherit",fontWeight:600,cursor:"pointer"},ze={display:"block",marginTop:"6px",color:"#ff9b9b",fontSize:"13px",textAlign:"center"};var tt="e000c6afc62f69cc",nt="b59a5e563e7306ba",rt="d668e18c1bdc33f1",ee=new web3_js.PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"),ot="1nc1nerator11111111111111111111111111111111",Ae=177,at=3e5,Ee=40,xe=4,De=Ee+32*xe,it=De+8,A=class extends Error{constructor(r,o){super(o);this.code=r;this.name="PlatformPoolError";}code};function X(e){let t=(e??"").replace(/^0x/i,""),r=new Uint8Array(t.length>>1);for(let o=0;o<r.length;o++)r[o]=parseInt(t.slice(o*2,o*2+2),16);return r}function G(e){let t=buffer.Buffer.alloc(8);return t.writeBigUInt64LE(BigInt(e||0)),t}function st(e){let t=buffer.Buffer.alloc(8);return t.writeBigInt64LE(BigInt(e||0)),t}function q(e){let t=buffer.Buffer.from(e??"","utf8"),r=buffer.Buffer.alloc(4);return r.writeUInt32LE(t.length),buffer.Buffer.concat([r,t])}function lt(e){return buffer.Buffer.concat([buffer.Buffer.from(tt,"hex"),G(e.amountRaw),q(e.userID),q(e.titleID),q(e.category)])}function ct(e){let t=e.Splits??[],r=buffer.Buffer.alloc(4);return r.writeUInt32LE(t.length),buffer.Buffer.concat([buffer.Buffer.from(e.Domain==="SPL_DEV"?rt:nt,"hex"),G(e.Amount),G(e.BurnAmount),G(e.Nonce),st(e.ExpiresAt),r,...t.map(o=>buffer.Buffer.concat([buffer.Buffer.from(new web3_js.PublicKey(o.To??"").toBytes()),G(o.Amount)])),q(e.UserID),q(e.TitleID),q(e.Category)])}function H(e,t,r){return web3_js.PublicKey.findProgramAddressSync([t.toBuffer(),r.toBuffer(),e.toBuffer()],ee)[0]}function pt(e,t,r,o,l){return new web3_js.TransactionInstruction({programId:ee,keys:[{pubkey:e,isSigner:true,isWritable:true},{pubkey:t,isSigner:false,isWritable:true},{pubkey:r,isSigner:false,isWritable:false},{pubkey:o,isSigner:false,isWritable:false},{pubkey:web3_js.SystemProgram.programId,isSigner:false,isWritable:false},{pubkey:l,isSigner:false,isWritable:false}],data:buffer.Buffer.from([1])})}function V(e,...t){return web3_js.PublicKey.findProgramAddressSync(t,e)[0]}function ut(e){let{programId:t,user:r,mint:o,tokenProgram:l}=e,n=V(t,buffer.Buffer.from("vault"));return new web3_js.TransactionInstruction({programId:t,keys:[{pubkey:V(t,buffer.Buffer.from("config")),isSigner:false,isWritable:false},{pubkey:n,isSigner:false,isWritable:true},{pubkey:o,isSigner:false,isWritable:false},{pubkey:r,isSigner:true,isWritable:true},{pubkey:H(o,r,l),isSigner:false,isWritable:true},{pubkey:H(o,n,l),isSigner:false,isWritable:true},{pubkey:l,isSigner:false,isWritable:false},{pubkey:ee,isSigner:false,isWritable:false},{pubkey:web3_js.SystemProgram.programId,isSigner:false,isWritable:false}],data:lt(e)})}function dt(e){let{sig:t,payer:r,tokenProgram:o}=e,l=new web3_js.PublicKey(t.ProgramID??""),n=new web3_js.PublicKey(t.Mint??""),p=new web3_js.PublicKey(t.WalletAddress??""),s=V(l,buffer.Buffer.from("vault")),a=new web3_js.PublicKey(ot),i=(t.Splits??[]).map(w=>new web3_js.PublicKey(w.To??"")),c=i.map(w=>H(n,w,o)),u=web3_js.Ed25519Program.createInstructionWithPublicKey({publicKey:X(t.Ed25519PublicKey),message:X(t.Ed25519Message),signature:X(t.SignatureHex)}),f=i.map((w,g)=>pt(r,c[g],w,n,o)),T=new web3_js.TransactionInstruction({programId:l,keys:[{pubkey:V(l,buffer.Buffer.from("config")),isSigner:false,isWritable:false},{pubkey:r,isSigner:true,isWritable:true},{pubkey:s,isSigner:false,isWritable:true},{pubkey:V(l,buffer.Buffer.from("nonce"),G(t.Nonce)),isSigner:false,isWritable:true},{pubkey:n,isSigner:false,isWritable:false},{pubkey:p,isSigner:false,isWritable:false},{pubkey:H(n,s,o),isSigner:false,isWritable:true},{pubkey:H(n,p,o),isSigner:false,isWritable:true},{pubkey:a,isSigner:false,isWritable:false},{pubkey:H(n,a,o),isSigner:false,isWritable:true},{pubkey:web3_js.SYSVAR_INSTRUCTIONS_PUBKEY,isSigner:false,isWritable:false},{pubkey:o,isSigner:false,isWritable:false},{pubkey:ee,isSigner:false,isWritable:false},{pubkey:web3_js.SystemProgram.programId,isSigner:false,isWritable:false},...c.map(w=>({pubkey:w,isSigner:false,isWritable:true}))],data:ct(t)});return [u,...f,T]}function ge(e){let{connection:t,signTransaction:r}=e;async function o(n){let p=await t.getAccountInfo(n);if(!p)throw new A("MINT_NOT_FOUND",`mint ${n.toBase58()} not found`);return p.owner}async function l(n,p){let{blockhash:s,lastValidBlockHeight:a}=await t.getLatestBlockhash("confirmed"),i=new web3_js.Transaction;i.feePayer=n,i.recentBlockhash=s,i.add(...p);let c=await r(i),u=await t.sendRawTransaction(c.serialize());return await t.confirmTransaction({signature:u,blockhash:s,lastValidBlockHeight:a},"confirmed"),u}return {async depositSpl({mint:n,amountRaw:p,userID:s,titleID:a,category:i}){let c=new web3_js.PublicKey(e.owner),u=new web3_js.PublicKey(n),f=await o(u);return l(c,[ut({programId:new web3_js.PublicKey(e.programId),user:c,mint:u,tokenProgram:f,amountRaw:p,userID:s,titleID:a,category:i})])},async submitWithdrawal(n){if(!n.ProgramID||!n.Mint||!n.WalletAddress)throw new A("BAD_VOUCHER","the voucher has no program, mint or wallet");let p=new web3_js.PublicKey(e.owner),s=new web3_js.PublicKey(n.ProgramID),a=await t.getAccountInfo(V(s,buffer.Buffer.from("config")));if(!a)throw new A("POOL_NOT_ON_THIS_CLUSTER","the pool's config account is not on this cluster");if(a.data.length!==Ae)throw new A("POOL_NOT_MIGRATED",`config is ${a.data.length} bytes, expected ${Ae} (migrate_config not run)`);let i=buffer.Buffer.from(a.data);if(i[it]===1)throw new A("POOL_PAUSED","pool withdrawals are paused");let c=i.readBigUInt64LE(De);if(c!==BigInt(n.SignatureEpoch||0))throw new A("VOUCHER_REVOKED",`signature epoch mismatch: voucher ${n.SignatureEpoch}, on-chain ${c}`);let u=buffer.Buffer.from(X(n.Ed25519PublicKey)),f=false;for(let w=0;w<xe;w++){let g=Ee+w*32;u.equals(i.subarray(g,g+32))&&(f=true);}if(!f)throw new A("SIGNER_NOT_TRUSTED","the voucher's signer is not in the pool's server_pubkeys");let T=await o(new web3_js.PublicKey(n.Mint));return l(p,[web3_js.ComputeBudgetProgram.setComputeUnitLimit({units:at}),...dt({sig:n,payer:p,tokenProgram:T})])}}}var mt={pointerEvents:"auto",background:"#04276bf5",border:"1px solid #1e59c8",borderRadius:12,padding:16,color:"#fff",width:320,boxSizing:"border-box",fontFamily:"system-ui, sans-serif",display:"flex",flexDirection:"column",gap:10,maxHeight:"80vh",overflow:"auto"},yt={fontWeight:700,fontSize:16},N={fontSize:12,opacity:.7},ye={background:"#052e7e",border:"1px solid #1e59c8",borderRadius:8,color:"#fff",padding:"8px 10px",width:"100%",boxSizing:"border-box"},wt={background:"#0d66fe",color:"#fff",border:"none",borderRadius:8,padding:"9px 14px",fontWeight:700,cursor:"pointer"},te={background:"#1e59c8",color:"#fff",border:"none",borderRadius:8,padding:"7px 12px",fontWeight:600,cursor:"pointer"},we={display:"flex",gap:8};function ve({client:e,engine:t,onClose:r,style:o}){let[,l]=react$1.useReducer(d=>d+1,0),[n,p]=react$1.useState({}),[s,a]=react$1.useState({}),[i,c]=react$1.useState(""),[u,f]=react$1.useState(""),[T,w]=react$1.useState(""),[g,m]=react$1.useState(false),[I,W]=react$1.useState(null);react$1.useEffect(()=>{let d=true;return (async()=>{let S=await e.blockchain.getDefinitions();if(await e.blockchain.getUserState(),!d||!S.ok)return;let v={};for(let[B,_]of Object.entries(S.data.Blockchain?.Networks??{}))_.Type===t.networkType&&(v[B]=_);p(v),a(S.data.CryptoCurrencies??{}),c(Object.keys(v)[0]??"");})(),()=>{d=false;}},[e,t.networkType]),react$1.useEffect(()=>e.on("user:anyUpdated",l),[e]);let x=react$1.useMemo(()=>Object.entries(s).filter(([,d])=>d.Networks?.some(S=>S.NetworkID===i&&!!S.ContractAddress)),[s,i]);react$1.useEffect(()=>{let d=x[0]?.[0]??"";f(S=>x.some(([v])=>v===S)?S:d);},[x]);let R=i?n[i]:void 0,D=u?s[u]?.Networks?.find(d=>d.NetworkID===i):void 0,Z=u?e.data.user.getCryptoCurrencyAmount(u):"0",E=!!t.address;async function O(d){m(true),W(null);try{let S=await d();W(S),S.ok&&await e.blockchain.getUserState();}finally{m(false);}}return jsxRuntime.jsxs("div",{style:{...mt,...o},children:[jsxRuntime.jsxs("div",{style:{...we,justifyContent:"space-between"},children:[jsxRuntime.jsx("span",{style:yt,children:"Crypto wallet"}),r&&jsxRuntime.jsx("button",{type:"button",style:te,onClick:r,children:"\u2715"})]}),E?jsxRuntime.jsxs("div",{style:we,children:[jsxRuntime.jsxs("span",{style:{...N,flex:1,alignSelf:"center"},children:[t.address.slice(0,6),"\u2026",t.address.slice(-4)]}),jsxRuntime.jsx("button",{type:"button",style:te,onClick:t.disconnect,children:"Disconnect"})]}):jsxRuntime.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:6},children:[jsxRuntime.jsx("span",{style:N,children:"Connect a browser or mobile wallet"}),t.connectChoices.length===0?jsxRuntime.jsx("span",{style:N,children:"Wallet connection is not configured for this title."}):t.connectChoices.map(d=>jsxRuntime.jsx("button",{type:"button",style:te,onClick:d.connect,children:d.label},d.key))]}),Object.keys(n).length===0?jsxRuntime.jsxs("span",{style:N,children:["No ",t.networkType," networks configured for this title."]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("div",{style:N,children:"Network"}),jsxRuntime.jsx("select",{style:ye,value:i,onChange:d=>c(d.target.value),children:Object.entries(n).map(([d,S])=>jsxRuntime.jsx("option",{value:d,children:S.DisplayName??d},d))})]}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("div",{style:N,children:"Token"}),jsxRuntime.jsxs("select",{style:ye,value:u,onChange:d=>f(d.target.value),children:[x.length===0&&jsxRuntime.jsx("option",{value:"",children:"\u2014 no depositable tokens \u2014"}),x.map(([d,S])=>jsxRuntime.jsx("option",{value:d,children:S.DisplayName??d},d))]})]}),jsxRuntime.jsxs("div",{style:N,children:["In-game balance: ",jsxRuntime.jsx("b",{children:Z})," ",u]}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("div",{style:N,children:"Amount"}),jsxRuntime.jsx("input",{style:ye,inputMode:"decimal",placeholder:"0.0",value:T,onChange:d=>w(d.target.value)})]}),jsxRuntime.jsxs("div",{style:we,children:[jsxRuntime.jsx("button",{type:"button",style:{...wt,flex:1,opacity:g?.6:1},disabled:g||!E||!D?.ContractAddress,onClick:()=>{!R||!D||O(()=>t.deposit({network:R,binding:D,currencyID:u,amount:T||"0"}));},children:"Deposit"}),jsxRuntime.jsx("button",{type:"button",style:{...te,flex:1,opacity:g?.6:1},disabled:g||!E||!u,onClick:()=>{R&&O(()=>t.withdraw({network:R,networkID:i,currencyID:u,amount:T||"0"}));},children:"Withdraw"})]})]}),I&&jsxRuntime.jsx(ht,{result:I})]})}function ht({result:e}){let t={fontSize:12,borderRadius:8,padding:"8px 10px",background:e.ok?"#1e3a2a":"#3a1e28",color:e.ok?"#8ef0b0":"#f2a0b4",wordBreak:"break-all"};return e.ok?jsxRuntime.jsxs("div",{style:t,children:["\u2713 Done \xB7 tx ",e.onChainTxHash]}):jsxRuntime.jsxs("div",{style:t,children:["\u2715 [",e.stage,"] ",e.error,e.titleTransactionID?` \xB7 already debited (tx ${e.titleTransactionID}) \u2014 retry/confirm, don't re-request`:""]})}var At=103;function Et(e){return (e.ChainID===At?re:j).rpcUrls.default.http[0]}function xt(e){let{client:t,walletConnectProjectId:r,appName:o,onClose:l,style:n}=e,[p,s]=react$1.useState(r??"");react$1.useEffect(()=>{if(r)return;let g=true;return (async()=>{let m=await t.blockchain.getDefinitions();if(!g||!m.ok)return;let I=m.data.Blockchain?.WalletLogin?.WalletConnectProjectId;I&&s(I);})(),()=>{g=false;}},[t,r]);let a=react$1.useMemo(()=>p?(oe({walletConnectProjectId:p,appName:o}),true):false,[p,o]),{address:i,isConnected:c}=react.useAppKitAccount(),{walletProvider:u}=react.useAppKitProvider("solana"),f=c&&i?i:null,T=(g,m)=>ge({connection:new web3_js.Connection(Et(g),"confirmed"),owner:m,programId:g.RewardPoolAddress??"",signTransaction:async I=>{if(!u)throw new Error("Wallet not connected.");return u.signTransaction(I)}});return jsxRuntime.jsx(ve,{client:t,engine:{networkType:"Solana",address:f,connectChoices:a?[{key:"appkit",label:"Connect wallet",connect:()=>{U()?.open();}}]:[],disconnect:()=>{U()?.disconnect("solana");},deposit:async({network:g,binding:m,amount:I})=>{if(!f)return h("deposit-onchain","Wallet not connected.");if(!m.ContractAddress)return h("deposit-onchain","This token cannot be deposited.");if(!g.RewardPoolAddress)return h("deposit-onchain","POOL_NOT_IN_REGISTRY");let W;try{W=viem.parseUnits(I,m.Decimals??9);}catch{return h("deposit-onchain","Invalid amount.")}return Y({client:t,adapter:T(g,f),network:g,mint:m.ContractAddress,amountRaw:W,titleID:t.titleID})},withdraw:async({network:g,networkID:m,currencyID:I,amount:W})=>f?z({client:t,adapter:T(g,f),currencyID:I,networkID:m,walletAddress:f,amount:W}):h("request","Wallet not connected.")},onClose:l,style:n})}
2
- exports.PlatformPoolError=A;exports.SolanaWalletLogin=je;exports.SolanaWalletPanel=xt;exports.createPlatformPoolAdapter=ge;exports.createSolanaWalletConfig=oe;exports.solanaDevnet=re;exports.solanaMainnet=j;exports.useSolanaBridge=Me;
1
+ 'use strict';var appkitAdapterSolana=require('@reown/appkit-adapter-solana'),react=require('@reown/appkit/react'),core=require('@idosgames/core'),viem=require('viem'),react$1=require('react'),jsxRuntime=require('react/jsx-runtime'),web3_js=require('@solana/web3.js'),buffer=require('buffer');var le={id:"5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",name:"Solana",network:"solana-mainnet",nativeCurrency:{name:"Solana",symbol:"SOL",decimals:9},rpcUrls:{default:{http:["https://api.mainnet-beta.solana.com"]}},blockExplorers:{default:{name:"Solscan",url:"https://solscan.io"}},testnet:false,chainNamespace:"solana",caipNetworkId:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"},ke={id:"EtWTRABZaYq6iMfeYKouRu166VU2xqa1",name:"Solana Devnet",network:"solana-devnet",nativeCurrency:{name:"Solana",symbol:"SOL",decimals:9},rpcUrls:{default:{http:["https://api.devnet.solana.com"]}},blockExplorers:{default:{name:"Solscan",url:"https://solscan.io"}},testnet:true,chainNamespace:"solana",caipNetworkId:"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"};var Ge=null;function $e(e){Ge=e;}function Q(){return Ge}var ze=new Map;function xe(e){let{walletConnectProjectId:t,appName:n,appUrl:o,appIcon:a,wallets:r}=e,l=ze.get(t);if(l)return l;let p=e.networks??[le],s=o??(typeof window<"u"?window.location.origin:""),f={name:n??"iDosGames",description:n??"iDosGames game",url:s,icons:a?[a]:[]},d=new appkitAdapterSolana.SolanaAdapter(r?{wallets:r}:{});return $e(react.createAppKit({adapters:[d],networks:p,projectId:t,metadata:f,features:{analytics:false,email:false,socials:false}})),ze.set(t,d),d}function ee(e){return e instanceof viem.BaseError?e.shortMessage:e instanceof Error?e.message:String(e)}function x(e,t,n){return {ok:false,stage:e,error:t,...n}}function v(e,t){return {ok:false,stage:e,error:t}}var Ve="WALLET_USE_SITE_PANEL",Tt=/^[a-z0-9]{8}-preview\.idos\.games$/;function Pt(e=typeof window>"u"?"":window.location.hostname){let t=e.toLowerCase();return Tt.test(t)?true:t!=="localhost"&&t!=="127.0.0.1"?false:globalThis.__IDOS_PREVIEW__!=null}function te(){if(typeof window>"u"||Pt())return false;try{return window.self!==window.top}catch{return true}}function Te(e){return x(e,Ve)}function Pe(e){return v(e,Ve)}async function ce(e){let{client:t,adapter:n,network:o,mint:a,amountRaw:r,titleID:l,category:p}=e;if(te())return Te("deposit-onchain");let s=t.auth.context?.userID;if(!s)return x("deposit-onchain","Not logged in.");if(r<=0n)return x("deposit-onchain","Amount must be positive.");let f;try{f=await n.depositSpl({mint:a,amountRaw:r,userID:s,titleID:l,category:core.normalizeBlockchainCategory(p)});}catch(y){return x("deposit-onchain",ee(y))}let d=await t.blockchain.depositToken(o.NetworkID??"",f);return d.ok?{ok:true,onChainTxHash:f,data:d.data}:x("report",d.error,{onChainTxHash:f})}async function pe(e){let{client:t,adapter:n,currencyID:o,networkID:a,walletAddress:r,amount:l,category:p}=e;if(te())return Te("request");let s=await t.blockchain.requestTokenWithdrawal(o,a,r,l,p);if(!s.ok)return x("request",s.error);let f=s.data.SolanaSignature,d=s.data.TitleTransactionID??void 0;if(!f)return x("request","Withdrawal response carried no Solana signature.",{titleTransactionID:d});let y;try{y=await n.submitWithdrawal(f);}catch(D){return x("withdraw-onchain",ee(D),{titleTransactionID:d})}if(!d)return x("confirm","Missing TitleTransactionID.",{onChainTxHash:y});let h=await t.blockchain.confirmWithdrawal(d,y);return h.ok?{ok:true,onChainTxHash:y,data:s.data}:x("confirm",h.error,{onChainTxHash:y,titleTransactionID:d})}async function de(e){let{client:t,networkID:n,walletAddress:o,signMessage:a}=e;if(te())return Pe("challenge");let r=await t.auth.requestWalletChallenge(o,n);if(!r.ok)return v("challenge",r.error);let l;try{let s=await a(new TextEncoder().encode(r.data.Message));l=qe(s);}catch(s){return v("sign",ee(s))}let p=await t.auth.loginWithWallet(o,n,l);return p.ok?{ok:true,data:p.data}:v("login",p.error)}async function Ce(e){let{client:t,networkID:n,walletAddress:o,signMessage:a}=e;if(te())return Pe("challenge");let r=await t.auth.linkWallet(o,n);if(!r.ok)return v("challenge",r.error);if(!r.data.Challenge)return v("challenge","No challenge was issued.");let l;try{let s=await a(new TextEncoder().encode(r.data.Challenge));l=qe(s);}catch(s){return v("sign",ee(s))}let p=await t.auth.linkWallet(o,n,l);return p.ok?{ok:true,data:p.data}:v("login",p.error)}function qe(e){let t="0x";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}var je="Wallet not connected.";function Dt(e,t,n){let{address:o}=react.useAppKitAccount(),{walletProvider:a}=react.useAppKitProvider("solana"),r=o??null,l=a?.signMessage?.bind(a);return {connected:!!r,account:r,loginWithWallet:(p,s)=>{let f=s??r;return f?l?de({client:e,networkID:p,walletAddress:f,signMessage:l}):Promise.resolve(v("sign","The connected wallet does not support message signing.")):Promise.resolve(v("challenge",je))},depositToken:p=>ce({client:e,adapter:n,titleID:t,...p}),withdrawToken:p=>{let s=p.walletAddress??r;return s?pe({client:e,adapter:n,...p,walletAddress:s}):Promise.resolve(x("request",je))}}}var Et=18e4,Ze=9e4;function Rt(e){try{let n=e?.session?.peer?.metadata?.redirect,o=n?.native||n?.universal;return !o||typeof window>"u"?!1:(window.location.href=o,!0)}catch{return false}}function Je(e,t){return new Promise((n,o)=>{let a=setTimeout(()=>o(new Error("The wallet request timed out.")),t);e.then(r=>{clearTimeout(a),n(r);},r=>{clearTimeout(a),o(r instanceof Error?r:new Error(String(r)));});})}function vt(e){let t="Wallet sign-in failed. Please try again.";return e instanceof Error?/user (rejected|denied|cancelled|canceled)|rejected the request/i.test(e.message)?"Request declined in the wallet.":/timed? ?out/i.test(e.message)?"The wallet did not respond. Open your wallet and try again.":t:t}function Bt(e){let{client:t,networkID:n,onAuthenticated:o,disabled:a,label:r,style:l,autoStart:p,mode:s="login",onLinked:f}=e,{address:d,isConnected:y}=react.useAppKitAccount(),{walletProvider:h}=react.useAppKitProvider("solana"),[D,S]=react$1.useState(false),[A,g]=react$1.useState(null),[W,P]=react$1.useState(false),[O,Y]=react$1.useState(false),z=react$1.useRef(null),Z=react$1.useRef(0),M=react$1.useCallback(()=>{z.current&&clearTimeout(z.current),z.current=null;},[]);react$1.useEffect(()=>M,[M]);let ie=react$1.useRef(false),J=react$1.useCallback(async()=>{let U=++Z.current,R=()=>Z.current===U,V=h?.signMessage?.bind(h);if(!d||!V){g("The connected wallet cannot sign messages."),S(false);return}S(true),g(null);try{if(Y(!0),s==="link"){let F=await Je(Ce({client:t,networkID:n,walletAddress:d,signMessage:V}),Ze);if(!R())return;if(F.ok){f?.(F.data.PlayAccess??null);return}g(F.stage==="sign"?"Signature declined.":core.authErrorText(F.error,"Could not link the wallet."));return}let K=await Je(de({client:t,networkID:n,walletAddress:d,signMessage:V}),Ze);if(!R())return;if(K.ok){o();return}g(K.stage==="sign"?"Signature declined.":core.authErrorText(K.error,"Wallet sign-in failed."));}catch(K){if(!R())return;console.error("[idosgames/wallet] solana sign-in failed:",K),g(vt(K));}finally{R()&&(S(false),Y(false));}},[d,h,t,n,o,s,f]),$=react$1.useCallback(()=>{Rt(h)||Q()?.open();},[h]);react$1.useEffect(()=>{!W||!y||!d||!h||(P(false),M(),J());},[W,y,d,h,J,M]);let L=()=>{if(O){$();return}if(g(null),ie.current=true,y&&d&&h){J();return}let U=Q();if(!U){g("Wallet sign-in is not configured for this title.");return}S(true),P(true),M(),z.current=setTimeout(()=>{P(false),S(false),g("No wallet was connected.");},Et),U.open();};return react$1.useEffect(()=>{!p||ie.current||(ie.current=true,L());},[p]),jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("button",{type:"button",onClick:L,disabled:a,style:{...Ot,...a?{opacity:.6,cursor:"default"}:null,...l},children:O?"Waiting for signature \u2014 tap to open wallet":D?"Check your wallet\u2026":y?r??(s==="link"?"Link wallet":"Sign in with wallet"):"Connect wallet"}),A&&jsxRuntime.jsx("span",{role:"alert",style:_t,children:A})]})}var Ot={padding:"11px 16px",borderRadius:"8px",border:"none",background:"#4c3fa8",color:"#fff",font:"inherit",fontWeight:600,cursor:"pointer"},_t={display:"block",marginTop:"6px",color:"#ff9b9b",fontSize:"13px",textAlign:"center"};var Gt="e000c6afc62f69cc",$t="b59a5e563e7306ba",zt="d668e18c1bdc33f1",ye=new web3_js.PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"),Vt="1nc1nerator11111111111111111111111111111111",Qe=177,qt=3e5,tt=40,nt=4,ot=tt+32*nt,jt=ot+8,B=class extends Error{constructor(n,o){super(o);this.code=n;this.name="PlatformPoolError";}code};function me(e){let t=(e??"").replace(/^0x/i,""),n=new Uint8Array(t.length>>1);for(let o=0;o<n.length;o++)n[o]=parseInt(t.slice(o*2,o*2+2),16);return n}function ne(e){let t=buffer.Buffer.alloc(8);return t.writeBigUInt64LE(BigInt(e||0)),t}function Yt(e){let t=buffer.Buffer.alloc(8);return t.writeBigInt64LE(BigInt(e||0)),t}function re(e){let t=buffer.Buffer.from(e??"","utf8"),n=buffer.Buffer.alloc(4);return n.writeUInt32LE(t.length),buffer.Buffer.concat([n,t])}async function et(e){let t=await globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(e??""));return new Uint8Array(t)}function rt(e,t,n){return j(e,buffer.Buffer.from("title_balance"),buffer.Buffer.from(t),n.toBuffer())}function Zt(e){return buffer.Buffer.concat([buffer.Buffer.from(Gt,"hex"),ne(e.amountRaw),re(e.userID),re(e.titleID),re(e.category),buffer.Buffer.from(e.titleHash)])}function Jt(e,t){let n=e.Splits??[],o=buffer.Buffer.alloc(4);return o.writeUInt32LE(n.length),buffer.Buffer.concat([buffer.Buffer.from(e.Domain==="SPL_DEV"?zt:$t,"hex"),ne(e.Amount),ne(e.BurnAmount),ne(e.Nonce),Yt(e.ExpiresAt),o,...n.map(a=>buffer.Buffer.concat([buffer.Buffer.from(new web3_js.PublicKey(a.To??"").toBytes()),ne(a.Amount)])),re(e.UserID),re(e.TitleID),re(e.Category),buffer.Buffer.from(t)])}function oe(e,t,n){return web3_js.PublicKey.findProgramAddressSync([t.toBuffer(),n.toBuffer(),e.toBuffer()],ye)[0]}function Xt(e,t,n,o,a){return new web3_js.TransactionInstruction({programId:ye,keys:[{pubkey:e,isSigner:true,isWritable:true},{pubkey:t,isSigner:false,isWritable:true},{pubkey:n,isSigner:false,isWritable:false},{pubkey:o,isSigner:false,isWritable:false},{pubkey:web3_js.SystemProgram.programId,isSigner:false,isWritable:false},{pubkey:a,isSigner:false,isWritable:false}],data:buffer.Buffer.from([1])})}function j(e,...t){return web3_js.PublicKey.findProgramAddressSync(t,e)[0]}function Qt(e){let{programId:t,user:n,mint:o,tokenProgram:a}=e,r=j(t,buffer.Buffer.from("vault"));return new web3_js.TransactionInstruction({programId:t,keys:[{pubkey:j(t,buffer.Buffer.from("config")),isSigner:false,isWritable:false},{pubkey:r,isSigner:false,isWritable:true},{pubkey:o,isSigner:false,isWritable:false},{pubkey:n,isSigner:true,isWritable:true},{pubkey:oe(o,n,a),isSigner:false,isWritable:true},{pubkey:oe(o,r,a),isSigner:false,isWritable:true},{pubkey:a,isSigner:false,isWritable:false},{pubkey:ye,isSigner:false,isWritable:false},{pubkey:web3_js.SystemProgram.programId,isSigner:false,isWritable:false},{pubkey:rt(t,e.titleHash,o),isSigner:false,isWritable:true}],data:Zt(e)})}function en(e){let{sig:t,payer:n,tokenProgram:o,titleHash:a}=e,r=new web3_js.PublicKey(t.ProgramID??""),l=new web3_js.PublicKey(t.Mint??""),p=new web3_js.PublicKey(t.WalletAddress??""),s=j(r,buffer.Buffer.from("vault")),f=new web3_js.PublicKey(Vt),d=(t.Splits??[]).map(A=>new web3_js.PublicKey(A.To??"")),y=d.map(A=>oe(l,A,o)),h=web3_js.Ed25519Program.createInstructionWithPublicKey({publicKey:me(t.Ed25519PublicKey),message:me(t.Ed25519Message),signature:me(t.SignatureHex)}),D=d.map((A,g)=>Xt(n,y[g],A,l,o)),S=new web3_js.TransactionInstruction({programId:r,keys:[{pubkey:j(r,buffer.Buffer.from("config")),isSigner:false,isWritable:false},{pubkey:n,isSigner:true,isWritable:true},{pubkey:s,isSigner:false,isWritable:true},{pubkey:j(r,buffer.Buffer.from("nonce"),ne(t.Nonce)),isSigner:false,isWritable:true},{pubkey:l,isSigner:false,isWritable:false},{pubkey:p,isSigner:false,isWritable:false},{pubkey:oe(l,s,o),isSigner:false,isWritable:true},{pubkey:oe(l,p,o),isSigner:false,isWritable:true},{pubkey:f,isSigner:false,isWritable:false},{pubkey:oe(l,f,o),isSigner:false,isWritable:true},{pubkey:web3_js.SYSVAR_INSTRUCTIONS_PUBKEY,isSigner:false,isWritable:false},{pubkey:o,isSigner:false,isWritable:false},{pubkey:ye,isSigner:false,isWritable:false},{pubkey:web3_js.SystemProgram.programId,isSigner:false,isWritable:false},{pubkey:rt(r,a,l),isSigner:false,isWritable:true},...y.map(A=>({pubkey:A,isSigner:false,isWritable:true}))],data:Jt(t,a)});return [h,...D,S]}async function tn(e,t,n){let o=async r=>{let l=(await e.getSignatureStatuses([t],{searchTransactionHistory:r})).value[0];if(l?.err)throw new B("TRANSACTION_FAILED",`transaction ${t} failed: ${JSON.stringify(l.err)}`);return l},a=r=>r?.confirmationStatus==="confirmed"||r?.confirmationStatus==="finalized";for(let r=1;;r++){await new Promise(s=>setTimeout(s,nn));let l=null;try{l=await o(!1);}catch(s){if(s instanceof B)throw s}if(a(l))return;if(!(l||r%on!==0||await e.getBlockHeight("confirmed").catch(()=>-1)<=n)){if(a(await o(true).catch(()=>null)))return;throw new B("TRANSACTION_EXPIRED",`transaction ${t} expired: block height exceeded`)}}}var nn=2e3,on=5;function Ee(e){let{connection:t,signTransaction:n}=e;async function o(r){let l=await t.getAccountInfo(r);if(!l)throw new B("MINT_NOT_FOUND",`mint ${r.toBase58()} not found`);return l.owner}async function a(r,l){let{blockhash:p,lastValidBlockHeight:s}=await t.getLatestBlockhash("confirmed"),f=new web3_js.Transaction;f.feePayer=r,f.recentBlockhash=p,f.add(...l);let d=await n(f),y=await t.sendRawTransaction(d.serialize());return await tn(t,y,s),y}return {async depositSpl({mint:r,amountRaw:l,userID:p,titleID:s,category:f}){let d=new web3_js.PublicKey(e.owner),y=new web3_js.PublicKey(r),h=await o(y);return a(d,[Qt({programId:new web3_js.PublicKey(e.programId),user:d,mint:y,tokenProgram:h,amountRaw:l,userID:p,titleID:s,category:f,titleHash:await et(s)})])},async submitWithdrawal(r){if(!r.ProgramID||!r.Mint||!r.WalletAddress)throw new B("BAD_VOUCHER","the voucher has no program, mint or wallet");let l=new web3_js.PublicKey(e.owner),p=new web3_js.PublicKey(r.ProgramID),s=await t.getAccountInfo(j(p,buffer.Buffer.from("config")));if(!s)throw new B("POOL_NOT_ON_THIS_CLUSTER","the pool's config account is not on this cluster");if(s.data.length!==Qe)throw new B("POOL_NOT_MIGRATED",`config is ${s.data.length} bytes, expected ${Qe} (migrate_config not run)`);let f=buffer.Buffer.from(s.data);if(f[jt]===1)throw new B("POOL_PAUSED","pool withdrawals are paused");let d=f.readBigUInt64LE(ot);if(d!==BigInt(r.SignatureEpoch||0))throw new B("VOUCHER_REVOKED",`signature epoch mismatch: voucher ${r.SignatureEpoch}, on-chain ${d}`);let y=buffer.Buffer.from(me(r.Ed25519PublicKey)),h=false;for(let S=0;S<nt;S++){let A=tt+S*32;y.equals(f.subarray(A,A+32))&&(h=true);}if(!h)throw new B("SIGNER_NOT_TRUSTED","the voucher's signer is not in the pool's server_pubkeys");let D=await o(new web3_js.PublicKey(r.Mint));return a(l,[web3_js.ComputeBudgetProgram.setComputeUnitLimit({units:qt}),...en({sig:r,payer:l,tokenProgram:D,titleHash:await et(r.TitleID??"")})])}}}var b=(e,t)=>`var(--idos-ui-${e}, ${t})`,i={panel:b("panel","#2c3480"),panelDeep:b("panel-deep","#1d2360"),panelEdge:b("panel-edge","#4f5bc9"),text:b("text","#ffffff"),textDim:b("text-dim","#aeb6f0"),gold:b("gold","#ffd24a"),goldDeep:b("gold-deep","#e89a12"),green:b("green","#59d35b"),greenDeep:b("green-deep","#2b9936"),blue:b("blue","#4fb1ff"),blueDeep:b("blue-deep","#2276d6"),red:b("red","#ff5a5a"),redDeep:b("red-deep","#b83232"),onGreen:b("on-green","#ffffff"),onBlue:b("on-blue","#ffffff"),onGold:b("on-gold","#ffffff"),textOutline:b("text-outline","0 2px 0 rgba(0,0,0,.45), 0 0 1px rgba(0,0,0,.6)"),well:b("well","rgba(8, 10, 40, 0.6)"),wellSoft:b("well-soft","rgba(0, 0, 0, 0.3)"),wellShadow:b("well-shadow","inset 0 2px 4px rgba(0, 0, 0, 0.4)"),edge:b("edge","rgba(0, 0, 0, 0.35)"),line:b("line","rgba(255, 255, 255, 0.2)"),panelShadow:b("panel-shadow","0 6px 0 rgba(4, 6, 30, 0.55), inset 0 2px 0 rgba(255, 255, 255, 0.12)"),radius:b("radius","18px"),buttonRadius:b("button-radius","14px"),font:b("font","'Baloo 2', 'Nunito', 'Trebuchet MS', system-ui, sans-serif"),fast:b("fast","120ms")},it={green:[i.green,i.greenDeep,i.onGreen],blue:[i.blue,i.blueDeep,i.onBlue],gold:[i.gold,i.goldDeep,i.onGold],red:[i.red,i.redDeep,"#ffffff"]},I={color:i.text,fontWeight:800,textShadow:i.textOutline,letterSpacing:.2},Re={boxSizing:"border-box",background:`linear-gradient(180deg, ${i.panel} 0%, ${i.panelDeep} 100%)`,border:`2px solid ${i.panelEdge}`,borderRadius:i.radius,boxShadow:i.panelShadow},G={boxSizing:"border-box",background:i.well,border:`2px solid ${i.panelEdge}`,boxShadow:i.wellShadow,borderRadius:14};function ue(e,t=false,n="md"){let[o,a,r]=t?["#8e95b8","#5b6187","#ffffff"]:it[e];return {...I,color:r,boxSizing:"border-box",fontFamily:i.font,fontSize:n==="sm"?13:n==="lg"?18:16,border:"none",borderRadius:i.buttonRadius,padding:n==="sm"?"6px 12px":n==="lg"?"13px 22px":"10px 18px",minHeight:n==="sm"?34:n==="lg"?52:44,cursor:t?"default":"pointer",background:`linear-gradient(180deg, ${o} 0%, ${a} 100%)`,boxShadow:`0 4px 0 ${i.edge}, inset 0 2px 0 rgba(255,255,255,.35)`,opacity:t?.75:1,display:"inline-flex",alignItems:"center",justifyContent:"center",gap:8}}function st(e){let[t,n,o]=it[e];return {background:`linear-gradient(180deg, ${t} 0%, ${n} 100%)`,color:o,borderRadius:16,boxShadow:`0 4px 0 ${i.edge}, inset 0 2px 0 rgba(255,255,255,.3)`}}var N={...I,fontSize:13,color:i.textDim},rn=["ru","kk","uk","be","ky","uz","tg"];function an(){if(typeof navigator>"u")return false;let e=(navigator.language||"").toLowerCase();return rn.some(t=>e.startsWith(t))}var at={title:"Wallet",topUpTitle:"Top up to buy",connectHint:"Connect a wallet to deposit and withdraw",connect:"Connect wallet",notConfigured:"Wallet connection is not set up for this app.",disconnect:"Disconnect",balance:"In-game balance",deposit:"Deposit",withdraw:"Withdraw",network:"Network",token:"Token",amount:"Amount",max:"MAX",minWithdraw:"Minimum to withdraw: {n}",noNetworks:"Crypto is not set up for this app yet.",noTokens:"No tokens on this network.",depositing:"Confirm in your wallet\u2026",withdrawing:"Withdrawing\u2026",confirming:"Waiting for the network to confirm\u2026",loading:"Loading\u2026",doneDeposit:"Deposited \u2014 the balance is updated.",doneWithdraw:"Sent to your wallet.",topUpNeed:"This purchase needs",topUpMore:"more",topUpHint:"Deposit it from your wallet \u2014 the purchase completes by itself once it is credited.",topUpCannot:"{name} cannot be deposited here.",depositAmount:"Deposit {amount} {name}",failed:"Did not go through",debited:"The amount is already debited \u2014 retry this withdrawal, do not request a new one.",tx:"Transaction",backed:"Crypto (withdrawable)",unbacked:"IOU (not backed yet)",total:"Total",iouHint:"IOUs spend in the app like crypto, but you can withdraw only the backed part; the developer backs IOUs later.",backedHint:"All of it is real crypto and can be withdrawn."},sn={title:"\u041A\u043E\u0448\u0435\u043B\u0451\u043A",topUpTitle:"\u041F\u043E\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 \u0434\u043B\u044F \u043F\u043E\u043A\u0443\u043F\u043A\u0438",connectHint:"\u041F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u0435 \u043A\u043E\u0448\u0435\u043B\u0451\u043A, \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u043F\u043E\u043B\u043D\u044F\u0442\u044C \u0438 \u0432\u044B\u0432\u043E\u0434\u0438\u0442\u044C",connect:"\u041F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043A\u043E\u0448\u0435\u043B\u0451\u043A",notConfigured:"\u041F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u043A\u043E\u0448\u0435\u043B\u044C\u043A\u0430 \u0434\u043B\u044F \u044D\u0442\u043E\u0433\u043E \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043D\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043D\u043E.",disconnect:"\u041E\u0442\u043A\u043B\u044E\u0447\u0438\u0442\u044C",balance:"\u0411\u0430\u043B\u0430\u043D\u0441 \u0432 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0438",deposit:"\u041F\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u044C",withdraw:"\u0412\u044B\u0432\u0435\u0441\u0442\u0438",network:"\u0421\u0435\u0442\u044C",token:"\u0422\u043E\u043A\u0435\u043D",amount:"\u0421\u0443\u043C\u043C\u0430",max:"\u0412\u0421\u0401",minWithdraw:"\u041C\u0438\u043D\u0438\u043C\u0443\u043C \u0434\u043B\u044F \u0432\u044B\u0432\u043E\u0434\u0430: {n}",noNetworks:"\u041A\u0440\u0438\u043F\u0442\u0430 \u0434\u043B\u044F \u044D\u0442\u043E\u0433\u043E \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0435\u0449\u0451 \u043D\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043D\u0430.",noTokens:"\u0412 \u044D\u0442\u043E\u0439 \u0441\u0435\u0442\u0438 \u043D\u0435\u0442 \u0442\u043E\u043A\u0435\u043D\u043E\u0432.",depositing:"\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0432 \u043A\u043E\u0448\u0435\u043B\u044C\u043A\u0435\u2026",withdrawing:"\u0412\u044B\u0432\u043E\u0434\u0438\u043C\u2026",confirming:"\u0416\u0434\u0451\u043C \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F \u0441\u0435\u0442\u0438\u2026",loading:"\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430\u2026",doneDeposit:"\u041F\u043E\u043F\u043E\u043B\u043D\u0435\u043D\u043E \u2014 \u0431\u0430\u043B\u0430\u043D\u0441 \u043E\u0431\u043D\u043E\u0432\u043B\u0451\u043D.",doneWithdraw:"\u041E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E \u043D\u0430 \u0432\u0430\u0448 \u043A\u043E\u0448\u0435\u043B\u0451\u043A.",topUpNeed:"\u0414\u043B\u044F \u043F\u043E\u043A\u0443\u043F\u043A\u0438 \u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442",topUpMore:"",topUpHint:"\u041F\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u0441 \u043A\u043E\u0448\u0435\u043B\u044C\u043A\u0430 \u2014 \u043F\u043E\u043A\u0443\u043F\u043A\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044F \u0441\u0430\u043C\u0430, \u043A\u0430\u043A \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 \u0437\u0430\u0447\u0438\u0441\u043B\u0438\u0442\u0441\u044F.",topUpCannot:"{name} \u0437\u0434\u0435\u0441\u044C \u043F\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043D\u0435\u043B\u044C\u0437\u044F.",depositAmount:"\u041F\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043D\u0430 {amount} {name}",failed:"\u041D\u0435 \u043F\u0440\u043E\u0448\u043B\u043E",debited:"\u0421\u0443\u043C\u043C\u0430 \u0443\u0436\u0435 \u0441\u043F\u0438\u0441\u0430\u043D\u0430 \u2014 \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 \u044D\u0442\u043E\u0442 \u0432\u044B\u0432\u043E\u0434, \u043D\u043E\u0432\u044B\u0439 \u043D\u0435 \u0437\u0430\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0439\u0442\u0435.",tx:"\u0422\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u044F",backed:"\u041A\u0440\u0438\u043F\u0442\u0430 (\u043C\u043E\u0436\u043D\u043E \u0432\u044B\u0432\u0435\u0441\u0442\u0438)",unbacked:"\u0420\u0430\u0441\u043F\u0438\u0441\u043A\u0438 (\u043F\u043E\u043A\u0430 \u043D\u0435 \u043E\u0431\u0435\u0441\u043F\u0435\u0447\u0435\u043D\u044B)",total:"\u0412\u0441\u0435\u0433\u043E",iouHint:"\u0420\u0430\u0441\u043F\u0438\u0441\u043A\u0438 \u0442\u0440\u0430\u0442\u044F\u0442\u0441\u044F \u0432 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0438 \u043A\u0430\u043A \u043A\u0440\u0438\u043F\u0442\u0430, \u043D\u043E \u0432\u044B\u0432\u0435\u0441\u0442\u0438 \u043C\u043E\u0436\u043D\u043E \u0442\u043E\u043B\u044C\u043A\u043E \u043E\u0431\u0435\u0441\u043F\u0435\u0447\u0435\u043D\u043D\u0443\u044E \u0447\u0430\u0441\u0442\u044C; \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A \u043E\u0431\u0435\u0441\u043F\u0435\u0447\u0438\u0442 \u0440\u0430\u0441\u043F\u0438\u0441\u043A\u0438 \u043F\u043E\u0437\u0436\u0435.",backedHint:"\u042D\u0442\u043E \u043D\u0430\u0441\u0442\u043E\u044F\u0449\u0430\u044F \u043A\u0440\u0438\u043F\u0442\u0430, \u0435\u0451 \u043C\u043E\u0436\u043D\u043E \u0432\u044B\u0432\u0435\u0441\u0442\u0438 \u0446\u0435\u043B\u0438\u043A\u043E\u043C."};function u(e,t){let n=(an()?sn:at)[e]??at[e];for(let[o,a]of Object.entries(t??{}))n=n.replace(`{${o}}`,String(a));return n}var pn=/^(Not enough confirmations|Transaction not found on chain)/,dn=8,un=5e3;function fn(e,t){let n=Math.max(0,Math.floor(t||0)),[o="0",a=""]=e.split(".");if(a.length<=n)return e;let r=a.slice(0,n),l=BigInt(o+r)+(/^0*$/.test(a.slice(n))?BigInt(0):BigInt(1));if(n===0)return l.toString();let p=l.toString().padStart(n+1,"0");return `${p.slice(0,-n)}.${p.slice(-n)}`.replace(/\.?0+$/,"")}function Oe(e,t=6){let n=Number(e);return Number.isFinite(n)?n.toLocaleString("en-US",{maximumFractionDigits:Math.max(0,t)}).replace(/,/g," "):String(e)}var pt=e=>e.length>14?`${e.slice(0,6)}\u2026${e.slice(-4)}`:e,lt=e=>/^\d+(\.\d+)?$/.test(e)&&Number(e)>0;function dt({client:e,engine:t,onClose:n,style:o,topUp:a}){let[,r]=react$1.useReducer(m=>m+1,0),[l,p]=react$1.useState(false),[s,f]=react$1.useState({}),[d,y]=react$1.useState({}),[h,D]=react$1.useState("deposit"),[S,A]=react$1.useState(""),[g,W]=react$1.useState(""),[P,O]=react$1.useState(""),[Y,z]=react$1.useState(false),[Z,M]=react$1.useState(null),[ie,J]=react$1.useState(false);react$1.useEffect(()=>{let m=true;return (async()=>{let[C]=await Promise.all([e.blockchain.getDefinitions(),e.cache.ensureState(["InventoryV2","Blockchain"])]);if(!m||(p(true),!C.ok))return;let T={};for(let[H,q]of Object.entries(C.data.Blockchain?.Networks??{}))q.Type===t.networkType&&(T[H]=q);f(T);let X=C.data.CryptoCurrencies??{};y(X);let se=a?X[a.currencyID]?.Networks?.find(H=>!!H.NetworkID&&!!T[H.NetworkID]&&!!H.ContractAddress&&H.DepositsEnabled!==false&&T[H.NetworkID]?.DepositsEnabled!==false)?.NetworkID:null;A(se??Object.keys(T)[0]??"");})(),()=>{m=false;}},[e,t.networkType]),react$1.useEffect(()=>e.on("user:anyUpdated",r),[e]);let $=react$1.useMemo(()=>Object.entries(d).filter(([,m])=>m.Networks?.some(C=>C.NetworkID===S&&!!C.ContractAddress)),[d,S]);react$1.useEffect(()=>{let m=$[0]?.[0]??"";W(C=>a?a.currencyID:$.some(([T])=>T===C)?C:m);},[$,a]);let L=S?s[S]:void 0,U=g?d[g]:void 0,R=U?.Networks?.find(m=>m.NetworkID===S),V=g?e.data.user.getCryptoCurrencyAmount(g):"0",K=U?.DisplayName??g,F=g?U?.UnbackedRewardCurrencyID||`${g}_IOU`:"",ut=F&&Number(e.data.user.state?.InventoryV2?.VirtualCurrencies?.[F]?.Amount??0)||0,ft=!!F&&e.data.user.state?.InventoryV2?.VirtualCurrencies?.[F]!=null,_e=U?.DisplayDecimals??6,fe=!!t.address,Le=!!a&&!!R?.ContractAddress&&g===a.currencyID,we=a&&R?fn(a.amount,R.Decimals??18):"",he=a?d[a.currencyID]?.DisplayName??a.currencyID:"",Ue=Number(R?.MinWithdraw??0);async function be(m,C){z(true),M(null);try{let T=await C();return M({tab:m,res:T}),T.ok&&O(""),T}finally{z(false);}}async function Ke(m){let C=await He();if(!C)return x("approve",u("noNetworks"));let T=await t.deposit({...m,network:C});if(T.ok||T.stage!=="report"||!T.onChainTxHash)return T;let X=T.onChainTxHash,se=T.error;J(true);try{for(let H=1;H<=dn&&pn.test(se);H++){await new Promise(bt=>setTimeout(bt,un));let q=await e.blockchain.depositToken(S,X);if(q.ok)return {ok:!0,onChainTxHash:X,data:q.data};if(/^Transaction hash already used/.test(q.error))return await e.cache.ensureState(["InventoryV2"],{force:!0}),{ok:!0,onChainTxHash:X,data:null};se=q.error;}}finally{J(false);}return {...T,error:se}}async function He(){let m=await e.blockchain.getDefinitions({forceRefresh:true});return m.ok?m.data.Blockchain?.Networks?.[S]??null:null}async function gt(){let m=await He();return m?t.withdraw({network:m,networkID:S,currencyID:g,amount:P}):x("request",u("noNetworks"))}let Se=ie?u("confirming"):h==="withdraw"&&!a?u("withdrawing"):u("depositing"),mt=fe?jsxRuntime.jsxs("div",{style:{...G,display:"flex",alignItems:"center",gap:10,padding:"8px 8px 8px 12px"},children:[jsxRuntime.jsx("span",{style:yn,"aria-hidden":true}),jsxRuntime.jsxs("div",{style:{display:"grid",flex:1,minWidth:0},children:[jsxRuntime.jsx("span",{style:{...I,fontSize:15,fontFamily:"ui-monospace, Consolas, monospace"},children:pt(t.address)}),L?jsxRuntime.jsx("span",{style:{...N,fontSize:12},children:L.DisplayName??S}):null]}),jsxRuntime.jsx("button",{type:"button",className:"idos-press",style:wn,onClick:t.disconnect,children:u("disconnect")})]}):jsxRuntime.jsxs("div",{style:{display:"grid",gap:8},children:[jsxRuntime.jsx("span",{style:N,children:u("connectHint")}),t.connectChoices.length===0?jsxRuntime.jsx("div",{style:{...G,padding:"10px 12px",...N},children:u("notConfigured")}):t.connectChoices.length===1?jsxRuntime.jsx("button",{type:"button",className:"idos-press",style:{...ue("blue",false,"lg"),width:"100%"},onClick:t.connectChoices[0].connect,children:u("connect")}):t.connectChoices.map(m=>jsxRuntime.jsxs("button",{type:"button",className:"idos-press",style:hn,onClick:m.connect,children:[jsxRuntime.jsx("span",{style:{flex:1,textAlign:"left"},children:m.label}),jsxRuntime.jsx("span",{"aria-hidden":true,style:{color:i.textDim},children:"\u203A"})]},m.key))]}),Me=g?jsxRuntime.jsx(xn,{icon:jsxRuntime.jsx(kn,{assets:U?.AssetPaths,name:K}),name:K,backed:Number(V)||0,unbacked:ut,hasIou:ft,decimals:_e}):null,yt=jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[Object.keys(s).length>1?jsxRuntime.jsx(ct,{caption:u("network"),value:S,onChange:A,options:Object.entries(s).map(([m,C])=>[m,C.DisplayName??m])}):null,$.length===0?jsxRuntime.jsx("div",{style:{...G,padding:"10px 12px",...N},children:u("noTokens")}):$.length>1?jsxRuntime.jsx(ct,{caption:u("token"),value:g,onChange:W,options:$.map(([m,C])=>[m,C.DisplayName??m])}):null]}),wt=jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(Tn,{value:h,onChange:m=>{D(m),M(null),O("");}}),yt,jsxRuntime.jsxs("div",{style:{display:"grid",gap:6},children:[jsxRuntime.jsx("span",{style:N,children:u("amount")}),jsxRuntime.jsxs("div",{style:{...G,display:"flex",alignItems:"center",gap:8,padding:"4px 6px 4px 14px"},children:[jsxRuntime.jsx("input",{style:Sn,inputMode:"decimal",placeholder:"0.0",value:P,onChange:m=>O(m.target.value.replace(",","."))}),jsxRuntime.jsx("span",{style:{...N,fontSize:14},children:K}),h==="withdraw"&&Number(V)>0?jsxRuntime.jsx("button",{type:"button",className:"idos-press",style:ue("gold",false,"sm"),onClick:()=>O(String(V)),children:u("max")}):null]}),h==="withdraw"&&Ue>0?jsxRuntime.jsx("span",{style:{...N,fontSize:12},children:u("minWithdraw",{n:Oe(Ue,_e)})}):null]}),h==="deposit"?jsxRuntime.jsx(Be,{tone:"green",busy:Y,busyText:Se,disabled:!fe||!R?.ContractAddress||!lt(P),onClick:()=>{!L||!R||be("deposit",()=>Ke({network:L,binding:R,currencyID:g,amount:P}));},children:u("deposit")}):jsxRuntime.jsx(Be,{tone:"blue",busy:Y,busyText:Se,disabled:!fe||!g||!lt(P),onClick:()=>{L&&be("withdraw",()=>gt());},children:u("withdraw")})]}),ht=a?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{style:{...st("gold"),padding:"12px 14px",display:"grid",gap:4},children:Le?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{style:{...I,color:"inherit",fontSize:13,opacity:.9},children:u("topUpNeed")}),jsxRuntime.jsxs("span",{style:{...I,color:"inherit",fontSize:24,lineHeight:1.1},children:[we," ",he," ",u("topUpMore")]}),jsxRuntime.jsx("span",{style:{fontSize:13,fontWeight:600,opacity:.95},children:u("topUpHint")})]}):jsxRuntime.jsx("span",{style:{...I,color:"inherit",fontSize:15},children:l?u("topUpCannot",{name:he}):u("loading")})}),Me,jsxRuntime.jsx(Be,{tone:"green",busy:Y,busyText:Se,disabled:!fe||!Le,onClick:()=>{!L||!R||be("deposit",()=>Ke({network:L,binding:R,currencyID:g,amount:we})).then(m=>{m.ok&&a.onDone(true);});},children:u("depositAmount",{amount:we,name:he})})]}):null,Fe=!!n;return jsxRuntime.jsxs("div",{style:{...mn,...Fe?{...Re,padding:16,width:360,maxWidth:"100%",maxHeight:"80vh",overflow:"auto"}:{},...o},children:[jsxRuntime.jsx("style",{children:gn}),Fe?jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[jsxRuntime.jsx("span",{style:{...I,fontSize:20},children:a?u("topUpTitle"):u("title")}),jsxRuntime.jsx("button",{type:"button",className:"idos-press",style:bn,onClick:n,"aria-label":"\u2715",children:"\u2715"})]}):null,mt,l?Object.keys(s).length===0?jsxRuntime.jsx("div",{style:{...G,padding:"12px 14px",...N},children:u("noNetworks")}):a?ht:jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[Me,wt]}):jsxRuntime.jsx("div",{style:{...N,textAlign:"center",padding:12},children:u("loading")}),Z?jsxRuntime.jsx(Pn,{tab:Z.tab,result:Z.res}):null]})}var gn="@keyframes idosw-spin { to { transform: rotate(360deg) } }",mn={pointerEvents:"auto",color:i.text,fontFamily:i.font,display:"flex",flexDirection:"column",gap:12,boxSizing:"border-box",width:"100%",minWidth:0,maxWidth:"100%"},yn={width:10,height:10,borderRadius:"50%",background:i.green,boxShadow:`0 0 0 3px color-mix(in srgb, ${i.green} 30%, transparent)`,flex:"none"},wn={...I,fontFamily:i.font,fontSize:13,color:i.textDim,background:"transparent",border:`2px solid ${i.line}`,borderRadius:10,padding:"5px 10px",cursor:"pointer"},hn={...G,...I,fontFamily:i.font,fontSize:15,display:"flex",alignItems:"center",gap:10,padding:"10px 12px",cursor:"pointer",width:"100%"},bn={...ue("red",false,"sm"),width:36,minHeight:36,padding:0,borderRadius:"50%"},Sn={...I,fontFamily:i.font,fontSize:22,flex:1,minWidth:0,background:"transparent",border:"none",outline:"none",padding:"6px 0"};function kn({assets:e,name:t}){let n=e?.Default||e?.Icon||"",o={width:40,height:40,borderRadius:"50%",flex:"none",display:"grid",placeItems:"center",background:`linear-gradient(180deg, ${i.gold}, ${i.goldDeep})`,boxShadow:`0 3px 0 ${i.edge}`,overflow:"hidden",fontSize:22};return /^(https?:)?\/\/|^\//.test(n)?jsxRuntime.jsx("span",{style:o,children:jsxRuntime.jsx("img",{src:n,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}})}):jsxRuntime.jsx("span",{style:{...o,...I,fontSize:20},"aria-hidden":true,children:(t.trim()[0]??"?").toUpperCase()})}function xn({icon:e,name:t,backed:n,unbacked:o,hasIou:a,decimals:r}){let[l,p]=react$1.useState(false),s=(f,d,y=false)=>jsxRuntime.jsxs("div",{style:{display:"flex",justifyContent:"space-between",gap:16},children:[jsxRuntime.jsx("span",{style:{...N,fontSize:13},children:f}),jsxRuntime.jsx("span",{style:{...I,fontSize:14,color:y?i.textDim:i.text},children:Oe(d,r)})]});return jsxRuntime.jsxs("div",{style:{position:"relative"},onMouseEnter:()=>p(true),onMouseLeave:()=>p(false),children:[jsxRuntime.jsxs("button",{type:"button","aria-expanded":l,onClick:()=>p(f=>!f),onBlur:()=>p(false),style:{...G,display:"flex",alignItems:"center",gap:12,padding:"10px 14px",width:"100%",cursor:"pointer",font:"inherit",textAlign:"left"},children:[e,jsxRuntime.jsxs("span",{style:{display:"grid",minWidth:0,flex:1},children:[jsxRuntime.jsx("span",{style:{...N,fontSize:12},children:u("balance")}),jsxRuntime.jsxs("span",{style:{...I,fontSize:22,lineHeight:1.1},children:[Oe(n+o,r)," ",jsxRuntime.jsx("span",{style:{fontSize:15,color:i.textDim},children:t})]})]}),jsxRuntime.jsx("span",{"aria-hidden":true,style:{...N,fontSize:16},children:"\u24D8"})]}),l?jsxRuntime.jsxs("div",{role:"tooltip",style:{...Re,position:"absolute",left:0,right:0,top:"calc(100% + 6px)",zIndex:5,padding:"10px 12px",display:"grid",gap:6},children:[s(u("backed"),n),a?s(u("unbacked"),o,o===0):null,jsxRuntime.jsx("div",{style:{height:1,background:i.line}}),s(u("total"),n+o),jsxRuntime.jsx("span",{style:{fontSize:12,color:i.textDim,lineHeight:1.35},children:a?u("iouHint"):u("backedHint")})]}):null]})}function Tn({value:e,onChange:t}){let n=[["deposit",u("deposit")],["withdraw",u("withdraw")]];return jsxRuntime.jsx("div",{role:"tablist",style:{display:"flex",gap:6,padding:4,borderRadius:16,background:i.wellSoft},children:n.map(([o,a])=>{let r=o===e;return jsxRuntime.jsx("button",{role:"tab","aria-selected":r,type:"button",className:"idos-press",onClick:()=>!r&&t(o),style:{...I,fontFamily:i.font,fontSize:15,flex:1,border:"none",borderRadius:12,padding:"9px 14px",cursor:"pointer",color:r?i.onBlue:i.textDim,background:r?`linear-gradient(180deg, ${i.blue}, ${i.blueDeep})`:"transparent",boxShadow:r?`0 3px 0 ${i.edge}, inset 0 2px 0 rgba(255,255,255,.3)`:"none",transition:`background ${i.fast} ease`},children:a},o)})})}function ct({caption:e,value:t,onChange:n,options:o}){return jsxRuntime.jsxs("label",{style:{display:"grid",gap:6},children:[jsxRuntime.jsx("span",{style:N,children:e}),jsxRuntime.jsxs("span",{style:{position:"relative",display:"block"},children:[jsxRuntime.jsx("select",{value:t,onChange:a=>n(a.target.value),style:{...G,...I,fontFamily:i.font,fontSize:15,width:"100%",padding:"10px 36px 10px 12px",appearance:"none",WebkitAppearance:"none",cursor:"pointer",outline:"none"},children:o.map(([a,r])=>jsxRuntime.jsx("option",{value:a,style:{color:"#111"},children:r},a))}),jsxRuntime.jsx("span",{"aria-hidden":true,style:{position:"absolute",right:14,top:"50%",transform:"translateY(-50%)",color:i.textDim,pointerEvents:"none"},children:"\u25BE"})]})]})}function Be({tone:e,busy:t,busyText:n,disabled:o,onClick:a,children:r}){return jsxRuntime.jsx("button",{type:"button",className:"idos-press",disabled:o||t,onClick:a,style:{...ue(e,o&&!t,"lg"),width:"100%"},children:t?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{"aria-hidden":true,style:{width:18,height:18,borderRadius:"50%",border:"3px solid rgba(255,255,255,.35)",borderTopColor:"#fff",animation:"idosw-spin .8s linear infinite"}}),n]}):r})}function Pn({tab:e,result:t}){let n=t.ok,o={borderRadius:14,padding:"10px 12px",display:"grid",gap:4,background:`color-mix(in srgb, ${n?i.green:i.red} 22%, transparent)`,border:`2px solid color-mix(in srgb, ${n?i.green:i.red} 60%, transparent)`,wordBreak:"break-word"};return n?jsxRuntime.jsxs("div",{style:o,role:"status",children:[jsxRuntime.jsxs("span",{style:{...I,fontSize:15},children:["\u2713 ",e==="withdraw"?u("doneWithdraw"):u("doneDeposit")]}),jsxRuntime.jsxs("span",{style:{...N,fontSize:12},children:[u("tx"),": ",pt(t.onChainTxHash)]})]}):jsxRuntime.jsxs("div",{style:o,role:"alert",children:[jsxRuntime.jsxs("span",{style:{...I,fontSize:15},children:["\u2715 ",u("failed")]}),jsxRuntime.jsx("span",{style:{fontSize:13,color:i.text,opacity:.9},children:t.error}),t.titleTransactionID?jsxRuntime.jsx("span",{style:{...N,fontSize:12},children:u("debited")}):null]})}var Rn=103;function vn(e){return (e.ChainID===Rn?ke:le).rpcUrls.default.http[0]}function Bn(e){let{client:t,walletConnectProjectId:n,appName:o,onClose:a,style:r,topUp:l}=e,[p,s]=react$1.useState(n??"");react$1.useEffect(()=>{if(n)return;let g=true;return (async()=>{let W=await t.blockchain.getDefinitions();if(!g||!W.ok)return;let P=W.data.Blockchain?.WalletLogin?.WalletConnectProjectId;P&&s(P);})(),()=>{g=false;}},[t,n]);let f=react$1.useMemo(()=>p?(xe({walletConnectProjectId:p,appName:o}),true):false,[p,o]),{address:d,isConnected:y}=react.useAppKitAccount(),{walletProvider:h}=react.useAppKitProvider("solana"),D=y&&d?d:null,S=(g,W)=>Ee({connection:new web3_js.Connection(vn(g),"confirmed"),owner:W,programId:g.RewardPoolAddress??"",signTransaction:async P=>{if(!h)throw new Error("Wallet not connected.");return h.signTransaction(P)}});return jsxRuntime.jsx(dt,{client:t,engine:{networkType:"Solana",address:D,connectChoices:f?[{key:"appkit",label:"Connect wallet",connect:()=>{Q()?.open();}}]:[],disconnect:()=>{Q()?.disconnect("solana");},deposit:async({network:g,binding:W,amount:P})=>{if(!D)return x("deposit-onchain","Wallet not connected.");if(!W.ContractAddress)return x("deposit-onchain","This token cannot be deposited.");if(!g.RewardPoolAddress)return x("deposit-onchain","POOL_NOT_IN_REGISTRY");let O;try{O=viem.parseUnits(P,W.Decimals??9);}catch{return x("deposit-onchain","Invalid amount.")}return ce({client:t,adapter:S(g,D),network:g,mint:W.ContractAddress,amountRaw:O,titleID:t.titleID})},withdraw:async({network:g,networkID:W,currencyID:P,amount:O})=>D?pe({client:t,adapter:S(g,D),currencyID:P,networkID:W,walletAddress:D,amount:O}):x("request","Wallet not connected.")},onClose:a,style:r,topUp:l})}
2
+ exports.PlatformPoolError=B;exports.SolanaWalletLogin=Bt;exports.SolanaWalletPanel=Bn;exports.createPlatformPoolAdapter=Ee;exports.createSolanaWalletConfig=xe;exports.solanaDevnet=ke;exports.solanaMainnet=le;exports.useSolanaBridge=Dt;
@@ -3,8 +3,9 @@ import { BaseWalletAdapter } from '@solana/wallet-adapter-base';
3
3
  import { a as AppKitSolanaNetwork, W as WalletLoginResult, B as BridgeResult } from '../chains-B2jQ-L0B.cjs';
4
4
  export { r as solanaDevnet, t as solanaMainnet } from '../chains-B2jQ-L0B.cjs';
5
5
  import { ClientState, DepositTokenResponse, TokenWithdrawalResponse, IDosGamesClient, PlayAccessStatus } from '@idosgames/core';
6
- import { D as DepositTokenSolanaParams, W as WithdrawTokenSolanaParams, S as SolanaProgramAdapter } from '../bridge-C5z9TgKG.cjs';
6
+ import { D as DepositTokenSolanaParams, W as WithdrawTokenSolanaParams, S as SolanaProgramAdapter } from '../bridge-BAyA43hM.cjs';
7
7
  import { CSSProperties, ReactNode } from 'react';
8
+ import { W as WalletTopUpRequest } from '../topUp-CCNQcHcH.cjs';
8
9
  import { Connection, Transaction } from '@solana/web3.js';
9
10
  import 'viem';
10
11
 
@@ -105,6 +106,11 @@ interface SolanaWalletPanelProps {
105
106
  appName?: string;
106
107
  onClose?: () => void;
107
108
  style?: CSSProperties;
109
+ /**
110
+ * Top up for a purchase the engine refused for a crypto shortfall: the panel shows only this
111
+ * currency and the missing amount, then calls `topUp.onDone(true)` (see `useWalletTopUp`).
112
+ */
113
+ topUp?: WalletTopUpRequest;
108
114
  }
109
115
  declare function SolanaWalletPanel(props: SolanaWalletPanelProps): ReactNode;
110
116
 
@@ -114,8 +120,8 @@ declare function SolanaWalletPanel(props: SolanaWalletPanelProps): ReactNode;
114
120
  * debited at this point, so the player must not be left with a hex code.
115
121
  */
116
122
  declare class PlatformPoolError extends Error {
117
- readonly code: "NO_WALLET" | "POOL_NOT_ON_THIS_CLUSTER" | "POOL_NOT_MIGRATED" | "POOL_PAUSED" | "VOUCHER_REVOKED" | "SIGNER_NOT_TRUSTED" | "MINT_NOT_FOUND" | "BAD_VOUCHER";
118
- constructor(code: "NO_WALLET" | "POOL_NOT_ON_THIS_CLUSTER" | "POOL_NOT_MIGRATED" | "POOL_PAUSED" | "VOUCHER_REVOKED" | "SIGNER_NOT_TRUSTED" | "MINT_NOT_FOUND" | "BAD_VOUCHER", message: string);
123
+ readonly code: "NO_WALLET" | "POOL_NOT_ON_THIS_CLUSTER" | "POOL_NOT_MIGRATED" | "POOL_PAUSED" | "VOUCHER_REVOKED" | "SIGNER_NOT_TRUSTED" | "MINT_NOT_FOUND" | "BAD_VOUCHER" | "TRANSACTION_FAILED" | "TRANSACTION_EXPIRED";
124
+ constructor(code: "NO_WALLET" | "POOL_NOT_ON_THIS_CLUSTER" | "POOL_NOT_MIGRATED" | "POOL_PAUSED" | "VOUCHER_REVOKED" | "SIGNER_NOT_TRUSTED" | "MINT_NOT_FOUND" | "BAD_VOUCHER" | "TRANSACTION_FAILED" | "TRANSACTION_EXPIRED", message: string);
119
125
  }
120
126
  /** Signs a transaction with the connected wallet (AppKit's Solana provider, a wallet adapter…). */
121
127
  type SolanaTransactionSigner = (tx: Transaction) => Promise<Transaction>;
@@ -3,8 +3,9 @@ import { BaseWalletAdapter } from '@solana/wallet-adapter-base';
3
3
  import { a as AppKitSolanaNetwork, W as WalletLoginResult, B as BridgeResult } from '../chains-B2jQ-L0B.js';
4
4
  export { r as solanaDevnet, t as solanaMainnet } from '../chains-B2jQ-L0B.js';
5
5
  import { ClientState, DepositTokenResponse, TokenWithdrawalResponse, IDosGamesClient, PlayAccessStatus } from '@idosgames/core';
6
- import { D as DepositTokenSolanaParams, W as WithdrawTokenSolanaParams, S as SolanaProgramAdapter } from '../bridge-BPZNXQuQ.js';
6
+ import { D as DepositTokenSolanaParams, W as WithdrawTokenSolanaParams, S as SolanaProgramAdapter } from '../bridge-BsVqE7-T.js';
7
7
  import { CSSProperties, ReactNode } from 'react';
8
+ import { W as WalletTopUpRequest } from '../topUp-CCNQcHcH.js';
8
9
  import { Connection, Transaction } from '@solana/web3.js';
9
10
  import 'viem';
10
11
 
@@ -105,6 +106,11 @@ interface SolanaWalletPanelProps {
105
106
  appName?: string;
106
107
  onClose?: () => void;
107
108
  style?: CSSProperties;
109
+ /**
110
+ * Top up for a purchase the engine refused for a crypto shortfall: the panel shows only this
111
+ * currency and the missing amount, then calls `topUp.onDone(true)` (see `useWalletTopUp`).
112
+ */
113
+ topUp?: WalletTopUpRequest;
108
114
  }
109
115
  declare function SolanaWalletPanel(props: SolanaWalletPanelProps): ReactNode;
110
116
 
@@ -114,8 +120,8 @@ declare function SolanaWalletPanel(props: SolanaWalletPanelProps): ReactNode;
114
120
  * debited at this point, so the player must not be left with a hex code.
115
121
  */
116
122
  declare class PlatformPoolError extends Error {
117
- readonly code: "NO_WALLET" | "POOL_NOT_ON_THIS_CLUSTER" | "POOL_NOT_MIGRATED" | "POOL_PAUSED" | "VOUCHER_REVOKED" | "SIGNER_NOT_TRUSTED" | "MINT_NOT_FOUND" | "BAD_VOUCHER";
118
- constructor(code: "NO_WALLET" | "POOL_NOT_ON_THIS_CLUSTER" | "POOL_NOT_MIGRATED" | "POOL_PAUSED" | "VOUCHER_REVOKED" | "SIGNER_NOT_TRUSTED" | "MINT_NOT_FOUND" | "BAD_VOUCHER", message: string);
123
+ readonly code: "NO_WALLET" | "POOL_NOT_ON_THIS_CLUSTER" | "POOL_NOT_MIGRATED" | "POOL_PAUSED" | "VOUCHER_REVOKED" | "SIGNER_NOT_TRUSTED" | "MINT_NOT_FOUND" | "BAD_VOUCHER" | "TRANSACTION_FAILED" | "TRANSACTION_EXPIRED";
124
+ constructor(code: "NO_WALLET" | "POOL_NOT_ON_THIS_CLUSTER" | "POOL_NOT_MIGRATED" | "POOL_PAUSED" | "VOUCHER_REVOKED" | "SIGNER_NOT_TRUSTED" | "MINT_NOT_FOUND" | "BAD_VOUCHER" | "TRANSACTION_FAILED" | "TRANSACTION_EXPIRED", message: string);
119
125
  }
120
126
  /** Signs a transaction with the connected wallet (AppKit's Solana provider, a wallet adapter…). */
121
127
  type SolanaTransactionSigner = (tx: Transaction) => Promise<Transaction>;
@@ -1 +1 @@
1
- import {b,a as a$1,c,d}from'../chunk-MLIXKTS6.js';import {a,c as c$2,b as b$2,d as d$1}from'../chunk-XJV2C5QX.js';import {v,b as b$1,c as c$1,w}from'../chunk-K3THMWU2.js';export{w as solanaDevnet,v as solanaMainnet}from'../chunk-K3THMWU2.js';import {SolanaAdapter}from'@reown/appkit-adapter-solana';import {createAppKit,useAppKitAccount,useAppKitProvider}from'@reown/appkit/react';import {useState,useRef,useCallback,useEffect,useMemo}from'react';import {jsxs,Fragment,jsx}from'react/jsx-runtime';import {parseUnits}from'viem';import {PublicKey,ComputeBudgetProgram,Connection,Transaction,Ed25519Program,TransactionInstruction,SYSVAR_INSTRUCTIONS_PUBKEY,SystemProgram}from'@solana/web3.js';import {Buffer}from'buffer';var se=new Map;function $(t){let{walletConnectProjectId:e,appName:o,appUrl:r,appIcon:a$1,wallets:n}=t,i=se.get(e);if(i)return i;let u=t.networks??[v],s=r??(typeof window<"u"?window.location.origin:""),l={name:o??"iDosGames",description:o??"iDosGames game",url:s,icons:a$1?[a$1]:[]},c=new SolanaAdapter(n?{wallets:n}:{});return a(createAppKit({adapters:[c],networks:u,projectId:e,metadata:l,features:{analytics:false,email:false,socials:false}})),se.set(e,c),c}var le="Wallet not connected.";function Te(t,e,o){let{address:r}=useAppKitAccount(),{walletProvider:a}=useAppKitProvider("solana"),n=r??null,i=a?.signMessage?.bind(a);return {connected:!!n,account:n,loginWithWallet:(u,s)=>{let l=s??n;return l?i?c({client:t,networkID:u,walletAddress:l,signMessage:i}):Promise.resolve(c$1("sign","The connected wallet does not support message signing.")):Promise.resolve(c$1("challenge",le))},depositToken:u=>a$1({client:t,adapter:o,titleID:e,...u}),withdrawToken:u=>{let s=u.walletAddress??n;return s?b({client:t,adapter:o,...u,walletAddress:s}):Promise.resolve(b$1("request",le))}}}var Ae=18e4,ce=9e4;function he(t){try{let o=t?.session?.peer?.metadata?.redirect,r=o?.native||o?.universal;return !r||typeof window>"u"?!1:(window.location.href=r,!0)}catch{return false}}function ue(t,e){return new Promise((o,r)=>{let a=setTimeout(()=>r(new Error("The wallet request timed out.")),e);t.then(n=>{clearTimeout(a),o(n);},n=>{clearTimeout(a),r(n instanceof Error?n:new Error(String(n)));});})}function We(t){let e="Wallet sign-in failed. Please try again.";return t instanceof Error?/user (rejected|denied|cancelled|canceled)|rejected the request/i.test(t.message)?"Request declined in the wallet.":/timed? ?out/i.test(t.message)?"The wallet did not respond. Open your wallet and try again.":e:e}function Ce(t){let{client:e,networkID:o,onAuthenticated:r,disabled:a,label:n,style:i,autoStart:u,mode:s="login",onLinked:l}=t,{address:c$1,isConnected:S}=useAppKitAccount(),{walletProvider:p}=useAppKitProvider("solana"),[b,m]=useState(false),[f,g]=useState(null),[y,T]=useState(false),[ee,te]=useState(false),_=useRef(null),ne=useRef(0),D=useCallback(()=>{_.current&&clearTimeout(_.current),_.current=null;},[]);useEffect(()=>D,[D]);let G=useRef(false),F=useCallback(async()=>{let N=++ne.current,R=()=>ne.current===N,H=p?.signMessage?.bind(p);if(!c$1||!H){g("The connected wallet cannot sign messages."),m(false);return}m(true),g(null);try{if(te(!0),s==="link"){let K=await ue(d({client:e,networkID:o,walletAddress:c$1,signMessage:H}),ce);if(!R())return;if(K.ok){l?.(K.data.PlayAccess??null);return}g(K.stage==="sign"?"Signature declined.":c$2(K.error,"Could not link the wallet."));return}let k=await ue(c({client:e,networkID:o,walletAddress:c$1,signMessage:H}),ce);if(!R())return;if(k.ok){r();return}g(k.stage==="sign"?"Signature declined.":c$2(k.error,"Wallet sign-in failed."));}catch(k){if(!R())return;console.error("[idosgames/wallet] solana sign-in failed:",k),g(We(k));}finally{R()&&(m(false),te(false));}},[c$1,p,e,o,r,s,l]),Se=useCallback(()=>{he(p)||b$2()?.open();},[p]);useEffect(()=>{!y||!S||!c$1||!p||(T(false),D(),F());},[y,S,c$1,p,F,D]);let re=()=>{if(ee){Se();return}if(g(null),G.current=true,S&&c$1&&p){F();return}let N=b$2();if(!N){g("Wallet sign-in is not configured for this title.");return}m(true),T(true),D(),_.current=setTimeout(()=>{T(false),m(false),g("No wallet was connected.");},Ae),N.open();};return useEffect(()=>{!u||G.current||(G.current=true,re());},[u]),jsxs(Fragment,{children:[jsx("button",{type:"button",onClick:re,disabled:a,style:{...Ee,...a?{opacity:.6,cursor:"default"}:null,...i},children:ee?"Waiting for signature \u2014 tap to open wallet":b?"Check your wallet\u2026":S?n??(s==="link"?"Link wallet":"Sign in with wallet"):"Connect wallet"}),f&&jsx("span",{role:"alert",style:De,children:f})]})}var Ee={padding:"11px 16px",borderRadius:"8px",border:"none",background:"#4c3fa8",color:"#fff",font:"inherit",fontWeight:600,cursor:"pointer"},De={display:"block",marginTop:"6px",color:"#ff9b9b",fontSize:"13px",textAlign:"center"};var ve="e000c6afc62f69cc",Be="b59a5e563e7306ba",Le="d668e18c1bdc33f1",M=new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"),Ue="1nc1nerator11111111111111111111111111111111",de=177,Me=3e5,fe=40,ge=4,me=fe+32*ge,Ge=me+8,P=class extends Error{constructor(o,r){super(r);this.code=o;this.name="PlatformPoolError";}code};function U(t){let e=(t??"").replace(/^0x/i,""),o=new Uint8Array(e.length>>1);for(let r=0;r<o.length;r++)o[r]=parseInt(e.slice(r*2,r*2+2),16);return o}function h(t){let e=Buffer.alloc(8);return e.writeBigUInt64LE(BigInt(t||0)),e}function Fe(t){let e=Buffer.alloc(8);return e.writeBigInt64LE(BigInt(t||0)),e}function C(t){let e=Buffer.from(t??"","utf8"),o=Buffer.alloc(4);return o.writeUInt32LE(e.length),Buffer.concat([o,e])}function He(t){return Buffer.concat([Buffer.from(ve,"hex"),h(t.amountRaw),C(t.userID),C(t.titleID),C(t.category)])}function Ve(t){let e=t.Splits??[],o=Buffer.alloc(4);return o.writeUInt32LE(e.length),Buffer.concat([Buffer.from(t.Domain==="SPL_DEV"?Le:Be,"hex"),h(t.Amount),h(t.BurnAmount),h(t.Nonce),Fe(t.ExpiresAt),o,...e.map(r=>Buffer.concat([Buffer.from(new PublicKey(r.To??"").toBytes()),h(r.Amount)])),C(t.UserID),C(t.TitleID),C(t.Category)])}function W(t,e,o){return PublicKey.findProgramAddressSync([e.toBuffer(),o.toBuffer(),t.toBuffer()],M)[0]}function je(t,e,o,r,a){return new TransactionInstruction({programId:M,keys:[{pubkey:t,isSigner:true,isWritable:true},{pubkey:e,isSigner:false,isWritable:true},{pubkey:o,isSigner:false,isWritable:false},{pubkey:r,isSigner:false,isWritable:false},{pubkey:SystemProgram.programId,isSigner:false,isWritable:false},{pubkey:a,isSigner:false,isWritable:false}],data:Buffer.from([1])})}function E(t,...e){return PublicKey.findProgramAddressSync(e,t)[0]}function qe(t){let{programId:e,user:o,mint:r,tokenProgram:a}=t,n=E(e,Buffer.from("vault"));return new TransactionInstruction({programId:e,keys:[{pubkey:E(e,Buffer.from("config")),isSigner:false,isWritable:false},{pubkey:n,isSigner:false,isWritable:true},{pubkey:r,isSigner:false,isWritable:false},{pubkey:o,isSigner:true,isWritable:true},{pubkey:W(r,o,a),isSigner:false,isWritable:true},{pubkey:W(r,n,a),isSigner:false,isWritable:true},{pubkey:a,isSigner:false,isWritable:false},{pubkey:M,isSigner:false,isWritable:false},{pubkey:SystemProgram.programId,isSigner:false,isWritable:false}],data:He(t)})}function $e(t){let{sig:e,payer:o,tokenProgram:r}=t,a=new PublicKey(e.ProgramID??""),n=new PublicKey(e.Mint??""),i=new PublicKey(e.WalletAddress??""),u=E(a,Buffer.from("vault")),s=new PublicKey(Ue),l=(e.Splits??[]).map(m=>new PublicKey(m.To??"")),c=l.map(m=>W(n,m,r)),S=Ed25519Program.createInstructionWithPublicKey({publicKey:U(e.Ed25519PublicKey),message:U(e.Ed25519Message),signature:U(e.SignatureHex)}),p=l.map((m,f)=>je(o,c[f],m,n,r)),b=new TransactionInstruction({programId:a,keys:[{pubkey:E(a,Buffer.from("config")),isSigner:false,isWritable:false},{pubkey:o,isSigner:true,isWritable:true},{pubkey:u,isSigner:false,isWritable:true},{pubkey:E(a,Buffer.from("nonce"),h(e.Nonce)),isSigner:false,isWritable:true},{pubkey:n,isSigner:false,isWritable:false},{pubkey:i,isSigner:false,isWritable:false},{pubkey:W(n,u,r),isSigner:false,isWritable:true},{pubkey:W(n,i,r),isSigner:false,isWritable:true},{pubkey:s,isSigner:false,isWritable:false},{pubkey:W(n,s,r),isSigner:false,isWritable:true},{pubkey:SYSVAR_INSTRUCTIONS_PUBKEY,isSigner:false,isWritable:false},{pubkey:r,isSigner:false,isWritable:false},{pubkey:M,isSigner:false,isWritable:false},{pubkey:SystemProgram.programId,isSigner:false,isWritable:false},...c.map(m=>({pubkey:m,isSigner:false,isWritable:true}))],data:Ve(e)});return [S,...p,b]}function X(t){let{connection:e,signTransaction:o}=t;async function r(n){let i=await e.getAccountInfo(n);if(!i)throw new P("MINT_NOT_FOUND",`mint ${n.toBase58()} not found`);return i.owner}async function a(n,i){let{blockhash:u,lastValidBlockHeight:s}=await e.getLatestBlockhash("confirmed"),l=new Transaction;l.feePayer=n,l.recentBlockhash=u,l.add(...i);let c=await o(l),S=await e.sendRawTransaction(c.serialize());return await e.confirmTransaction({signature:S,blockhash:u,lastValidBlockHeight:s},"confirmed"),S}return {async depositSpl({mint:n,amountRaw:i,userID:u,titleID:s,category:l}){let c=new PublicKey(t.owner),S=new PublicKey(n),p=await r(S);return a(c,[qe({programId:new PublicKey(t.programId),user:c,mint:S,tokenProgram:p,amountRaw:i,userID:u,titleID:s,category:l})])},async submitWithdrawal(n){if(!n.ProgramID||!n.Mint||!n.WalletAddress)throw new P("BAD_VOUCHER","the voucher has no program, mint or wallet");let i=new PublicKey(t.owner),u=new PublicKey(n.ProgramID),s=await e.getAccountInfo(E(u,Buffer.from("config")));if(!s)throw new P("POOL_NOT_ON_THIS_CLUSTER","the pool's config account is not on this cluster");if(s.data.length!==de)throw new P("POOL_NOT_MIGRATED",`config is ${s.data.length} bytes, expected ${de} (migrate_config not run)`);let l=Buffer.from(s.data);if(l[Ge]===1)throw new P("POOL_PAUSED","pool withdrawals are paused");let c=l.readBigUInt64LE(me);if(c!==BigInt(n.SignatureEpoch||0))throw new P("VOUCHER_REVOKED",`signature epoch mismatch: voucher ${n.SignatureEpoch}, on-chain ${c}`);let S=Buffer.from(U(n.Ed25519PublicKey)),p=false;for(let m=0;m<ge;m++){let f=fe+m*32;S.equals(l.subarray(f,f+32))&&(p=true);}if(!p)throw new P("SIGNER_NOT_TRUSTED","the voucher's signer is not in the pool's server_pubkeys");let b=await r(new PublicKey(n.Mint));return a(i,[ComputeBudgetProgram.setComputeUnitLimit({units:Me}),...$e({sig:n,payer:i,tokenProgram:b})])}}}var tt=103;function nt(t){return (t.ChainID===tt?w:v).rpcUrls.default.http[0]}function rt(t){let{client:e,walletConnectProjectId:o,appName:r,onClose:a,style:n}=t,[i,u]=useState(o??"");useEffect(()=>{if(o)return;let f=true;return (async()=>{let g=await e.blockchain.getDefinitions();if(!f||!g.ok)return;let y=g.data.Blockchain?.WalletLogin?.WalletConnectProjectId;y&&u(y);})(),()=>{f=false;}},[e,o]);let s=useMemo(()=>i?($({walletConnectProjectId:i,appName:r}),true):false,[i,r]),{address:l,isConnected:c}=useAppKitAccount(),{walletProvider:S}=useAppKitProvider("solana"),p=c&&l?l:null,b$3=(f,g)=>X({connection:new Connection(nt(f),"confirmed"),owner:g,programId:f.RewardPoolAddress??"",signTransaction:async y=>{if(!S)throw new Error("Wallet not connected.");return S.signTransaction(y)}});return jsx(d$1,{client:e,engine:{networkType:"Solana",address:p,connectChoices:s?[{key:"appkit",label:"Connect wallet",connect:()=>{b$2()?.open();}}]:[],disconnect:()=>{b$2()?.disconnect("solana");},deposit:async({network:f,binding:g,amount:y})=>{if(!p)return b$1("deposit-onchain","Wallet not connected.");if(!g.ContractAddress)return b$1("deposit-onchain","This token cannot be deposited.");if(!f.RewardPoolAddress)return b$1("deposit-onchain","POOL_NOT_IN_REGISTRY");let T;try{T=parseUnits(y,g.Decimals??9);}catch{return b$1("deposit-onchain","Invalid amount.")}return a$1({client:e,adapter:b$3(f,p),network:f,mint:g.ContractAddress,amountRaw:T,titleID:e.titleID})},withdraw:async({network:f,networkID:g,currencyID:y,amount:T})=>p?b({client:e,adapter:b$3(f,p),currencyID:y,networkID:g,walletAddress:p,amount:T}):b$1("request","Wallet not connected.")},onClose:a,style:n})}export{P as PlatformPoolError,Ce as SolanaWalletLogin,rt as SolanaWalletPanel,X as createPlatformPoolAdapter,$ as createSolanaWalletConfig,Te as useSolanaBridge};
1
+ import {b,a as a$1,c,d}from'../chunk-MLIXKTS6.js';import {a,b as b$2,c as c$2}from'../chunk-NU3WMVH2.js';import'../chunk-ZOWZE7MU.js';import {v,b as b$1,c as c$1,w}from'../chunk-K3THMWU2.js';export{w as solanaDevnet,v as solanaMainnet}from'../chunk-K3THMWU2.js';import {SolanaAdapter}from'@reown/appkit-adapter-solana';import {createAppKit,useAppKitAccount,useAppKitProvider}from'@reown/appkit/react';import {useState,useRef,useCallback,useEffect,useMemo}from'react';import {authErrorText}from'@idosgames/core';import {jsxs,Fragment,jsx}from'react/jsx-runtime';import {parseUnits}from'viem';import {PublicKey,ComputeBudgetProgram,Connection,Transaction,Ed25519Program,TransactionInstruction,SYSVAR_INSTRUCTIONS_PUBKEY,SystemProgram}from'@solana/web3.js';import {Buffer}from'buffer';var ie=new Map;function $(t){let{walletConnectProjectId:e,appName:o,appUrl:r,appIcon:i,wallets:n}=t,a$1=ie.get(e);if(a$1)return a$1;let l=t.networks??[v],s=r??(typeof window<"u"?window.location.origin:""),p={name:o??"iDosGames",description:o??"iDosGames game",url:s,icons:i?[i]:[]},c=new SolanaAdapter(n?{wallets:n}:{});return a(createAppKit({adapters:[c],networks:l,projectId:e,metadata:p,features:{analytics:false,email:false,socials:false}})),ie.set(e,c),c}var se="Wallet not connected.";function Ae(t,e,o){let{address:r}=useAppKitAccount(),{walletProvider:i}=useAppKitProvider("solana"),n=r??null,a=i?.signMessage?.bind(i);return {connected:!!n,account:n,loginWithWallet:(l,s)=>{let p=s??n;return p?a?c({client:t,networkID:l,walletAddress:p,signMessage:a}):Promise.resolve(c$1("sign","The connected wallet does not support message signing.")):Promise.resolve(c$1("challenge",se))},depositToken:l=>a$1({client:t,adapter:o,titleID:e,...l}),withdrawToken:l=>{let s=l.walletAddress??n;return s?b({client:t,adapter:o,...l,walletAddress:s}):Promise.resolve(b$1("request",se))}}}var We=18e4,ce=9e4;function Ee(t){try{let o=t?.session?.peer?.metadata?.redirect,r=o?.native||o?.universal;return !r||typeof window>"u"?!1:(window.location.href=r,!0)}catch{return false}}function ue(t,e){return new Promise((o,r)=>{let i=setTimeout(()=>r(new Error("The wallet request timed out.")),e);t.then(n=>{clearTimeout(i),o(n);},n=>{clearTimeout(i),r(n instanceof Error?n:new Error(String(n)));});})}function Ce(t){let e="Wallet sign-in failed. Please try again.";return t instanceof Error?/user (rejected|denied|cancelled|canceled)|rejected the request/i.test(t.message)?"Request declined in the wallet.":/timed? ?out/i.test(t.message)?"The wallet did not respond. Open your wallet and try again.":e:e}function Oe(t){let{client:e,networkID:o,onAuthenticated:r,disabled:i,label:n,style:a,autoStart:l,mode:s="login",onLinked:p}=t,{address:c$1,isConnected:g}=useAppKitAccount(),{walletProvider:f}=useAppKitProvider("solana"),[b,S]=useState(false),[w,d$1]=useState(null),[y,T]=useState(false),[A,ee]=useState(false),N=useRef(null),te=useRef(0),D=useCallback(()=>{N.current&&clearTimeout(N.current),N.current=null;},[]);useEffect(()=>D,[D]);let G=useRef(false),F=useCallback(async()=>{let R=++te.current,x=()=>te.current===R,V=f?.signMessage?.bind(f);if(!c$1||!V){d$1("The connected wallet cannot sign messages."),S(false);return}S(true),d$1(null);try{if(ee(!0),s==="link"){let K=await ue(d({client:e,networkID:o,walletAddress:c$1,signMessage:V}),ce);if(!x())return;if(K.ok){p?.(K.data.PlayAccess??null);return}d$1(K.stage==="sign"?"Signature declined.":authErrorText(K.error,"Could not link the wallet."));return}let k=await ue(c({client:e,networkID:o,walletAddress:c$1,signMessage:V}),ce);if(!x())return;if(k.ok){r();return}d$1(k.stage==="sign"?"Signature declined.":authErrorText(k.error,"Wallet sign-in failed."));}catch(k){if(!x())return;console.error("[idosgames/wallet] solana sign-in failed:",k),d$1(Ce(k));}finally{x()&&(S(false),ee(false));}},[c$1,f,e,o,r,s,p]),ye=useCallback(()=>{Ee(f)||b$2()?.open();},[f]);useEffect(()=>{!y||!g||!c$1||!f||(T(false),D(),F());},[y,g,c$1,f,F,D]);let ne=()=>{if(A){ye();return}if(d$1(null),G.current=true,g&&c$1&&f){F();return}let R=b$2();if(!R){d$1("Wallet sign-in is not configured for this title.");return}S(true),T(true),D(),N.current=setTimeout(()=>{T(false),S(false),d$1("No wallet was connected.");},We),R.open();};return useEffect(()=>{!l||G.current||(G.current=true,ne());},[l]),jsxs(Fragment,{children:[jsx("button",{type:"button",onClick:ne,disabled:i,style:{...De,...i?{opacity:.6,cursor:"default"}:null,...a},children:A?"Waiting for signature \u2014 tap to open wallet":b?"Check your wallet\u2026":g?n??(s==="link"?"Link wallet":"Sign in with wallet"):"Connect wallet"}),w&&jsx("span",{role:"alert",style:_e,children:w})]})}var De={padding:"11px 16px",borderRadius:"8px",border:"none",background:"#4c3fa8",color:"#fff",font:"inherit",fontWeight:600,cursor:"pointer"},_e={display:"block",marginTop:"6px",color:"#ff9b9b",fontSize:"13px",textAlign:"center"};var Ue="e000c6afc62f69cc",Le="b59a5e563e7306ba",Me="d668e18c1bdc33f1",H=new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"),He="1nc1nerator11111111111111111111111111111111",de=177,Ge=3e5,ge=40,me=4,Se=ge+32*me,Fe=Se+8,P=class extends Error{constructor(o,r){super(r);this.code=o;this.name="PlatformPoolError";}code};function M(t){let e=(t??"").replace(/^0x/i,""),o=new Uint8Array(e.length>>1);for(let r=0;r<o.length;r++)o[r]=parseInt(e.slice(r*2,r*2+2),16);return o}function E(t){let e=Buffer.alloc(8);return e.writeBigUInt64LE(BigInt(t||0)),e}function Ve(t){let e=Buffer.alloc(8);return e.writeBigInt64LE(BigInt(t||0)),e}function O(t){let e=Buffer.from(t??"","utf8"),o=Buffer.alloc(4);return o.writeUInt32LE(e.length),Buffer.concat([o,e])}async function fe(t){let e=await globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(t??""));return new Uint8Array(e)}function we(t,e,o){return I(t,Buffer.from("title_balance"),Buffer.from(e),o.toBuffer())}function qe(t){return Buffer.concat([Buffer.from(Ue,"hex"),E(t.amountRaw),O(t.userID),O(t.titleID),O(t.category),Buffer.from(t.titleHash)])}function je(t,e){let o=t.Splits??[],r=Buffer.alloc(4);return r.writeUInt32LE(o.length),Buffer.concat([Buffer.from(t.Domain==="SPL_DEV"?Me:Le,"hex"),E(t.Amount),E(t.BurnAmount),E(t.Nonce),Ve(t.ExpiresAt),r,...o.map(i=>Buffer.concat([Buffer.from(new PublicKey(i.To??"").toBytes()),E(i.Amount)])),O(t.UserID),O(t.TitleID),O(t.Category),Buffer.from(e)])}function C(t,e,o){return PublicKey.findProgramAddressSync([e.toBuffer(),o.toBuffer(),t.toBuffer()],H)[0]}function $e(t,e,o,r,i){return new TransactionInstruction({programId:H,keys:[{pubkey:t,isSigner:true,isWritable:true},{pubkey:e,isSigner:false,isWritable:true},{pubkey:o,isSigner:false,isWritable:false},{pubkey:r,isSigner:false,isWritable:false},{pubkey:SystemProgram.programId,isSigner:false,isWritable:false},{pubkey:i,isSigner:false,isWritable:false}],data:Buffer.from([1])})}function I(t,...e){return PublicKey.findProgramAddressSync(e,t)[0]}function ze(t){let{programId:e,user:o,mint:r,tokenProgram:i}=t,n=I(e,Buffer.from("vault"));return new TransactionInstruction({programId:e,keys:[{pubkey:I(e,Buffer.from("config")),isSigner:false,isWritable:false},{pubkey:n,isSigner:false,isWritable:true},{pubkey:r,isSigner:false,isWritable:false},{pubkey:o,isSigner:true,isWritable:true},{pubkey:C(r,o,i),isSigner:false,isWritable:true},{pubkey:C(r,n,i),isSigner:false,isWritable:true},{pubkey:i,isSigner:false,isWritable:false},{pubkey:H,isSigner:false,isWritable:false},{pubkey:SystemProgram.programId,isSigner:false,isWritable:false},{pubkey:we(e,t.titleHash,r),isSigner:false,isWritable:true}],data:qe(t)})}function Ye(t){let{sig:e,payer:o,tokenProgram:r,titleHash:i}=t,n=new PublicKey(e.ProgramID??""),a=new PublicKey(e.Mint??""),l=new PublicKey(e.WalletAddress??""),s=I(n,Buffer.from("vault")),p=new PublicKey(He),c=(e.Splits??[]).map(w=>new PublicKey(w.To??"")),g=c.map(w=>C(a,w,r)),f=Ed25519Program.createInstructionWithPublicKey({publicKey:M(e.Ed25519PublicKey),message:M(e.Ed25519Message),signature:M(e.SignatureHex)}),b=c.map((w,d)=>$e(o,g[d],w,a,r)),S=new TransactionInstruction({programId:n,keys:[{pubkey:I(n,Buffer.from("config")),isSigner:false,isWritable:false},{pubkey:o,isSigner:true,isWritable:true},{pubkey:s,isSigner:false,isWritable:true},{pubkey:I(n,Buffer.from("nonce"),E(e.Nonce)),isSigner:false,isWritable:true},{pubkey:a,isSigner:false,isWritable:false},{pubkey:l,isSigner:false,isWritable:false},{pubkey:C(a,s,r),isSigner:false,isWritable:true},{pubkey:C(a,l,r),isSigner:false,isWritable:true},{pubkey:p,isSigner:false,isWritable:false},{pubkey:C(a,p,r),isSigner:false,isWritable:true},{pubkey:SYSVAR_INSTRUCTIONS_PUBKEY,isSigner:false,isWritable:false},{pubkey:r,isSigner:false,isWritable:false},{pubkey:H,isSigner:false,isWritable:false},{pubkey:SystemProgram.programId,isSigner:false,isWritable:false},{pubkey:we(n,i,a),isSigner:false,isWritable:true},...g.map(w=>({pubkey:w,isSigner:false,isWritable:true}))],data:je(e,i)});return [f,...b,S]}async function Je(t,e,o){let r=async n=>{let a=(await t.getSignatureStatuses([e],{searchTransactionHistory:n})).value[0];if(a?.err)throw new P("TRANSACTION_FAILED",`transaction ${e} failed: ${JSON.stringify(a.err)}`);return a},i=n=>n?.confirmationStatus==="confirmed"||n?.confirmationStatus==="finalized";for(let n=1;;n++){await new Promise(s=>setTimeout(s,Xe));let a=null;try{a=await r(!1);}catch(s){if(s instanceof P)throw s}if(i(a))return;if(!(a||n%Ze!==0||await t.getBlockHeight("confirmed").catch(()=>-1)<=o)){if(i(await r(true).catch(()=>null)))return;throw new P("TRANSACTION_EXPIRED",`transaction ${e} expired: block height exceeded`)}}}var Xe=2e3,Ze=5;function Q(t){let{connection:e,signTransaction:o}=t;async function r(n){let a=await e.getAccountInfo(n);if(!a)throw new P("MINT_NOT_FOUND",`mint ${n.toBase58()} not found`);return a.owner}async function i(n,a){let{blockhash:l,lastValidBlockHeight:s}=await e.getLatestBlockhash("confirmed"),p=new Transaction;p.feePayer=n,p.recentBlockhash=l,p.add(...a);let c=await o(p),g=await e.sendRawTransaction(c.serialize());return await Je(e,g,s),g}return {async depositSpl({mint:n,amountRaw:a,userID:l,titleID:s,category:p}){let c=new PublicKey(t.owner),g=new PublicKey(n),f=await r(g);return i(c,[ze({programId:new PublicKey(t.programId),user:c,mint:g,tokenProgram:f,amountRaw:a,userID:l,titleID:s,category:p,titleHash:await fe(s)})])},async submitWithdrawal(n){if(!n.ProgramID||!n.Mint||!n.WalletAddress)throw new P("BAD_VOUCHER","the voucher has no program, mint or wallet");let a=new PublicKey(t.owner),l=new PublicKey(n.ProgramID),s=await e.getAccountInfo(I(l,Buffer.from("config")));if(!s)throw new P("POOL_NOT_ON_THIS_CLUSTER","the pool's config account is not on this cluster");if(s.data.length!==de)throw new P("POOL_NOT_MIGRATED",`config is ${s.data.length} bytes, expected ${de} (migrate_config not run)`);let p=Buffer.from(s.data);if(p[Fe]===1)throw new P("POOL_PAUSED","pool withdrawals are paused");let c=p.readBigUInt64LE(Se);if(c!==BigInt(n.SignatureEpoch||0))throw new P("VOUCHER_REVOKED",`signature epoch mismatch: voucher ${n.SignatureEpoch}, on-chain ${c}`);let g=Buffer.from(M(n.Ed25519PublicKey)),f=false;for(let S=0;S<me;S++){let w=ge+S*32;g.equals(p.subarray(w,w+32))&&(f=true);}if(!f)throw new P("SIGNER_NOT_TRUSTED","the voucher's signer is not in the pool's server_pubkeys");let b=await r(new PublicKey(n.Mint));return i(a,[ComputeBudgetProgram.setComputeUnitLimit({units:Ge}),...Ye({sig:n,payer:a,tokenProgram:b,titleHash:await fe(n.TitleID??"")})])}}}var it=103;function st(t){return (t.ChainID===it?w:v).rpcUrls.default.http[0]}function lt(t){let{client:e,walletConnectProjectId:o,appName:r,onClose:i,style:n,topUp:a}=t,[l,s]=useState(o??"");useEffect(()=>{if(o)return;let d=true;return (async()=>{let y=await e.blockchain.getDefinitions();if(!d||!y.ok)return;let T=y.data.Blockchain?.WalletLogin?.WalletConnectProjectId;T&&s(T);})(),()=>{d=false;}},[e,o]);let p=useMemo(()=>l?($({walletConnectProjectId:l,appName:r}),true):false,[l,r]),{address:c,isConnected:g}=useAppKitAccount(),{walletProvider:f}=useAppKitProvider("solana"),b$3=g&&c?c:null,S=(d,y)=>Q({connection:new Connection(st(d),"confirmed"),owner:y,programId:d.RewardPoolAddress??"",signTransaction:async T=>{if(!f)throw new Error("Wallet not connected.");return f.signTransaction(T)}});return jsx(c$2,{client:e,engine:{networkType:"Solana",address:b$3,connectChoices:p?[{key:"appkit",label:"Connect wallet",connect:()=>{b$2()?.open();}}]:[],disconnect:()=>{b$2()?.disconnect("solana");},deposit:async({network:d,binding:y,amount:T})=>{if(!b$3)return b$1("deposit-onchain","Wallet not connected.");if(!y.ContractAddress)return b$1("deposit-onchain","This token cannot be deposited.");if(!d.RewardPoolAddress)return b$1("deposit-onchain","POOL_NOT_IN_REGISTRY");let A;try{A=parseUnits(T,y.Decimals??9);}catch{return b$1("deposit-onchain","Invalid amount.")}return a$1({client:e,adapter:S(d,b$3),network:d,mint:y.ContractAddress,amountRaw:A,titleID:e.titleID})},withdraw:async({network:d,networkID:y,currencyID:T,amount:A})=>b$3?b({client:e,adapter:S(d,b$3),currencyID:T,networkID:y,walletAddress:b$3,amount:A}):b$1("request","Wallet not connected.")},onClose:i,style:n,topUp:a})}export{P as PlatformPoolError,Oe as SolanaWalletLogin,lt as SolanaWalletPanel,Q as createPlatformPoolAdapter,$ as createSolanaWalletConfig,Ae as useSolanaBridge};
@@ -0,0 +1,18 @@
1
+ import { IDosGamesClient } from '@idosgames/core';
2
+
3
+ /** What the wallet panel tops up: one currency, the missing amount, and who is waiting for it. */
4
+ interface WalletTopUpRequest {
5
+ currencyID: string;
6
+ /** Missing tokens, exact decimal string ("0.6"); the panel rounds up to the token's decimals. */
7
+ amount: string;
8
+ /** `true` once the engine has CREDITED the deposit (the purchase is then sent again). */
9
+ onDone: (ok: boolean) => void;
10
+ }
11
+ /**
12
+ * Installs the game's wallet as the top-up handler while the component lives, and returns the request
13
+ * to show (`null` — nothing to top up). Render `LazyWalletPanel` with `topUp={request}` while it is
14
+ * set, and call `request.onDone(false)` when the player closes it. Does nothing inside a frame.
15
+ */
16
+ declare function useWalletTopUp(client: IDosGamesClient): WalletTopUpRequest | null;
17
+
18
+ export { type WalletTopUpRequest as W, useWalletTopUp as u };
@@ -0,0 +1,18 @@
1
+ import { IDosGamesClient } from '@idosgames/core';
2
+
3
+ /** What the wallet panel tops up: one currency, the missing amount, and who is waiting for it. */
4
+ interface WalletTopUpRequest {
5
+ currencyID: string;
6
+ /** Missing tokens, exact decimal string ("0.6"); the panel rounds up to the token's decimals. */
7
+ amount: string;
8
+ /** `true` once the engine has CREDITED the deposit (the purchase is then sent again). */
9
+ onDone: (ok: boolean) => void;
10
+ }
11
+ /**
12
+ * Installs the game's wallet as the top-up handler while the component lives, and returns the request
13
+ * to show (`null` — nothing to top up). Render `LazyWalletPanel` with `topUp={request}` while it is
14
+ * set, and call `request.onDone(false)` when the player closes it. Does nothing inside a frame.
15
+ */
16
+ declare function useWalletTopUp(client: IDosGamesClient): WalletTopUpRequest | null;
17
+
18
+ export { type WalletTopUpRequest as W, useWalletTopUp as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idosgames/wallet",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Wallet-bridge companion to @idosgames/core: connect browser & mobile wallets (EVM via wagmi/viem/WalletConnect, Solana via wallet-adapter) and move tokens/NFTs in and out of the game through client.blockchain.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -70,7 +70,7 @@
70
70
  },
71
71
  "//": "@idosgames/core не '*': опубликованный пакет обязан назвать диапазон, иначе установка wallet притянет любую версию core, включая будущую ломающую. На 0.x '^' даёт >=0.1.0 <0.2.0 — ровно ту зону, где core обещает совместимость (см. RELEASING.md). Поднимать при мажорном/минорном бампе core.",
72
72
  "dependencies": {
73
- "@idosgames/core": "^0.21.0",
73
+ "@idosgames/core": "^0.21.3",
74
74
  "viem": "^2.55.2"
75
75
  },
76
76
  "peerDependencies": {
@@ -1 +0,0 @@
1
- import {c}from'./chunk-K3THMWU2.js';import {isPlatformParentOrigin,PLATFORM_ORIGINS}from'@idosgames/core';var d={addressRequest:"IDOS_PLATFORM_WALLET_ADDRESS_REQUEST",addressResponse:"IDOS_PLATFORM_WALLET_ADDRESS_RESPONSE",signRequest:"IDOS_PLATFORM_WALLET_SIGN_REQUEST",signResponse:"IDOS_PLATFORM_WALLET_SIGN_RESPONSE",ack:"IDOS_PLATFORM_WALLET_ACK",openRequest:"IDOS_PLATFORM_WALLET_OPEN_REQUEST",openResponse:"IDOS_PLATFORM_WALLET_OPEN_RESPONSE"},m="PLATFORM_WALLET_UNAVAILABLE",p=5e3,A=18e4;function S(){let t=[...PLATFORM_ORIGINS],r=window.location.ancestorOrigins?.[0];return r&&!t.includes(r)&&isPlatformParentOrigin(r)&&t.push(r),t}function T(){return `wallet-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function L(t,r,i){if(typeof window>"u"||window.self===window.top)return Promise.resolve({ok:false,error:m});let n=window.parent;if(!n)return Promise.resolve({ok:false,error:m});let e=T();return new Promise(f=>{let l=false,a,u=o=>{l||(l=true,window.removeEventListener("message",g),clearTimeout(a),f(o));},g=o=>{if(!isPlatformParentOrigin(o.origin))return;let s=o.data;if(!(!s||s.requestId!==e)){if(s.type===d.ack){clearTimeout(a),a=setTimeout(()=>u({ok:false,error:"TIMEOUT"}),A);return}s.type===r&&u({ok:s.ok===true,error:typeof s.error=="string"?s.error:void 0,address:typeof s.address=="string"?s.address:void 0,signature:typeof s.signature=="string"?s.signature:void 0});}};a=setTimeout(()=>u({ok:false,error:m}),p),window.addEventListener("message",g);for(let o of S())try{n.postMessage({type:t,requestId:e,...i},o);}catch{}})}async function W(){return (await L(d.openRequest,d.openResponse,{})).ok}async function k(t){let{client:r,networkID:i}=t;return R(t,async n=>{let e=await r.auth.requestWalletChallenge(n,i);return e.ok?{ok:true,message:e.data.Message}:{ok:false,error:e.error}},(n,e)=>r.auth.loginWithWallet(n,i,e))}async function O(t){let{client:r,networkID:i}=t;return R(t,async n=>{let e=await r.auth.linkWallet(n,i);return e.ok?e.data.Challenge?{ok:true,message:e.data.Challenge}:{ok:false,error:"No challenge was issued."}:{ok:false,error:e.error}},(n,e)=>r.auth.linkWallet(n,i,e))}async function R(t,r,i){let{client:n,family:e}=t,f=n.titleID,l=await L(d.addressRequest,d.addressResponse,{titleID:f,family:e});if(!l.ok||!l.address)return c("challenge",l.error??"NO_WALLET");let a=l.address,u=await r(a);if(!u.ok)return c("challenge",u.error);let g=await L(d.signRequest,d.signResponse,{titleID:f,family:e,address:a,message:u.message});if(!g.ok||!g.signature)return c("sign",g.error??"SIGN_FAILED");let o=await i(a,g.signature);return o.ok?{ok:true,data:o.data}:c("login",o.error)}export{d as a,m as b,W as c,k as d,O as e};
@@ -1 +0,0 @@
1
- import {useReducer,useState,useEffect,useMemo}from'react';import {jsxs,jsx,Fragment}from'react/jsx-runtime';var E=null;function M(t){E=t;}function q(){return E}function Q(t,o){switch(t){case null:case void 0:case "":return o;case "PLAY_ACCESS_WALLET_USED_BY_ANOTHER_ACCOUNT":return "This wallet already plays with another account.";case "WALLET_UNLINK_COOLDOWN":return "This wallet was unlinked from another account less than 7 days ago. Try again after the 7 days.";case "WALLET_CHANGES_TOO_FREQUENT":return "Too many wallets were changed this week. Try again in a few days.";case "PLAY_ACCESS_WALLET_LOGIN_ONLY":return "This game is played with a wallet login only.";case "INVALID_WALLET_SIGNATURE":return "The signature does not match the wallet. Please try again.";case "WALLET_CHALLENGE_EXPIRED":return "The request expired. Please try again.";default:return t}}var j={pointerEvents:"auto",background:"#04276bf5",border:"1px solid #1e59c8",borderRadius:12,padding:16,color:"#fff",width:320,boxSizing:"border-box",fontFamily:"system-ui, sans-serif",display:"flex",flexDirection:"column",gap:10,maxHeight:"80vh",overflow:"auto"},z={fontWeight:700,fontSize:16},a={fontSize:12,opacity:.7},v={background:"#052e7e",border:"1px solid #1e59c8",borderRadius:8,color:"#fff",padding:"8px 10px",width:"100%",boxSizing:"border-box"},H={background:"#0d66fe",color:"#fff",border:"none",borderRadius:8,padding:"9px 14px",fontWeight:700,cursor:"pointer"},f={background:"#1e59c8",color:"#fff",border:"none",borderRadius:8,padding:"7px 12px",fontWeight:600,cursor:"pointer"},m={display:"flex",gap:8};function J({client:t,engine:o,onClose:S,style:L}){let[,I]=useReducer(e=>e+1,0),[g,_]=useState({}),[k,B]=useState({}),[l,x]=useState(""),[s,N]=useState(""),[w,W]=useState(""),[p,D]=useState(false),[T,A]=useState(null);useEffect(()=>{let e=true;return (async()=>{let r=await t.blockchain.getDefinitions();if(await t.blockchain.getUserState(),!e||!r.ok)return;let u={};for(let[K,R]of Object.entries(r.data.Blockchain?.Networks??{}))R.Type===o.networkType&&(u[K]=R);_(u),B(r.data.CryptoCurrencies??{}),x(Object.keys(u)[0]??"");})(),()=>{e=false;}},[t,o.networkType]),useEffect(()=>t.on("user:anyUpdated",I),[t]);let d=useMemo(()=>Object.entries(k).filter(([,e])=>e.Networks?.some(r=>r.NetworkID===l&&!!r.ContractAddress)),[k,l]);useEffect(()=>{let e=d[0]?.[0]??"";N(r=>d.some(([u])=>u===r)?r:e);},[d]);let y=l?g[l]:void 0,b=s?k[s]?.Networks?.find(e=>e.NetworkID===l):void 0,O=s?t.data.user.getCryptoCurrencyAmount(s):"0",C=!!o.address;async function P(e){D(true),A(null);try{let r=await e();A(r),r.ok&&await t.blockchain.getUserState();}finally{D(false);}}return jsxs("div",{style:{...j,...L},children:[jsxs("div",{style:{...m,justifyContent:"space-between"},children:[jsx("span",{style:z,children:"Crypto wallet"}),S&&jsx("button",{type:"button",style:f,onClick:S,children:"\u2715"})]}),C?jsxs("div",{style:m,children:[jsxs("span",{style:{...a,flex:1,alignSelf:"center"},children:[o.address.slice(0,6),"\u2026",o.address.slice(-4)]}),jsx("button",{type:"button",style:f,onClick:o.disconnect,children:"Disconnect"})]}):jsxs("div",{style:{display:"flex",flexDirection:"column",gap:6},children:[jsx("span",{style:a,children:"Connect a browser or mobile wallet"}),o.connectChoices.length===0?jsx("span",{style:a,children:"Wallet connection is not configured for this title."}):o.connectChoices.map(e=>jsx("button",{type:"button",style:f,onClick:e.connect,children:e.label},e.key))]}),Object.keys(g).length===0?jsxs("span",{style:a,children:["No ",o.networkType," networks configured for this title."]}):jsxs(Fragment,{children:[jsxs("div",{children:[jsx("div",{style:a,children:"Network"}),jsx("select",{style:v,value:l,onChange:e=>x(e.target.value),children:Object.entries(g).map(([e,r])=>jsx("option",{value:e,children:r.DisplayName??e},e))})]}),jsxs("div",{children:[jsx("div",{style:a,children:"Token"}),jsxs("select",{style:v,value:s,onChange:e=>N(e.target.value),children:[d.length===0&&jsx("option",{value:"",children:"\u2014 no depositable tokens \u2014"}),d.map(([e,r])=>jsx("option",{value:e,children:r.DisplayName??e},e))]})]}),jsxs("div",{style:a,children:["In-game balance: ",jsx("b",{children:O})," ",s]}),jsxs("div",{children:[jsx("div",{style:a,children:"Amount"}),jsx("input",{style:v,inputMode:"decimal",placeholder:"0.0",value:w,onChange:e=>W(e.target.value)})]}),jsxs("div",{style:m,children:[jsx("button",{type:"button",style:{...H,flex:1,opacity:p?.6:1},disabled:p||!C||!b?.ContractAddress,onClick:()=>{!y||!b||P(()=>o.deposit({network:y,binding:b,currencyID:s,amount:w||"0"}));},children:"Deposit"}),jsx("button",{type:"button",style:{...f,flex:1,opacity:p?.6:1},disabled:p||!C||!s,onClick:()=>{y&&P(()=>o.withdraw({network:y,networkID:l,currencyID:s,amount:w||"0"}));},children:"Withdraw"})]})]}),T&&jsx(V,{result:T})]})}function V({result:t}){let o={fontSize:12,borderRadius:8,padding:"8px 10px",background:t.ok?"#1e3a2a":"#3a1e28",color:t.ok?"#8ef0b0":"#f2a0b4",wordBreak:"break-all"};return t.ok?jsxs("div",{style:o,children:["\u2713 Done \xB7 tx ",t.onChainTxHash]}):jsxs("div",{style:o,children:["\u2715 [",t.stage,"] ",t.error,t.titleTransactionID?` \xB7 already debited (tx ${t.titleTransactionID}) \u2014 retry/confirm, don't re-request`:""]})}export{M as a,q as b,Q as c,J as d};