@gotake/gotake-sdk
Version:
SDK for interacting with GoTake blockchain contracts
157 lines (156 loc) • 6.07 kB
JavaScript
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();
}
}