From 08ec8328c2096e650d38850d751cd6c469a950be Mon Sep 17 00:00:00 2001 From: Oleksandr Myshchyshyn Date: Fri, 20 Dec 2024 12:52:58 +0200 Subject: [PATCH 1/4] Add transaction builders, updated documentation, added prefix for signature --- README.md | 78 ++--- migration-guide-v2-v5.md | 77 ++++- src/types/Deploy.ts | 4 +- src/types/Transaction.test.ts | 28 ++ src/types/Transaction.ts | 13 +- src/types/TransactionBuilder.md | 167 +++++++++ src/types/TransactionBuilder.ts | 580 ++++++++++++++++++++++++++++++++ 7 files changed, 870 insertions(+), 77 deletions(-) create mode 100644 src/types/TransactionBuilder.md create mode 100644 src/types/TransactionBuilder.ts diff --git a/README.md b/README.md index 13f3e560c..96c083028 100644 --- a/README.md +++ b/README.md @@ -114,81 +114,43 @@ Example of how to construct a transaction and push it to the network: ```ts import { - Args, - CLValue, - CLValueOption, - CLValueUInt64, - CLValueUInt512, - Duration, HttpHandler, - InitiatorAddr, - KeyAlgorithm, - PricingMode, + RpcClient, + NativeTransferBuilder, PrivateKey, + KeyAlgorithm, PublicKey, - RpcClient, - Timestamp, - TransactionEntryPoint, - TransactionScheduling, - TransactionTarget, - TransactionV1, - TransactionV1Payload, - TransactionEntryPointEnum, - PaymentLimitedMode + Transaction } from 'casper-js-sdk'; const rpcHandler = new HttpHandler('http://:7777/rpc'); const rpcClient = new RpcClient(rpcHandler); const privateKey = await PrivateKey.generate(KeyAlgorithm.ED25519); -const timestamp = new Timestamp(new Date()); -const paymentAmount = '20000000000000'; - -const pricingMode = new PricingMode(); -const paymentLimitedMode = new PaymentLimitedMode(); -paymentLimitedMode.gasPriceTolerance = 1; -paymentLimitedMode.paymentAmount = paymentAmount; -paymentLimitedMode.standardPayment = true; -pricingMode.paymentLimited = paymentLimitedMode; - -const args = Args.fromMap({ - target: CLValue.newCLPublicKey( + +const transactionV1 = new NativeTransferBuilder() + .from(privateKey.publicKey) + .target( PublicKey.fromHex( '0202f5a92ab6da536e7b1a351406f3744224bec85d7acbab1497b65de48a1a707b64' ) - ), - amount: CLValueUInt512.newCLUInt512(paymentAmount), - id: CLValueOption.newCLOption(CLValueUInt64.newCLUint64(3)) // memo ( optional ) -}); + ) + .amount('25000000000') // Amount in motes + .id(Date.now()) + .chainName('casper-net-1') + .payment(100_000_000) + .build(); -const transactionTarget = new TransactionTarget({}); // Native target; -const entryPoint = new TransactionEntryPoint( - TransactionEntryPointEnum.Transfer -); -const scheduling = new TransactionScheduling({}); // Standard; - -const transactionPayload = TransactionV1Payload.build({ - initiatorAddr: new InitiatorAddr(privateKey.publicKey), - ttl: new Duration(1800000), - args, - timestamp, - entryPoint, - scheduling, - transactionTarget, - chainName: 'casper-net-1', - pricingMode -}); - -const transactionV1 = TransactionV1.makeTransactionV1( - transactionPayload -); await transactionV1.sign(privateKey); const tx = Transaction.fromTransactionV1(transactionV1); -const result = await rpcClient.putTransaction(tx); - -console.log(`Transaction Hash: ${result.transactionHash}`); +try { + const result = await rpcClient.putTransaction(tx); + console.log(`Transaction Hash: ${result.transactionHash}`); +} catch (e) { + console.error(e); +} ``` ### Creating a legacy deploy diff --git a/migration-guide-v2-v5.md b/migration-guide-v2-v5.md index 32f865226..df863e1c4 100644 --- a/migration-guide-v2-v5.md +++ b/migration-guide-v2-v5.md @@ -197,10 +197,10 @@ const publicKey = privateKey.publicKey; ```typescript const args = Args.fromMap({ - target: CLValue.newCLPublicKey( - PublicKey.fromHex('') - ), - amount: CLValueUInt512.newCLUInt512('2000000000') // 2 CSPR + target: CLValue.newCLPublicKey( + PublicKey.fromHex('') + ), + amount: CLValueUInt512.newCLUInt512('2000000000') // 2 CSPR }); ``` @@ -216,7 +216,7 @@ const transactionTarget = new TransactionTarget({}); // Native target; ```typescript const entryPoint = new TransactionEntryPoint( - TransactionEntryPointEnum.Transfer + TransactionEntryPointEnum.Transfer ); ``` @@ -242,19 +242,19 @@ pricingMode.paymentLimited = paymentLimitedMode; ```typescript const transactionPayload = TransactionV1Payload.build({ - initiatorAddr: new InitiatorAddr(publicKey), - ttl: new Duration(1800000), - args, - timestamp: new Timestamp(new Date()), - entryPoint, - scheduling, - transactionTarget, - chainName: 'casper-net-1', - pricingMode + initiatorAddr: new InitiatorAddr(publicKey), + ttl: new Duration(1800000), + args, + timestamp: new Timestamp(new Date()), + entryPoint, + scheduling, + transactionTarget, + chainName: 'casper-net-1', + pricingMode }); const transaction = TransactionV1.makeTransactionV1( - transactionPayload + transactionPayload ); await transaction.sign(privateKey); ``` @@ -265,3 +265,50 @@ await transaction.sign(privateKey); const result = await rpcClient.putTransactionV1(transaction); console.log(`Transaction Hash: ${result.transactionHash}`); ``` + +## Using [TransactionBuilder](./src/types/TransactionBuilder.md) + +The TransactionV1Builder is a base class used to create various types of transactions. By extending this class, you can build custom transaction types with specific methods and properties. + +#### Example of how to construct a transaction with TransactionBuilder and push it to the network: + +```ts +import { + HttpHandler, + RpcClient, + NativeTransferBuilder, + PrivateKey, + KeyAlgorithm, + PublicKey, + Transaction +} from 'casper-js-sdk'; + +const rpcHandler = new HttpHandler('http://:7777/rpc'); +const rpcClient = new RpcClient(rpcHandler); + +const privateKey = await PrivateKey.generate(KeyAlgorithm.ED25519); + +const transactionV1 = new NativeTransferBuilder() + .from(sender.publicKey) + .target( + PublicKey.fromHex( + '0202f5a92ab6da536e7b1a351406f3744224bec85d7acbab1497b65de48a1a707b64' + ) + ) + .amount('25000000000') // Amount in motes + .id(Date.now()) + .chainName('casper-net-1') + .payment(100_000_000) + .build(); + +await transactionV1.sign(privateKey); + +const tx = Transaction.fromTransactionV1(transactionV1); + +try { + const result = await rpcClient.putTransaction(tx); + console.log(`Transaction Hash: ${result.transactionHash}`); +} catch (e) { + console.error(e); +} +``` diff --git a/src/types/Deploy.ts b/src/types/Deploy.ts index b4c3c39e6..50bb6b47c 100644 --- a/src/types/Deploy.ts +++ b/src/types/Deploy.ts @@ -269,7 +269,9 @@ export class Deploy { * @param keys The private key used to sign the deploy. */ public async sign(keys: PrivateKey): Promise { - const signatureBytes = await keys.sign(this.hash.toBytes()); + const signatureBytes = await keys.signAndAddAlgorithmBytes( + this.hash.toBytes() + ); const signature = new HexBytes(signatureBytes); this.approvals.push(new Approval(keys.publicKey, signature)); } diff --git a/src/types/Transaction.test.ts b/src/types/Transaction.test.ts index b1a106320..8d152147b 100644 --- a/src/types/Transaction.test.ts +++ b/src/types/Transaction.test.ts @@ -24,6 +24,7 @@ import { CLValueUInt64 } from './clvalue'; import { TransactionV1Payload } from './TransactionV1Payload'; +import { NativeTransferBuilder } from './TransactionBuilder'; describe('Test Transaction', () => { it('should create a TransactionV1 with correct payload instance', async () => { @@ -90,4 +91,31 @@ describe('Test Transaction', () => { expect(transaction.payload.fields.scheduling).to.deep.equal(scheduling); expect(transaction.payload.fields.entryPoint).to.deep.equal(entryPoint); }); + + it('should create native transfer TransactionV1 with builder', async () => { + const sender = await PrivateKey.generate(KeyAlgorithm.ED25519); + + const transaction = new NativeTransferBuilder() + .from(sender.publicKey) + .target( + PublicKey.fromHex( + '0202f5a92ab6da536e7b1a351406f3744224bec85d7acbab1497b65de48a1a707b64' + ) + ) + .amount('25000000000') + .id(Date.now()) + .chainName('casper-net-1') + .payment(100_000_000) + .build(); + + await transaction.sign(sender); + + const transactionPaymentAmount = transaction.payload.fields.args.args + .get('amount')! + .toString(); + + assert.deepEqual(transaction.approvals[0].signer, sender.publicKey); + assert.deepEqual(parseInt(transactionPaymentAmount, 10), 25000000000); + expect(transaction.payload.chainName).to.deep.equal('casper-net-1'); + }); }); diff --git a/src/types/Transaction.ts b/src/types/Transaction.ts index cdb61d4cc..27f771bf9 100644 --- a/src/types/Transaction.ts +++ b/src/types/Transaction.ts @@ -170,7 +170,9 @@ export class TransactionV1 { * @param keys The private key to sign the transaction. */ async sign(keys: PrivateKey): Promise { - const signatureBytes = await keys.sign(this.hash.toBytes()); + const signatureBytes = await keys.signAndAddAlgorithmBytes( + this.hash.toBytes() + ); const signature = new HexBytes(signatureBytes); if (!this.approvals) { @@ -467,7 +469,10 @@ export class Transaction { } public getTransactionWrapper(): TransactionWrapper { - return new TransactionWrapper(this.originDeployV1, this.originTransactionV1); + return new TransactionWrapper( + this.originDeployV1, + this.originTransactionV1 + ); } /** @@ -489,7 +494,9 @@ export class Transaction { * @param key The private key to sign the transaction. */ async sign(key: PrivateKey): Promise { - const signatureBytes = await key.sign(this.hash.toBytes()); + const signatureBytes = await key.signAndAddAlgorithmBytes( + this.hash.toBytes() + ); this.setSignature(signatureBytes, key.publicKey); } diff --git a/src/types/TransactionBuilder.md b/src/types/TransactionBuilder.md new file mode 100644 index 000000000..2a936fceb --- /dev/null +++ b/src/types/TransactionBuilder.md @@ -0,0 +1,167 @@ +# TransactionV1 Builders + +TransactionBuilder contains classes and methods for building and managing Casper blockchain transactions. The provided classes extend the `TransactionV1Builder` base class to create specific types of transactions, such as transfers, bids, delegations, and contract calls. + +## Table of Contents + +- [Overview](#overview) +- [Classes](#classes) + - [TransactionV1Builder](#transactionv1builder) + - [NativeTransferBuilder](#nativetransferbuilder) + - [NativeAddBidBuilder](#nativeaddbidbuilder) + - [NativeWithdrawBidBuilder](#nativewithdrawbidbuilder) + - [NativeDelegateBuilder](#nativedelegatebuilder) + - [NativeUndelegateBuilder](#nativeundelegatebuilder) + - [NativeRedelegateBuilder](#nativeredelegatebuilder) + - [NativeActivateBidBuilder](#nativeactivatebidbuilder) + - [NativeChangeBidPublicKeyBuilder](#nativechangebidpublickeybuilder) + - [ContractCallBuilder](#contractcallbuilder) + - [SessionBuilder](#sessionbuilder) + +## Overview + +The provided classes allow developers to build, customize, and execute transactions on the Casper blockchain. By using builder patterns, developers can chain methods to configure each aspect of the transaction before calling `build()` to create the final `TransactionV1` instance. + +## Classes + +### TransactionV1Builder + +The abstract base class for all transaction builders. This class provides common methods for setting basic transaction parameters such as: + +- `from(publicKey: PublicKey)`: Sets the initiator of the transaction. +- `chainName(chainName: string)`: Sets the name of the target blockchain. +- `timestamp(timestamp: Timestamp)`: Sets the timestamp for the transaction. +- `ttl(ttl: number)`: Sets the transaction's time-to-live (TTL). +- `payment(paymentAmount: number)`: Sets the payment details. + +### NativeTransferBuilder + +Used to create native transfers on the Casper blockchain. + +#### Key Methods: + +- `target(publicKey: PublicKey)`: Sets the transfer target using a public key. +- `targetAccountHash(accountHashKey: AccountHash)`: Sets the transfer target using an account hash. +- `amount(amount: BigNumber | string)`: Sets the amount to be transferred. +- `id(id: number)`: Sets the optional ID for the transfer. + +### NativeAddBidBuilder + +Used to create an add-bid transaction. + +#### Key Methods: + +- `validator(publicKey: PublicKey)`: Sets the validator's public key. +- `amount(amount: BigNumber | string)`: Sets the bid amount. +- `delegationRate(delegationRate: number)`: Sets the delegation rate. +- `minimumDelegationAmount(amount: BigNumberish)`: Sets the minimum delegation amount. +- `maximumDelegationAmount(amount: BigNumberish)`: Sets the maximum delegation amount. + +### NativeWithdrawBidBuilder + +Used to create a withdraw-bid transaction. + +#### Key Methods: + +- `validator(publicKey: PublicKey)`: Sets the validator's public key. +- `amount(amount: BigNumber | string)`: Sets the amount to be withdrawn. + +### NativeDelegateBuilder + +Used to create a delegate transaction. + +#### Key Methods: + +- `validator(publicKey: PublicKey)`: Sets the validator's public key. +- `amount(amount: BigNumber | string)`: Sets the delegation amount. + +### NativeUndelegateBuilder + +Used to create an undelegate transaction. + +#### Key Methods: + +- `validator(publicKey: PublicKey)`: Sets the validator's public key. +- `amount(amount: BigNumber | string)`: Sets the amount to be undelegated. + +### NativeRedelegateBuilder + +Used to create a redelegate transaction. + +#### Key Methods: + +- `validator(publicKey: PublicKey)`: Sets the validator's public key. +- `newValidator(publicKey: PublicKey)`: Sets the new validator's public key. +- `amount(amount: BigNumber | string)`: Sets the redelegation amount. + +### NativeActivateBidBuilder + +Used to create an activate-bid transaction. + +#### Key Methods: + +- `validator(publicKey: PublicKey)`: Sets the validator's public key. + +### NativeChangeBidPublicKeyBuilder + +Used to change the public key for an existing bid. + +#### Key Methods: + +- `previousPublicKey(publicKey: PublicKey)`: Sets the previous public key. +- `newPublicKey(publicKey: PublicKey)`: Sets the new public key. + +### ContractCallBuilder + +Used to create and call stored contracts. + +#### Key Methods: + +- `byHash(contractHash: string)`: Calls a contract by its hash. +- `byName(name: string)`: Calls a contract by its name. +- `byPackageHash(contractHash: string, version?: number)`: Calls a contract within a package by its hash. +- `byPackageName(name: string, version?: number)`: Calls a contract within a package by its name. +- `entryPoint(name: string)`: Sets the entry point for the contract call. +- `runtimeArgs(args: Args)`: Sets the runtime arguments for the contract call. + +### SessionBuilder + +Used to create session transactions. + +#### Key Methods: + +- `wasm(wasmBytes: Uint8Array)`: Sets the session WebAssembly (WASM) module. +- `installOrUpgrade()`: Sets the transaction as an install or upgrade. +- `runtimeArgs(args: Args)`: Sets the runtime arguments for the session. + +## Usage Example + +```typescript +import { PublicKey, Args, PrivateKey } from 'casper-js-sdk'; + +const sender = await PrivateKey.generate(KeyAlgorithm.ED25519); + +// Create a simple native transfer +const transactionV1 = new NativeTransferBuilder() + .from(sender.publicKey) + .target(PublicKey.fromHex('abcdef0123456789')) + .amount('25000000000') // Amount in motes + .id(Date.now()) + .chainName('casper-net-1') + .payment(100_000_000) + .build(); + +await transactionV1.sign(sender); + +// Create a contract call +const transactionV1ContractCall = new ContractCallBuilder() + .from(sender.publicKey) + .byHash('example_contract') + .entryPoint('unstake') + .runtimeArgs(Args.fromMap({ key: 'value' })) + .payment(3_000000000) // Amount in motes + .chainName('casper-net-1') + .build(); + +await transactionV1ContractCall.sign(sender); +``` diff --git a/src/types/TransactionBuilder.ts b/src/types/TransactionBuilder.ts new file mode 100644 index 000000000..7aa0415e0 --- /dev/null +++ b/src/types/TransactionBuilder.ts @@ -0,0 +1,580 @@ +import { BigNumber, BigNumberish } from '@ethersproject/bignumber'; + +import { InitiatorAddr } from './InitiatorAddr'; +import { PaymentLimitedMode, PricingMode } from './PricingMode'; +import { + ByPackageHashInvocationTarget, + ByPackageNameInvocationTarget, + SessionTarget, + StoredTarget, + TransactionInvocationTarget, + TransactionRuntime, + TransactionTarget +} from './TransactionTarget'; +import { + TransactionEntryPoint, + TransactionEntryPointEnum +} from './TransactionEntryPoint'; +import { TransactionScheduling } from './TransactionScheduling'; +import { Args } from './Args'; +import { PublicKey } from './keypair'; +import { AccountHash, Hash } from './key'; +import { TransactionV1 } from './Transaction'; +import { TransactionV1Payload } from './TransactionV1Payload'; +import { Duration, Timestamp } from './Time'; +import { + CLValue, + CLValueByteArray, + CLValueOption, + CLValueUInt32, + CLValueUInt512, + CLValueUInt64, + CLValueUInt8 +} from './clvalue'; + +abstract class TransactionV1Builder> { + protected _initiatorAddr!: InitiatorAddr; + protected _chainName!: string; + protected _timestamp = new Timestamp(new Date()); + protected _ttl = new Duration(1800000); + protected _pricingMode!: PricingMode; + protected _invocationTarget!: TransactionTarget; + protected _entryPoint!: TransactionEntryPoint; + protected _scheduling: TransactionScheduling = new TransactionScheduling({}); // Standard + protected _runtimeArgs: Args; + + public from(publicKey: PublicKey): T { + this._initiatorAddr = new InitiatorAddr(publicKey); + return (this as unknown) as T; + } + + public fromAccountHash(accountHashKey: AccountHash): T { + this._initiatorAddr = new InitiatorAddr(undefined, accountHashKey); + return (this as unknown) as T; + } + + public chainName(chainName: string): T { + this._chainName = chainName; + return (this as unknown) as T; + } + + public timestamp(timestamp: Timestamp): T { + this._timestamp = timestamp; + return (this as unknown) as T; + } + + public ttl(ttl: number): T { + this._ttl = new Duration(ttl); + return (this as unknown) as T; + } + + public payment(paymentAmount: number): T { + const pricingMode = new PricingMode(); + const paymentLimited = new PaymentLimitedMode(); + paymentLimited.standardPayment = true; + paymentLimited.paymentAmount = paymentAmount; + paymentLimited.gasPriceTolerance = 1; + + pricingMode.paymentLimited = paymentLimited; + this._pricingMode = pricingMode; + return (this as unknown) as T; + } + + public build(): TransactionV1 { + const transactionPayload = TransactionV1Payload.build({ + initiatorAddr: this._initiatorAddr, + timestamp: this._timestamp, + ttl: this._ttl, + chainName: this._chainName, + pricingMode: this._pricingMode, + args: this._runtimeArgs, + transactionTarget: this._invocationTarget, + entryPoint: this._entryPoint, + scheduling: this._scheduling + }); + + return TransactionV1.makeTransactionV1(transactionPayload); + } +} + +export class NativeTransferBuilder extends TransactionV1Builder< + NativeTransferBuilder +> { + private _target!: CLValue; + private _amount: CLValue = CLValueUInt512.newCLUInt512('0'); + private _idTransfer?: number; + + constructor() { + super(); + this._invocationTarget = new TransactionTarget({}); // Native + this._entryPoint = new TransactionEntryPoint( + TransactionEntryPointEnum.Transfer + ); + } + + public target(publicKey: PublicKey): NativeTransferBuilder { + this._target = CLValue.newCLPublicKey(publicKey); + return this; + } + + public targetAccountHash(accountHashKey: AccountHash): NativeTransferBuilder { + this._target = CLValueByteArray.newCLByteArray(accountHashKey.toBytes()); + return this; + } + + public amount(amount: BigNumber | string): NativeTransferBuilder { + this._amount = CLValueUInt512.newCLUInt512(amount); + return this; + } + + public id(id: number): NativeTransferBuilder { + this._idTransfer = id; + return this; + } + + public build(): TransactionV1 { + const runtimeArgs = Args.fromMap({}); + + runtimeArgs.insert('target', this._target); + runtimeArgs.insert('amount', this._amount); + + if (this._idTransfer) { + runtimeArgs.insert( + 'id', + CLValueOption.newCLOption(CLValueUInt64.newCLUint64(this._idTransfer)) + ); + } + + this._runtimeArgs = runtimeArgs; + + return super.build(); + } +} + +export class NativeAddBidBuilder extends TransactionV1Builder< + NativeAddBidBuilder +> { + private _validator!: CLValue; + private _amount!: CLValue; + private _delegationRate!: CLValue; + private _minimumDelegationAmount?: CLValue; + private _maximumDelegationAmount?: CLValue; + private _reservedSlots?: CLValue; + + constructor() { + super(); + this._invocationTarget = new TransactionTarget({}); // Native + this._entryPoint = new TransactionEntryPoint( + TransactionEntryPointEnum.AddBid + ); + } + + public validator(publicKey: PublicKey): NativeAddBidBuilder { + this._validator = CLValue.newCLPublicKey(publicKey); + return this; + } + + public amount(amount: BigNumber | string): NativeAddBidBuilder { + this._amount = CLValueUInt512.newCLUInt512(amount); + return this; + } + + public delegationRate(delegationRate: number): NativeAddBidBuilder { + this._delegationRate = CLValueUInt8.newCLUint8(delegationRate); + return this; + } + + public minimumDelegationAmount( + minimumDelegationAmount: BigNumberish + ): NativeAddBidBuilder { + this._minimumDelegationAmount = CLValueUInt64.newCLUint64( + minimumDelegationAmount + ); + return this; + } + + public maximumDelegationAmount( + maximumDelegationAmount: BigNumberish + ): NativeAddBidBuilder { + this._maximumDelegationAmount = CLValueUInt64.newCLUint64( + maximumDelegationAmount + ); + return this; + } + + public reservedSlots(reservedSlots: BigNumber): NativeAddBidBuilder { + this._reservedSlots = CLValueUInt32.newCLUInt32(reservedSlots); + return this; + } + + public build(): TransactionV1 { + const runtimeArgs = Args.fromMap({}); + + runtimeArgs.insert('public_key', this._validator); + runtimeArgs.insert('amount', this._amount); + runtimeArgs.insert('delegation_rate', this._delegationRate); + + if (this._minimumDelegationAmount) { + runtimeArgs.insert( + 'minimum_delegation_amount', + this._minimumDelegationAmount + ); + } + + if (this._maximumDelegationAmount) { + runtimeArgs.insert( + 'maximum_delegation_amount', + this._maximumDelegationAmount + ); + } + + if (this._reservedSlots) { + runtimeArgs.insert('reserved_slots', this._reservedSlots); + } + + this._runtimeArgs = runtimeArgs; + + return super.build(); + } +} + +export class NativeWithdrawBidBuilder extends TransactionV1Builder< + NativeWithdrawBidBuilder +> { + private _validator!: CLValue; + private _amount: CLValue = CLValueUInt512.newCLUInt512('0'); + + constructor() { + super(); + this._invocationTarget = new TransactionTarget({}); // Native + this._entryPoint = new TransactionEntryPoint( + TransactionEntryPointEnum.WithdrawBid + ); + } + + public validator(publicKey: PublicKey): NativeWithdrawBidBuilder { + this._validator = CLValue.newCLPublicKey(publicKey); + return this; + } + + public amount(amount: BigNumber | string): NativeWithdrawBidBuilder { + this._amount = CLValueUInt512.newCLUInt512(amount); + return this; + } + + public build(): TransactionV1 { + this._runtimeArgs = Args.fromMap({ + public_key: this._validator, + amount: this._amount + }); + + return super.build(); + } +} + +export class NativeDelegateBuilder extends TransactionV1Builder< + NativeDelegateBuilder +> { + private _validator!: CLValue; + private _amount: CLValue = CLValueUInt512.newCLUInt512('0'); + + constructor() { + super(); + this._invocationTarget = new TransactionTarget({}); + this._entryPoint = new TransactionEntryPoint( + TransactionEntryPointEnum.Delegate + ); + } + + public validator(publicKey: PublicKey): NativeDelegateBuilder { + this._validator = CLValue.newCLPublicKey(publicKey); + return this; + } + + public amount(amount: BigNumber | string): NativeDelegateBuilder { + this._amount = CLValueUInt512.newCLUInt512(amount); + return this; + } + + public build(): TransactionV1 { + if (!this._initiatorAddr.publicKey) { + throw new Error('Initiator addr is not specified'); + } + + this._runtimeArgs = Args.fromMap({ + delegator: CLValue.newCLPublicKey(this._initiatorAddr.publicKey), + validator: this._validator, + amount: this._amount + }); + + return super.build(); + } +} + +export class NativeUndelegateBuilder extends TransactionV1Builder< + NativeUndelegateBuilder +> { + private _validator!: CLValue; + private _amount: CLValue = CLValueUInt512.newCLUInt512('0'); + + constructor() { + super(); + this._invocationTarget = new TransactionTarget({}); + this._entryPoint = new TransactionEntryPoint( + TransactionEntryPointEnum.Undelegate + ); + } + + public validator(publicKey: PublicKey): NativeUndelegateBuilder { + this._validator = CLValue.newCLPublicKey(publicKey); + return this; + } + + public amount(amount: BigNumber | string): NativeUndelegateBuilder { + this._amount = CLValueUInt512.newCLUInt512(amount); + return this; + } + + public build(): TransactionV1 { + if (!this._initiatorAddr.publicKey) { + throw new Error('Initiator addr is not specified'); + } + + this._runtimeArgs = Args.fromMap({ + delegator: CLValue.newCLPublicKey(this._initiatorAddr.publicKey), + validator: this._validator, + amount: this._amount + }); + + return super.build(); + } +} + +export class NativeRedelegateBuilder extends TransactionV1Builder< + NativeRedelegateBuilder +> { + private _validator!: CLValue; + private _newValidator!: CLValue; + private _amount: CLValue = CLValueUInt512.newCLUInt512('0'); + + constructor() { + super(); + this._invocationTarget = new TransactionTarget({}); + this._entryPoint = new TransactionEntryPoint( + TransactionEntryPointEnum.Redelegate + ); + } + + public validator(publicKey: PublicKey): NativeRedelegateBuilder { + this._validator = CLValue.newCLPublicKey(publicKey); + return this; + } + + public newValidator(publicKey: PublicKey): NativeRedelegateBuilder { + this._newValidator = CLValue.newCLPublicKey(publicKey); + return this; + } + + public amount(amount: BigNumber | string): NativeRedelegateBuilder { + this._amount = CLValueUInt512.newCLUInt512(amount); + return this; + } + + public build(): TransactionV1 { + if (!this._initiatorAddr.publicKey) { + throw new Error('Initiator addr is not specified'); + } + + this._runtimeArgs = Args.fromMap({ + delegator: CLValue.newCLPublicKey(this._initiatorAddr.publicKey), + validator: this._validator, + amount: this._amount, + new_validator: this._newValidator + }); + + return super.build(); + } +} + +export class NativeActivateBidBuilder extends TransactionV1Builder< + NativeActivateBidBuilder +> { + private _validator!: CLValue; + + constructor() { + super(); + this._invocationTarget = new TransactionTarget({}); // Native + this._entryPoint = new TransactionEntryPoint( + TransactionEntryPointEnum.ActivateBid + ); + } + + public validator(publicKey: PublicKey): NativeActivateBidBuilder { + this._validator = CLValue.newCLPublicKey(publicKey); + return this; + } + + public build(): TransactionV1 { + this._runtimeArgs = Args.fromMap({ + validator: this._validator + }); + + return super.build(); + } +} + +export class NativeChangeBidPublicKeyBuilder extends TransactionV1Builder< + NativeChangeBidPublicKeyBuilder +> { + private _public_key!: CLValue; + private _new_public_key!: CLValue; + + constructor() { + super(); + this._invocationTarget = new TransactionTarget({}); + this._entryPoint = new TransactionEntryPoint( + TransactionEntryPointEnum.ChangeBidPublicKey + ); + } + + public previousPublicKey( + publicKey: PublicKey + ): NativeChangeBidPublicKeyBuilder { + this._public_key = CLValue.newCLPublicKey(publicKey); + return this; + } + + public newPublicKey(publicKey: PublicKey): NativeChangeBidPublicKeyBuilder { + this._new_public_key = CLValue.newCLPublicKey(publicKey); + return this; + } + + public build(): TransactionV1 { + this._runtimeArgs = Args.fromMap({ + public_key: this._public_key, + new_public_key: this._new_public_key + }); + + return super.build(); + } +} + +export class ContractCallBuilder extends TransactionV1Builder< + ContractCallBuilder +> { + constructor() { + super(); + } + + public byHash(contractHash: string): ContractCallBuilder { + const invocationTarget = new TransactionInvocationTarget(); + invocationTarget.byHash = Hash.fromHex(contractHash); + + const storedTarget = new StoredTarget(); + storedTarget.id = invocationTarget; + storedTarget.runtime = TransactionRuntime.vmCasperV1(); + + this._invocationTarget = new TransactionTarget(undefined, storedTarget); + return this; + } + + public byName(name: string): ContractCallBuilder { + const invocationTarget = new TransactionInvocationTarget(); + invocationTarget.byName = name; + + const storedTarget = new StoredTarget(); + storedTarget.id = invocationTarget; + storedTarget.runtime = TransactionRuntime.vmCasperV1(); + + this._invocationTarget = new TransactionTarget(undefined, storedTarget); + return this; + } + + public byPackageHash( + contractHash: string, + version?: number + ): ContractCallBuilder { + const packageHashInvocationTarget = new ByPackageHashInvocationTarget(); + packageHashInvocationTarget.addr = Hash.fromHex(contractHash); + packageHashInvocationTarget.version = version; + const transactionInvocationTarget = new TransactionInvocationTarget(); + transactionInvocationTarget.byPackageHash = packageHashInvocationTarget; + + const storedTarget = new StoredTarget(); + + storedTarget.id = transactionInvocationTarget; + storedTarget.runtime = TransactionRuntime.vmCasperV1(); + + this._invocationTarget = new TransactionTarget(undefined, storedTarget); + return this; + } + + public byPackageName(name: string, version?: number): ContractCallBuilder { + const packageNameInvocationTarget = new ByPackageNameInvocationTarget(); + packageNameInvocationTarget.name = name; + packageNameInvocationTarget.version = version; + const transactionInvocationTarget = new TransactionInvocationTarget(); + transactionInvocationTarget.byPackageName = packageNameInvocationTarget; + + const storedTarget = new StoredTarget(); + + storedTarget.id = transactionInvocationTarget; + storedTarget.runtime = TransactionRuntime.vmCasperV1(); + + this._invocationTarget = new TransactionTarget(undefined, storedTarget); + + return this; + } + + public entryPoint(name: string): ContractCallBuilder { + this._entryPoint = new TransactionEntryPoint( + TransactionEntryPointEnum.Custom, + name + ); + return this; + } + + public runtimeArgs(args: Args): ContractCallBuilder { + this._runtimeArgs = args; + return this; + } +} + +export class SessionBuilder extends TransactionV1Builder { + private _isInstallOrUpgrade = false; + + constructor() { + super(); + this._entryPoint = new TransactionEntryPoint( + TransactionEntryPointEnum.Call + ); + } + + public wasm(wasmBytes: Uint8Array): SessionBuilder { + const sessionTarget = new SessionTarget(); + sessionTarget.moduleBytes = wasmBytes; + sessionTarget.isInstallUpgrade = this._isInstallOrUpgrade; + sessionTarget.runtime = TransactionRuntime.vmCasperV1(); + + this._invocationTarget = new TransactionTarget( + undefined, + undefined, + sessionTarget + ); + + return this; + } + + public installOrUpgrade(): SessionBuilder { + this._isInstallOrUpgrade = true; + if (this._invocationTarget?.session) { + this._invocationTarget.session.isInstallUpgrade = true; + } + return this; + } + + public runtimeArgs(args: Args): SessionBuilder { + this._runtimeArgs = args; + return this; + } +} From f430d2c0b3b9a985646ad653b7f227a7caab1f22 Mon Sep 17 00:00:00 2001 From: Oleksandr Myshchyshyn Date: Fri, 20 Dec 2024 12:57:59 +0200 Subject: [PATCH 2/4] Add basic typedoc and export --- src/types/TransactionBuilder.ts | 43 ++++++++++++++++++++++++++++++++- src/types/index.ts | 1 + 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/types/TransactionBuilder.ts b/src/types/TransactionBuilder.ts index 7aa0415e0..e3441b625 100644 --- a/src/types/TransactionBuilder.ts +++ b/src/types/TransactionBuilder.ts @@ -32,6 +32,9 @@ import { CLValueUInt8 } from './clvalue'; +/** + * Abstract base class for building Transaction V1 instances. + */ abstract class TransactionV1Builder> { protected _initiatorAddr!: InitiatorAddr; protected _chainName!: string; @@ -43,31 +46,49 @@ abstract class TransactionV1Builder> { protected _scheduling: TransactionScheduling = new TransactionScheduling({}); // Standard protected _runtimeArgs: Args; + /** + * Sets the initiator address using a public key. + */ public from(publicKey: PublicKey): T { this._initiatorAddr = new InitiatorAddr(publicKey); return (this as unknown) as T; } + /** + * Sets the initiator address using an account hash. + */ public fromAccountHash(accountHashKey: AccountHash): T { this._initiatorAddr = new InitiatorAddr(undefined, accountHashKey); return (this as unknown) as T; } + /** + * Sets the chain name for the transaction. + */ public chainName(chainName: string): T { this._chainName = chainName; return (this as unknown) as T; } + /** + * Sets the timestamp for the transaction. + */ public timestamp(timestamp: Timestamp): T { this._timestamp = timestamp; return (this as unknown) as T; } + /** + * Sets the time-to-live for the transaction. + */ public ttl(ttl: number): T { this._ttl = new Duration(ttl); return (this as unknown) as T; } + /** + * Sets the payment amount for the transaction. + */ public payment(paymentAmount: number): T { const pricingMode = new PricingMode(); const paymentLimited = new PaymentLimitedMode(); @@ -80,6 +101,9 @@ abstract class TransactionV1Builder> { return (this as unknown) as T; } + /** + * Builds and returns the TransactionV1 instance. + */ public build(): TransactionV1 { const transactionPayload = TransactionV1Payload.build({ initiatorAddr: this._initiatorAddr, @@ -97,6 +121,9 @@ abstract class TransactionV1Builder> { } } +/** + * Builder for creating Native Transfer transactions. + */ export class NativeTransferBuilder extends TransactionV1Builder< NativeTransferBuilder > { @@ -112,26 +139,41 @@ export class NativeTransferBuilder extends TransactionV1Builder< ); } + /** + * Sets the target public key for the transfer. + */ public target(publicKey: PublicKey): NativeTransferBuilder { this._target = CLValue.newCLPublicKey(publicKey); return this; } + /** + * Sets the target account hash for the transfer. + */ public targetAccountHash(accountHashKey: AccountHash): NativeTransferBuilder { this._target = CLValueByteArray.newCLByteArray(accountHashKey.toBytes()); return this; } + /** + * Sets the amount to transfer. + */ public amount(amount: BigNumber | string): NativeTransferBuilder { this._amount = CLValueUInt512.newCLUInt512(amount); return this; } + /** + * Sets the transfer ID. + */ public id(id: number): NativeTransferBuilder { this._idTransfer = id; return this; } + /** + * Builds and returns the Native Transfer transaction. + */ public build(): TransactionV1 { const runtimeArgs = Args.fromMap({}); @@ -146,7 +188,6 @@ export class NativeTransferBuilder extends TransactionV1Builder< } this._runtimeArgs = runtimeArgs; - return super.build(); } } diff --git a/src/types/index.ts b/src/types/index.ts index 969c0e635..b485a774b 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -40,3 +40,4 @@ export * from './key'; export * from './clvalue'; export * from './keypair'; export * from './ContractWasm'; +export * from './TransactionBuilder'; From 67458eca7c8a77adbe9afee6f4a1daafae0370a4 Mon Sep 17 00:00:00 2001 From: Oleksandr Myshchyshyn Date: Fri, 20 Dec 2024 13:45:23 +0200 Subject: [PATCH 3/4] Return Transaction instance from builder instead of TransactionV1 --- README.md | 11 +++----- migration-guide-v2-v5.md | 32 +++++++++++----------- src/types/Transaction.test.ts | 5 ++-- src/types/TransactionBuilder.md | 26 +++++++++++------- src/types/TransactionBuilder.ts | 47 +++++++++++++++++---------------- 5 files changed, 62 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 96c083028..36061cc67 100644 --- a/README.md +++ b/README.md @@ -119,8 +119,7 @@ import { NativeTransferBuilder, PrivateKey, KeyAlgorithm, - PublicKey, - Transaction + PublicKey } from 'casper-js-sdk'; const rpcHandler = new HttpHandler('http://:7777/rpc'); @@ -128,7 +127,7 @@ const rpcClient = new RpcClient(rpcHandler); const privateKey = await PrivateKey.generate(KeyAlgorithm.ED25519); -const transactionV1 = new NativeTransferBuilder() +const transaction = new NativeTransferBuilder() .from(privateKey.publicKey) .target( PublicKey.fromHex( @@ -141,12 +140,10 @@ const transactionV1 = new NativeTransferBuilder() .payment(100_000_000) .build(); -await transactionV1.sign(privateKey); - -const tx = Transaction.fromTransactionV1(transactionV1); +await transaction.sign(privateKey); try { - const result = await rpcClient.putTransaction(tx); + const result = await rpcClient.putTransaction(transaction); console.log(`Transaction Hash: ${result.transactionHash}`); } catch (e) { console.error(e); diff --git a/migration-guide-v2-v5.md b/migration-guide-v2-v5.md index df863e1c4..956ff2eda 100644 --- a/migration-guide-v2-v5.md +++ b/migration-guide-v2-v5.md @@ -100,13 +100,14 @@ const nativeTarget = new TransactionTarget({}); const stored = new StoredTarget(); const invocationTarget = new TransactionInvocationTarget(); invocationTarget.byHash = new Hash(Uint8Array.from([])); // an example of hash -storedTarget.runtime = 'VmCasperV1'; // an example of runtime +storedTarget.runtime = TransactionRuntime.vmCasperV1(); // an example of runtime storedTarget.id = invocationTarget; const storedTransactionTarget = new TransactionTarget( undefined, stored ); + // OR const storedTransactionTarget1 = new TransactionTarget(); storedTransactionTarget1.stored = stored; @@ -117,16 +118,15 @@ storedTransactionTarget1.stored = stored; ```typescript const sessionTarget = new SessionTarget(); sessionTarget.moduleBytes = Uint8Array.from([]); // an example of module bytes -sessionTarget.runtime = 'VmCasperV1'; // an example of runtime -sessionTarget.transferredValue = 1000; // an example of transferredValue +sessionTarget.runtime = TransactionRuntime.vmCasperV1(); // an example of runtime sessionTarget.isInstallUpgrade = true; // an example of isInstallUpgrade -sessionTarget.seed = new Hash(Uint8Array.from([])); // an example of seed const sessionTransactionTarget = new TransactionTarget( undefined, undefined, sessionTarget ); + // OR const sessionTransactionTarget1 = new TransactionTarget(); sessionTransactionTarget1.session = sessionTarget; @@ -158,19 +158,20 @@ Specifies how transaction fees are calculated. Supports three modes: #### Examples: -- **FixedMode**: +- **PaymentLimitedMode**: ```typescript -const fixedMode = new FixedMode(); -fixedMode.gasPriceTolerance = 2; -fixedMode.additionalComputationFactor = 1; +const paymentLimited = new PaymentLimitedMode(); +paymentLimited.standardPayment = true; +paymentLimited.paymentAmount = '250000000'; +paymentLimited.gasPriceTolerance = 1; ``` - **Assign Pricing Mode**: ```typescript const pricingMode = new PricingMode(); -pricingMode.fixed = fixedMode; +pricingMode.paymentLimited = paymentLimited; ``` --- @@ -268,7 +269,7 @@ console.log(`Transaction Hash: ${result.transactionHash}`); ## Using [TransactionBuilder](./src/types/TransactionBuilder.md) -The TransactionV1Builder is a base class used to create various types of transactions. By extending this class, you can build custom transaction types with specific methods and properties. +The `TransactionBuilder` is a base class used to create various types of transactions. By extending this class, you can build custom transaction types with specific methods and properties. #### Example of how to construct a transaction with TransactionBuilder and push it to the network: @@ -279,8 +280,7 @@ import { NativeTransferBuilder, PrivateKey, KeyAlgorithm, - PublicKey, - Transaction + PublicKey } from 'casper-js-sdk'; const rpcHandler = new HttpHandler('http://:7777/rpc'); @@ -288,7 +288,7 @@ const rpcClient = new RpcClient(rpcHandler); const privateKey = await PrivateKey.generate(KeyAlgorithm.ED25519); -const transactionV1 = new NativeTransferBuilder() +const transaction = new NativeTransferBuilder() .from(sender.publicKey) .target( PublicKey.fromHex( @@ -301,12 +301,10 @@ const transactionV1 = new NativeTransferBuilder() .payment(100_000_000) .build(); -await transactionV1.sign(privateKey); - -const tx = Transaction.fromTransactionV1(transactionV1); +await transaction.sign(privateKey); try { - const result = await rpcClient.putTransaction(tx); + const result = await rpcClient.putTransaction(transaction); console.log(`Transaction Hash: ${result.transactionHash}`); } catch (e) { console.error(e); diff --git a/src/types/Transaction.test.ts b/src/types/Transaction.test.ts index 8d152147b..fff24f67f 100644 --- a/src/types/Transaction.test.ts +++ b/src/types/Transaction.test.ts @@ -110,12 +110,13 @@ describe('Test Transaction', () => { await transaction.sign(sender); - const transactionPaymentAmount = transaction.payload.fields.args.args + const transactionV2 = transaction.getTransactionV1()!; + const transactionPaymentAmount = transactionV2.payload.fields.args.args .get('amount')! .toString(); assert.deepEqual(transaction.approvals[0].signer, sender.publicKey); assert.deepEqual(parseInt(transactionPaymentAmount, 10), 25000000000); - expect(transaction.payload.chainName).to.deep.equal('casper-net-1'); + expect(transactionV2.payload.chainName).to.deep.equal('casper-net-1'); }); }); diff --git a/src/types/TransactionBuilder.md b/src/types/TransactionBuilder.md index 2a936fceb..d98e3de61 100644 --- a/src/types/TransactionBuilder.md +++ b/src/types/TransactionBuilder.md @@ -1,12 +1,12 @@ -# TransactionV1 Builders +# Transaction Builders -TransactionBuilder contains classes and methods for building and managing Casper blockchain transactions. The provided classes extend the `TransactionV1Builder` base class to create specific types of transactions, such as transfers, bids, delegations, and contract calls. +TransactionBuilder contains classes and methods for building and managing Casper blockchain transactions. The provided classes extend the `TransactionBuilder` base class to create specific types of transactions, such as transfers, bids, delegations, and contract calls. ## Table of Contents - [Overview](#overview) - [Classes](#classes) - - [TransactionV1Builder](#transactionv1builder) + - [TransactionBuilder](#transactionv1builder) - [NativeTransferBuilder](#nativetransferbuilder) - [NativeAddBidBuilder](#nativeaddbidbuilder) - [NativeWithdrawBidBuilder](#nativewithdrawbidbuilder) @@ -20,11 +20,11 @@ TransactionBuilder contains classes and methods for building and managing Casper ## Overview -The provided classes allow developers to build, customize, and execute transactions on the Casper blockchain. By using builder patterns, developers can chain methods to configure each aspect of the transaction before calling `build()` to create the final `TransactionV1` instance. +The provided classes allow developers to build, customize, and execute transactions on the Casper blockchain. By using builder patterns, developers can chain methods to configure each aspect of the transaction before calling `build()` to create the final [Transaction](./Transaction.ts) instance. ## Classes -### TransactionV1Builder +### TransactionBuilder The abstract base class for all transaction builders. This class provides common methods for setting basic transaction parameters such as: @@ -137,12 +137,18 @@ Used to create session transactions. ## Usage Example ```typescript -import { PublicKey, Args, PrivateKey } from 'casper-js-sdk'; +import { + PublicKey, + Args, + PrivateKey, + NativeTransferBuilder, + ContractCallBuilder +} from 'casper-js-sdk'; const sender = await PrivateKey.generate(KeyAlgorithm.ED25519); // Create a simple native transfer -const transactionV1 = new NativeTransferBuilder() +const transaction = new NativeTransferBuilder() .from(sender.publicKey) .target(PublicKey.fromHex('abcdef0123456789')) .amount('25000000000') // Amount in motes @@ -151,10 +157,10 @@ const transactionV1 = new NativeTransferBuilder() .payment(100_000_000) .build(); -await transactionV1.sign(sender); +await transaction.sign(sender); // Create a contract call -const transactionV1ContractCall = new ContractCallBuilder() +const contractCallTransaction = new ContractCallBuilder() .from(sender.publicKey) .byHash('example_contract') .entryPoint('unstake') @@ -163,5 +169,5 @@ const transactionV1ContractCall = new ContractCallBuilder() .chainName('casper-net-1') .build(); -await transactionV1ContractCall.sign(sender); +await contractCallTransaction.sign(sender); ``` diff --git a/src/types/TransactionBuilder.ts b/src/types/TransactionBuilder.ts index e3441b625..a6bed25d3 100644 --- a/src/types/TransactionBuilder.ts +++ b/src/types/TransactionBuilder.ts @@ -19,7 +19,7 @@ import { TransactionScheduling } from './TransactionScheduling'; import { Args } from './Args'; import { PublicKey } from './keypair'; import { AccountHash, Hash } from './key'; -import { TransactionV1 } from './Transaction'; +import { Transaction, TransactionV1 } from './Transaction'; import { TransactionV1Payload } from './TransactionV1Payload'; import { Duration, Timestamp } from './Time'; import { @@ -35,7 +35,7 @@ import { /** * Abstract base class for building Transaction V1 instances. */ -abstract class TransactionV1Builder> { +abstract class TransactionBuilder> { protected _initiatorAddr!: InitiatorAddr; protected _chainName!: string; protected _timestamp = new Timestamp(new Date()); @@ -102,9 +102,9 @@ abstract class TransactionV1Builder> { } /** - * Builds and returns the TransactionV1 instance. + * Builds and returns the Transaction instance. */ - public build(): TransactionV1 { + public build(): Transaction { const transactionPayload = TransactionV1Payload.build({ initiatorAddr: this._initiatorAddr, timestamp: this._timestamp, @@ -117,14 +117,15 @@ abstract class TransactionV1Builder> { scheduling: this._scheduling }); - return TransactionV1.makeTransactionV1(transactionPayload); + const transactionV1 = TransactionV1.makeTransactionV1(transactionPayload); + return Transaction.fromTransactionV1(transactionV1); } } /** * Builder for creating Native Transfer transactions. */ -export class NativeTransferBuilder extends TransactionV1Builder< +export class NativeTransferBuilder extends TransactionBuilder< NativeTransferBuilder > { private _target!: CLValue; @@ -174,7 +175,7 @@ export class NativeTransferBuilder extends TransactionV1Builder< /** * Builds and returns the Native Transfer transaction. */ - public build(): TransactionV1 { + public build(): Transaction { const runtimeArgs = Args.fromMap({}); runtimeArgs.insert('target', this._target); @@ -192,7 +193,7 @@ export class NativeTransferBuilder extends TransactionV1Builder< } } -export class NativeAddBidBuilder extends TransactionV1Builder< +export class NativeAddBidBuilder extends TransactionBuilder< NativeAddBidBuilder > { private _validator!: CLValue; @@ -248,7 +249,7 @@ export class NativeAddBidBuilder extends TransactionV1Builder< return this; } - public build(): TransactionV1 { + public build(): Transaction { const runtimeArgs = Args.fromMap({}); runtimeArgs.insert('public_key', this._validator); @@ -279,7 +280,7 @@ export class NativeAddBidBuilder extends TransactionV1Builder< } } -export class NativeWithdrawBidBuilder extends TransactionV1Builder< +export class NativeWithdrawBidBuilder extends TransactionBuilder< NativeWithdrawBidBuilder > { private _validator!: CLValue; @@ -303,7 +304,7 @@ export class NativeWithdrawBidBuilder extends TransactionV1Builder< return this; } - public build(): TransactionV1 { + public build(): Transaction { this._runtimeArgs = Args.fromMap({ public_key: this._validator, amount: this._amount @@ -313,7 +314,7 @@ export class NativeWithdrawBidBuilder extends TransactionV1Builder< } } -export class NativeDelegateBuilder extends TransactionV1Builder< +export class NativeDelegateBuilder extends TransactionBuilder< NativeDelegateBuilder > { private _validator!: CLValue; @@ -337,7 +338,7 @@ export class NativeDelegateBuilder extends TransactionV1Builder< return this; } - public build(): TransactionV1 { + public build(): Transaction { if (!this._initiatorAddr.publicKey) { throw new Error('Initiator addr is not specified'); } @@ -352,7 +353,7 @@ export class NativeDelegateBuilder extends TransactionV1Builder< } } -export class NativeUndelegateBuilder extends TransactionV1Builder< +export class NativeUndelegateBuilder extends TransactionBuilder< NativeUndelegateBuilder > { private _validator!: CLValue; @@ -376,7 +377,7 @@ export class NativeUndelegateBuilder extends TransactionV1Builder< return this; } - public build(): TransactionV1 { + public build(): Transaction { if (!this._initiatorAddr.publicKey) { throw new Error('Initiator addr is not specified'); } @@ -391,7 +392,7 @@ export class NativeUndelegateBuilder extends TransactionV1Builder< } } -export class NativeRedelegateBuilder extends TransactionV1Builder< +export class NativeRedelegateBuilder extends TransactionBuilder< NativeRedelegateBuilder > { private _validator!: CLValue; @@ -421,7 +422,7 @@ export class NativeRedelegateBuilder extends TransactionV1Builder< return this; } - public build(): TransactionV1 { + public build(): Transaction { if (!this._initiatorAddr.publicKey) { throw new Error('Initiator addr is not specified'); } @@ -437,7 +438,7 @@ export class NativeRedelegateBuilder extends TransactionV1Builder< } } -export class NativeActivateBidBuilder extends TransactionV1Builder< +export class NativeActivateBidBuilder extends TransactionBuilder< NativeActivateBidBuilder > { private _validator!: CLValue; @@ -455,7 +456,7 @@ export class NativeActivateBidBuilder extends TransactionV1Builder< return this; } - public build(): TransactionV1 { + public build(): Transaction { this._runtimeArgs = Args.fromMap({ validator: this._validator }); @@ -464,7 +465,7 @@ export class NativeActivateBidBuilder extends TransactionV1Builder< } } -export class NativeChangeBidPublicKeyBuilder extends TransactionV1Builder< +export class NativeChangeBidPublicKeyBuilder extends TransactionBuilder< NativeChangeBidPublicKeyBuilder > { private _public_key!: CLValue; @@ -490,7 +491,7 @@ export class NativeChangeBidPublicKeyBuilder extends TransactionV1Builder< return this; } - public build(): TransactionV1 { + public build(): Transaction { this._runtimeArgs = Args.fromMap({ public_key: this._public_key, new_public_key: this._new_public_key @@ -500,7 +501,7 @@ export class NativeChangeBidPublicKeyBuilder extends TransactionV1Builder< } } -export class ContractCallBuilder extends TransactionV1Builder< +export class ContractCallBuilder extends TransactionBuilder< ContractCallBuilder > { constructor() { @@ -581,7 +582,7 @@ export class ContractCallBuilder extends TransactionV1Builder< } } -export class SessionBuilder extends TransactionV1Builder { +export class SessionBuilder extends TransactionBuilder { private _isInstallOrUpgrade = false; constructor() { From 098fcdeb65374b16eca47b16c6a52ca589318dda Mon Sep 17 00:00:00 2001 From: Oleksandr Myshchyshyn Date: Fri, 20 Dec 2024 13:47:02 +0200 Subject: [PATCH 4/4] Fix typo issue --- src/types/Transaction.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/types/Transaction.test.ts b/src/types/Transaction.test.ts index fff24f67f..222888715 100644 --- a/src/types/Transaction.test.ts +++ b/src/types/Transaction.test.ts @@ -110,13 +110,13 @@ describe('Test Transaction', () => { await transaction.sign(sender); - const transactionV2 = transaction.getTransactionV1()!; - const transactionPaymentAmount = transactionV2.payload.fields.args.args + const transactionV1 = transaction.getTransactionV1()!; + const transactionPaymentAmount = transactionV1.payload.fields.args.args .get('amount')! .toString(); assert.deepEqual(transaction.approvals[0].signer, sender.publicKey); assert.deepEqual(parseInt(transactionPaymentAmount, 10), 25000000000); - expect(transactionV2.payload.chainName).to.deep.equal('casper-net-1'); + expect(transactionV1.payload.chainName).to.deep.equal('casper-net-1'); }); });