diff --git a/package.json b/package.json index f12645ce..14c414c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "juneojs", - "version": "0.0.90", + "version": "0.0.91", "description": "Juneo JS Library", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/chain/jevm.ts b/src/chain/jevm.ts index d472586b..81af6c80 100644 --- a/src/chain/jevm.ts +++ b/src/chain/jevm.ts @@ -14,6 +14,7 @@ export const NativeAssetBalanceContract: string = '0x010000000000000000000000000 export const NativeAssetCallContract: string = '0x0100000000000000000000000000000000000002' export const SendEtherGasLimit: bigint = BigInt(21_000) +const Transferables: string[] = [TokenType.ERC20, TokenType.JRC20, TokenType.Wrapped] export class JEVMBlockchain extends AbstractBlockchain { override asset: JEVMGasToken @@ -22,7 +23,6 @@ export class JEVMBlockchain extends AbstractBlockchain { ethProvider: ethers.JsonRpcProvider jrc20Assets: JRC20Asset[] wrappedAsset: WrappedAsset | undefined - private readonly erc20Handler: ERC20TokenHandler private readonly contractManager: ContractManager = new ContractManager() constructor ( @@ -47,8 +47,7 @@ export class JEVMBlockchain extends AbstractBlockchain { if (typeof wrappedAsset !== 'undefined') { this.addRegisteredAsset(wrappedAsset) } - this.erc20Handler = new ERC20TokenHandler(this.ethProvider) - this.contractManager.registerHandler(this.erc20Handler) + this.contractManager.registerHandler(new ERC20TokenHandler(this.ethProvider)) } async getContractTransactionData ( @@ -60,9 +59,8 @@ export class JEVMBlockchain extends AbstractBlockchain { // could rather use contract manager but it would require one extra network call // we avoid it if the asset is already registered const asset: TokenAsset = await this.getAsset(provider, assetId) - const erc20Types: string[] = [TokenType.ERC20, TokenType.JRC20, TokenType.Wrapped] - if (erc20Types.includes(asset.type)) { - return this.erc20Handler.getTransferData(assetId, to, amount) + if (Transferables.includes(asset.type)) { + return this.contractManager.getTransferData(this.ethProvider, assetId, to, amount) } return '0x' } @@ -82,7 +80,7 @@ export class JEVMBlockchain extends AbstractBlockchain { return ethers.isAddress(address) } - async queryEVMBalance (api: JEVMAPI, address: string, assetId: string): Promise { + async queryBalance (api: JEVMAPI, address: string, assetId: string): Promise { // native asset if (assetId === this.assetId) { return await api.eth_getBalance(address, 'pending') @@ -95,10 +93,6 @@ export class JEVMBlockchain extends AbstractBlockchain { if (!isContractAddress(assetId)) { throw new ChainError(`cannot query balance of invalid asset id ${assetId}`) } - const handler: SolidityTokenHandler | null = await this.contractManager.getHandler(assetId) - if (handler !== null) { - return await handler.queryBalance(assetId, address) - } - return BigInt(0) + return await this.contractManager.balanceOf(this.ethProvider, assetId, address) } } diff --git a/src/chain/solidity/abi.ts b/src/chain/solidity/abi.ts index ea6d2d9b..7353407a 100644 --- a/src/chain/solidity/abi.ts +++ b/src/chain/solidity/abi.ts @@ -1,3 +1,7 @@ +export const TransferABI: string[] = ['function transfer(address to, uint amount) returns (bool)'] + +export const BalanceOfABI: string[] = ['function balanceOf(address owner) view returns (uint256)'] + export const ERC20ABI: string[] = [ 'function name() view returns (string)', 'function decimals() view returns (uint8)', diff --git a/src/chain/solidity/contract.ts b/src/chain/solidity/contract.ts index d1059410..b3ce3a64 100644 --- a/src/chain/solidity/contract.ts +++ b/src/chain/solidity/contract.ts @@ -22,16 +22,22 @@ export class ContractManager { // Should do a better getHandler function in the future this.handlers.unshift(handler) } + + async balanceOf (provider: ethers.JsonRpcProvider, contractAddress: string, address: string): Promise { + const contract: ethers.Contract = new ethers.Contract(contractAddress, abi.BalanceOfABI, provider) + return BigInt.asUintN(256, BigInt(await contract.balanceOf(address))) + } + + getTransferData (provider: ethers.JsonRpcProvider, contractAddress: string, to: string, amount: bigint): string { + const contract: ethers.Contract = new ethers.Contract(contractAddress, abi.TransferABI, provider) + return contract.interface.encodeFunctionData('transfer', [to, amount]) + } } export interface SolidityTokenHandler { instanceOf: (contractAddress: string) => Promise - queryBalance: (contractAddress: string, address: string) => Promise - queryTokenData: (contractAddress: string) => Promise - - getTransferData: (contractAddress: string, to: string, amount: bigint) => string } export class ERC20TokenHandler implements SolidityTokenHandler { @@ -52,11 +58,6 @@ export class ERC20TokenHandler implements SolidityTokenHandler { return true } - async queryBalance (contractAddress: string, address: string): Promise { - const contract: ethers.Contract = this.getContract(contractAddress) - return BigInt.asUintN(256, BigInt(await contract.balanceOf(address))) - } - async queryTokenData (contractAddress: string): Promise { const contract: ethers.Contract = this.getContract(contractAddress) const name: string = await contract.name() @@ -65,11 +66,6 @@ export class ERC20TokenHandler implements SolidityTokenHandler { return new ERC20Asset(contractAddress, name, symbol, decimals) } - getTransferData (contractAddress: string, to: string, amount: bigint): string { - const contract: ethers.Contract = new ethers.Contract(contractAddress, abi.ERC20ABI) - return contract.interface.encodeFunctionData('transfer', [to, amount]) - } - protected getContract (contractAddress: string): ethers.Contract { return new ethers.Contract(contractAddress, abi.ERC20ABI, this.provider) } diff --git a/src/wallet/account/evm.ts b/src/wallet/account/evm.ts index 5807287f..ba567a67 100644 --- a/src/wallet/account/evm.ts +++ b/src/wallet/account/evm.ts @@ -119,6 +119,6 @@ export class EVMAccount extends AbstractChainAccount { } const balance: Balance = this.balances.get(assetId)! const address: string = this.chainWallet.getAddress() - await balance.updateAsync(this.chain.queryEVMBalance(this.provider.jevmApi[this.chain.id], address, assetId)) + await balance.updateAsync(this.chain.queryBalance(this.provider.jevmApi[this.chain.id], address, assetId)) } } diff --git a/src/wallet/account/platform.ts b/src/wallet/account/platform.ts index 894b6d54..e8f7730f 100644 --- a/src/wallet/account/platform.ts +++ b/src/wallet/account/platform.ts @@ -6,7 +6,10 @@ import { estimatePlatformValidatePrimaryOperation, estimatePlatformDelegatePrimaryOperation, estimateSendOperation, - estimateSendUtxoOperation + estimateSendUtxoOperation, + estimatePlatformCreateSupernetOperation, + estimatePlatformAddSupernetValidatorOperation, + estimatePlatformRemoveSupernetValidatorOperation } from '../transaction' import { AccountError } from '../../utils' import { @@ -17,7 +20,10 @@ import { type ValidatePrimaryOperation, type ChainNetworkOperation, type SendOperation, - type SendUtxoOperation + type SendUtxoOperation, + type CreateSupernetOperation, + type AddSupernetValidatorOperation, + type RemoveSupernetValidatorOperation } from '../operation' import { type MCNWallet } from '../wallet' import { UtxoAccount } from './account' @@ -41,6 +47,20 @@ export class PlatformAccount extends UtxoAccount { return await estimateSendOperation(provider, this.chain, this, operation as SendOperation) } else if (operation.type === NetworkOperationType.SendUtxo) { return await estimateSendUtxoOperation(provider, this.chain, this, operation as SendUtxoOperation) + } else if (operation.type === NetworkOperationType.CreateSupernet) { + return await estimatePlatformCreateSupernetOperation(provider, operation as CreateSupernetOperation, this) + } else if (operation.type === NetworkOperationType.ValidateSupernet) { + return await estimatePlatformAddSupernetValidatorOperation( + provider, + operation as AddSupernetValidatorOperation, + this + ) + } else if (operation.type === NetworkOperationType.RemoveSupernetValidator) { + return await estimatePlatformRemoveSupernetValidatorOperation( + provider, + operation as RemoveSupernetValidatorOperation, + this + ) } throw new AccountError(`unsupported operation: ${operation.type} for the chain with id: ${this.chain.id}`) } @@ -56,6 +76,12 @@ export class PlatformAccount extends UtxoAccount { await this.executeAndTrackTransaction(summary, TransactionType.Send) } else if (operation === NetworkOperationType.SendUtxo) { await this.executeAndTrackTransaction(summary, TransactionType.Send) + } else if (operation === NetworkOperationType.CreateSupernet) { + await this.executeAndTrackTransaction(summary, TransactionType.CreateSupernet) + } else if (operation === NetworkOperationType.ValidateSupernet) { + await this.executeAndTrackTransaction(summary, TransactionType.ValidateSupernet) + } else if (operation === NetworkOperationType.RemoveSupernetValidator) { + await this.executeAndTrackTransaction(summary, TransactionType.RemoveSupernetValidator) } // balances fetching is needed to get new utxos creating from this operation await super.refreshBalances() diff --git a/src/wallet/operation/operation.ts b/src/wallet/operation/operation.ts index ece74c59..efe6c596 100644 --- a/src/wallet/operation/operation.ts +++ b/src/wallet/operation/operation.ts @@ -1,6 +1,5 @@ import { type JRC20Asset, type WrappedAsset } from '../../asset' -import { type JEVMBlockchain, type Blockchain } from '../../chain' -import { type MCN } from '../../network' +import { type JEVMBlockchain, type Blockchain, type PlatformBlockchain } from '../../chain' import { BLSPublicKey, BLSSignature, type Utxo } from '../../transaction' export enum NetworkOperationType { @@ -17,6 +16,9 @@ export enum NetworkOperationType { RedeemAuction = 'Redeem auction', WithdrawStream = 'Withdraw stream', CancelStream = 'Cancel stream', + CreateSupernet = 'Create supernet', + ValidateSupernet = 'Validate supernet', + RemoveSupernetValidator = 'Remove supernet validator', } export enum NetworkOperationRange { @@ -164,7 +166,7 @@ export abstract class Staking extends ChainNetworkOperation { constructor ( type: NetworkOperationType, - mcn: MCN, + chain: PlatformBlockchain, nodeId: string, amount: bigint, startTime: bigint, @@ -174,7 +176,7 @@ export abstract class Staking extends ChainNetworkOperation { rewardAddresses: string[], rewardThreshold: number ) { - super(type, mcn.primary.platform) + super(type, chain) this.nodeId = nodeId this.amount = amount this.startTime = startTime @@ -191,7 +193,7 @@ export class ValidatePrimaryOperation extends Staking { signature: BLSSignature constructor ( - mcn: MCN, + chain: PlatformBlockchain, nodeId: string, publicKey: string, signature: string, @@ -205,7 +207,7 @@ export class ValidatePrimaryOperation extends Staking { ) { super( NetworkOperationType.ValidatePrimary, - mcn, + chain, nodeId, amount, startTime, @@ -222,7 +224,7 @@ export class ValidatePrimaryOperation extends Staking { export class DelegatePrimaryOperation extends Staking { constructor ( - mcn: MCN, + chain: PlatformBlockchain, nodeId: string, amount: bigint, startTime: bigint, @@ -234,7 +236,7 @@ export class DelegatePrimaryOperation extends Staking { ) { super( NetworkOperationType.DelegatePrimary, - mcn, + chain, nodeId, amount, startTime, @@ -247,6 +249,52 @@ export class DelegatePrimaryOperation extends Staking { } } +export class CreateSupernetOperation extends ChainNetworkOperation { + supernetAuthAddresses: string[] + supernetAuthThreshold: number + + constructor (chain: PlatformBlockchain, supernetAuthAddresses: string[], supernetAuthThreshold: number) { + super(NetworkOperationType.CreateSupernet, chain) + this.supernetAuthAddresses = supernetAuthAddresses + this.supernetAuthThreshold = supernetAuthThreshold + } +} + +export class AddSupernetValidatorOperation extends ChainNetworkOperation { + supernetId: string + nodeId: string + amount: bigint + startTime: bigint + endTime: bigint + + constructor ( + chain: PlatformBlockchain, + supernetId: string, + nodeId: string, + amount: bigint, + startTime: bigint, + endTime: bigint + ) { + super(NetworkOperationType.ValidateSupernet, chain) + this.supernetId = supernetId + this.nodeId = nodeId + this.amount = amount + this.startTime = startTime + this.endTime = endTime + } +} + +export class RemoveSupernetValidatorOperation extends ChainNetworkOperation { + supernetId: string + nodeId: string + + constructor (chain: PlatformBlockchain, supernetId: string, nodeId: string) { + super(NetworkOperationType.RemoveSupernetValidator, chain) + this.supernetId = supernetId + this.nodeId = nodeId + } +} + export class CrossOperation implements NetworkOperation { type: NetworkOperationType = NetworkOperationType.Cross range: NetworkOperationRange = NetworkOperationRange.Supernet diff --git a/src/wallet/transaction/base.ts b/src/wallet/transaction/base.ts index f9dd9816..d4c34dab 100644 --- a/src/wallet/transaction/base.ts +++ b/src/wallet/transaction/base.ts @@ -4,8 +4,7 @@ import { buildJVMBaseTransaction, buildPlatformBaseTransaction, type UnsignedTransaction, - UserInput, - type Utxo + UserInput } from '../../transaction' import { type UtxoAccount } from '../account' import { ChainOperationSummary, type SendOperation, type SendUtxoOperation } from '../operation' @@ -24,7 +23,6 @@ export async function estimateBaseTransaction ( amount: bigint, addresses: string[], threshold: number, - utxoSet: Utxo[], locktime: bigint = BigInt(0) ): Promise { const fee: BaseFeeData = await getBaseTxFee(provider, FeeType.BaseFee, chain) @@ -32,7 +30,7 @@ export async function estimateBaseTransaction ( chain.id === provider.platformChain.id ? buildPlatformBaseTransaction( [new UserInput(assetId, chain, amount, addresses, threshold, chain, locktime)], - utxoSet, + account.utxoSet, account.getSignersAddresses(), fee.amount, account.address, @@ -40,7 +38,7 @@ export async function estimateBaseTransaction ( ) : buildJVMBaseTransaction( [new UserInput(assetId, chain, amount, addresses, threshold, chain, locktime)], - utxoSet, + account.utxoSet, account.getSignersAddresses(), fee.amount, account.address, @@ -64,7 +62,6 @@ export async function estimateSendOperation ( send.amount, [send.address], 1, - account.utxoSet, BigInt(0) ).then( (fee) => { @@ -100,7 +97,6 @@ export async function estimateSendUtxoOperation ( send.amount, send.addresses, send.threshold, - account.utxoSet, send.locktime ).then( (fee) => { diff --git a/src/wallet/transaction/evm.ts b/src/wallet/transaction/evm.ts index 04f14b1c..36e914b1 100644 --- a/src/wallet/transaction/evm.ts +++ b/src/wallet/transaction/evm.ts @@ -194,7 +194,15 @@ export async function estimateEVMWrapOperation ( }, async () => { const gasPrice: bigint = await estimateEVMGasPrice(api) - const fee: BaseFeeData = new BaseFeeData(chain, DefaultWrapEstimate * gasPrice, type) + const transactionData: EVMTransactionData = new EVMTransactionData(from, wrap.asset.address, BigInt(0), data) + const fee: EVMFeeData = new EVMFeeData( + chain, + gasPrice * DefaultWrapEstimate, + type, + gasPrice, + DefaultWrapEstimate, + transactionData + ) const spending: BaseSpending = new BaseSpending(chain, wrap.amount, chain.assetId) return new ChainOperationSummary(provider, wrap, chain, fee, [spending, fee.spending], values) } @@ -218,7 +226,15 @@ export async function estimateEVMUnwrapOperation ( }, async () => { const gasPrice: bigint = await estimateEVMGasPrice(api) - const fee: BaseFeeData = new BaseFeeData(chain, DefaultUnwrapEstimate * gasPrice, type) + const transactionData: EVMTransactionData = new EVMTransactionData(from, unwrap.asset.address, BigInt(0), data) + const fee: EVMFeeData = new EVMFeeData( + chain, + gasPrice * DefaultUnwrapEstimate, + type, + gasPrice, + DefaultUnwrapEstimate, + transactionData + ) const spending: BaseSpending = new BaseSpending(chain, unwrap.amount, unwrap.asset.assetId) return new ChainOperationSummary(provider, unwrap, chain, fee, [spending, fee.spending], values) } @@ -241,7 +257,15 @@ export async function estimateEVMRedeemAuctionOperation ( }, async () => { const gasPrice: bigint = await estimateEVMGasPrice(api) - const fee: BaseFeeData = new BaseFeeData(chain, DefaultRedeemAuctionEstimate * gasPrice, type) + const transactionData: EVMTransactionData = new EVMTransactionData(from, redeem.auctionAddress, BigInt(0), data) + const fee: EVMFeeData = new EVMFeeData( + chain, + gasPrice * DefaultRedeemAuctionEstimate, + type, + gasPrice, + DefaultRedeemAuctionEstimate, + transactionData + ) return new ChainOperationSummary(provider, redeem, chain, fee, [fee.spending], new Map()) } ) @@ -263,7 +287,15 @@ export async function estimateEVMWithdrawStreamOperation ( }, async () => { const gasPrice: bigint = await estimateEVMGasPrice(api) - const fee: BaseFeeData = new BaseFeeData(chain, DefaultWithdrawStreamEstimate * gasPrice, type) + const transactionData: EVMTransactionData = new EVMTransactionData(from, withdraw.streamAddress, BigInt(0), data) + const fee: EVMFeeData = new EVMFeeData( + chain, + gasPrice * DefaultWithdrawStreamEstimate, + type, + gasPrice, + DefaultWithdrawStreamEstimate, + transactionData + ) return new ChainOperationSummary(provider, withdraw, chain, fee, [fee.spending], new Map()) } ) @@ -285,7 +317,15 @@ export async function estimateEVMCancelStreamOperation ( }, async () => { const gasPrice: bigint = await estimateEVMGasPrice(api) - const fee: BaseFeeData = new BaseFeeData(chain, DefaultCancelStreamEstimate * gasPrice, type) + const transactionData: EVMTransactionData = new EVMTransactionData(from, cancel.streamAddress, BigInt(0), data) + const fee: EVMFeeData = new EVMFeeData( + chain, + gasPrice * DefaultCancelStreamEstimate, + type, + gasPrice, + DefaultCancelStreamEstimate, + transactionData + ) return new ChainOperationSummary(provider, cancel, chain, fee, [fee.spending], new Map()) } ) diff --git a/src/wallet/transaction/fee.ts b/src/wallet/transaction/fee.ts index fca47549..46269258 100644 --- a/src/wallet/transaction/fee.ts +++ b/src/wallet/transaction/fee.ts @@ -18,6 +18,8 @@ export enum FeeType { RedeemAuction = 'Redeem fee', WithdrawStream = 'Withdraw stream fee', CancelStream = 'Cancel stream fee', + CreateSupernet = 'Create supernet fee', + RemoveSupernetValidator = 'Remove supernet validator fee', } export interface FeeData { diff --git a/src/wallet/transaction/platform.ts b/src/wallet/transaction/platform.ts index f1362a2e..8ff8fa25 100644 --- a/src/wallet/transaction/platform.ts +++ b/src/wallet/transaction/platform.ts @@ -2,18 +2,25 @@ import { type PlatformBlockchain } from '../../chain' import { type MCNProvider } from '../../juneo' import { Validator, - type Utxo, type UnsignedTransaction, NodeId, buildAddPermissionlessValidatorTransaction, ProofOfPossession, PrimarySigner, - buildAddPermissionlessDelegatorTransaction + buildAddPermissionlessDelegatorTransaction, + buildCreateSupernetTransaction, + buildAddSupernetValidatorTransaction, + CreateSupernetTransaction, + Address, + buildRemoveSupernetValidatorTransaction } from '../../transaction' import { type PlatformAccount } from '../account' import { + type AddSupernetValidatorOperation, ChainOperationSummary, + type CreateSupernetOperation, type DelegatePrimaryOperation, + type RemoveSupernetValidatorOperation, StakingOperationSummary, type ValidatePrimaryOperation } from '../operation' @@ -30,6 +37,21 @@ async function getPlatformAddPrimaryDelegatorFee (provider: MCNProvider): Promis return new BaseFeeData(provider.platformChain, fee, FeeType.DelegateFee) } +async function getPlatformCreateSupernetFee (provider: MCNProvider): Promise { + const fee: bigint = BigInt((await provider.info.getTxFee()).createSupernetTxFee) + return new BaseFeeData(provider.platformChain, fee, FeeType.CreateSupernet) +} + +async function getPlatformAddSupernetValidatorFee (provider: MCNProvider): Promise { + const fee: bigint = BigInt((await provider.info.getTxFee()).addSupernetValidatorFee) + return new BaseFeeData(provider.platformChain, fee, FeeType.ValidateFee) +} + +async function getPlatformRemoveSupernetValidatorFee (provider: MCNProvider): Promise { + const fee: bigint = BigInt((await provider.info.getTxFee()).txFee) + return new BaseFeeData(provider.platformChain, fee, FeeType.RemoveSupernetValidator) +} + export async function estimatePlatformAddPrimaryValidatorTransaction ( provider: MCNProvider, account: PlatformAccount, @@ -39,12 +61,11 @@ export async function estimatePlatformAddPrimaryValidatorTransaction ( stakeAddresses: string[], stakeThreshold: number, rewardAddresses: string[], - rewardThreshold: number, - utxoSet: Utxo[] + rewardThreshold: number ): Promise { const fee: BaseFeeData = await getPlatformAddPrimaryValidatorFee(provider) const transaction: UnsignedTransaction = buildAddPermissionlessValidatorTransaction( - utxoSet, + account.utxoSet, account.getSignersAddresses(), fee.amount, provider.platformChain, @@ -94,8 +115,7 @@ export async function estimatePlatformValidatePrimaryOperation ( validate.stakeAddresses, validate.stakeThreshold, validate.rewardAddresses, - validate.rewardThreshold, - account.utxoSet + validate.rewardThreshold ).then( (fee) => { const spending: UtxoSpending = new UtxoSpending(chain, validate.amount, chain.assetId, fee.transaction.getUtxos()) @@ -130,12 +150,11 @@ export async function estimatePlatformAddPrimaryDelegatorTransaction ( stakeAddresses: string[], stakeThreshold: number, rewardAddresses: string[], - rewardThreshold: number, - utxoSet: Utxo[] + rewardThreshold: number ): Promise { const fee: BaseFeeData = await getPlatformAddPrimaryDelegatorFee(provider) const transaction: UnsignedTransaction = buildAddPermissionlessDelegatorTransaction( - utxoSet, + account.utxoSet, account.getSignersAddresses(), fee.amount, provider.platformChain, @@ -181,8 +200,7 @@ export async function estimatePlatformDelegatePrimaryOperation ( delegate.stakeAddresses, delegate.stakeThreshold, delegate.rewardAddresses, - delegate.rewardThreshold, - account.utxoSet + delegate.rewardThreshold ).then( (fee) => { const spending: UtxoSpending = new UtxoSpending(chain, delegate.amount, chain.assetId, fee.transaction.getUtxos()) @@ -209,3 +227,149 @@ export async function estimatePlatformDelegatePrimaryOperation ( } ) } + +export async function estimatePlatformCreateSupernetTransaction ( + provider: MCNProvider, + account: PlatformAccount, + supernetAuthAddresses: string[], + supernetAuthThreshold: number +): Promise { + const fee: BaseFeeData = await getPlatformCreateSupernetFee(provider) + const transaction: UnsignedTransaction = buildCreateSupernetTransaction( + account.utxoSet, + account.getSignersAddresses(), + fee.amount, + provider.platformChain, + supernetAuthAddresses, + supernetAuthThreshold, + account.address, + provider.mcn.id + ) + return new UtxoFeeData(fee.chain, fee.amount, fee.type, transaction) +} + +export async function estimatePlatformCreateSupernetOperation ( + provider: MCNProvider, + createSupernet: CreateSupernetOperation, + account: PlatformAccount +): Promise { + const chain: PlatformBlockchain = provider.platformChain + const values = new Map() + return await estimatePlatformCreateSupernetTransaction( + provider, + account, + createSupernet.supernetAuthAddresses, + createSupernet.supernetAuthThreshold + ).then( + (fee) => { + return new ChainOperationSummary(provider, createSupernet, chain, fee, [fee.spending], values) + }, + async () => { + const fee: BaseFeeData = await getPlatformCreateSupernetFee(provider) + return new ChainOperationSummary(provider, createSupernet, chain, fee, [fee.spending], values) + } + ) +} + +export async function estimatePlatformAddSupernetValidatorTransaction ( + provider: MCNProvider, + account: PlatformAccount, + supernetId: string, + validator: Validator +): Promise { + const fee: BaseFeeData = await getPlatformAddSupernetValidatorFee(provider) + const createSupernetTx: CreateSupernetTransaction = CreateSupernetTransaction.parse( + (await provider.platformApi.getTx(supernetId)).tx + ) + const transaction: UnsignedTransaction = buildAddSupernetValidatorTransaction( + account.utxoSet, + account.getSignersAddresses(), + fee.amount, + provider.platformChain, + validator.nodeId, + validator.startTime, + validator.endTime, + validator.weight, + supernetId, + createSupernetTx.getSupernetAuth(Address.toAddresses(account.getSignersAddresses())), + account.address, + provider.mcn.id + ) + return new UtxoFeeData(fee.chain, fee.amount, fee.type, transaction) +} + +export async function estimatePlatformAddSupernetValidatorOperation ( + provider: MCNProvider, + addValidator: AddSupernetValidatorOperation, + account: PlatformAccount +): Promise { + const chain: PlatformBlockchain = provider.platformChain + const validator: Validator = new Validator( + new NodeId(addValidator.nodeId), + addValidator.startTime, + addValidator.endTime, + addValidator.amount + ) + const values = new Map() + return await estimatePlatformAddSupernetValidatorTransaction( + provider, + account, + addValidator.supernetId, + validator + ).then( + (fee) => { + return new ChainOperationSummary(provider, addValidator, chain, fee, [fee.spending], values) + }, + async () => { + const fee: BaseFeeData = await getPlatformAddSupernetValidatorFee(provider) + return new ChainOperationSummary(provider, addValidator, chain, fee, [fee.spending], values) + } + ) +} + +export async function estimatePlatformRemoveSupernetValidatorTransaction ( + provider: MCNProvider, + account: PlatformAccount, + supernetId: string, + nodeId: string +): Promise { + const fee: BaseFeeData = await getPlatformRemoveSupernetValidatorFee(provider) + const createSupernetTx: CreateSupernetTransaction = CreateSupernetTransaction.parse( + (await provider.platformApi.getTx(supernetId)).tx + ) + const transaction: UnsignedTransaction = buildRemoveSupernetValidatorTransaction( + account.utxoSet, + account.getSignersAddresses(), + fee.amount, + provider.platformChain, + nodeId, + supernetId, + createSupernetTx.getSupernetAuth(Address.toAddresses(account.getSignersAddresses())), + account.address, + provider.mcn.id + ) + return new UtxoFeeData(fee.chain, fee.amount, fee.type, transaction) +} + +export async function estimatePlatformRemoveSupernetValidatorOperation ( + provider: MCNProvider, + removeValidator: RemoveSupernetValidatorOperation, + account: PlatformAccount +): Promise { + const chain: PlatformBlockchain = provider.platformChain + const values = new Map() + return await estimatePlatformRemoveSupernetValidatorTransaction( + provider, + account, + removeValidator.supernetId, + removeValidator.nodeId + ).then( + (fee) => { + return new ChainOperationSummary(provider, removeValidator, chain, fee, [fee.spending], values) + }, + async () => { + const fee: BaseFeeData = await getPlatformRemoveSupernetValidatorFee(provider) + return new ChainOperationSummary(provider, removeValidator, chain, fee, [fee.spending], values) + } + ) +} diff --git a/src/wallet/transaction/transaction.ts b/src/wallet/transaction/transaction.ts index 382c1515..e2b06f24 100644 --- a/src/wallet/transaction/transaction.ts +++ b/src/wallet/transaction/transaction.ts @@ -15,6 +15,9 @@ export enum TransactionType { RedeemAuction = 'Redeem auction transaction', WithdrawStream = 'Withdraw stream transaction', CancelStream = 'Cancel stream transaction', + CreateSupernet = 'Create supernet transaction', + ValidateSupernet = 'Supernet validation transaction', + RemoveSupernetValidator = 'Remove supernet validator transaction', } export class TransactionReceipt {