openchain-sdk-yxl-ts
Version:
OpenChain SDK for browser
199 lines (172 loc) • 5.7 kB
JavaScript
import JSONbig from 'json-bigint';
import humps from 'humps';
import { keypair } from 'openchain-encryption-nodejs-yxl-ts';
import errors from '../exception/index.js';
import CommonUtil from '../common/util.js';
class Contract extends CommonUtil {
constructor(options = {}) {
super(options);
if (!(this instanceof Contract)) {
return new Contract(options);
}
}
async getInfo(contractAddress) {
try {
console.log('Contract address:', contractAddress);
// 验证合约地址
if (!contractAddress || typeof contractAddress !== 'string') {
return this._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
}
// 发送请求
const res = await this._request('get', 'getAccount', {
address: contractAddress,
});
console.log('API Response:', res);
// 检查响应状态
if (!res || res.error_code !== 0) {
if (res?.error_code === 4) { // 账户不存在
return this._responseError(errors.ACCOUNT_NOT_EXIST);
}
return this._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
}
const result = res.result;
// 检查合约信息
if (result.contract && result.contract.payload) {
return this._responseData({
contract: {
type: 0,
payload: result.contract.payload,
},
});
}
// 如果没有合约信息,返回错误
return this._responseError(errors.INVALID_CONTRACT_HASH_ERROR);
} catch (err) {
console.error('Error in getInfo:', err);
// 网络错误处理
if (err.code === 'ECONNRESET' || err.code === 'ECONNREFUSED') {
return this._responseError({
CODE: 11006,
MSG: 'Network connection error'
});
}
return this._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
}
}
async checkValid(contractAddress) {
try {
if (!contractAddress || typeof contractAddress !== 'string') {
return this._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
}
const data = await this._request('get', 'getAccount', {
address: contractAddress,
});
console.log('Check valid response:', data);
// 检查响应状态
if (!data || data.error_code !== 0) {
if (data?.error_code === 4) {
return this._responseError(errors.ACCOUNT_NOT_EXIST);
}
return this._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
}
const result = data.result;
return this._responseData({
isValid: !!result.contract
});
} catch (err) {
console.error('Error in checkValid:', err);
return this._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
}
}
async call(args) {
try {
if (Array.isArray(args) || typeof args !== 'object' || args === null) {
return this._responseError(errors.INVALID_ARGUMENTS);
}
const schema = {
contractAddress: {
required: false,
address: true,
},
sourceAddress: {
required: false,
address: true,
},
code: {
required: false,
string: true,
},
input: {
required: false,
string: true,
},
contractBalance: {
required: false,
numeric: true,
},
feeLimit: {
required: false,
numeric: true,
},
gasPrice: {
required: false,
numeric: true,
},
};
const validation = this._validate(args, schema);
if (!validation.tag) {
return this._responseError(errors[validation.msg]);
}
if (![0, 1, 2].includes(args.optType)) {
return this._responseError(errors.INVALID_OPTTYPE_ERROR);
}
if (!args.contractAddress && !args.code) {
return this._responseError(errors.CONTRACTADDRESS_CODE_BOTH_NULL_ERROR);
}
const isContractAddress = await this._isContractAddress(args.contractAddress);
if (!isContractAddress) {
return this._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
}
const decamelizedArgs = humps.decamelizeKeys(args, { separator: '_' });
const data = JSONbig.stringify(decamelizedArgs);
const info = await this._request('post', 'callContract', data);
if (info.error_code === 0) {
return this._responseData(info.result);
}
return this._responseData(info);
} catch (err) {
console.error('Error in call:', err);
return this._responseError(errors.INVALID_CONTRACTADDRESS_ERROR);
}
}
async getAddress(hash) {
try {
if (!hash || typeof hash !== 'string') {
return this._responseError(errors.INVALID_HASH_ERROR);
}
const accountInfo = await this._request('get', 'getTransactionHistory', {
hash,
});
const contractAddressList = [];
if (accountInfo.error_code === 0 &&
accountInfo.result.transactions?.length > 0) {
const account = accountInfo.result.transactions[0];
if (account.error_desc) {
try {
const info = JSON.parse(account.error_desc);
if (Array.isArray(info)) {
contractAddressList.push(...info);
}
} catch (parseErr) {
console.error('Error parsing error_desc:', parseErr);
}
}
}
return this._responseData({ contractAddressList });
} catch (err) {
console.error('Error in getAddress:', err);
return this._responseError(errors.INVALID_HASH_ERROR);
}
}
}
export default Contract;