Skip to content

Commit

Permalink
Merge branch 'main' into fix-param-serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmus-kirk authored Sep 12, 2023
2 parents 86abcc2 + c8e5030 commit e1c3dc8
Show file tree
Hide file tree
Showing 15 changed files with 236 additions and 164 deletions.
3 changes: 1 addition & 2 deletions examples/ccd-js-gen/wCCD/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,10 @@ const contractAddress: SDK.ContractAddress = {
`Fetching smart contract module source with reference '${info.sourceModule.moduleRef}'.`
);
const moduleSource = await grpcClient.getModuleSource(info.sourceModule);
const mod = SDK.Module.fromModuleSource(moduleSource);
const filePath = Url.fileURLToPath(import.meta.url);
const outDir = Path.join(Path.dirname(filePath), 'lib');
console.info(`Generating smart contract module client at '${outDir}'.`);
await Gen.generateContractClients(mod, 'wCCD', outDir, {
await Gen.generateContractClients(moduleSource, 'wCCD', outDir, {
output: 'TypeScript',
});
console.info('Code generation was successful.');
Expand Down
2 changes: 1 addition & 1 deletion packages/ccd-js-gen/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@concordium/common-sdk": "9.3.0",
"@concordium/common-sdk": "9.4.0",
"buffer": "^6.0.3",
"commander": "^11.0.0",
"ts-morph": "^19.0.0"
Expand Down
16 changes: 10 additions & 6 deletions packages/ccd-js-gen/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import * as tsm from 'ts-morph';
import * as SDK from '@concordium/common-sdk';
import { Buffer } from 'buffer/';

/**
* Output options for the generated code.
Expand Down Expand Up @@ -42,26 +41,31 @@ export async function generateContractClientsFromFile(
throw e;
});
const outputName = path.basename(modulePath, '.wasm.v1');
const scModule = SDK.Module.fromRawBytes(Buffer.from(fileBytes));
return generateContractClients(scModule, outputName, outDirPath, options);
const moduleSource = SDK.versionedModuleSourceFromBuffer(fileBytes);
return generateContractClients(
moduleSource,
outputName,
outDirPath,
options
);
}

/**
* Generate smart contract client code for a given smart contract module.
* @param scModule Buffer with bytes for the smart contract module.
* @param moduleSource Buffer with bytes for the smart contract module.
* @param outName Name for the output file.
* @param outDirPath Path to the directory to use for the output.
* @param options Options for generating the clients.
* @throws If unable to write to provided directory `outDirPath`.
*/
export async function generateContractClients(
scModule: SDK.Module,
moduleSource: SDK.VersionedModuleSource,
outName: string,
outDirPath: string,
options: GenerateContractClientsOptions = {}
): Promise<void> {
const outputOption = options.output ?? 'Everything';
const moduleInterface = await scModule.parseModuleInterface();
const moduleInterface = await SDK.parseModuleInterface(moduleSource);
const outputFilePath = path.format({
dir: outDirPath,
name: outName,
Expand Down
7 changes: 4 additions & 3 deletions packages/common/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## Unreleased
## 9.4.0

### Breaking changes

Expand All @@ -15,11 +15,12 @@
- All JSON serialization in `serialization.ts` is now handled by `json-bigint` meaning that all functions now correctly handles bigint inputs
- `sendUpdateInstruction` to the gRPC Client.
- `healthCheck` to the gRPC Client.
- `Module` class for functionality related to smart contract modules, such as parsing the WebAssembly and interface of the module.
- Smart contract related types `ContractName`, `EntrypointName` and helper functions `isInitName`, `isReceiveName`, `getContractNameFromInit` and `getNamesFromReceive`.
- Functions `calculateModuleReference` for getting the module reference and `parseModuleInterface` for getting the interface from the source of a smart contract module.
- Smart contract related types `ContractName`, `EntrypointName` and helper functions `isInitName`, `isReceiveName`, `getContractNameFromInit` and `getNamesFromReceive`.

### Fixed
- Added missing fields to `getBlockChainParameters` response. (rootKeys, level1Keys, level2Keys)
- Use of bigint exponentiation causing issues in web.

## 9.3.0

Expand Down
2 changes: 1 addition & 1 deletion packages/common/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@concordium/common-sdk",
"version": "9.3.0",
"version": "9.4.0",
"license": "Apache-2.0",
"engines": {
"node": ">=14.16.0"
Expand Down
100 changes: 95 additions & 5 deletions packages/common/src/deserializationHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,30 @@ export class Cursor {
return new Cursor(Buffer.from(data, 'hex'));
}

/** Read a number of bytes from the cursor */
/**
* Constructs a `Cursor` from a buffer of bytes.
*
* @param {ArrayBuffer} buffer - the buffer containing bytes.
*
* @returns {Cursor} a Cursor wrapping the data.
*/
public static fromBuffer(buffer: ArrayBuffer): Cursor {
return new Cursor(Buffer.from(buffer));
}

/**
* Read a number of bytes from the cursor.
* @throws If the buffer contains fewer bytes than being read.
*/
public read(numBytes: number): Buffer {
const data = Buffer.from(
this.data.subarray(this.cursor, this.cursor + numBytes)
);
const end = this.cursor + numBytes;
if (this.data.length < end) {
throw new Error(
`Failed to read ${numBytes} bytes from the cursor.`
);
}
const data = Buffer.from(this.data.subarray(this.cursor, end));
this.cursor += numBytes;

return data;
}

Expand All @@ -42,6 +59,79 @@ export class Cursor {
}
}

/**
* Represents function for deserilizing some value from a {@link Cursor}.
* @template A The value to deserialize.
*/
export interface Deserializer<A> {
(cursor: Cursor): A;
}

/**
* Deserialize a single byte from the cursor.
* @param {Cursor} cursor Cursor over the data to deserialize from.
* @returns {number} The value of the single byte.
* @throws If the buffer contains fewer bytes than being read.
*/
export function deserializeUInt8(cursor: Cursor): number {
return cursor.read(1).readUInt8(0);
}
/**
* Deserialize a u16 little endian from the cursor.
* @param {Cursor} cursor Cursor over the data to deserialize from.
* @returns {number} The deserialized value.
* @throws If the buffer contains fewer bytes than being read.
*/
export function deserializeUInt16LE(cursor: Cursor): number {
return cursor.read(2).readUInt16LE(0);
}
/**
* Deserialize a u32 little endian from the cursor.
* @param {Cursor} cursor Cursor over the data to deserialize from.
* @returns {number} The deserialized value.
* @throws If the buffer contains fewer bytes than being read.
*/
export function deserializeUInt32LE(cursor: Cursor): number {
return cursor.read(4).readUInt32LE(0);
}
/**
* Deserialize a u64 little endian from the cursor.
* @param {Cursor} cursor Cursor over the data to deserialize from.
* @returns {bigint} The deserialized value.
* @throws If the buffer contains fewer bytes than being read.
*/
export function deserializeBigUInt64LE(cursor: Cursor): bigint {
return cursor.read(8).readBigInt64LE(0).valueOf();
}

/**
* Deserialize a u16 big endian from the cursor.
* @param {Cursor} cursor Cursor over the data to deserialize from.
* @returns {number} The deserialized value.
* @throws If the buffer contains fewer bytes than being read.
*/
export function deserializeUInt16BE(cursor: Cursor): number {
return cursor.read(2).readUInt16BE(0);
}
/**
* Deserialize a u32 big endian from the cursor.
* @param {Cursor} cursor Cursor over the data to deserialize from.
* @returns {number} The deserialized value.
* @throws If the buffer contains fewer bytes than being read.
*/
export function deserializeUInt32BE(cursor: Cursor): number {
return cursor.read(4).readUInt32BE(0);
}
/**
* Deserialize a u64 big endian from the cursor.
* @param {Cursor} cursor Cursor over the data to deserialize from.
* @returns {bigint} The deserialized value.
* @throws If the buffer contains fewer bytes than being read.
*/
export function deserializeBigUInt64BE(cursor: Cursor): bigint {
return cursor.read(8).readBigInt64BE(0).valueOf();
}

/**
* Helper function to create a function that deserializes a `HexString` value received in a smart contract response into a list of dynamic type values
* determined by the deserialization logic defined in the callback function.
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export { CcdAmount } from './types/ccdAmount';
export { TransactionExpiry } from './types/transactionExpiry';
export { DataBlob } from './types/DataBlob';
export { ModuleReference } from './types/moduleReference';
export * from './types/Module';
export * from './types/VersionedModuleSource';
export {
VerifiablePresentation,
reviveDateFromTimeStampAttribute,
Expand Down
136 changes: 0 additions & 136 deletions packages/common/src/types/Module.ts

This file was deleted.

Loading

0 comments on commit e1c3dc8

Please sign in to comment.