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

feat: update js client #152

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions client-js/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ module.exports = {
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/strict-boolean-expressions': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'no-return-await': 'off',
'@typescript-eslint/return-await': 'warn',
'no-console': ['error', { allow: ['warn'] }],
Expand Down
27 changes: 4 additions & 23 deletions client-js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions client-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
"typescript": "^5.3.3"
},
"peerDependencies": {
"casper-js-sdk": "^2.15.4",
"@make-software/ces-js-parser": "^1.3.3"
"casper-js-sdk": "3.0.0-rc03"
}
}
}
53 changes: 11 additions & 42 deletions client-js/src/CEP18Client.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import { BigNumber, type BigNumberish } from '@ethersproject/bignumber';
import { blake2b } from '@noble/hashes/blake2b';
import {
CasperServiceByJsonRPC,
type CLKeyParameters,
type CLPublicKey,
CLKeyVariant,
CLPublicKey,
type CLU256,
CLValueBuilder,
CLValueParsers,
DeployUtil,
encodeBase16,
encodeBase64,
GetDeployResult,
type Keys,
RuntimeArgs
} from 'casper-js-sdk';

import { ContractError } from './error';
import TypedContract from './TypedContract';
import {
ApproveArgs,
Expand All @@ -29,13 +26,16 @@ import {
} from './types';

export default class CEP18Client extends TypedContract {
constructor(public nodeAddress: string, public networkName: string) {
constructor(
public nodeAddress: string,
public networkName: string
) {
super(nodeAddress, networkName);
}

public setContractHash(
contractHash: `hash-${string}`,
contractPackageHash?: `hash-${string}`
contractHash: `entity-contract-${string}`,
contractPackageHash?: `package-${string}`
) {
this.contractClient.setContractHash(contractHash, contractPackageHash);
}
Expand Down Expand Up @@ -390,7 +390,7 @@ export default class CEP18Client extends TypedContract {
* @param account account info to get balance
* @returns account's balance
*/
public async balanceOf(account: CLKeyParameters): Promise<BigNumber> {
public async balanceOf(account: CLKeyVariant): Promise<BigNumber> {
const keyBytes = CLValueParsers.toBytes(
CLValueBuilder.key(account)
).unwrap();
Expand Down Expand Up @@ -421,8 +421,8 @@ export default class CEP18Client extends TypedContract {
* @returns approved amount
*/
public async allowances(
owner: CLKeyParameters,
spender: CLKeyParameters
owner: CLKeyVariant,
spender: CLKeyVariant
): Promise<BigNumber> {
const keyOwner = CLValueParsers.toBytes(CLValueBuilder.key(owner)).unwrap();
const keySpender = CLValueParsers.toBytes(
Expand Down Expand Up @@ -511,35 +511,4 @@ export default class CEP18Client extends TypedContract {
const u8res = internalValue.toNumber();
return u8res !== 0;
}

/**
* Parse deploy result by given hash.
* It the deploy wasn't successful, throws `ContractError` if there was operational error, otherwise `Error` with original error message.
* @param deployHash deploy hash
* @returns `GetDeployResult`
*/
public async parseDeployResult(deployHash: string): Promise<GetDeployResult> {
const casperClient = new CasperServiceByJsonRPC(this.nodeAddress);

const result = await casperClient.getDeployInfo(deployHash);
if (
result.execution_results.length > 0 &&
result.execution_results[0].result.Failure
) {
// Parse execution result
const { error_message } = result.execution_results[0].result.Failure;
const contractErrorMessagePrefix = 'User error: ';
if (error_message.startsWith(contractErrorMessagePrefix)) {
const errorCode = parseInt(
error_message.substring(
contractErrorMessagePrefix.length,
error_message.length
),
10
);
throw new ContractError(errorCode);
} else throw new Error(error_message);
}
return result;
}
}
111 changes: 6 additions & 105 deletions client-js/src/EventEnabledContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,9 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { Parser } from '@make-software/ces-js-parser';
import {
CasperClient,
Contracts,
encodeBase16,
EventName,
EventStream,
ExecutionResult
} from 'casper-js-sdk';
import { CasperClient, Contracts } from 'casper-js-sdk';

import { CEP18Event, CEP18EventWithDeployInfo, WithDeployInfo } from './events';
import { CEP18Event, WithDeployInfo } from './events';

const { Contract } = Contracts;

Expand All @@ -21,107 +13,16 @@ export default class EventEnabledContract {

casperClient: CasperClient;

eventStream?: EventStream;

parser?: Parser;

private readonly events: Record<
string,
((event: WithDeployInfo<CEP18Event>) => void)[]
> = {};

constructor(public nodeAddress: string, public networkName: string) {
constructor(
public nodeAddress: string,
public networkName: string
) {
this.casperClient = new CasperClient(nodeAddress);
this.contractClient = new Contract(this.casperClient);
}

async setupEventStream(eventStream: EventStream) {
this.eventStream = eventStream;

if (!this.parser) {
this.parser = await Parser.create(this.casperClient.nodeClient, [
this.contractClient.contractHash.slice(5)
]);
}

await this.eventStream.start();

this.eventStream.subscribe(EventName.DeployProcessed, deployProcessed => {
const {
execution_result,
timestamp,
deploy_hash: deployHash
} = deployProcessed.body.DeployProcessed;

if (!execution_result.Success || !this.parser) {
return;
}

const results = this.parseExecutionResult(
execution_result as ExecutionResult
);

results
.map(
r =>
({
...r,
deployInfo: { deployHash, timestamp }
} as CEP18EventWithDeployInfo)
)
.forEach(event => this.emit(event));
});
}

on(name: string, listener: (event: CEP18EventWithDeployInfo) => void) {
this.addEventListener(name, listener);
}

addEventListener(
name: string,
listener: (event: CEP18EventWithDeployInfo) => void
) {
if (!this.events[name]) this.events[name] = [];

this.events[name].push(listener);
}

off(name: string, listener: (event: CEP18EventWithDeployInfo) => void) {
this.removeEventListener(name, listener);
}

removeEventListener(
name: string,
listenerToRemove: (event: CEP18EventWithDeployInfo) => void
) {
if (!this.events[name]) {
throw new Error(
`Can't remove a listener. Event "${name}" doesn't exits.`
);
}

const filterListeners = (
listener: (event: CEP18EventWithDeployInfo) => void
) => listener !== listenerToRemove;

this.events[name] = this.events[name].filter(filterListeners);
}

emit(event: CEP18EventWithDeployInfo) {
this.events[event.name]?.forEach(cb => cb(event));
}

parseExecutionResult(result: ExecutionResult): CEP18Event[] {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const results = this.parser.parseExecutionResult(result);

return results
.filter(r => r.error === null)
.map(r => ({
...r.event,
contractHash: `hash-${encodeBase16(r.event.contractHash)}`,
contractPackageHash: `hash-${encodeBase16(r.event.contractPackageHash)}`
})) as CEP18Event[];
}
}
8 changes: 1 addition & 7 deletions client-js/src/TypedContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ interface ITypedContract {
): void;
}

const TypedContract = EventEnabledContract as {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
new (public nodeAddress: string, public networkName: string): ITypedContract;

prototype: ITypedContract;
};
const TypedContract = EventEnabledContract;

export default TypedContract;
22 changes: 11 additions & 11 deletions client-js/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type BigNumberish } from '@ethersproject/bignumber';
import { type CLKeyParameters } from 'casper-js-sdk';
import { CLKeyVariant } from 'casper-js-sdk';

export enum EVENTS_MODE {
NoEvents = 0,
Expand All @@ -26,29 +26,29 @@ export interface TransferableArgs {
}

export interface TransferArgs extends TransferableArgs {
recipient: CLKeyParameters;
recipient: CLKeyVariant;
}

export interface TransferFromArgs extends TransferArgs {
owner: CLKeyParameters;
owner: CLKeyVariant;
}

export interface ApproveArgs extends TransferableArgs {
spender: CLKeyParameters;
spender: CLKeyVariant;
}

export interface MintArgs extends TransferableArgs {
owner: CLKeyParameters;
owner: CLKeyVariant;
}

export interface BurnArgs extends TransferableArgs {
owner: CLKeyParameters;
owner: CLKeyVariant;
}

export interface ChangeSecurityArgs {
adminList?: CLKeyParameters[];
minterList?: CLKeyParameters[];
burnerList?: CLKeyParameters[];
mintAndBurnList?: CLKeyParameters[];
noneList?: CLKeyParameters[];
adminList?: CLKeyVariant[];
minterList?: CLKeyVariant[];
burnerList?: CLKeyVariant[];
mintAndBurnList?: CLKeyVariant[];
noneList?: CLKeyVariant[];
}
Loading