UNPKG

@gotake/gotake-sdk

Version:

SDK for interacting with GoTake blockchain contracts

157 lines (156 loc) 6.07 kB
import { ethers } from 'ethers'; import { BaseApi } from './base-api.js'; import { ERC6551RegistryWrapper, TBAWrapper } from '../wrappers/index.js'; import { getContractAddress } from 'gotake-contracts'; /** * Account API module, providing Token Bound Account (TBA) related functionality */ export class AccountApi extends BaseApi { /** * Create Account API instance * @param provider Provider instance * @param signer Signer instance */ constructor(provider, signer) { super(provider, signer); this._registryWrapper = new ERC6551RegistryWrapper(provider, signer); this._tbaWrapper = new TBAWrapper(provider, signer); } /** * Calculate TBA address for an NFT (without creating the account) * @param params Creation parameters * @returns TBA address */ async computeTBAAddress(params) { // Ensure networkId is initialized await this.init(); await this._registryWrapper.init(); const { tokenContract, tokenId, salt = '0x0000000000000000000000000000000000000000000000000000000000000000' } = params; if (!this._networkId) { throw new Error("NetworkId not initialized. Make sure signer is connected to a network."); } // Use implementation from contract address configuration const networkKey = this.getNetworkKey(this._networkId); const implAddress = getContractAddress(networkKey, 'accountImplementation'); const tokenIdBN = ethers.BigNumber.from(tokenId); // Ensure salt is string or BigNumber type const saltValue = typeof salt === 'number' ? ethers.BigNumber.from(salt) : salt; const chainId = this._networkId; return this._registryWrapper.account(implAddress, typeof saltValue === 'string' ? saltValue : saltValue.toString(), chainId, tokenContract, tokenIdBN.toString()); } /** * Create TBA account * @param params Creation parameters * @param options Transaction options * @returns TBA address and transaction */ async createTBA(params, options) { // Ensure networkId is initialized await this.init(); await this._registryWrapper.init(); const { tokenContract, tokenId, salt = '0x0000000000000000000000000000000000000000000000000000000000000000' } = params; if (!this._networkId) { throw new Error("NetworkId not initialized. Make sure signer is connected to a network."); } // Use implementation from contract address configuration const networkKey = this.getNetworkKey(this._networkId); const implAddress = getContractAddress(networkKey, 'accountImplementation'); const tokenIdBN = ethers.BigNumber.from(tokenId); // Ensure salt is string or BigNumber type const saltValue = typeof salt === 'number' ? ethers.BigNumber.from(salt) : salt; const chainId = this._networkId; // Use new parameter structure const registryParams = { implementation: implAddress, salt: typeof saltValue === 'string' ? saltValue : saltValue.toString(), chainId: chainId, tokenContract: tokenContract, tokenId: tokenIdBN.toString() }; // Get creation result const result = await this._registryWrapper.createAccount(registryParams, options); // Return result with accountAddress renamed to tbaAddress return { tbaAddress: result.accountAddress, tx: result.tx }; } /** * Initialize TBA account * @param params Initialization parameters * @param options Transaction options * @returns Transaction object */ async initializeTBA(params, options) { await this._tbaWrapper.init(); return this._tbaWrapper.initialize(params, options); } /** * Get TBA information related to an NFT * @param accountAddress TBA address * @returns TBA information */ async getTBAInfo(accountAddress) { await this._tbaWrapper.init(); const tokenInfo = await this._tbaWrapper.tokenOf(accountAddress); const state = await this._tbaWrapper.getState(accountAddress); return { ...tokenInfo, state }; } /** * Execute a transaction from TBA * @param params Transaction parameters * @param options Transaction options * @returns Transaction result */ async executeTBATransaction(params, options) { await this._tbaWrapper.init(); return this._tbaWrapper.execute(params, options); } /** * Check if an address is a valid signer for a TBA * @param accountAddress TBA address * @param signerAddress Signer address * @returns Whether it's a valid signer */ async isValidSigner(accountAddress, signerAddress) { await this._tbaWrapper.init(); return this._tbaWrapper.isValidSigner(accountAddress, signerAddress); } /** * Convert NetworkId to network key string * @param networkId Network ID * @returns Network key */ getNetworkKey(networkId) { const networkMap = { 1: 'ethereum_mainnet', 5: 'ethereum_goerli', 11155111: 'ethereum_sepolia', 8453: 'base_mainnet', 84531: 'base_goerli', 84532: 'base_sepolia', }; const key = networkMap[networkId]; if (!key) { throw new Error(`Network ID ${networkId} not supported`); } return key; } /** * Handle connection update */ async onConnectionUpdated() { // First update our own connection await super.onConnectionUpdated(); // Update wrappers' connections this._registryWrapper.updateConnection(this._provider, this._signer); await this._registryWrapper.init(); this._tbaWrapper.updateConnection(this._provider, this._signer); await this._tbaWrapper.init(); } }