Skip to content

Commit

Permalink
feat: device-simulator
Browse files Browse the repository at this point in the history
  • Loading branch information
CanvasL committed Jul 24, 2024
1 parent 5567491 commit 5513672
Show file tree
Hide file tree
Showing 63 changed files with 342 additions and 9 deletions.
48 changes: 46 additions & 2 deletions pnpm-lock.yaml

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

4 changes: 1 addition & 3 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
packages:
- "."
- "tool"
- "tool/demo"
- "tool/**"
- "templates"
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "dephy-id-evm-tool-demo",
"name": "tool-contracts-demo",
"private": true,
"version": "0.0.0",
"scripts": {
Expand Down
File renamed without changes
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useState, useEffect } from "react";
import "./App.scss";
import { ContractTransaction, Signer, ethers } from "ethers";
import { ProductFactory, ChainId } from "../../dist";
import ADDRESS_JSON from "../../../addresses.json";
import { ProductFactory, ChainId } from "dephy-id-evm-tool/dist";
import ADDRESS_JSON from "../../../../addresses.json";

const BASE_SEPOLIA_PARAMS = {
chainId: "0x14a34",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
22 changes: 22 additions & 0 deletions tool/packages/contracts-sdk/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "tool-contracts-sdk",
"module": "src/index.ts",
"type": "module",
"scripts": {
"typechain": "rimraf src/generated/* && typechain --target ethers-v5 --out-dir src/generated/ '../out/ProductFactory.sol/ProductFactory.json' '../out/IProductFactory.sol/IProductFactory.json'",
"build": "rimraf dist/* && tsc -p tsconfig.json"
},
"devDependencies": {
"@ethersproject/abi": "^5.7.0",
"@ethersproject/providers": "^5.7.2",
"rimraf": "^6.0.0",
"typechain": "^8.3.1",
"@typechain/ethers-v5": "^11.1.1"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"dependencies": {
"ethers": "^5.7.2"
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
15 changes: 15 additions & 0 deletions tool/packages/contracts-sdk/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"module": "ESNext" /* Specify what module code is generated. */,
"rootDir": "./src" /* Specify the root folder within your source files. */,
"moduleResolution": "Bundler",
"resolveJsonModule": true /* Enable importing .json files. */,
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
"strict": true /* Enable all strict type-checking options. */,
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
}
86 changes: 86 additions & 0 deletions tool/packages/device-simulator/dist/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ethers_1 = require("ethers");
const yargs_1 = __importDefault(require("yargs"));
const helpers_1 = require("yargs/helpers");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
// Function to write JSON data to a file
function writeJsonToFile(filePath, data) {
fs_1.default.writeFileSync(filePath, JSON.stringify(data, null, 2));
}
// Define the paths for the private key and signature files relative to the current working directory
const tmpDir = path_1.default.resolve(process.cwd(), "./tmp");
const privateKeyFilePath = path_1.default.join(tmpDir, "privatekey.json");
const signatureFilePath = path_1.default.join(tmpDir, "signature.json");
(0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
.command("create", "Create a new private key and save it to a file. If a private key already exists, the command will exit with a message.", () => __awaiter(void 0, void 0, void 0, function* () {
// Ensure the tmp directory exists
if (!fs_1.default.existsSync(tmpDir)) {
fs_1.default.mkdirSync(tmpDir);
}
// Check if the private key file already exists
if (fs_1.default.existsSync(privateKeyFilePath)) {
console.log("A private key already exists in ./tmp/privatekey.json. Exiting without creating a new key.");
process.exit(1);
}
// Generate a new private key
const wallet = ethers_1.ethers.Wallet.createRandom();
const privateKeyData = {
privateKey: wallet.privateKey,
address: wallet.address,
};
// Write the private key to the file
writeJsonToFile(privateKeyFilePath, privateKeyData);
console.log("A new private key has been created and saved to:", privateKeyFilePath);
}))
.command("sign", "Sign a message using the existing private key. The signature and the message expiration time will be saved to a file.", {
expiration: {
type: "number",
demandOption: false,
description: "The expiration time for the message signature in seconds. Defaults to 3600 seconds (1 hour).",
},
}, (args) => __awaiter(void 0, void 0, void 0, function* () {
// Ensure the tmp directory exists
if (!fs_1.default.existsSync(tmpDir)) {
fs_1.default.mkdirSync(tmpDir);
}
// Check if the private key file exists
if (!fs_1.default.existsSync(privateKeyFilePath)) {
console.log("No private key found. Please create a private key first using the 'create' command.");
process.exit(1);
}
// Read the private key from the file
const privateKeyData = JSON.parse(fs_1.default.readFileSync(privateKeyFilePath, "utf-8"));
const wallet = new ethers_1.ethers.Wallet(privateKeyData.privateKey);
// Set default expiration time if not provided
if (!args.expiration) {
args.expiration = 3600;
}
// Calculate the device deadline
const deviceDeadline = (Math.floor(Date.now() / 1000) + args.expiration).toString();
// Hash the message
const hashedMessage = ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode(["uint256"], [deviceDeadline]));
const digest = ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.solidityPack(["string", "bytes32"], ["DEPHY_ID_SIGNED_MESSAGE:", hashedMessage]));
const { v, r, s } = wallet._signingKey().signDigest(digest);
const deviceSignature = ethers_1.ethers.utils.solidityPack(["bytes32", "bytes32", "uint8"], [r, s, v]);
const signatureData = {
deviceSignature,
deviceDeadline,
};
writeJsonToFile(signatureFilePath, signatureData);
console.log("The message has been signed and the signature has been saved to:", signatureFilePath);
}))
.help().argv;
17 changes: 17 additions & 0 deletions tool/packages/device-simulator/dist/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./cli"), exports);
22 changes: 22 additions & 0 deletions tool/packages/device-simulator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "tool-device-simulator",
"main": "dist/index.js",
"scripts": {
"build": "rimraf dist/* && tsc -p tsconfig.json",
"cli": "node ./dist/index.js"
},
"devDependencies": {
"@types/yargs": "^17.0.32",
"rimraf": "^6.0.0"
},
"bin": {
"device-simulator": "./dist/index.js"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"dependencies": {
"ethers": "^5.7.2",
"yargs": "^17.7.2"
}
}
119 changes: 119 additions & 0 deletions tool/packages/device-simulator/src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { ethers } from "ethers";
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import fs from "fs";
import path from "path";

// Function to write JSON data to a file
function writeJsonToFile(filePath: string, data: object) {
fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
}

// Define the paths for the private key and signature files relative to the current working directory
const tmpDir = path.resolve(process.cwd(), "./tmp");
const privateKeyFilePath = path.join(tmpDir, "privatekey.json");
const signatureFilePath = path.join(tmpDir, "signature.json");

yargs(hideBin(process.argv))
.command(
"create",
"Create a new private key and save it to a file. If a private key already exists, the command will exit with a message.",
async () => {
// Ensure the tmp directory exists
if (!fs.existsSync(tmpDir)) {
fs.mkdirSync(tmpDir);
}

// Check if the private key file already exists
if (fs.existsSync(privateKeyFilePath)) {
console.log(
"A private key already exists in ./tmp/privatekey.json. Exiting without creating a new key."
);
process.exit(1);
}

// Generate a new private key
const wallet = ethers.Wallet.createRandom();
const privateKeyData = {
privateKey: wallet.privateKey,
address: wallet.address,
};

// Write the private key to the file
writeJsonToFile(privateKeyFilePath, privateKeyData);
console.log(
"A new private key has been created and saved to:",
privateKeyFilePath
);
}
)
.command(
"sign",
"Sign a message using the existing private key. The signature and the message expiration time will be saved to a file.",
{
expiration: {
type: "number",
demandOption: false,
description:
"The expiration time for the message signature in seconds. Defaults to 3600 seconds (1 hour).",
},
},
async (args) => {
// Ensure the tmp directory exists
if (!fs.existsSync(tmpDir)) {
fs.mkdirSync(tmpDir);
}

// Check if the private key file exists
if (!fs.existsSync(privateKeyFilePath)) {
console.log(
"No private key found. Please create a private key first using the 'create' command."
);
process.exit(1);
}

// Read the private key from the file
const privateKeyData = JSON.parse(
fs.readFileSync(privateKeyFilePath, "utf-8")
);
const wallet = new ethers.Wallet(privateKeyData.privateKey);

// Set default expiration time if not provided
if (!args.expiration) {
args.expiration = 3600;
}

// Calculate the device deadline
const deviceDeadline = (
Math.floor(Date.now() / 1000) + args.expiration
).toString();

// Hash the message
const hashedMessage = ethers.utils.keccak256(
ethers.utils.defaultAbiCoder.encode(["uint256"], [deviceDeadline])
);
const digest = ethers.utils.keccak256(
ethers.utils.solidityPack(
["string", "bytes32"],
["DEPHY_ID_SIGNED_MESSAGE:", hashedMessage]
)
);

const { v, r, s } = wallet._signingKey().signDigest(digest);
const deviceSignature = ethers.utils.solidityPack(
["bytes32", "bytes32", "uint8"],
[r, s, v]
);

const signatureData = {
deviceSignature,
deviceDeadline,
};
writeJsonToFile(signatureFilePath, signatureData);
console.log(
"The message has been signed and the signature has been saved to:",
signatureFilePath
);
}
)
.help().argv;
1 change: 1 addition & 0 deletions tool/packages/device-simulator/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./cli";
10 changes: 10 additions & 0 deletions tool/packages/device-simulator/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "ES2015",
"module": "CommonJS",
"strict": true,
"outDir": "./dist",
"esModuleInterop": true,
"moduleResolution": "node"
},
}
1 change: 0 additions & 1 deletion tool/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@
"strict": true /* Enable all strict type-checking options. */,
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"exclude": ["dist", "demo"]
}

0 comments on commit 5513672

Please sign in to comment.