@keccak256-evg/passport-sdk
Version:
T-REX Passport SDK for interacting with Passport and Registry contracts
3 lines (2 loc) • 33.9 kB
JavaScript
import{getContract as t,readContract as e,prepareContractCall as r,sendTransaction as n,waitForReceipt as s}from"thirdweb";import{defineChain as a,createPublicClient as i,http as o,createWalletClient as c,getContract as l,custom as d}from"viem";import{useState as u,useRef as h,useCallback as p,useMemo as g,useEffect as y}from"react";const w=[{inputs:[{components:[{type:"address",name:"to"},{type:"uint128",name:"validityStartTimestamp"},{type:"uint128",name:"validityEndTimestamp"}],name:"request",type:"tuple"},{type:"bytes",name:"signature"}],name:"createPassport",outputs:[{type:"address"}],stateMutability:"nonpayable",type:"function"},{inputs:[{type:"address"}],name:"walletToPassportId",outputs:[{type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{type:"uint256"}],name:"passportIdToContractAddress",outputs:[{type:"address"}],stateMutability:"view",type:"function"},{inputs:[{type:"address"}],name:"abolishedWallets",outputs:[{type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{type:"address"}],name:"predictPassportAddress",outputs:[{type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"upgradeMyPassport",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"getPassportImplementation",outputs:[{type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"getPassportIdCounter",outputs:[{type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{type:"address"}],name:"isWalletAbolished",outputs:[{type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{type:"uint256"},{type:"address"}],name:"isWalletUnboundFromPassport",outputs:[{type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{type:"address"},{type:"address"}],name:"hasPassport",outputs:[{type:"bool"}],stateMutability:"view",type:"function"}],f=[{inputs:[],name:"passportId",outputs:[{type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"getBoundWallets",outputs:[{type:"address[]"}],stateMutability:"view",type:"function"},{inputs:[],name:"getWalletCount",outputs:[{type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{type:"address"}],name:"isWalletBound",outputs:[{type:"bool"}],stateMutability:"view",type:"function"},{inputs:[],name:"unbindWallet",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"getPendingBindWallets",outputs:[{type:"address[]"}],stateMutability:"view",type:"function"},{inputs:[{type:"address"}],name:"requestBindWallet",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{type:"address"}],name:"getPendingBindRequest",outputs:[{type:"bool"},{type:"address"},{type:"uint256"},{type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{type:"address"}],name:"cancelBindRequest",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"acceptBindRequest",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"rejectBindRequest",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"requireUpgrade",outputs:[{type:"bool"}],stateMutability:"view",type:"function"},{inputs:[],name:"implementation",outputs:[{type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"registry",outputs:[{type:"address"}],stateMutability:"view",type:"function"},{inputs:[{type:"uint256"}],name:"boundWallets",outputs:[{type:"address"}],stateMutability:"view",type:"function"},{inputs:[{type:"address"}],name:"hasPendingBindRequest",outputs:[{type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{type:"address"}],name:"cancelExpiredBindRequest",outputs:[],stateMutability:"nonpayable",type:"function"}],m="0x1B326360Ec9E3cEF6129173D35b86a6803e5751F";var b;!function(t){t.DEV="DEV",t.BETA="BETA",t.PROD="PROD"}(b||(b={}));const P={1962:{registryAddress:m}},C={id:1962,name:"T-Rex Testnet",nativeCurrency:{decimals:18,name:"Ether",symbol:"ETH"},rpcUrls:{default:{http:["https://testnetrpc.trex.xyz"]}},blockExplorers:{default:{name:"T-Rex Explorer",url:"https://explorer.trex.com"}},testnet:!0};function E(t){const e=a({id:1962,name:"T-Rex Testnet",nativeCurrency:{decimals:18,name:"Ether",symbol:"ETH"},rpcUrls:{default:{http:[t]}},blockExplorers:{default:{name:"T-Rex Explorer",url:"https://explorer.trex.com"}},testnet:!0});return i({chain:e,transport:o(t)})}function A(t){const e=t.chain||a(C);return i({chain:e,transport:o(t.rpcUrl)})}function v(t){const e=t.chain||a(C);return c({chain:e,transport:o(t.rpcUrl),account:t.account})}async function B(t,e,r){try{return await t.readContract({address:e,abi:f,functionName:"getPendingBindWallets",account:r})}catch(t){throw console.error("Viem getPendingBindWallets error:",t),t}}class W{constructor(t){Object.defineProperty(this,"config",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"viemClient",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"defaultAccount",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.config=t,this.defaultAccount=t.account,this.viemClient=E(t.chain.rpc)}async validateConfiguration(){const r=[];try{this.config.registryAddress&&this.config.registryAddress.startsWith("0x")||r.push("Invalid registry address format"),this.config.chain&&this.config.chain.id||r.push("Invalid chain configuration"),this.config.client||r.push("Thirdweb client not configured");try{const r=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w});await e({contract:r,method:"getPassportIdCounter",params:[]}),console.log("✅ Registry contract is accessible")}catch(t){r.push(`Registry contract not accessible: ${t}`),console.error("❌ Registry contract access failed:",t)}return{isValid:0===r.length,issues:r}}catch(t){return r.push(`Configuration validation error: ${t}`),{isValid:!1,issues:r}}}async createPassport(e,a,i){try{const o=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w}),c=r({contract:o,method:"createPassport",params:[e,a]});if(i?.sendTransaction){const t=i.account||this.defaultAccount;if(!t)throw new Error("Account is required to send transaction");const e=await n({transaction:c,account:t});return await s({chain:this.config.chain,transactionHash:e.transactionHash,client:this.config.client})}return{preparedTransaction:c}}catch(t){throw console.error("Error preparing create passport transaction:",t),t}}async checkWalletHasPassport(r){try{const n=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w}),s=await e({contract:n,method:"walletToPassportId",params:[r]});if(0n===s)return{hasPassport:!1};const a=await e({contract:n,method:"passportIdToContractAddress",params:[s]});return{hasPassport:!0,passportId:Number(s),passportAddress:a}}catch(t){throw console.error("Error checking wallet passport:",t),t}}async getPassportInfo(r){try{const n=t({client:this.config.client,chain:this.config.chain,address:r,abi:f}),[s,a,i]=await Promise.all([e({contract:n,method:"passportId",params:[]}),e({contract:n,method:"getBoundWallets",params:[]}),e({contract:n,method:"getWalletCount",params:[]})]);return{passportId:Number(s),passportAddress:r,boundWallets:a,walletCount:Number(i)}}catch(t){throw console.error("Error getting passport info:",t),t}}async predictPassportAddress(r){try{const n=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w});return await e({contract:n,method:"predictPassportAddress",params:[r]})}catch(t){throw console.error("Error predicting passport address:",t),t}}async getPassportImplementation(){try{const r=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w});return await e({contract:r,method:"getPassportImplementation",params:[]})}catch(t){throw console.error("Error getting passport implementation:",t),t}}async getPassportIdCounter(){try{const r=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w}),n=await e({contract:r,method:"getPassportIdCounter",params:[]});return Number(n)}catch(t){throw console.error("Error getting passport ID counter:",t),t}}async getPassportAddressById(r){try{const n=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w});return await e({contract:n,method:"passportIdToContractAddress",params:[BigInt(r)]})}catch(t){throw console.error("Error getting passport address by ID:",t),t}}async isWalletAbolished(r){try{if(!r||!r.startsWith("0x"))throw new Error("Invalid wallet address format");console.log("Checking wallet abolished status for:",r),console.log("Registry address:",this.config.registryAddress),console.log("Chain ID:",this.config.chain.id);const n=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w}),s=await e({contract:n,method:"isWalletAbolished",params:[r]});return Boolean(s)}catch(t){throw console.error("Error checking if wallet is abolished:",t),console.error("Wallet address:",r),console.error("Registry address:",this.config.registryAddress),console.error("❌ isWalletAbolished 方法调用失败"),console.error("💡 可能的原因:"),console.error("1. 合约地址不正确"),console.error("2. 网络配置不匹配"),console.error("3. 合约版本不兼容"),console.error("4. RPC 连接问题"),t}}async isWalletUnboundFromPassport(r,n){try{if(!n||!n.startsWith("0x"))throw new Error("Invalid wallet address format");if(r<0)throw new Error("Invalid passport ID");console.log("Checking wallet unbound status for:",n,"from passport ID:",r),console.log("Registry address:",this.config.registryAddress),console.log("Chain ID:",this.config.chain.id);const s=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w}),a=await e({contract:s,method:"isWalletUnboundFromPassport",params:[BigInt(r),n]});return Boolean(a)}catch(t){throw console.error("Error checking if wallet is unbound from passport:",t),console.error("Wallet address:",n),console.error("Passport ID:",r),console.error("Registry address:",this.config.registryAddress),t}}async hasPassport(r,n){try{const s=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w}),a=await e({contract:s,method:"hasPassport",params:[r,n]});return Boolean(a)}catch(t){throw console.error("Error checking if wallet has passport:",t),t}}async getPassportImplementationAddress(r){try{const n=t({client:this.config.client,chain:this.config.chain,address:r,abi:f});return await e({contract:n,method:"implementation",params:[]})}catch(t){throw console.error("Error getting passport implementation address:",t),t}}async getPassportId(r){try{const n=t({client:this.config.client,chain:this.config.chain,address:r,abi:f}),s=await e({contract:n,method:"passportId",params:[]});return Number(s)}catch(t){throw console.error("Error getting passport ID:",t),t}}async getRegistryAddress(r){try{const n=t({client:this.config.client,chain:this.config.chain,address:r,abi:f});return await e({contract:n,method:"registry",params:[]})}catch(t){throw console.error("Error getting registry address:",t),t}}async isWalletBound(r,n){try{const s=t({client:this.config.client,chain:this.config.chain,address:r,abi:f}),a=await e({contract:s,method:"isWalletBound",params:[n]});return Boolean(a)}catch(t){throw console.error("Error checking if wallet is bound:",t),t}}async getBoundWallets(r){try{const n=t({client:this.config.client,chain:this.config.chain,address:r,abi:f});return await e({contract:n,method:"getBoundWallets",params:[]})}catch(t){throw console.error("Error getting bound wallets:",t),t}}async getWalletCount(r){try{const n=t({client:this.config.client,chain:this.config.chain,address:r,abi:f}),s=await e({contract:n,method:"getWalletCount",params:[]});return Number(s)}catch(t){throw console.error("Error getting wallet count:",t),t}}async getBoundWalletByIndex(r,n){try{const s=t({client:this.config.client,chain:this.config.chain,address:r,abi:f});return await e({contract:s,method:"boundWallets",params:[BigInt(n)]})}catch(t){throw console.error("Error getting bound wallet by index:",t),t}}async hasPendingBindRequest(r,n){try{const s=t({client:this.config.client,chain:this.config.chain,address:r,abi:f}),a=await e({contract:s,method:"hasPendingBindRequest",params:[n]});return Boolean(a)}catch(t){throw console.error("Error checking if wallet has pending bind request:",t),t}}async cancelExpiredBindRequest(e,s,a){try{const i=t({client:this.config.client,chain:this.config.chain,address:e,abi:f}),o=r({contract:i,method:"cancelExpiredBindRequest",params:[s]});if(a?.sendTransaction){const t=a.account||this.defaultAccount;if(!t)throw new Error("Account is required to send transaction");const e=await n({transaction:o,account:t});return{transactionHash:e.transactionHash,receipt:e}}return{preparedTransaction:o}}catch(t){throw console.error("Error preparing cancel expired bind request transaction:",t),t}}async unbindWallet(e,s){try{const a=t({client:this.config.client,chain:this.config.chain,address:e,abi:f}),i=r({contract:a,method:"unbindWallet",params:[]});if(s?.sendTransaction){const t=s.account||this.defaultAccount;if(!t)throw new Error("Account is required to send transaction");const e=await n({transaction:i,account:t});return{transactionHash:e.transactionHash,receipt:e}}return{preparedTransaction:i}}catch(t){throw console.error("Error preparing unbind wallet transaction:",t),t}}async requestBindWallet(e,a,i){try{const o=t({client:this.config.client,chain:this.config.chain,address:e,abi:f}),c=r({contract:o,method:"requestBindWallet",params:[a]});if(i?.sendTransaction){const t=i.account||this.defaultAccount;if(!t)throw new Error("Account is required to send transaction");const e=await n({transaction:c,account:t});return await s({chain:this.config.chain,transactionHash:e.transactionHash,client:this.config.client})}return{preparedTransaction:c}}catch(t){throw console.error("Error preparing request bind wallet transaction:",t),t}}async getPendingBindRequest(r,n){try{const s=t({client:this.config.client,chain:this.config.chain,address:r,abi:f}),[a,i,o,c]=await e({contract:s,method:"getPendingBindRequest",params:[n]});return{exists:Boolean(a),requester:i,timestamp:Number(o),expired:Boolean(c)}}catch(t){throw console.error("Error getting pending bind request:",t),t}}async cancelBindRequest(e,s,a){try{const i=t({client:this.config.client,chain:this.config.chain,address:e,abi:f}),o=r({contract:i,method:"cancelBindRequest",params:[s]});if(a?.sendTransaction){const t=a.account||this.defaultAccount;if(!t)throw new Error("Account is required to send transaction");const e=await n({transaction:o,account:t});return{transactionHash:e.transactionHash,receipt:e}}return{preparedTransaction:o}}catch(t){throw console.error("Error preparing cancel bind request transaction:",t),t}}async acceptBindRequest(e,a){try{const i=t({client:this.config.client,chain:this.config.chain,address:e,abi:f}),o=r({contract:i,method:"acceptBindRequest",params:[]});if(a?.sendTransaction){const t=a.account||this.defaultAccount;if(!t)throw new Error("Account is required to send transaction");const e=await n({transaction:o,account:t});return await s({chain:this.config.chain,transactionHash:e.transactionHash,client:this.config.client})}return{preparedTransaction:o}}catch(t){throw console.error("Error preparing accept bind request transaction:",t),t}}async rejectBindRequest(e,s){try{const a=t({client:this.config.client,chain:this.config.chain,address:e,abi:f}),i=r({contract:a,method:"rejectBindRequest",params:[]});if(s?.sendTransaction){const t=s.account||this.defaultAccount;if(!t)throw new Error("Account is required to send transaction");const e=await n({transaction:i,account:t});return{transactionHash:e.transactionHash,receipt:e}}return{preparedTransaction:i}}catch(t){throw console.error("Error preparing reject bind request transaction:",t),t}}async getPendingBindWallets(t,e){return B(this.viemClient,t,e)}async checkPassportUpgrade(r){try{const n=t({client:this.config.client,chain:this.config.chain,address:r,abi:f});return await e({contract:n,method:"requireUpgrade"})}catch(t){throw console.error("Error checking passport upgrade:",t),t}}async upgradeMyPassport(e){try{const s=t({client:this.config.client,chain:this.config.chain,address:this.config.registryAddress,abi:w}),a=await r({contract:s,method:"upgradeMyPassport"});if(e?.sendTransaction){const t=e.account||this.defaultAccount;if(!t)throw new Error("Account is required to send transaction");const r=await n({transaction:a,account:t});return{transactionHash:r.transactionHash,receipt:r}}return{preparedTransaction:a}}catch(t){throw console.error("Error preparing upgrade transaction:",t),t}}}class I{constructor(t){Object.defineProperty(this,"config",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"publicClient",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"walletClient",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"registryAddress",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.config=t,this.publicClient=t.publicClient,this.walletClient=t.walletClient,this.registryAddress=t.registryAddress||P[t.network.id]?.registryAddress||P[1962].registryAddress}setWalletClient(t){return this.walletClient=t,this}getRegistryContract(){return l({address:this.registryAddress,abi:w,client:this.publicClient})}getPassportContract(t){return l({address:t,abi:f,client:this.publicClient})}async createPassport(t,e){if(!this.walletClient)throw new Error("Wallet client is required for write operations");return l({address:this.registryAddress,abi:w,client:this.walletClient}).write.createPassport([t,e])}async checkWalletHasPassport(t){try{const e=this.getRegistryContract(),r=await e.read.walletToPassportId([t]);if(0n===r)return{hasPassport:!1};const n=await e.read.passportIdToContractAddress([r]);return{hasPassport:!0,passportId:Number(r),passportAddress:n}}catch(t){throw console.error("Error checking wallet passport:",t),t}}async getPassportInfo(t){try{const e=this.getPassportContract(t),[r,n,s]=await Promise.all([e.read.passportId(),e.read.getBoundWallets(),e.read.getWalletCount()]);return{passportId:Number(r),passportAddress:t,boundWallets:n,walletCount:Number(s)}}catch(t){throw console.error("Error getting passport info:",t),t}}async predictPassportAddress(t){try{const e=this.getRegistryContract();return await e.read.predictPassportAddress([t])}catch(t){throw console.error("Error predicting passport address:",t),t}}async upgradeMyPassport(){if(!this.walletClient)throw new Error("Wallet client is required for write operations");return l({address:this.registryAddress,abi:w,client:this.walletClient}).write.upgradeMyPassport()}async getPassportImplementation(){try{const t=this.getRegistryContract();return await t.read.getPassportImplementation()}catch(t){throw console.error("Error getting passport implementation:",t),t}}async getPassportIdCounter(){try{const t=this.getRegistryContract(),e=await t.read.getPassportIdCounter();return Number(e)}catch(t){throw console.error("Error getting passport ID counter:",t),t}}async getPassportAddressById(t){try{const e=this.getRegistryContract();return await e.read.passportIdToContractAddress([BigInt(t)])}catch(t){throw console.error("Error getting passport address by ID:",t),t}}async isWalletAbolished(t){try{const e=this.getRegistryContract(),r=await e.read.isWalletAbolished([t]);return Boolean(r)}catch(t){throw console.error("Error checking if wallet is abolished:",t),t}}async isWalletUnboundFromPassport(t,e){try{const r=this.getRegistryContract(),n=await r.read.isWalletUnboundFromPassport([BigInt(t),e]);return Boolean(n)}catch(t){throw console.error("Error checking if wallet is unbound from passport:",t),t}}async hasPassport(t,e){try{const r=this.getRegistryContract(),n=await r.read.hasPassport([t,e]);return Boolean(n)}catch(t){throw console.error("Error checking if wallet has passport:",t),t}}async unbindWallet(t){if(!this.walletClient)throw new Error("Wallet client is required for write operations");return l({address:t,abi:f,client:this.walletClient}).write.unbindWallet()}async requestBindWallet(t,e){if(!this.walletClient)throw new Error("Wallet client is required for write operations");return l({address:t,abi:f,client:this.walletClient}).write.requestBindWallet([e])}async getPendingBindRequest(t,e){try{const r=this.getPassportContract(t),[n,s,a,i]=await r.read.getPendingBindRequest([e]);return{exists:Boolean(n),requester:s,timestamp:Number(a),expired:Boolean(i)}}catch(t){throw console.error("Error getting pending bind request:",t),t}}async cancelBindRequest(t,e){if(!this.walletClient)throw new Error("Wallet client is required for write operations");return l({address:t,abi:f,client:this.walletClient}).write.cancelBindRequest([e])}async acceptBindRequest(t){if(!this.walletClient)throw new Error("Wallet client is required for write operations");return l({address:t,abi:f,client:this.walletClient}).write.acceptBindRequest()}async rejectBindRequest(t){if(!this.walletClient)throw new Error("Wallet client is required for write operations");return l({address:t,abi:f,client:this.walletClient}).write.rejectBindRequest()}async getPendingBindWallets(t,e){return B(this.publicClient,t,e)}async checkPassportUpgrade(t){try{const e=this.getPassportContract(t),r=await e.read.requireUpgrade();return Boolean(r)}catch(t){throw console.error("Error checking passport upgrade:",t),t}}async getPassportImplementationAddress(t){try{const e=this.getPassportContract(t);return await e.read.implementation()}catch(t){throw console.error("Error getting passport implementation address:",t),t}}async getPassportId(t){try{const e=this.getPassportContract(t),r=await e.read.passportId();return Number(r)}catch(t){throw console.error("Error getting passport ID:",t),t}}async getRegistryAddress(t){try{const e=this.getPassportContract(t);return await e.read.registry()}catch(t){throw console.error("Error getting registry address:",t),t}}async isWalletBound(t,e){try{const r=this.getPassportContract(t),n=await r.read.isWalletBound([e]);return Boolean(n)}catch(t){throw console.error("Error checking if wallet is bound:",t),t}}async getBoundWallets(t){try{const e=this.getPassportContract(t);return await e.read.getBoundWallets()}catch(t){throw console.error("Error getting bound wallets:",t),t}}async getWalletCount(t){try{const e=this.getPassportContract(t),r=await e.read.getWalletCount();return Number(r)}catch(t){throw console.error("Error getting wallet count:",t),t}}async getBoundWalletByIndex(t,e){try{const r=this.getPassportContract(t);return await r.read.boundWallets([BigInt(e)])}catch(t){throw console.error("Error getting bound wallet by index:",t),t}}async hasPendingBindRequest(t,e){try{const r=this.getPassportContract(t),n=await r.read.hasPendingBindRequest([e]);return Boolean(n)}catch(t){throw console.error("Error checking if wallet has pending bind request:",t),t}}async cancelExpiredBindRequest(t,e){if(!this.walletClient)throw new Error("Wallet client is required for write operations");return l({address:t,abi:f,client:this.walletClient}).write.cancelExpiredBindRequest([e])}}function q(t){const e=t.chain||C,r=A({rpcUrl:t.rpcUrl,chain:e}),n=t.account?v({rpcUrl:t.rpcUrl,chain:e,account:t.account}):void 0;return new I({publicClient:r,walletClient:n,network:e,env:t.env||b.DEV,registryAddress:t.registryAddress,rpcUrl:t.rpcUrl})}class x{constructor(t){Object.defineProperty(this,"config",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"publicClient",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"walletClient",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"registryAddress",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.config=t;const e={id:t.chain.id,name:t.chain.name,nativeCurrency:t.chain.nativeCurrency||{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:t.chain.rpcUrls,blockExplorers:t.chain.blockExplorers};this.publicClient=i({chain:e,transport:d(t.provider)}),this.walletClient=c({chain:e,transport:d(t.provider)}),this.registryAddress=t.registryAddress||P[t.chain.id]?.registryAddress||P[1962].registryAddress}getProviderInfo(){const t=this.config.provider;return{isMetaMask:t.isMetaMask||!1,isCoinbaseWallet:t.isCoinbaseWallet||!1,chainId:t.chainId,selectedAddress:t.selectedAddress}}async connectWallet(){return await this.config.provider.request({method:"eth_requestAccounts"})}async getAccounts(){return await this.config.provider.request({method:"eth_accounts"})}async switchChain(){const t=`0x${this.config.chain.id.toString(16)}`;try{await this.config.provider.request({method:"wallet_switchEthereumChain",params:[{chainId:t}]})}catch(t){if(4902!==t.code)throw t;await this.addChain()}}async addChain(){const t={chainId:`0x${this.config.chain.id.toString(16)}`,chainName:this.config.chain.name,rpcUrls:this.config.chain.rpcUrls.default.http,nativeCurrency:this.config.chain.nativeCurrency,blockExplorerUrls:this.config.chain.blockExplorers?[this.config.chain.blockExplorers.default.url]:void 0};await this.config.provider.request({method:"wallet_addEthereumChain",params:[t]})}async createPassport(t,e){const r=l({address:this.registryAddress,abi:w,client:this.walletClient});return await r.write.createPassport([t,e])}async checkWalletHasPassport(t){try{const e=l({address:this.registryAddress,abi:w,client:this.publicClient}),r=await e.read.walletToPassportId([t]);if(0n===r)return{hasPassport:!1};const n=await e.read.passportIdToContractAddress([r]);return{hasPassport:!0,passportId:Number(r),passportAddress:n}}catch(t){throw console.error("Error checking wallet passport:",t),t}}async getPassportInfo(t){try{const e=l({address:t,abi:f,client:this.publicClient}),[r,n,s]=await Promise.all([e.read.passportId(),e.read.getBoundWallets(),e.read.getWalletCount()]);return{passportId:Number(r),passportAddress:t,boundWallets:n,walletCount:Number(s)}}catch(t){throw console.error("Error getting passport info:",t),t}}async requestBindWallet(t,e){const r=l({address:t,abi:f,client:this.walletClient});return await r.write.requestBindWallet([e])}async acceptBindRequest(t){const e=l({address:t,abi:f,client:this.walletClient});return await e.write.acceptBindRequest()}async rejectBindRequest(t){const e=l({address:t,abi:f,client:this.walletClient});return await e.write.rejectBindRequest()}async unbindWallet(t){const e=l({address:t,abi:f,client:this.walletClient});return await e.write.unbindWallet()}async cancelBindRequest(t,e){const r=l({address:t,abi:f,client:this.walletClient});return await r.write.cancelBindRequest([e])}async getPendingBindRequest(t,e){try{const r=l({address:t,abi:f,client:this.publicClient}),[n,s,a,i]=await r.read.getPendingBindRequest([e]);return{exists:Boolean(n),requester:s,timestamp:Number(a),expired:Boolean(i)}}catch(t){throw console.error("Error getting pending bind request:",t),t}}onAccountsChanged(t){this.config.provider.on&&this.config.provider.on("accountsChanged",e=>{t(e)})}onChainChanged(t){this.config.provider.on&&this.config.provider.on("chainChanged",e=>{t(e)})}removeListener(t,e){this.config.provider.removeListener&&this.config.provider.removeListener(t,e)}}async function R(r,n,s){const a={contractAddress:s,chainId:n.id,isAccessible:!1,supportedMethods:[],recommendations:[]};try{const i=t({client:r,chain:n,address:s,abi:w});try{await e({contract:i,method:"getPassportIdCounter",params:[]}),a.isAccessible=!0}catch(t){return a.isAccessible=!1,a.recommendations.push("合约无法访问,请检查地址和网络配置"),a}const o=[{name:"isWalletAbolished",params:["0x0000000000000000000000000000000000000000"]},{name:"isWalletUnboundFromPassport",params:[1n,"0x0000000000000000000000000000000000000000"]},{name:"walletToPassportId",params:["0x0000000000000000000000000000000000000000"]},{name:"passportIdToContractAddress",params:[1n]},{name:"getPassportIdCounter",params:[]},{name:"getPassportImplementation",params:[]},{name:"predictPassportAddress",params:["0x0000000000000000000000000000000000000000"]},{name:"hasPassport",params:["0x0000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000"]}];for(const t of o){const r={method:t.name,exists:!1};try{await e({contract:i,method:t.name,params:t.params}),r.exists=!0}catch(e){r.exists=!1,r.error=e.message,(e.message?.includes("does not exist")||e.message?.includes("not found")||e.message?.includes("execution reverted"))&&(r.error=`方法 ${t.name} 在此合约中不存在`)}a.supportedMethods.push(r)}const c=a.supportedMethods.filter(t=>!t.exists);if(c.length>0){a.recommendations.push(`以下方法不受支持: ${c.map(t=>t.method).join(", ")}`),"0x1B326360Ec9E3cEF6129173D35b86a6803e5751F"!==s&&a.recommendations.push("建议使用标准Registry地址: 0x1B326360Ec9E3cEF6129173D35b86a6803e5751F");const t=a.supportedMethods.find(t=>"isWalletAbolished"===t.method)?.exists,e=a.supportedMethods.find(t=>"isWalletUnboundFromPassport"===t.method)?.exists;t||a.recommendations.push("合约缺少 isWalletAbolished 方法,可能是不兼容的版本"),e||a.recommendations.push("合约缺少 isWalletUnboundFromPassport 方法,可能是不兼容的版本")}return a}catch(t){return a.recommendations.push(`合约验证失败: ${t}`),a}}async function M(t,e,r){const n=await R(t,e,r),s=["walletToPassportId","getPassportIdCounter"],a=[],i=[];if(!n.isAccessible)return a.push("合约无法访问"),i.push("检查合约地址和网络配置"),{isCompatible:!1,issues:a,suggestions:i};for(const t of s){const e=n.supportedMethods.find(e=>e.method===t);e?.exists||a.push(`缺少必需方法: ${t}`)}const o=n.supportedMethods.find(t=>"isWalletAbolished"===t.method)?.exists,c=n.supportedMethods.find(t=>"isWalletUnboundFromPassport"===t.method)?.exists;o||a.push("isWalletAbolished 方法不存在"),c||a.push("isWalletUnboundFromPassport 方法不存在");const l=0===a.length;return l||"0x1B326360Ec9E3cEF6129173D35b86a6803e5751F"===r||i.push("尝试使用标准Registry地址: 0x1B326360Ec9E3cEF6129173D35b86a6803e5751F"),{isCompatible:l,issues:a,suggestions:i}}function k(t){const[e,r]=u(null),[n,s]=u(!1),[a,i]=u(null),o=h(!1),c=p(()=>{if("undefined"==typeof window)return null;if(window.ethereum?.isMetaMask)return window.ethereum;if(window.ethereum)return window.ethereum;const t=[window.coinbaseWalletExtension,window.bitkeep?.ethereum,window.trustwallet];for(const e of t)if(e?.isConnected?.())return e;return window.ethereum?window.ethereum:null},[]),l=p(async()=>{if(!o.current){o.current=!0,s(!0),i(null);try{const e=c();if(!e)throw new Error("No EIP-1193 compatible wallet provider found. Please install MetaMask or another compatible wallet.");const n={provider:e,chain:t.chain,env:t.env||"dev",registryAddress:t.registryAddress},s=new x(n);r(s),console.log("✅ UnifiedPassportSDK initialized successfully")}catch(t){const e=t instanceof Error?t:new Error("Failed to initialize SDK");i(e),console.error("❌ Error initializing UnifiedPassportSDK:",e)}finally{s(!1),o.current=!1}}},[t,c]),d=p(()=>{e&&(r(null),i(null),console.log("🧹 UnifiedPassportSDK cleaned up"))},[e]),w=g(()=>e?e.getProviderInfo():null,[e]);return y(()=>(!1!==t.autoInitialize&&l(),()=>{e&&d()}),[t.userAddress,l]),y(()=>{if(!e)return;let r=!0;const n=t=>{r&&(console.log("👤 Accounts changed:",t),0===t.length&&(console.log("🔓 Wallet disconnected"),d()))},s=e=>{if(!r)return;console.log("🌐 Chain changed:",e);const n=`0x${t.chain.id.toString(16)}`;e!==n&&console.warn(`⚠️ Chain mismatch. Expected: ${n}, Got: ${e}`)};return e.onAccountsChanged(n),e.onChainChanged(s),()=>{r=!1,e.removeListener&&(e.removeListener("accountsChanged",n),e.removeListener("chainChanged",s))}},[e,t.chain.id,d]),{sdk:e,isInitializing:n,error:a,initialize:l,cleanup:d,providerInfo:w}}function T(t){const{sdk:e,passportAddress:r,autoFetch:n=!0,pollingInterval:s=0}=t,[a,i]=u(null),[o,c]=u(!1),[l,d]=u(null),g=h(!1),w=p(async()=>{if(e&&r&&!g.current){g.current=!0,c(!0),d(null);try{const t=await e.getPassportInfo(r);i(t)}catch(t){const e=t instanceof Error?t:new Error("Failed to fetch passport info");d(e),console.error("❌ Error fetching passport info:",e)}finally{c(!1),g.current=!1}}},[e,r]),f=p(async()=>{await w()},[w]),m=p(()=>{i(null),d(null)},[]);return y(()=>{n&&e&&r&&w()},[n,e,r,w]),y(()=>{if(!s||s<=0||!e||!r)return;const t=setInterval(()=>{!g.current&&e&&r&&w()},s);return()=>clearInterval(t)},[s,e,r]),y(()=>{e&&r||m()},[e,r,m]),{passportInfo:a,isLoading:o,error:l,refresh:f,clear:m}}function U(t){const{sdk:e,walletAddress:r,autoCheck:n=!0,pollingInterval:s=0}=t,[a,i]=u(null),[o,c]=u(!1),[l,d]=u(null),g=h(!1),w=p(async()=>{if(e&&r&&!g.current){g.current=!0,c(!0),d(null);try{const t=await e.checkWalletHasPassport(r);i(t)}catch(t){const e=t instanceof Error?t:new Error("Failed to check wallet passport");d(e),console.error("❌ Error checking wallet passport:",e)}finally{c(!1),g.current=!1}}},[e,r]),f=p(async()=>{await w()},[w]),m=p(()=>{i(null),d(null)},[]);return y(()=>{n&&e&&r&&w()},[n,e,r,w]),y(()=>{if(!s||s<=0||!e||!r)return;const t=setInterval(()=>{!g.current&&e&&r&&w()},s);return()=>clearInterval(t)},[s,e,r]),y(()=>{e&&r||m()},[e,r,m]),{walletPassport:a,isLoading:o,error:l,check:f,clear:m}}export{P as CONTRACT_ADDRESSES,b as Environment,f as PASSPORT_ABI,w as PASSPORT_REGISTRY_ABI,W as PassportSDK,m as REGISTRY_ADDRESS,x as UnifiedPassportSDK,I as ViemPassportSDK,E as createViemClient,q as createViemPassportSDK,A as createViemPublicClient,v as createViemWalletClient,B as getPendingBindWalletsWithViem,M as quickContractCheck,C as tRexTestnet,T as usePassportInfo,k as useUnifiedPassportSDK,U as useWalletPassport,R as verifyContractMethods};
//# sourceMappingURL=index.js.map