@idosgames/wallet 0.1.0

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.
@@ -0,0 +1,335 @@
1
+ import { E as EvmBridgeClients, W as WalletLoginResult } from './bridge-BCxf6AHE.js';
2
+ export { B as BridgeFailure, a as BridgeResult, b as BridgeStage, c as BridgeSuccess, D as DepositNft721EvmParams, d as DepositNftEvmParams, e as DepositTokenEvmParams, f as DepositTokenSolanaParams, S as SolanaProgramAdapter, g as WalletLoginFailure, h as WalletLoginStage, i as WalletLoginSuccess, j as WithdrawNftEvmParams, k as WithdrawTokenEvmParams, l as WithdrawTokenSolanaParams, m as bridgeFail, n as depositNftEvm, o as depositNftEvm721, p as depositTokenEvm, q as depositTokenSolana, r as ensureErc20Allowance, s as submitEvmNftWithdrawal, t as submitEvmNftWithdrawal721, u as submitEvmTokenWithdrawal, v as toErrorMessage, w as walletLoginFail, x as withdrawNftEvm, y as withdrawTokenEvm, z as withdrawTokenSolana, A as writeAndWait } from './bridge-BCxf6AHE.js';
3
+ import { Hex } from 'viem';
4
+ import { IDosGamesClient, ClientState } from '@idosgames/core';
5
+
6
+ declare const rewardPoolAbi: readonly [{
7
+ readonly type: "function";
8
+ readonly name: "depositERC20";
9
+ readonly stateMutability: "nonpayable";
10
+ readonly inputs: readonly [{
11
+ readonly name: "token";
12
+ readonly type: "address";
13
+ }, {
14
+ readonly name: "amount";
15
+ readonly type: "uint256";
16
+ }, {
17
+ readonly name: "userID";
18
+ readonly type: "string";
19
+ }, {
20
+ readonly name: "titleID";
21
+ readonly type: "string";
22
+ }, {
23
+ readonly name: "category";
24
+ readonly type: "string";
25
+ }];
26
+ readonly outputs: readonly [{
27
+ readonly name: "";
28
+ readonly type: "bool";
29
+ }];
30
+ }, {
31
+ readonly type: "function";
32
+ readonly name: "withdrawERC20";
33
+ readonly stateMutability: "nonpayable";
34
+ readonly inputs: readonly [{
35
+ readonly name: "token";
36
+ readonly type: "address";
37
+ }, {
38
+ readonly name: "to";
39
+ readonly type: "address";
40
+ }, {
41
+ readonly name: "amount";
42
+ readonly type: "uint256";
43
+ }, {
44
+ readonly name: "burnAmount";
45
+ readonly type: "uint256";
46
+ }, {
47
+ readonly name: "nonce";
48
+ readonly type: "uint256";
49
+ }, {
50
+ readonly name: "signature";
51
+ readonly type: "bytes";
52
+ }, {
53
+ readonly name: "userID";
54
+ readonly type: "string";
55
+ }, {
56
+ readonly name: "titleID";
57
+ readonly type: "string";
58
+ }, {
59
+ readonly name: "category";
60
+ readonly type: "string";
61
+ }, {
62
+ readonly name: "deadline";
63
+ readonly type: "uint256";
64
+ }];
65
+ readonly outputs: readonly [];
66
+ }, {
67
+ readonly type: "function";
68
+ readonly name: "withdrawERC1155";
69
+ readonly stateMutability: "nonpayable";
70
+ readonly inputs: readonly [{
71
+ readonly name: "token";
72
+ readonly type: "address";
73
+ }, {
74
+ readonly name: "to";
75
+ readonly type: "address";
76
+ }, {
77
+ readonly name: "id";
78
+ readonly type: "uint256";
79
+ }, {
80
+ readonly name: "amount";
81
+ readonly type: "uint256";
82
+ }, {
83
+ readonly name: "nonce";
84
+ readonly type: "uint256";
85
+ }, {
86
+ readonly name: "signature";
87
+ readonly type: "bytes";
88
+ }, {
89
+ readonly name: "userID";
90
+ readonly type: "string";
91
+ }, {
92
+ readonly name: "titleID";
93
+ readonly type: "string";
94
+ }, {
95
+ readonly name: "category";
96
+ readonly type: "string";
97
+ }, {
98
+ readonly name: "deadline";
99
+ readonly type: "uint256";
100
+ }];
101
+ readonly outputs: readonly [];
102
+ }, {
103
+ readonly type: "function";
104
+ readonly name: "withdrawERC721";
105
+ readonly stateMutability: "nonpayable";
106
+ readonly inputs: readonly [{
107
+ readonly name: "token";
108
+ readonly type: "address";
109
+ }, {
110
+ readonly name: "to";
111
+ readonly type: "address";
112
+ }, {
113
+ readonly name: "tokenId";
114
+ readonly type: "uint256";
115
+ }, {
116
+ readonly name: "nonce";
117
+ readonly type: "uint256";
118
+ }, {
119
+ readonly name: "signature";
120
+ readonly type: "bytes";
121
+ }, {
122
+ readonly name: "userID";
123
+ readonly type: "string";
124
+ }, {
125
+ readonly name: "titleID";
126
+ readonly type: "string";
127
+ }, {
128
+ readonly name: "category";
129
+ readonly type: "string";
130
+ }, {
131
+ readonly name: "deadline";
132
+ readonly type: "uint256";
133
+ }];
134
+ readonly outputs: readonly [];
135
+ }];
136
+ /** Minimal ERC-20 surface the bridge needs (approve/allowance for deposits, decimals/balance for UX). */
137
+ declare const erc20Abi: readonly [{
138
+ readonly type: "function";
139
+ readonly name: "approve";
140
+ readonly stateMutability: "nonpayable";
141
+ readonly inputs: readonly [{
142
+ readonly name: "spender";
143
+ readonly type: "address";
144
+ }, {
145
+ readonly name: "amount";
146
+ readonly type: "uint256";
147
+ }];
148
+ readonly outputs: readonly [{
149
+ readonly name: "";
150
+ readonly type: "bool";
151
+ }];
152
+ }, {
153
+ readonly type: "function";
154
+ readonly name: "allowance";
155
+ readonly stateMutability: "view";
156
+ readonly inputs: readonly [{
157
+ readonly name: "owner";
158
+ readonly type: "address";
159
+ }, {
160
+ readonly name: "spender";
161
+ readonly type: "address";
162
+ }];
163
+ readonly outputs: readonly [{
164
+ readonly name: "";
165
+ readonly type: "uint256";
166
+ }];
167
+ }, {
168
+ readonly type: "function";
169
+ readonly name: "decimals";
170
+ readonly stateMutability: "view";
171
+ readonly inputs: readonly [];
172
+ readonly outputs: readonly [{
173
+ readonly name: "";
174
+ readonly type: "uint8";
175
+ }];
176
+ }, {
177
+ readonly type: "function";
178
+ readonly name: "balanceOf";
179
+ readonly stateMutability: "view";
180
+ readonly inputs: readonly [{
181
+ readonly name: "account";
182
+ readonly type: "address";
183
+ }];
184
+ readonly outputs: readonly [{
185
+ readonly name: "";
186
+ readonly type: "uint256";
187
+ }];
188
+ }];
189
+ /**
190
+ * Minimal ERC-1155 surface. NFT deposits go through the collection contract's own
191
+ * `safeTransferFrom(from, to=pool, id, amount, data)`, where `data` carries the ABI-encoded
192
+ * (userID, titleID, category) the receiving RewardPool decodes — see {@link encodeNftDepositData}.
193
+ */
194
+ declare const erc1155Abi: readonly [{
195
+ readonly type: "function";
196
+ readonly name: "safeTransferFrom";
197
+ readonly stateMutability: "nonpayable";
198
+ readonly inputs: readonly [{
199
+ readonly name: "from";
200
+ readonly type: "address";
201
+ }, {
202
+ readonly name: "to";
203
+ readonly type: "address";
204
+ }, {
205
+ readonly name: "id";
206
+ readonly type: "uint256";
207
+ }, {
208
+ readonly name: "amount";
209
+ readonly type: "uint256";
210
+ }, {
211
+ readonly name: "data";
212
+ readonly type: "bytes";
213
+ }];
214
+ readonly outputs: readonly [];
215
+ }, {
216
+ readonly type: "function";
217
+ readonly name: "isApprovedForAll";
218
+ readonly stateMutability: "view";
219
+ readonly inputs: readonly [{
220
+ readonly name: "account";
221
+ readonly type: "address";
222
+ }, {
223
+ readonly name: "operator";
224
+ readonly type: "address";
225
+ }];
226
+ readonly outputs: readonly [{
227
+ readonly name: "";
228
+ readonly type: "bool";
229
+ }];
230
+ }, {
231
+ readonly type: "function";
232
+ readonly name: "setApprovalForAll";
233
+ readonly stateMutability: "nonpayable";
234
+ readonly inputs: readonly [{
235
+ readonly name: "operator";
236
+ readonly type: "address";
237
+ }, {
238
+ readonly name: "approved";
239
+ readonly type: "bool";
240
+ }];
241
+ readonly outputs: readonly [];
242
+ }, {
243
+ readonly type: "function";
244
+ readonly name: "balanceOf";
245
+ readonly stateMutability: "view";
246
+ readonly inputs: readonly [{
247
+ readonly name: "account";
248
+ readonly type: "address";
249
+ }, {
250
+ readonly name: "id";
251
+ readonly type: "uint256";
252
+ }];
253
+ readonly outputs: readonly [{
254
+ readonly name: "";
255
+ readonly type: "uint256";
256
+ }];
257
+ }];
258
+ /**
259
+ * Minimal ERC-721 surface. NFT deposits go through the collection contract's own 4-arg
260
+ * `safeTransferFrom(from, to=pool, tokenId, data)`, where `data` carries the ABI-encoded
261
+ * (userID, titleID, category) the receiving RewardPool decodes — see {@link encodeNftDepositData}.
262
+ */
263
+ declare const erc721Abi: readonly [{
264
+ readonly type: "function";
265
+ readonly name: "safeTransferFrom";
266
+ readonly stateMutability: "nonpayable";
267
+ readonly inputs: readonly [{
268
+ readonly name: "from";
269
+ readonly type: "address";
270
+ }, {
271
+ readonly name: "to";
272
+ readonly type: "address";
273
+ }, {
274
+ readonly name: "tokenId";
275
+ readonly type: "uint256";
276
+ }, {
277
+ readonly name: "data";
278
+ readonly type: "bytes";
279
+ }];
280
+ readonly outputs: readonly [];
281
+ }];
282
+
283
+ /**
284
+ * Builds the `data` blob for an ERC-1155 NFT deposit's `safeTransferFrom`.
285
+ *
286
+ * The updated RewardPool decodes this as `abi.encode(string userID, string titleID, string
287
+ * category)` — see RewardPoolEvmV2.GetDepositIdsFromNftTransferData / DepositIdsOutput on the
288
+ * backend. The three fields must be a non-packed ABI encode of exactly (string, string, string)
289
+ * in that order, or the receiver can't attribute the deposit and the backend rejects it with
290
+ * "Cannot extract userID from transaction."
291
+ */
292
+ declare function encodeNftDepositData(userID: string, titleID: string, category?: string): Hex;
293
+
294
+ interface LoginWithWalletEvmParams {
295
+ client: IDosGamesClient;
296
+ clients: EvmBridgeClients;
297
+ /** NetworkID (key of cfg.Blockchain.Networks) the wallet proves ownership on. Must be an EVM network. */
298
+ networkID: string;
299
+ /** Address to authenticate; defaults to the connected `clients.account`. */
300
+ walletAddress?: string;
301
+ }
302
+ /**
303
+ * Full EVM wallet-login flow: `requestWalletChallenge` → `personal_sign` the returned message with
304
+ * the connected wallet → `loginWithWallet`. On success the core client is logged in (auth context
305
+ * applied, client state fetched) and the fresh {@link ClientState} is returned.
306
+ *
307
+ * No on-chain transaction and no gas — this is an off-chain signature proving wallet ownership.
308
+ * A user-rejected signature surfaces as a `{ ok: false, stage: "sign" }` failure, not a throw.
309
+ */
310
+ declare function loginWithWalletEvm(params: LoginWithWalletEvmParams): Promise<WalletLoginResult<ClientState>>;
311
+
312
+ /**
313
+ * A wallet-adapter message signer: signs raw bytes and returns the 64-byte ed25519 signature.
314
+ * This is exactly the shape of `@solana/wallet-adapter-react`'s `useWallet().signMessage`.
315
+ */
316
+ type SolanaMessageSigner = (message: Uint8Array) => Promise<Uint8Array>;
317
+ interface LoginWithWalletSolanaParams {
318
+ client: IDosGamesClient;
319
+ /** NetworkID (key of cfg.Blockchain.Networks) the wallet proves ownership on. Must be a Solana network. */
320
+ networkID: string;
321
+ /** The connected wallet's base58 address (owner pubkey). */
322
+ walletAddress: string;
323
+ /** The connected wallet's message signer (e.g. `useWallet().signMessage`). */
324
+ signMessage: SolanaMessageSigner;
325
+ }
326
+ /**
327
+ * Full Solana wallet-login flow: `requestWalletChallenge` → sign the returned message bytes with
328
+ * the connected wallet (`signMessage`) → `loginWithWallet`. The signature is sent as 0x-hex, which
329
+ * the backend decodes unambiguously (base58/base64 ed25519 signatures can collide with each other's
330
+ * alphabets, so hex avoids the guesswork). On success the core client is logged in and the fresh
331
+ * {@link ClientState} is returned. No on-chain transaction — off-chain proof of ownership only.
332
+ */
333
+ declare function loginWithWalletSolana(params: LoginWithWalletSolanaParams): Promise<WalletLoginResult<ClientState>>;
334
+
335
+ export { EvmBridgeClients, type LoginWithWalletEvmParams, type LoginWithWalletSolanaParams, type SolanaMessageSigner, WalletLoginResult, encodeNftDepositData, erc1155Abi, erc20Abi, erc721Abi, loginWithWalletEvm, loginWithWalletSolana, rewardPoolAbi };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export{b as bridgeFail,l as depositNftEvm,m as depositNftEvm721,k as depositTokenEvm,t as depositTokenSolana,h as encodeNftDepositData,j as ensureErc20Allowance,f as erc1155Abi,e as erc20Abi,g as erc721Abi,s as loginWithWalletEvm,v as loginWithWalletSolana,d as rewardPoolAbi,o as submitEvmNftWithdrawal,p as submitEvmNftWithdrawal721,n as submitEvmTokenWithdrawal,a as toErrorMessage,c as walletLoginFail,r as withdrawNftEvm,q as withdrawTokenEvm,u as withdrawTokenSolana,i as writeAndWait}from'./chunk-Q6C5EFPV.js';
@@ -0,0 +1 @@
1
+ 'use strict';var wagmi=require('wagmi'),connectors=require('wagmi/connectors'),reactQuery=require('@tanstack/react-query'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),viem=require('viem'),core=require('@idosgames/core'),walletAdapterReact=require('@solana/wallet-adapter-react');function _(t){let{chains:e,walletConnectProjectId:n,appName:r,appUrl:s,appIcon:i,transports:l,connectors:p}=t,o=r||s?{name:r??"iDosGames",description:r??"iDosGames game",url:s??"",icons:i?[i]:[]}:void 0,m=p??[connectors.injected(),connectors.coinbaseWallet({appName:r??"iDosGames"}),...n?[connectors.walletConnect({projectId:n,metadata:o,showQrModal:true})]:[]],d={};for(let c of e)d[c.id]=l?.[c.id]??wagmi.http();return wagmi.createConfig({chains:e,connectors:m,transports:d})}function Y(t){let{wagmiConfig:e,queryClient:n,children:r}=t,[s]=react.useState(()=>n??new reactQuery.QueryClient);return jsxRuntime.jsx(wagmi.WagmiProvider,{config:e,children:jsxRuntime.jsx(reactQuery.QueryClientProvider,{client:s,children:r})})}var k=[{type:"function",name:"depositERC20",stateMutability:"nonpayable",inputs:[{name:"token",type:"address"},{name:"amount",type:"uint256"},{name:"userID",type:"string"},{name:"titleID",type:"string"},{name:"category",type:"string"}],outputs:[{name:"",type:"bool"}]},{type:"function",name:"withdrawERC20",stateMutability:"nonpayable",inputs:[{name:"token",type:"address"},{name:"to",type:"address"},{name:"amount",type:"uint256"},{name:"burnAmount",type:"uint256"},{name:"nonce",type:"uint256"},{name:"signature",type:"bytes"},{name:"userID",type:"string"},{name:"titleID",type:"string"},{name:"category",type:"string"},{name:"deadline",type:"uint256"}],outputs:[]},{type:"function",name:"withdrawERC1155",stateMutability:"nonpayable",inputs:[{name:"token",type:"address"},{name:"to",type:"address"},{name:"id",type:"uint256"},{name:"amount",type:"uint256"},{name:"nonce",type:"uint256"},{name:"signature",type:"bytes"},{name:"userID",type:"string"},{name:"titleID",type:"string"},{name:"category",type:"string"},{name:"deadline",type:"uint256"}],outputs:[]},{type:"function",name:"withdrawERC721",stateMutability:"nonpayable",inputs:[{name:"token",type:"address"},{name:"to",type:"address"},{name:"tokenId",type:"uint256"},{name:"nonce",type:"uint256"},{name:"signature",type:"bytes"},{name:"userID",type:"string"},{name:"titleID",type:"string"},{name:"category",type:"string"},{name:"deadline",type:"uint256"}],outputs:[]}],E=[{type:"function",name:"withdrawERC1155Mint",stateMutability:"nonpayable",inputs:[{name:"collection",type:"address"},{name:"to",type:"address"},{name:"id",type:"uint256"},{name:"amount",type:"uint256"},{name:"nonce",type:"uint256"},{name:"signature",type:"bytes"},{name:"userID",type:"string"},{name:"titleID",type:"string"},{name:"category",type:"string"},{name:"deadline",type:"uint256"}],outputs:[]},{type:"function",name:"withdrawERC721Mint",stateMutability:"nonpayable",inputs:[{name:"collection",type:"address"},{name:"to",type:"address"},{name:"tokenId",type:"uint256"},{name:"nonce",type:"uint256"},{name:"signature",type:"bytes"},{name:"userID",type:"string"},{name:"titleID",type:"string"},{name:"category",type:"string"},{name:"deadline",type:"uint256"}],outputs:[]}],D=[{type:"function",name:"approve",stateMutability:"nonpayable",inputs:[{name:"spender",type:"address"},{name:"amount",type:"uint256"}],outputs:[{name:"",type:"bool"}]},{type:"function",name:"allowance",stateMutability:"view",inputs:[{name:"owner",type:"address"},{name:"spender",type:"address"}],outputs:[{name:"",type:"uint256"}]},{type:"function",name:"decimals",stateMutability:"view",inputs:[],outputs:[{name:"",type:"uint8"}]},{type:"function",name:"balanceOf",stateMutability:"view",inputs:[{name:"account",type:"address"}],outputs:[{name:"",type:"uint256"}]}],N=[{type:"function",name:"safeTransferFrom",stateMutability:"nonpayable",inputs:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"id",type:"uint256"},{name:"amount",type:"uint256"},{name:"data",type:"bytes"}],outputs:[]},{type:"function",name:"isApprovedForAll",stateMutability:"view",inputs:[{name:"account",type:"address"},{name:"operator",type:"address"}],outputs:[{name:"",type:"bool"}]},{type:"function",name:"setApprovalForAll",stateMutability:"nonpayable",inputs:[{name:"operator",type:"address"},{name:"approved",type:"bool"}],outputs:[]},{type:"function",name:"balanceOf",stateMutability:"view",inputs:[{name:"account",type:"address"},{name:"id",type:"uint256"}],outputs:[{name:"",type:"uint256"}]}];function B(t,e,n){return viem.encodeAbiParameters([{type:"string"},{type:"string"},{type:"string"}],[t,e,core.normalizeBlockchainCategory(n)])}async function w(t,e){let{walletClient:n,publicClient:r,account:s}=t,i=await n.writeContract({address:e.address,abi:e.abi,functionName:e.functionName,args:e.args,account:s,chain:n.chain,value:e.value});if((await r.waitForTransactionReceipt({hash:i})).status==="reverted")throw new Error(`On-chain transaction reverted (${i}).`);return i}function g(t){return t instanceof viem.BaseError?t.shortMessage:t instanceof Error?t.message:String(t)}function a(t,e,n){return {ok:false,stage:t,error:e,...n}}function f(t,e){return {ok:false,stage:t,error:e}}function S(t){let e=t.PlatformPoolAddress;return e||null}async function R(t,e,n,r){return await t.publicClient.readContract({address:e,abi:D,functionName:"allowance",args:[t.account,n]})>=r?null:w(t,{address:e,abi:D,functionName:"approve",args:[n,r]})}async function T(t){let{client:e,clients:n,network:r,tokenAddress:s,amount:i,titleID:l,category:p}=t,o=e.auth.context?.userID;if(!o)return a("approve","Not logged in.");let m=S(r);if(!m)return a("approve","Network has no PlatformPoolAddress.");if(i<=0n)return a("approve","Amount must be positive.");try{await R(n,s,m,i);}catch(u){return a("approve",g(u))}let d;try{d=await w(n,{address:m,abi:k,functionName:"depositERC20",args:[s,i,o,l,p??""]});}catch(u){return a("deposit-onchain",g(u))}let c=await e.blockchain.depositToken(r.NetworkID??"",d);return c.ok?{ok:true,onChainTxHash:d,data:c.data}:a("report",c.error,{onChainTxHash:d})}async function C(t){let{client:e,clients:n,network:r,nftContractAddress:s,tokenId:i,amount:l,titleID:p,category:o}=t,m=e.auth.context?.userID;if(!m)return a("deposit-onchain","Not logged in.");let d=S(r);if(!d)return a("deposit-onchain","Network has no PlatformPoolAddress.");if(l<=0n)return a("deposit-onchain","Amount must be positive.");let c=B(m,p,o),u;try{u=await w(n,{address:s,abi:N,functionName:"safeTransferFrom",args:[n.account,d,i,l,c]});}catch(q){return a("deposit-onchain",g(q))}let y=await e.blockchain.depositNFT(r.NetworkID??"",u);return y.ok?{ok:true,onChainTxHash:u,data:y.data}:a("report",y.error,{onChainTxHash:u})}async function F(t,e){return w(t,{address:e.ContractAddress,abi:k,functionName:"withdrawERC20",args:[e.TokenAddress,e.WalletAddress,BigInt(e.Amount??"0"),BigInt(e.BurnAmount??"0"),BigInt(e.Nonce??"0"),e.Signature??"0x",e.UserID??"",e.TitleID??"",e.Category??"",BigInt(e.Deadline??"0")]})}async function M(t,e){return w(t,{address:e.ContractAddress,abi:E,functionName:"withdrawERC1155Mint",args:[e.TokenAddress,e.WalletAddress,BigInt(e.TokenId??"0"),BigInt(e.Amount??"0"),BigInt(e.Nonce??"0"),e.Signature??"0x",e.UserID??"",e.TitleID??"",e.Category??"",BigInt(e.Deadline??"0")]})}async function W(t){let{client:e,clients:n,currencyID:r,networkID:s,walletAddress:i,amount:l,category:p}=t,o=await e.blockchain.requestTokenWithdrawal(r,s,i,l,p);if(!o.ok)return a("request",o.error);let m=o.data.EvmSignature,d=o.data.TitleTransactionID??void 0;if(!m)return a("request","Withdrawal response carried no EVM signature.",{titleTransactionID:d});let c;try{c=await F(n,m);}catch(y){return a("withdraw-onchain",g(y),{titleTransactionID:d})}let u=await H(e,d,c);return u.ok?{ok:true,onChainTxHash:c,data:o.data}:u}async function v(t){let{client:e,clients:n,itemID:r,networkID:s,walletAddress:i,amount:l,category:p}=t,o=await e.blockchain.requestNFTWithdrawal(r,s,i,l,p);if(!o.ok)return a("request",o.error);let m=o.data.EvmSignature,d=o.data.TitleTransactionID??void 0;if(!m)return a("request","Withdrawal response carried no EVM signature.",{titleTransactionID:d});let c;try{c=await M(n,m);}catch(y){return a("withdraw-onchain",g(y),{titleTransactionID:d})}let u=await H(e,d,c);return u.ok?{ok:true,onChainTxHash:c,data:o.data}:u}async function H(t,e,n){if(!e)return a("confirm","Missing TitleTransactionID.",{onChainTxHash:n});let r=await t.blockchain.confirmWithdrawal(e,n);return r.ok?{ok:true,onChainTxHash:n,data:r.data}:a("confirm",r.error,{onChainTxHash:n,titleTransactionID:e})}async function A(t){let{client:e,clients:n,networkID:r}=t,s=t.walletAddress??n.account,i=await e.auth.requestWalletChallenge(s,r);if(!i.ok)return f("challenge",i.error);let l;try{l=await n.walletClient.signMessage({account:n.account,message:i.data.Message});}catch(o){return f("sign",g(o))}let p=await e.auth.loginWithWallet(s,r,l);return p.ok?{ok:true,data:p.data}:f("login",p.error)}function L(){let{address:t}=wagmi.useAccount(),e=wagmi.usePublicClient(),{data:n}=wagmi.useWalletClient();return !t||!e||!n?null:{account:t,publicClient:e,walletClient:n}}var h="Wallet not connected.";function oe(t,e){let n=L();return {connected:!!n,account:n?.account??null,loginWithWallet:(r,s)=>n?A({client:t,clients:n,networkID:r,walletAddress:s}):Promise.resolve(f("challenge",h)),depositToken:r=>n?T({client:t,clients:n,titleID:e,...r}):Promise.resolve(a("approve",h)),depositNft:r=>n?C({client:t,clients:n,titleID:e,...r}):Promise.resolve(a("deposit-onchain",h)),withdrawToken:r=>n?W({client:t,clients:n,...r}):Promise.resolve(a("withdraw-onchain",h)),withdrawNft:r=>n?v({client:t,clients:n,...r}):Promise.resolve(a("withdraw-onchain",h))}}function le(t){let{endpoint:e,wallets:n,autoConnect:r=true,children:s}=t;return jsxRuntime.jsx(walletAdapterReact.ConnectionProvider,{endpoint:e,children:jsxRuntime.jsx(walletAdapterReact.WalletProvider,{wallets:n,autoConnect:r,children:s})})}async function b(t){let{client:e,adapter:n,network:r,mint:s,amountRaw:i,titleID:l,category:p}=t,o=e.auth.context?.userID;if(!o)return a("deposit-onchain","Not logged in.");if(i<=0n)return a("deposit-onchain","Amount must be positive.");let m;try{m=await n.depositSpl({mint:s,amountRaw:i,userID:o,titleID:l,category:core.normalizeBlockchainCategory(p)});}catch(c){return a("deposit-onchain",g(c))}let d=await e.blockchain.depositToken(r.NetworkID??"",m);return d.ok?{ok:true,onChainTxHash:m,data:d.data}:a("report",d.error,{onChainTxHash:m})}async function P(t){let{client:e,adapter:n,currencyID:r,networkID:s,walletAddress:i,amount:l,category:p}=t,o=await e.blockchain.requestTokenWithdrawal(r,s,i,l,p);if(!o.ok)return a("request",o.error);let m=o.data.SolanaSignature,d=o.data.TitleTransactionID??void 0;if(!m)return a("request","Withdrawal response carried no Solana signature.",{titleTransactionID:d});let c;try{c=await n.submitWithdrawal(m);}catch(y){return a("withdraw-onchain",g(y),{titleTransactionID:d})}if(!d)return a("confirm","Missing TitleTransactionID.",{onChainTxHash:c});let u=await e.blockchain.confirmWithdrawal(d,c);return u.ok?{ok:true,onChainTxHash:c,data:o.data}:a("confirm",u.error,{onChainTxHash:c,titleTransactionID:d})}async function x(t){let{client:e,networkID:n,walletAddress:r,signMessage:s}=t,i=await e.auth.requestWalletChallenge(r,n);if(!i.ok)return f("challenge",i.error);let l;try{let o=await s(new TextEncoder().encode(i.data.Message));l=pe(o);}catch(o){return f("sign",g(o))}let p=await e.auth.loginWithWallet(r,n,l);return p.ok?{ok:true,data:p.data}:f("login",p.error)}function pe(t){let e="0x";for(let n of t)e+=n.toString(16).padStart(2,"0");return e}var O="Wallet not connected.";function me(t,e,n){let{publicKey:r,signMessage:s}=walletAdapterReact.useWallet(),i=r?.toBase58()??null;return {connected:!!i,account:i,loginWithWallet:(l,p)=>{let o=p??i;return o?s?x({client:t,networkID:l,walletAddress:o,signMessage:s}):Promise.resolve(f("sign","The connected wallet does not support message signing.")):Promise.resolve(f("challenge",O))},depositToken:l=>b({client:t,adapter:n,titleID:e,...l}),withdrawToken:l=>{let p=l.walletAddress??i;return p?P({client:t,adapter:n,...l,walletAddress:p}):Promise.resolve(a("request",O))}}}exports.IDosGamesWalletProvider=Y;exports.SolanaWalletBridgeProvider=le;exports.createEvmWalletConfig=_;exports.useEvmBridge=oe;exports.useEvmBridgeClients=L;exports.useSolanaBridge=me;
@@ -0,0 +1,150 @@
1
+ import * as wagmi from 'wagmi';
2
+ import { CreateConnectorFn, Config } from 'wagmi';
3
+ import { Chain, Transport } from 'viem';
4
+ import * as react from 'react';
5
+ import { ReactNode } from 'react';
6
+ import { QueryClient } from '@tanstack/react-query';
7
+ import { ClientState, DepositTokenResponse, DepositNFTResponse, TokenWithdrawalResponse, NFTWithdrawalResponse, IDosGamesClient } from '@idosgames/core';
8
+ import { W as WalletLoginResult, e as DepositTokenEvmParams, a as BridgeResult, d as DepositNftEvmParams, k as WithdrawTokenEvmParams, j as WithdrawNftEvmParams, E as EvmBridgeClients, f as DepositTokenSolanaParams, l as WithdrawTokenSolanaParams, S as SolanaProgramAdapter } from '../bridge-BCxf6AHE.cjs';
9
+ import { Adapter } from '@solana/wallet-adapter-base';
10
+
11
+ interface EvmWalletConfigOptions {
12
+ /** Chains the game supports, matching the EVM networks in the title's blockchain config. */
13
+ chains: readonly [Chain, ...Chain[]];
14
+ /**
15
+ * WalletConnect Cloud project id — required to connect MOBILE wallets (and desktop wallets via
16
+ * QR). Get one at https://cloud.walletconnect.com. Omit to support browser-extension wallets only.
17
+ */
18
+ walletConnectProjectId?: string;
19
+ /** App name/metadata shown in the wallet's connect prompt. */
20
+ appName?: string;
21
+ appUrl?: string;
22
+ appIcon?: string;
23
+ /**
24
+ * Per-chain RPC transports. Defaults to `http()` (each chain's public RPC) for every chain —
25
+ * pass your own keyed by `chain.id` to use a private RPC endpoint.
26
+ */
27
+ transports?: Record<number, Transport>;
28
+ /**
29
+ * Override the connector list entirely. By default you get: `injected()` (MetaMask & other
30
+ * browser extensions), `walletConnect()` (mobile + QR, when a projectId is given), and
31
+ * `coinbaseWallet()`.
32
+ */
33
+ connectors?: CreateConnectorFn[];
34
+ }
35
+ /**
36
+ * Builds a wagmi `Config` wired for both browser and mobile wallets, ready to hand to
37
+ * {@link IDosGamesWalletProvider} (or a bare `WagmiProvider`).
38
+ *
39
+ * - Browser: `injected()` picks up MetaMask and any EIP-1193 extension.
40
+ * - Mobile: `walletConnect()` opens the WalletConnect modal (QR on desktop, deep-link on mobile)
41
+ * so phone wallets like MetaMask Mobile, Trust, Rainbow can connect. Needs a `walletConnectProjectId`.
42
+ */
43
+ declare function createEvmWalletConfig(options: EvmWalletConfigOptions): wagmi.Config<readonly [Chain, ...Chain[]], Record<number, Transport>, CreateConnectorFn[]>;
44
+
45
+ interface IDosGamesWalletProviderProps {
46
+ /** A wagmi config, typically from {@link createEvmWalletConfig}. */
47
+ wagmiConfig: Config;
48
+ /** Reuse an existing react-query client; a fresh one is created if omitted. */
49
+ queryClient?: QueryClient;
50
+ children: ReactNode;
51
+ }
52
+ /**
53
+ * Drop-in provider that sets up the EVM wallet stack: `WagmiProvider` (connectors, chains) +
54
+ * `QueryClientProvider` (wagmi's required react-query dependency). Wrap your app once, then use the
55
+ * EVM hooks below anywhere inside. For Solana, additionally wrap with the wallet-adapter
56
+ * `ConnectionProvider` + `WalletProvider` from `@solana/wallet-adapter-react`.
57
+ *
58
+ * ```tsx
59
+ * const wagmiConfig = createEvmWalletConfig({ chains: [polygon], walletConnectProjectId: "…" });
60
+ * <IDosGamesWalletProvider wagmiConfig={wagmiConfig}>
61
+ * <App />
62
+ * </IDosGamesWalletProvider>
63
+ * ```
64
+ */
65
+ declare function IDosGamesWalletProvider(props: IDosGamesWalletProviderProps): react.JSX.Element;
66
+
67
+ /**
68
+ * Assembles the viem clients the bridge needs from the connected wagmi wallet, or null when no
69
+ * wallet is connected / the wallet client isn't ready yet.
70
+ */
71
+ declare function useEvmBridgeClients(): EvmBridgeClients | null;
72
+ type DepositTokenArgs$1 = Omit<DepositTokenEvmParams, "client" | "clients" | "titleID">;
73
+ type DepositNftArgs = Omit<DepositNftEvmParams, "client" | "clients" | "titleID">;
74
+ type WithdrawTokenArgs$1 = Omit<WithdrawTokenEvmParams, "client" | "clients">;
75
+ type WithdrawNftArgs = Omit<WithdrawNftEvmParams, "client" | "clients">;
76
+ interface EvmBridge {
77
+ /** Whether a wallet is connected and its client is ready. */
78
+ connected: boolean;
79
+ /** The connected signing address, or null. */
80
+ account: string | null;
81
+ /**
82
+ * Logs into the game with the connected wallet by signing a server challenge (no gas, no tx).
83
+ * `networkID` is the cfg.Blockchain.Networks key the wallet proves on; `walletAddress` defaults
84
+ * to the connected account. On success the core client is logged in and its ClientState returned.
85
+ */
86
+ loginWithWallet(networkID: string, walletAddress?: string): Promise<WalletLoginResult<ClientState>>;
87
+ depositToken(args: DepositTokenArgs$1): Promise<BridgeResult<DepositTokenResponse>>;
88
+ depositNft(args: DepositNftArgs): Promise<BridgeResult<DepositNFTResponse>>;
89
+ withdrawToken(args: WithdrawTokenArgs$1): Promise<BridgeResult<TokenWithdrawalResponse>>;
90
+ withdrawNft(args: WithdrawNftArgs): Promise<BridgeResult<NFTWithdrawalResponse>>;
91
+ }
92
+ /**
93
+ * The ergonomic EVM bridge hook: binds the connected wagmi wallet to the four deposit/withdraw
94
+ * flows against a given core client + title. Each method returns a {@link BridgeResult}; a
95
+ * disconnected wallet yields a `{ ok: false }` instead of throwing.
96
+ *
97
+ * ```tsx
98
+ * const bridge = useEvmBridge(client, "my-title");
99
+ * const res = await bridge.depositToken({ network, tokenAddress, amount: parseUnits("25", 6) });
100
+ * if (!res.ok) toast(res.error);
101
+ * ```
102
+ */
103
+ declare function useEvmBridge(client: IDosGamesClient, titleID: string): EvmBridge;
104
+
105
+ interface SolanaWalletBridgeProviderProps {
106
+ /** RPC endpoint for the Solana network the title uses (matches its blockchain config). */
107
+ endpoint: string;
108
+ /**
109
+ * Wallet adapters to offer (e.g. `new PhantomWalletAdapter()` from
110
+ * `@solana/wallet-adapter-wallets`). Mobile support comes from adapters that implement it
111
+ * (Mobile Wallet Adapter on Android, or a WalletConnect adapter).
112
+ */
113
+ wallets: Adapter[];
114
+ /** Auto-reconnect the last-used wallet on mount. */
115
+ autoConnect?: boolean;
116
+ children: ReactNode;
117
+ }
118
+ /**
119
+ * Thin wrapper over wallet-adapter's `ConnectionProvider` + `WalletProvider` so the
120
+ * {@link useSolanaBridge} hook has a connected wallet. Compose it alongside
121
+ * {@link IDosGamesWalletProvider} when a title supports both EVM and Solana networks.
122
+ */
123
+ declare function SolanaWalletBridgeProvider(props: SolanaWalletBridgeProviderProps): react.JSX.Element;
124
+
125
+ type DepositTokenArgs = Omit<DepositTokenSolanaParams, "client" | "adapter" | "titleID">;
126
+ /** `walletAddress` defaults to the connected wallet if omitted. */
127
+ type WithdrawTokenArgs = Omit<WithdrawTokenSolanaParams, "client" | "adapter" | "walletAddress"> & {
128
+ walletAddress?: string;
129
+ };
130
+ interface SolanaBridge {
131
+ connected: boolean;
132
+ account: string | null;
133
+ /**
134
+ * Logs into the game with the connected Solana wallet by signing a server challenge (no tx, no
135
+ * fee). `networkID` is the cfg.Blockchain.Networks key; `walletAddress` defaults to the connected
136
+ * account. Requires a wallet that supports `signMessage`. Returns the fresh ClientState.
137
+ */
138
+ loginWithWallet(networkID: string, walletAddress?: string): Promise<WalletLoginResult<ClientState>>;
139
+ depositToken(args: DepositTokenArgs): Promise<BridgeResult<DepositTokenResponse>>;
140
+ withdrawToken(args: WithdrawTokenArgs): Promise<BridgeResult<TokenWithdrawalResponse>>;
141
+ }
142
+ /**
143
+ * The ergonomic Solana bridge hook: binds the connected wallet-adapter wallet + your
144
+ * {@link SolanaProgramAdapter} to the deposit/withdraw flows against a core client + title.
145
+ * The on-chain instruction building lives in the adapter (it owns the program IDL); this hook
146
+ * just wires the connected address and threads the request → submit → confirm lifecycle.
147
+ */
148
+ declare function useSolanaBridge(client: IDosGamesClient, titleID: string, adapter: SolanaProgramAdapter): SolanaBridge;
149
+
150
+ export { type EvmBridge, type EvmWalletConfigOptions, IDosGamesWalletProvider, type IDosGamesWalletProviderProps, type SolanaBridge, SolanaWalletBridgeProvider, type SolanaWalletBridgeProviderProps, createEvmWalletConfig, useEvmBridge, useEvmBridgeClients, useSolanaBridge };
@@ -0,0 +1,150 @@
1
+ import * as wagmi from 'wagmi';
2
+ import { CreateConnectorFn, Config } from 'wagmi';
3
+ import { Chain, Transport } from 'viem';
4
+ import * as react from 'react';
5
+ import { ReactNode } from 'react';
6
+ import { QueryClient } from '@tanstack/react-query';
7
+ import { ClientState, DepositTokenResponse, DepositNFTResponse, TokenWithdrawalResponse, NFTWithdrawalResponse, IDosGamesClient } from '@idosgames/core';
8
+ import { W as WalletLoginResult, e as DepositTokenEvmParams, a as BridgeResult, d as DepositNftEvmParams, k as WithdrawTokenEvmParams, j as WithdrawNftEvmParams, E as EvmBridgeClients, f as DepositTokenSolanaParams, l as WithdrawTokenSolanaParams, S as SolanaProgramAdapter } from '../bridge-BCxf6AHE.js';
9
+ import { Adapter } from '@solana/wallet-adapter-base';
10
+
11
+ interface EvmWalletConfigOptions {
12
+ /** Chains the game supports, matching the EVM networks in the title's blockchain config. */
13
+ chains: readonly [Chain, ...Chain[]];
14
+ /**
15
+ * WalletConnect Cloud project id — required to connect MOBILE wallets (and desktop wallets via
16
+ * QR). Get one at https://cloud.walletconnect.com. Omit to support browser-extension wallets only.
17
+ */
18
+ walletConnectProjectId?: string;
19
+ /** App name/metadata shown in the wallet's connect prompt. */
20
+ appName?: string;
21
+ appUrl?: string;
22
+ appIcon?: string;
23
+ /**
24
+ * Per-chain RPC transports. Defaults to `http()` (each chain's public RPC) for every chain —
25
+ * pass your own keyed by `chain.id` to use a private RPC endpoint.
26
+ */
27
+ transports?: Record<number, Transport>;
28
+ /**
29
+ * Override the connector list entirely. By default you get: `injected()` (MetaMask & other
30
+ * browser extensions), `walletConnect()` (mobile + QR, when a projectId is given), and
31
+ * `coinbaseWallet()`.
32
+ */
33
+ connectors?: CreateConnectorFn[];
34
+ }
35
+ /**
36
+ * Builds a wagmi `Config` wired for both browser and mobile wallets, ready to hand to
37
+ * {@link IDosGamesWalletProvider} (or a bare `WagmiProvider`).
38
+ *
39
+ * - Browser: `injected()` picks up MetaMask and any EIP-1193 extension.
40
+ * - Mobile: `walletConnect()` opens the WalletConnect modal (QR on desktop, deep-link on mobile)
41
+ * so phone wallets like MetaMask Mobile, Trust, Rainbow can connect. Needs a `walletConnectProjectId`.
42
+ */
43
+ declare function createEvmWalletConfig(options: EvmWalletConfigOptions): wagmi.Config<readonly [Chain, ...Chain[]], Record<number, Transport>, CreateConnectorFn[]>;
44
+
45
+ interface IDosGamesWalletProviderProps {
46
+ /** A wagmi config, typically from {@link createEvmWalletConfig}. */
47
+ wagmiConfig: Config;
48
+ /** Reuse an existing react-query client; a fresh one is created if omitted. */
49
+ queryClient?: QueryClient;
50
+ children: ReactNode;
51
+ }
52
+ /**
53
+ * Drop-in provider that sets up the EVM wallet stack: `WagmiProvider` (connectors, chains) +
54
+ * `QueryClientProvider` (wagmi's required react-query dependency). Wrap your app once, then use the
55
+ * EVM hooks below anywhere inside. For Solana, additionally wrap with the wallet-adapter
56
+ * `ConnectionProvider` + `WalletProvider` from `@solana/wallet-adapter-react`.
57
+ *
58
+ * ```tsx
59
+ * const wagmiConfig = createEvmWalletConfig({ chains: [polygon], walletConnectProjectId: "…" });
60
+ * <IDosGamesWalletProvider wagmiConfig={wagmiConfig}>
61
+ * <App />
62
+ * </IDosGamesWalletProvider>
63
+ * ```
64
+ */
65
+ declare function IDosGamesWalletProvider(props: IDosGamesWalletProviderProps): react.JSX.Element;
66
+
67
+ /**
68
+ * Assembles the viem clients the bridge needs from the connected wagmi wallet, or null when no
69
+ * wallet is connected / the wallet client isn't ready yet.
70
+ */
71
+ declare function useEvmBridgeClients(): EvmBridgeClients | null;
72
+ type DepositTokenArgs$1 = Omit<DepositTokenEvmParams, "client" | "clients" | "titleID">;
73
+ type DepositNftArgs = Omit<DepositNftEvmParams, "client" | "clients" | "titleID">;
74
+ type WithdrawTokenArgs$1 = Omit<WithdrawTokenEvmParams, "client" | "clients">;
75
+ type WithdrawNftArgs = Omit<WithdrawNftEvmParams, "client" | "clients">;
76
+ interface EvmBridge {
77
+ /** Whether a wallet is connected and its client is ready. */
78
+ connected: boolean;
79
+ /** The connected signing address, or null. */
80
+ account: string | null;
81
+ /**
82
+ * Logs into the game with the connected wallet by signing a server challenge (no gas, no tx).
83
+ * `networkID` is the cfg.Blockchain.Networks key the wallet proves on; `walletAddress` defaults
84
+ * to the connected account. On success the core client is logged in and its ClientState returned.
85
+ */
86
+ loginWithWallet(networkID: string, walletAddress?: string): Promise<WalletLoginResult<ClientState>>;
87
+ depositToken(args: DepositTokenArgs$1): Promise<BridgeResult<DepositTokenResponse>>;
88
+ depositNft(args: DepositNftArgs): Promise<BridgeResult<DepositNFTResponse>>;
89
+ withdrawToken(args: WithdrawTokenArgs$1): Promise<BridgeResult<TokenWithdrawalResponse>>;
90
+ withdrawNft(args: WithdrawNftArgs): Promise<BridgeResult<NFTWithdrawalResponse>>;
91
+ }
92
+ /**
93
+ * The ergonomic EVM bridge hook: binds the connected wagmi wallet to the four deposit/withdraw
94
+ * flows against a given core client + title. Each method returns a {@link BridgeResult}; a
95
+ * disconnected wallet yields a `{ ok: false }` instead of throwing.
96
+ *
97
+ * ```tsx
98
+ * const bridge = useEvmBridge(client, "my-title");
99
+ * const res = await bridge.depositToken({ network, tokenAddress, amount: parseUnits("25", 6) });
100
+ * if (!res.ok) toast(res.error);
101
+ * ```
102
+ */
103
+ declare function useEvmBridge(client: IDosGamesClient, titleID: string): EvmBridge;
104
+
105
+ interface SolanaWalletBridgeProviderProps {
106
+ /** RPC endpoint for the Solana network the title uses (matches its blockchain config). */
107
+ endpoint: string;
108
+ /**
109
+ * Wallet adapters to offer (e.g. `new PhantomWalletAdapter()` from
110
+ * `@solana/wallet-adapter-wallets`). Mobile support comes from adapters that implement it
111
+ * (Mobile Wallet Adapter on Android, or a WalletConnect adapter).
112
+ */
113
+ wallets: Adapter[];
114
+ /** Auto-reconnect the last-used wallet on mount. */
115
+ autoConnect?: boolean;
116
+ children: ReactNode;
117
+ }
118
+ /**
119
+ * Thin wrapper over wallet-adapter's `ConnectionProvider` + `WalletProvider` so the
120
+ * {@link useSolanaBridge} hook has a connected wallet. Compose it alongside
121
+ * {@link IDosGamesWalletProvider} when a title supports both EVM and Solana networks.
122
+ */
123
+ declare function SolanaWalletBridgeProvider(props: SolanaWalletBridgeProviderProps): react.JSX.Element;
124
+
125
+ type DepositTokenArgs = Omit<DepositTokenSolanaParams, "client" | "adapter" | "titleID">;
126
+ /** `walletAddress` defaults to the connected wallet if omitted. */
127
+ type WithdrawTokenArgs = Omit<WithdrawTokenSolanaParams, "client" | "adapter" | "walletAddress"> & {
128
+ walletAddress?: string;
129
+ };
130
+ interface SolanaBridge {
131
+ connected: boolean;
132
+ account: string | null;
133
+ /**
134
+ * Logs into the game with the connected Solana wallet by signing a server challenge (no tx, no
135
+ * fee). `networkID` is the cfg.Blockchain.Networks key; `walletAddress` defaults to the connected
136
+ * account. Requires a wallet that supports `signMessage`. Returns the fresh ClientState.
137
+ */
138
+ loginWithWallet(networkID: string, walletAddress?: string): Promise<WalletLoginResult<ClientState>>;
139
+ depositToken(args: DepositTokenArgs): Promise<BridgeResult<DepositTokenResponse>>;
140
+ withdrawToken(args: WithdrawTokenArgs): Promise<BridgeResult<TokenWithdrawalResponse>>;
141
+ }
142
+ /**
143
+ * The ergonomic Solana bridge hook: binds the connected wallet-adapter wallet + your
144
+ * {@link SolanaProgramAdapter} to the deposit/withdraw flows against a core client + title.
145
+ * The on-chain instruction building lives in the adapter (it owns the program IDL); this hook
146
+ * just wires the connected address and threads the request → submit → confirm lifecycle.
147
+ */
148
+ declare function useSolanaBridge(client: IDosGamesClient, titleID: string, adapter: SolanaProgramAdapter): SolanaBridge;
149
+
150
+ export { type EvmBridge, type EvmWalletConfigOptions, IDosGamesWalletProvider, type IDosGamesWalletProviderProps, type SolanaBridge, SolanaWalletBridgeProvider, type SolanaWalletBridgeProviderProps, createEvmWalletConfig, useEvmBridge, useEvmBridgeClients, useSolanaBridge };