PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-hbar/src/lib
Просмотр файла: tokenTransferBuilder.ts
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import * as Long from 'long';
import { proto } from '@hashgraph/proto';
import { BuildTransactionError, InvalidParameterValueError } from '@bitgo/sdk-core';
import { Recipient } from './iface';
import { TransferBuilder } from './transferBuilder';
import { Transaction } from './transaction';
import {
buildHederaAccountID,
buildHederaTokenID,
getHederaTokenIdFromName,
getHederaTokenNameFromId,
isTokenTransfer,
stringifyAccountId,
stringifyTokenId,
} from './utils';
import { BigNumber } from 'bignumber.js';
export class TokenTransferBuilder extends TransferBuilder {
private _tokenName; // currently only support 1 token/transfer
constructor(_coinConfig: Readonly<CoinConfig>) {
super(_coinConfig);
}
/** @inheritdoc */
protected async buildImplementation(): Promise<Transaction> {
this._txBodyData.tokenTransfers = this.buildTokenTransferData(); // set to list by the contract
return await super.buildImplementation();
}
private buildTokenTransferData(): proto.ITokenTransferList[] {
let tokenTransferAmount = new BigNumber(0); // total send amount for each token
const tokenId = getHederaTokenIdFromName(this._tokenName);
const tokenTransferData: proto.IAccountAmount[] = [
{
accountID: buildHederaAccountID(this._source.address),
amount: Long.fromInt(0),
},
];
this._recipients.forEach((recipient) => {
tokenTransferAmount = tokenTransferAmount.plus(recipient.amount);
tokenTransferData.push(
{ accountID: buildHederaAccountID(recipient.address), amount: Long.fromString(recipient.amount) } // recipient
);
});
tokenTransferData[0].amount = Long.fromString(tokenTransferAmount.toString()).negate(); // update sender send amount
return [
{
token: buildHederaTokenID(tokenId!),
transfers: tokenTransferData,
},
];
}
/** @inheritdoc */
initBuilder(tx: Transaction): void {
super.initBuilder(tx);
const transferData = tx.txBody.cryptoTransfer!;
if (isTokenTransfer(transferData)) {
this.initTokenTransfers(transferData.tokenTransfers!);
}
}
/**
* Initialize the transfer specific data, getting the recipient account
* represented by the element with a positive amount on the transfer element.
* The negative amount represents the source account so it's ignored.
*
* @param {proto.IAccountAmount[]} transfers array of objects which contains accountID and transferred amount
*/
protected initTokenTransfers(tokenTransfers: proto.ITokenTransferList[]): void {
tokenTransfers.forEach((tokenTransfer: proto.ITokenTransferList) => {
if (!tokenTransfer.token) {
throw new BuildTransactionError('Invalid transaction: missing token id');
}
if (!tokenTransfer.transfers) {
throw new BuildTransactionError('Invalid transaction: missing transfer data');
}
const token = getHederaTokenNameFromId(stringifyTokenId(tokenTransfer.token!));
if (!token) {
throw new BuildTransactionError('Invalid transaction: invalid token id');
}
tokenTransfer.transfers.forEach((transferData) => {
const amount = Long.fromValue(transferData.amount!);
if (amount.isPositive()) {
this.send({
address: stringifyAccountId(transferData.accountID!),
amount: amount.toString(),
tokenName: token.name,
});
}
});
});
}
// region Transfer fields
/** @inheritdoc */
send(recipient: Recipient): this {
if (!recipient.tokenName) {
throw new InvalidParameterValueError('Invalid missing token name');
}
const tokenId = getHederaTokenIdFromName(recipient.tokenName);
if (!tokenId) {
throw new InvalidParameterValueError(`Invalid token name: ${recipient.tokenName}`);
}
if (this._tokenName && this._tokenName !== recipient.tokenName) {
throw new InvalidParameterValueError(`Invalid token: received ${recipient.tokenName} for ${this._tokenName} tx`);
}
this._tokenName = recipient.tokenName;
return super.send(recipient);
}
// endregion
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!