Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add transaction builders #473

Merged
merged 4 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 20 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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://<Node Address>: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
Expand Down
77 changes: 62 additions & 15 deletions migration-guide-v2-v5.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,10 @@ const publicKey = privateKey.publicKey;

```typescript
const args = Args.fromMap({
target: CLValue.newCLPublicKey(
PublicKey.fromHex('<Recipient Public Key>')
),
amount: CLValueUInt512.newCLUInt512('2000000000') // 2 CSPR
target: CLValue.newCLPublicKey(
PublicKey.fromHex('<Recipient Public Key>')
),
amount: CLValueUInt512.newCLUInt512('2000000000') // 2 CSPR
});
```

Expand All @@ -216,7 +216,7 @@ const transactionTarget = new TransactionTarget({}); // Native target;

```typescript
const entryPoint = new TransactionEntryPoint(
TransactionEntryPointEnum.Transfer
TransactionEntryPointEnum.Transfer
);
```

Expand All @@ -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);
```
Expand All @@ -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://<Node Address>: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);
}
```
4 changes: 3 additions & 1 deletion src/types/Deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,9 @@ export class Deploy {
* @param keys The private key used to sign the deploy.
*/
public async sign(keys: PrivateKey): Promise<void> {
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));
}
Expand Down
28 changes: 28 additions & 0 deletions src/types/Transaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down Expand Up @@ -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');
});
});
13 changes: 10 additions & 3 deletions src/types/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,9 @@ export class TransactionV1 {
* @param keys The private key to sign the transaction.
*/
async sign(keys: PrivateKey): Promise<void> {
const signatureBytes = await keys.sign(this.hash.toBytes());
const signatureBytes = await keys.signAndAddAlgorithmBytes(
this.hash.toBytes()
);
const signature = new HexBytes(signatureBytes);

if (!this.approvals) {
Expand Down Expand Up @@ -467,7 +469,10 @@ export class Transaction {
}

public getTransactionWrapper(): TransactionWrapper {
return new TransactionWrapper(this.originDeployV1, this.originTransactionV1);
return new TransactionWrapper(
this.originDeployV1,
this.originTransactionV1
);
}

/**
Expand All @@ -489,7 +494,9 @@ export class Transaction {
* @param key The private key to sign the transaction.
*/
async sign(key: PrivateKey): Promise<void> {
const signatureBytes = await key.sign(this.hash.toBytes());
const signatureBytes = await key.signAndAddAlgorithmBytes(
this.hash.toBytes()
);
this.setSignature(signatureBytes, key.publicKey);
}

Expand Down
Loading
Loading