UNPKG

@keccak256-evg/passport-sdk

Version:

T-REX Passport SDK for interacting with Passport and Registry contracts

916 lines 33.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PassportSDK = void 0; const thirdweb_1 = require("thirdweb"); const constants_1 = require("./constants"); const utils_1 = require("./utils"); class PassportSDK { constructor(config) { this.config = config; this.defaultAccount = config.account; this.viemClient = (0, utils_1.createViemClient)(config.chain.rpc); } /** * 验证合约配置是否正确 */ async validateConfiguration() { const issues = []; try { // 验证基本配置 if (!this.config.registryAddress || !this.config.registryAddress.startsWith('0x')) { issues.push('Invalid registry address format'); } if (!this.config.chain || !this.config.chain.id) { issues.push('Invalid chain configuration'); } if (!this.config.client) { issues.push('Thirdweb client not configured'); } // 验证合约是否可访问 try { const registryContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); // 尝试调用一个简单的只读方法 await (0, thirdweb_1.readContract)({ contract: registryContract, method: "getPassportIdCounter", params: [], }); console.log('✅ Registry contract is accessible'); } catch (contractError) { issues.push(`Registry contract not accessible: ${contractError}`); console.error('❌ Registry contract access failed:', contractError); } return { isValid: issues.length === 0, issues }; } catch (error) { issues.push(`Configuration validation error: ${error}`); return { isValid: false, issues }; } } // Registry 方法 /** * 创建 Passport */ async createPassport(options) { try { console.log("createPassport", options); const registryContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); console.log("registryContract", registryContract); const transaction = (0, thirdweb_1.prepareContractCall)({ contract: registryContract, method: "createPassport", params: [], }); console.log("transaction", transaction); // 如果指定发送交易,则直接发送 if (options?.sendTransaction) { const account = options.account || this.defaultAccount; if (!account) { throw new Error("Account is required to send transaction"); } console.log("account", account); const result = await (0, thirdweb_1.sendTransaction)({ transaction, account, }); console.log("result", result); const receipt = await (0, thirdweb_1.waitForReceipt)({ chain: this.config.chain, transactionHash: result.transactionHash, client: this.config.client, }); return receipt; } // 否则返回准备好的交易 return { preparedTransaction: transaction, }; } catch (error) { console.error("Error preparing create passport transaction:", error); throw error; } } /** * 检查钱包是否有 Passport */ async checkWalletHasPassport(walletAddress) { try { console.log("checkWalletHasPassport", walletAddress); const registryContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); console.log("registryContract", registryContract); const passportId = await (0, thirdweb_1.readContract)({ contract: registryContract, method: "walletToPassportId", params: [walletAddress], }); console.log("passportId", passportId); if (passportId === 0n) { return { hasPassport: false }; } console.log("passportId", passportId); const passportAddress = await (0, thirdweb_1.readContract)({ contract: registryContract, method: "passportIdToContractAddress", params: [passportId], }); return { hasPassport: true, passportId: Number(passportId), passportAddress: passportAddress, }; } catch (error) { console.error("Error checking wallet passport:", error); throw error; } } /** * 获取 Passport 信息 */ async getPassportInfo(passportAddress) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const [passportId, boundWallets, walletCount] = await Promise.all([ (0, thirdweb_1.readContract)({ contract: passportContract, method: "passportId", params: [], }), (0, thirdweb_1.readContract)({ contract: passportContract, method: "getBoundWallets", params: [], }), (0, thirdweb_1.readContract)({ contract: passportContract, method: "getWalletCount", params: [], }), ]); return { passportId: Number(passportId), passportAddress: passportAddress, boundWallets: boundWallets, walletCount: Number(walletCount), }; } catch (error) { console.error("Error getting passport info:", error); throw error; } } /** * 预测 Passport 地址 */ async predictPassportAddress(walletAddress) { try { const registryContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); const predictedAddress = await (0, thirdweb_1.readContract)({ contract: registryContract, method: "predictPassportAddress", params: [walletAddress], }); return predictedAddress; } catch (error) { console.error("Error predicting passport address:", error); throw error; } } /** * 获取 Passport 实现地址 */ async getPassportImplementation() { try { const registryContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); const implementation = await (0, thirdweb_1.readContract)({ contract: registryContract, method: "getPassportImplementation", params: [], }); return implementation; } catch (error) { console.error("Error getting passport implementation:", error); throw error; } } /** * 获取 Passport ID 计数器 */ async getPassportIdCounter() { try { const registryContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); const counter = await (0, thirdweb_1.readContract)({ contract: registryContract, method: "getPassportIdCounter", params: [], }); return Number(counter); } catch (error) { console.error("Error getting passport ID counter:", error); throw error; } } /** * 通过 Passport ID 获取合约地址 */ async getPassportAddressById(passportId) { try { const registryContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); const passportAddress = await (0, thirdweb_1.readContract)({ contract: registryContract, method: "passportIdToContractAddress", params: [BigInt(passportId)], }); return passportAddress; } catch (error) { console.error("Error getting passport address by ID:", error); throw error; } } /** * 检查钱包是否被废除 */ async isWalletAbolished(walletAddress) { try { // 参数验证 if (!walletAddress || !walletAddress.startsWith('0x')) { throw new Error('Invalid wallet address format'); } console.log('Checking wallet abolished status for:', walletAddress); console.log('Registry address:', this.config.registryAddress); console.log('Chain ID:', this.config.chain.id); const registryContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); const isAbolished = await (0, thirdweb_1.readContract)({ contract: registryContract, method: "isWalletAbolished", params: [walletAddress], }); return Boolean(isAbolished); } catch (error) { console.error("Error checking if wallet is abolished:", error); console.error("Wallet address:", walletAddress); console.error("Registry address:", this.config.registryAddress); // 没有备用方法,isWalletAbolished 是唯一的公开方法 console.error("❌ isWalletAbolished 方法调用失败"); console.error("💡 可能的原因:"); console.error("1. 合约地址不正确"); console.error("2. 网络配置不匹配"); console.error("3. 合约版本不兼容"); console.error("4. RPC 连接问题"); throw error; } } /** * 检查钱包是否从特定 Passport 解绑 */ async isWalletUnboundFromPassport(passportId, walletAddress) { try { // 参数验证 if (!walletAddress || !walletAddress.startsWith('0x')) { throw new Error('Invalid wallet address format'); } if (passportId < 0) { throw new Error('Invalid passport ID'); } console.log('Checking wallet unbound status for:', walletAddress, 'from passport ID:', passportId); console.log('Registry address:', this.config.registryAddress); console.log('Chain ID:', this.config.chain.id); const registryContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); const isUnbound = await (0, thirdweb_1.readContract)({ contract: registryContract, method: "isWalletUnboundFromPassport", params: [BigInt(passportId), walletAddress], }); return Boolean(isUnbound); } catch (error) { console.error("Error checking if wallet is unbound from passport:", error); console.error("Wallet address:", walletAddress); console.error("Passport ID:", passportId); console.error("Registry address:", this.config.registryAddress); throw error; } } /** * 检查钱包是否有特定 Passport */ async hasPassport(walletAddress, passportContractAddress) { try { const registryContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); const hasPassport = await (0, thirdweb_1.readContract)({ contract: registryContract, method: "hasPassport", params: [walletAddress, passportContractAddress], }); return Boolean(hasPassport); } catch (error) { console.error("Error checking if wallet has passport:", error); throw error; } } // Passport 方法 /** * 获取 Passport 当前实现地址 */ async getPassportImplementationAddress(passportAddress) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const implementation = await (0, thirdweb_1.readContract)({ contract: passportContract, method: "implementation", params: [], }); return implementation; } catch (error) { console.error("Error getting passport implementation address:", error); throw error; } } /** * 获取 Passport ID */ async getPassportId(passportAddress) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const passportId = await (0, thirdweb_1.readContract)({ contract: passportContract, method: "passportId", params: [], }); return Number(passportId); } catch (error) { console.error("Error getting passport ID:", error); throw error; } } /** * 获取 PassportRegistry 合约地址 */ async getRegistryAddress(passportAddress) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const registry = await (0, thirdweb_1.readContract)({ contract: passportContract, method: "registry", params: [], }); return registry; } catch (error) { console.error("Error getting registry address:", error); throw error; } } /** * 检查钱包是否绑定到 Passport */ async isWalletBound(passportAddress, walletAddress) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const isBound = await (0, thirdweb_1.readContract)({ contract: passportContract, method: "isWalletBound", params: [walletAddress], }); return Boolean(isBound); } catch (error) { console.error("Error checking if wallet is bound:", error); throw error; } } /** * 获取所有绑定钱包 */ async getBoundWallets(passportAddress) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const boundWallets = await (0, thirdweb_1.readContract)({ contract: passportContract, method: "getBoundWallets", params: [], }); return boundWallets; } catch (error) { console.error("Error getting bound wallets:", error); throw error; } } /** * 获取钱包数量 */ async getWalletCount(passportAddress) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const walletCount = await (0, thirdweb_1.readContract)({ contract: passportContract, method: "getWalletCount", params: [], }); return Number(walletCount); } catch (error) { console.error("Error getting wallet count:", error); throw error; } } /** * 通过索引获取绑定钱包 */ async getBoundWalletByIndex(passportAddress, index) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const wallet = await (0, thirdweb_1.readContract)({ contract: passportContract, method: "boundWallets", params: [BigInt(index)], }); return wallet; } catch (error) { console.error("Error getting bound wallet by index:", error); throw error; } } /** * 检查是否有待处理绑定请求 */ async hasPendingBindRequest(passportAddress, walletAddress) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const hasRequest = await (0, thirdweb_1.readContract)({ contract: passportContract, method: "hasPendingBindRequest", params: [walletAddress], }); return Boolean(hasRequest); } catch (error) { console.error("Error checking if wallet has pending bind request:", error); throw error; } } /** * 取消过期的绑定请求 */ async cancelExpiredBindRequest(passportAddress, walletAddress, options) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const transaction = (0, thirdweb_1.prepareContractCall)({ contract: passportContract, method: "cancelExpiredBindRequest", params: [walletAddress], }); // 如果指定发送交易,则直接发送 if (options?.sendTransaction) { const account = options.account || this.defaultAccount; if (!account) { throw new Error("Account is required to send transaction"); } const result = await (0, thirdweb_1.sendTransaction)({ transaction, account, }); return { transactionHash: result.transactionHash, receipt: result, }; } // 否则返回准备好的交易 return { preparedTransaction: transaction, }; } catch (error) { console.error("Error preparing cancel expired bind request transaction:", error); throw error; } } /** * 解绑钱包 */ async unbindWallet(passportAddress, options) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const transaction = (0, thirdweb_1.prepareContractCall)({ contract: passportContract, method: "unbindWallet", params: [], }); // 如果指定发送交易,则直接发送 if (options?.sendTransaction) { const account = options.account || this.defaultAccount; if (!account) { throw new Error("Account is required to send transaction"); } const result = await (0, thirdweb_1.sendTransaction)({ transaction, account, }); return { transactionHash: result.transactionHash, receipt: result, }; } // 否则返回准备好的交易 return { preparedTransaction: transaction, }; } catch (error) { console.error("Error preparing unbind wallet transaction:", error); throw error; } } /** * 请求绑定钱包 */ async requestBindWallet(passportAddress, walletAddress, options) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const transaction = (0, thirdweb_1.prepareContractCall)({ contract: passportContract, method: "requestBindWallet", params: [walletAddress], }); // 如果指定发送交易,则直接发送 if (options?.sendTransaction) { const account = options.account || this.defaultAccount; if (!account) { throw new Error("Account is required to send transaction"); } const result = await (0, thirdweb_1.sendTransaction)({ transaction, account, }); const receipt = await (0, thirdweb_1.waitForReceipt)({ chain: this.config.chain, transactionHash: result.transactionHash, client: this.config.client, }); return receipt; } // 否则返回准备好的交易 return { preparedTransaction: transaction, }; } catch (error) { console.error("Error preparing request bind wallet transaction:", error); throw error; } } /** * 获取待处理绑定请求信息 */ async getPendingBindRequest(passportAddress, walletAddress) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const [exists, requester, timestamp, expired] = await (0, thirdweb_1.readContract)({ contract: passportContract, method: "getPendingBindRequest", params: [walletAddress], }); return { exists: Boolean(exists), requester: requester, timestamp: Number(timestamp), expired: Boolean(expired), }; } catch (error) { console.error("Error getting pending bind request:", error); throw error; } } /** * 取消绑定请求 */ async cancelBindRequest(passportAddress, walletAddress, options) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const transaction = (0, thirdweb_1.prepareContractCall)({ contract: passportContract, method: "cancelBindRequest", params: [walletAddress], }); // 如果指定发送交易,则直接发送 if (options?.sendTransaction) { const account = options.account || this.defaultAccount; if (!account) { throw new Error("Account is required to send transaction"); } const result = await (0, thirdweb_1.sendTransaction)({ transaction, account, }); return { transactionHash: result.transactionHash, receipt: result, }; } // 否则返回准备好的交易 return { preparedTransaction: transaction, }; } catch (error) { console.error("Error preparing cancel bind request transaction:", error); throw error; } } /** * 接受绑定请求 */ async acceptBindRequest(passportAddress, options) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const transaction = (0, thirdweb_1.prepareContractCall)({ contract: passportContract, method: "acceptBindRequest", params: [], }); // 如果指定发送交易,则直接发送 if (options?.sendTransaction) { const account = options.account || this.defaultAccount; if (!account) { throw new Error("Account is required to send transaction"); } const result = await (0, thirdweb_1.sendTransaction)({ transaction, account, }); const receipt = await (0, thirdweb_1.waitForReceipt)({ chain: this.config.chain, transactionHash: result.transactionHash, client: this.config.client, }); return receipt; } // 否则返回准备好的交易 return { preparedTransaction: transaction, }; } catch (error) { console.error("Error preparing accept bind request transaction:", error); throw error; } } /** * 拒绝绑定请求 */ async rejectBindRequest(passportAddress, options) { try { const passportContract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const transaction = (0, thirdweb_1.prepareContractCall)({ contract: passportContract, method: "rejectBindRequest", params: [], }); // 如果指定发送交易,则直接发送 if (options?.sendTransaction) { const account = options.account || this.defaultAccount; if (!account) { throw new Error("Account is required to send transaction"); } const result = await (0, thirdweb_1.sendTransaction)({ transaction, account, }); return { transactionHash: result.transactionHash, receipt: result, }; } // 否则返回准备好的交易 return { preparedTransaction: transaction, }; } catch (error) { console.error("Error preparing reject bind request transaction:", error); throw error; } } /** * 获取待处理绑定钱包列表(使用 viem 确保 msg.sender 验证) */ async getPendingBindWallets(passportAddress, account) { return (0, utils_1.getPendingBindWalletsWithViem)(this.viemClient, passportAddress, account); } /** * Check if a Passport needs to be upgraded * @param passportAddress The Passport contract address * @returns True if upgrade is needed, false otherwise */ async checkPassportUpgrade(passportAddress) { try { const contract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: passportAddress, abi: constants_1.PASSPORT_ABI, }); const result = await (0, thirdweb_1.readContract)({ contract, method: "requireUpgrade", }); return result; } catch (error) { console.error('Error checking passport upgrade:', error); throw error; } } /** * Upgrade the caller's Passport to the latest implementation * @returns Prepared transaction for upgrading the Passport */ async upgradeMyPassport(options) { try { const contract = (0, thirdweb_1.getContract)({ client: this.config.client, chain: this.config.chain, address: this.config.registryAddress, abi: constants_1.PASSPORT_REGISTRY_ABI, }); const transaction = await (0, thirdweb_1.prepareContractCall)({ contract, method: "upgradeMyPassport", }); // 如果指定发送交易,则直接发送 if (options?.sendTransaction) { const account = options.account || this.defaultAccount; if (!account) { throw new Error("Account is required to send transaction"); } const result = await (0, thirdweb_1.sendTransaction)({ transaction, account, }); return { transactionHash: result.transactionHash, receipt: result, }; } // 否则返回准备好的交易 return { preparedTransaction: transaction, }; } catch (error) { console.error('Error preparing upgrade transaction:', error); throw error; } } } exports.PassportSDK = PassportSDK; //# sourceMappingURL=PassportSDK.js.map