Skip to content
This repository has been archived by the owner on Apr 9, 2021. It is now read-only.

Commit

Permalink
Merge #105
Browse files Browse the repository at this point in the history
105: Add argument to deploy, Balances as BigNumber r=zie1ony a=zie1ony

SDK Changes
## [1.0.17]

### Added

- Added `DeployUtils.addArgToDeploy(deploy: Deploy, name: string, value: CLValue)` to be able to modify Deploy's session arguments. It creates a new deploy instance. Can not be used on signed deploys.

### Changed

- Default `gasPrice` changed from `10` to `1`.
- Casper balances checks return `BigNumber` now. 

Co-authored-by: Maciej Zielinski <[email protected]>
  • Loading branch information
bors[bot] and zie1ony authored Feb 4, 2021
2 parents 6a8c605 + 66b9a44 commit fc22685
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 21 deletions.
20 changes: 16 additions & 4 deletions packages/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,24 @@

All notable changes to casper-client-sdk.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.17]

### Added

- Added `DeployUtils.addArgToDeploy(deploy: Deploy, name: string, value: CLValue)` to be able to modify Deploy's session arguments. It creates a new deploy instance. Can not be used on signed deploys.

### Changed

- Default `gasPrice` changed from `10` to `1`.
- Casper balances checks return `BigNumber` now.
## [1.0.15]

### Added
- Start using CHANGELOG.md.

- Started using CHANGELOG.md.

### Changed
- Change CLValue's `value` to `value()` and `remainder` to `remainder()`.

- Changed CLValue's `value` to `value()` and `remainder` to `remainder()`.
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "casper-client-sdk",
"version": "1.0.16",
"version": "1.0.17",
"license": "Apache 2.0",
"description": "SDK to interact with the Casper blockchain",
"main": "dist/index.js",
Expand Down
13 changes: 8 additions & 5 deletions packages/sdk/src/lib/CasperClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { encodeBase16 } from './Conversions';
import { Deploy, DeployParams, ExecutableDeployItem } from './DeployUtil';
import { AsymmetricKey, SignatureAlgorithm } from './Keys';
import { CasperHDKey } from './CasperHDKey';
import { BigNumber } from '@ethersproject/bignumber';

export class CasperClient {
private nodeClient: CasperServiceByJsonRPC;
Expand Down Expand Up @@ -190,37 +191,39 @@ export class CasperClient {
/**
* Get the balance of public key
*/
public async balanceOfByPublicKey(publicKey: PublicKey): Promise<number> {
public async balanceOfByPublicKey(publicKey: PublicKey): Promise<BigNumber> {
return this.balanceOfByAccountHash(encodeBase16(publicKey.toAccountHash()));
}

/**
* Get the balance by account hash
*/
public async balanceOfByAccountHash(accountHashStr: string): Promise<number> {
public async balanceOfByAccountHash(
accountHashStr: string
): Promise<BigNumber> {
try {
const stateRootHash = await this.nodeClient
.getLatestBlockInfo()
.then(it => it.block?.header.state_root_hash);
// Find the balance Uref and cache it if we don't have it.
if (!stateRootHash) {
return 0;
return BigNumber.from(0);
}
const balanceUref = await this.nodeClient.getAccountBalanceUrefByPublicKeyHash(
stateRootHash,
accountHashStr
);

if (!balanceUref) {
return 0;
return BigNumber.from(0);
}

return await this.nodeClient.getAccountBalance(
stateRootHash,
balanceUref
);
} catch (e) {
return 0;
return BigNumber.from(0);
}
}

Expand Down
53 changes: 49 additions & 4 deletions packages/sdk/src/lib/DeployUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
} from './byterepr';
import { RuntimeArgs } from './RuntimeArgs';
// import JSBI from 'jsbi';
import { Keys, URef } from './index';
import { DeployUtil, Keys, URef } from './index';
import { AsymmetricKey, SignatureAlgorithm } from './Keys';
import { BigNumberish } from '@ethersproject/bignumber';
import { jsonArrayMember, jsonMember, jsonObject, TypedJSON } from 'typedjson';
Expand Down Expand Up @@ -193,8 +193,12 @@ abstract class ExecutableDeployItemInternal implements ToBytes {

public abstract toBytes(): Uint8Array;

public getArgByName(argName: string): CLValue | undefined {
return this.args.args.get(argName);
public getArgByName(name: string): CLValue | undefined {
return this.args.args.get(name);
}

public setArg(name: string, value: CLValue) {
this.args.args.set(name, value);
}
}

Expand Down Expand Up @@ -532,6 +536,23 @@ export class ExecutableDeployItem implements ToBytes {
throw new Error('failed to serialize ExecutableDeployItemJsonWrapper');
}

public setArg(name: string, value: CLValue) {
if (this.isModuleBytes()) {
return this.moduleBytes!.setArg(name, value);
} else if (this.isStoredContractByHash()) {
return this.storedContractByHash!.setArg(name, value);
} else if (this.isStoredContractByName()) {
return this.storedContractByName!.setArg(name, value);
} else if (this.isStoredVersionContractByHash()) {
return this.storedVersionedContractByHash!.setArg(name, value);
} else if (this.isStoredVersionContractByName()) {
return this.storedVersionedContractByName!.setArg(name, value);
} else if (this.isTransfer()) {
return this.transfer!.setArg(name, value);
}
throw new Error('failed to serialize ExecutableDeployItemJsonWrapper');
}

public static fromExecutableDeployItemInternal(
item: ExecutableDeployItemInternal
) {
Expand Down Expand Up @@ -805,7 +826,7 @@ export class DeployParams {
constructor(
public accountPublicKey: PublicKey,
public chainName: string,
public gasPrice: number = 10,
public gasPrice: number = 1,
public ttl: number = 3600000,
public dependencies: Uint8Array[] = [],
public timestamp?: number
Expand Down Expand Up @@ -931,3 +952,27 @@ export const deployFromJson = (json: any) => {
const serializer = new TypedJSON(Deploy);
return serializer.parse(json.deploy);
};

export const addArgToDeploy = (
deploy: Deploy,
name: string,
value: CLValue
): Deploy => {
if (deploy.approvals.length !== 0) {
throw Error('Can not add argument to already signed deploy.');
}

const deployParams = new DeployUtil.DeployParams(
deploy.header.account,
deploy.header.chainName,
deploy.header.gasPrice,
deploy.header.ttl,
deploy.header.dependencies,
deploy.header.timestamp
);

const session = deploy.session;
session.setArg(name, value);

return makeDeploy(deployParams, session, deploy.payment);
};
3 changes: 2 additions & 1 deletion packages/sdk/src/services/BalanceServiceByJsonRPC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import { CasperServiceByJsonRPC } from './CasperServiceByJsonRPC';
import { PublicKey } from '../lib';
import { BigNumber } from '@ethersproject/bignumber';

export class BalanceServiceByJsonRPC {
private balanceUrefs = new Map<string, string>();
Expand All @@ -20,7 +21,7 @@ export class BalanceServiceByJsonRPC {
public async getAccountBalance(
blockHashBase16: string,
publicKey: PublicKey
): Promise<number | undefined> {
): Promise<BigNumber | undefined> {
try {
const stateRootHash = await this.casperService.getStateRootHash(
blockHashBase16
Expand Down
5 changes: 3 additions & 2 deletions packages/sdk/src/services/CasperServiceByJsonRPC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DeployUtil, encodeBase16, PublicKey } from '..';
import { deployToJson } from '../lib/DeployUtil';
import { TypedJSON } from 'typedjson';
import { StoredValue } from '../lib/StoredValue';
import { BigNumber } from '@ethersproject/bignumber';

interface RpcResult {
api_version: string;
Expand Down Expand Up @@ -236,7 +237,7 @@ export class CasperServiceByJsonRPC {
public async getAccountBalance(
stateRootHash: string,
balanceUref: string
): Promise<number> {
): Promise<BigNumber> {
return await this.client
.request({
method: 'state_get_balance',
Expand All @@ -245,7 +246,7 @@ export class CasperServiceByJsonRPC {
purse_uref: balanceUref
}
})
.then(res => parseInt(res.balance_value, 10));
.then(res => BigNumber.from(res.balance_value));
}

public async getStateRootHash(
Expand Down
101 changes: 99 additions & 2 deletions packages/sdk/test/lib/DeployUtil.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, assert } from 'chai';
import { Keys, DeployUtil } from '../../src/lib';
import { Keys, DeployUtil, CLValue } from '../../src/lib';
import { TypedJSON } from 'typedjson';

describe('DeployUtil', () => {
Expand Down Expand Up @@ -43,8 +43,10 @@ describe('DeployUtil', () => {
deploy = DeployUtil.signDeploy(deploy, senderKey);
deploy = DeployUtil.signDeploy(deploy, recipientKey);

// Serialize deploy to JSON.
let json = DeployUtil.deployToJson(deploy);
// console.log(json);

// Deserialize deploy from JSON.
deploy = DeployUtil.deployFromJson(json)!;

assert.isTrue(deploy.isTransfer());
Expand Down Expand Up @@ -74,4 +76,99 @@ describe('DeployUtil', () => {
assert.deepEqual(deploy.approvals[0].signer, senderKey.accountHex());
assert.deepEqual(deploy.approvals[1].signer, recipientKey.accountHex());
});

it('should allow to add arg to Deploy', function () {
const senderKey = Keys.Ed25519.new();
const recipientKey = Keys.Ed25519.new();
const networkName = 'test-network';
const paymentAmount = 10000000000000;
const transferAmount = 10;
const id = 34;
const customId = 60;

let deployParams = new DeployUtil.DeployParams(
senderKey.publicKey,
networkName
);
let session = DeployUtil.ExecutableDeployItem.newTransfer(
transferAmount,
recipientKey.publicKey,
undefined,
id
);
let payment = DeployUtil.standardPayment(paymentAmount);
let oldDeploy = DeployUtil.makeDeploy(deployParams, session, payment);

// Add new argument.
let deploy = DeployUtil.addArgToDeploy(
oldDeploy,
'custom_id',
CLValue.u32(customId)
);

// Serialize and deserialize deploy.
let json = DeployUtil.deployToJson(deploy);
deploy = DeployUtil.deployFromJson(json)!;

assert.deepEqual(
deploy.session.getArgByName('custom_id')!.asBigNumber().toNumber(),
customId
);
assert.isTrue(deploy.isTransfer());
assert.isTrue(deploy.isStandardPayment());
assert.deepEqual(deploy.header.account, senderKey.publicKey);
assert.deepEqual(
deploy.payment.getArgByName('amount')!.asBigNumber().toNumber(),
paymentAmount
);
assert.deepEqual(
deploy.session.getArgByName('amount')!.asBigNumber().toNumber(),
transferAmount
);
assert.deepEqual(
deploy.session.getArgByName('target')!.asBytesArray(),
recipientKey.accountHash()
);
assert.deepEqual(
deploy.session
.getArgByName('id')!
.asOption()
.getSome()
.asBigNumber()
.toNumber(),
id
);

assert.notEqual(oldDeploy.hash, deploy.hash);
assert.notEqual(oldDeploy.header.bodyHash, deploy.header.bodyHash);
});

it('should not allow to add arg to a signed Deploy', function () {
const senderKey = Keys.Ed25519.new();
const recipientKey = Keys.Ed25519.new();
const networkName = 'test-network';
const paymentAmount = 10000000000000;
const transferAmount = 10;
const id = 34;
const customId = 60;

let deployParams = new DeployUtil.DeployParams(
senderKey.publicKey,
networkName
);
let session = DeployUtil.ExecutableDeployItem.newTransfer(
transferAmount,
recipientKey.publicKey,
undefined,
id
);
let payment = DeployUtil.standardPayment(paymentAmount);
let deploy = DeployUtil.makeDeploy(deployParams, session, payment);
deploy = DeployUtil.signDeploy(deploy, senderKey);

expect(() => {
// Add new argument.
DeployUtil.addArgToDeploy(deploy, 'custom_id', CLValue.u32(customId));
}).to.throw('Can not add argument to already signed deploy.');
});
});
2 changes: 1 addition & 1 deletion packages/ui/src/containers/AuthContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export class AuthContainer {
this.balances.set(accountHash, {
checkedAt: now,
blockHashBase16: latestBlockHash,
balance: latestAccountBalance
balance: latestAccountBalance?.toNumber()
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/containers/BlockContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class BlockContainer {
PublicKey.fromEd25519(decodeBase16(accountKey.slice(2)))
);
if (balance !== undefined) {
this.balances.set(accountKey, balance);
this.balances.set(accountKey, balance.toNumber());
}
}
}
Expand Down

0 comments on commit fc22685

Please sign in to comment.