Skip to content
This repository was archived by the owner on Oct 1, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
d485411
feat(token-registry)!: token registry v4
osslgtm Sep 6, 2022
81f58a3
Merge branch 'master' into token-registry-v4
osslgtm Sep 6, 2022
b221d77
fix: added roles to token-registry issue
osslgtm Sep 6, 2022
e3ec56b
fix: rolesInput datatype
osslgtm Sep 6, 2022
674d817
feat: updated README
osslgtm Sep 6, 2022
7ddd12e
feat: e2e tests (wip)
osslgtm Sep 13, 2022
b61727f
feat: remove redundant tests
osslgtm Sep 13, 2022
068f7f7
fix: token registry deploy
osslgtm Sep 14, 2022
407e380
Merge branch 'master' into token-registry-v4
osslgtm Sep 15, 2022
8205a71
Merge branch 'token-registry-e2e' into token-registry-v4
osslgtm Sep 16, 2022
0540e29
fix: token-registry deploy
osslgtm Sep 16, 2022
c097554
feat: token-registry e2e test
osslgtm Sep 19, 2022
d38e6a8
feat: fixed linting
osslgtm Sep 21, 2022
7f56f7c
feat: fixed e2e test disconnect
osslgtm Sep 21, 2022
d4fc2e1
fix: removed fragile test message, e2e added
osslgtm Sep 21, 2022
a1b9ad4
Merge branch 'master' into token-registry-v4
osslgtm Sep 21, 2022
79338a3
fix: linting
osslgtm Sep 21, 2022
71ed72a
fix: typescript casting
osslgtm Sep 21, 2022
f80a0ef
fix: setAdminRole - update wording
osslgtm Sep 21, 2022
208452c
feat: update token registry
osslgtm Sep 22, 2022
ad97c6c
fix: update package-lock
osslgtm Sep 22, 2022
28969f9
feat: update token-registry e2e default goerli
osslgtm Sep 22, 2022
38680bb
fix: code
osslgtm Sep 29, 2022
517f1a6
fix: typo and moved to goerli
osslgtm Oct 7, 2022
65f300c
fix: clean up token regostry deploy
osslgtm Oct 10, 2022
1867a21
chore: remove files based on discussion
osslgtm Oct 10, 2022
e7e46c1
chore: update naming
osslgtm Oct 11, 2022
f5dc87d
chore: rename files
osslgtm Oct 11, 2022
e226910
chore: linting
osslgtm Oct 12, 2022
5de8151
Merge branch 'master' into token-registry-v4
osslgtm Oct 12, 2022
ea3ba41
fix: merge error
osslgtm Oct 12, 2022
fc1fa19
chore: split token-registry deploy helpers
osslgtm Oct 13, 2022
68afa4f
fix: lint
osslgtm Oct 13, 2022
861a3ba
fix: rename and update tests
osslgtm Oct 13, 2022
c7ee59a
chore: renaming
osslgtm Oct 13, 2022
8947ba8
feat: alias as parameter fallback
osslgtm Oct 13, 2022
ae6da0b
Merge branch 'master' into feat/token-registry-v4
osslgtm Oct 13, 2022
3d26bf5
feat: allow custom token-registry deploy factories
osslgtm Nov 3, 2022
7a54981
fix: test
osslgtm Nov 3, 2022
039a086
fix: address parsing error
osslgtm Nov 4, 2022
bd66537
feat: deprecate ropsten and rinkeby (#230)
isaackps Oct 27, 2022
52cd61b
fix: renamed newOwner to newBeneficiary
osslgtm Nov 9, 2022
e3171af
fix: renaming
osslgtm Nov 10, 2022
b08b025
fix: linting
osslgtm Nov 14, 2022
3127d74
fix: remove gas price scale
osslgtm Nov 16, 2022
6e09f0d
feat: upgrade to Token Registry 4.1.0
osslgtm Nov 29, 2022
15ea0fa
Merge branch 'master' into feat/token-registry-v4
osslgtm Nov 30, 2022
0674487
chore: remove gas-price-scale
osslgtm Nov 30, 2022
0bf6c99
chore: remove gps from tests
osslgtm Nov 30, 2022
bef0e59
feat: (wip) e2e tests
osslgtm Dec 2, 2022
6bcaf9c
fix: resolve ganache transaction fee spike
osslgtm Dec 6, 2022
fce3481
feat: most e2e working except surrender
osslgtm Dec 6, 2022
a8d573a
feat: surrender complete
osslgtm Dec 7, 2022
3de6ad2
feat: update token-registry to 4.1.2
osslgtm Dec 7, 2022
6d53ef4
Merge branch 'feat/token-registry-v4' into feat/e2e-tests
osslgtm Dec 7, 2022
d4995ed
fix: rename
osslgtm Dec 7, 2022
f86eafa
Merge branch 'master' into feat/token-registry-v4
osslgtm Dec 7, 2022
3dbe1ab
fix: lint
osslgtm Dec 7, 2022
0fdd151
fix: lint
osslgtm Dec 7, 2022
4799fea
feat: tests
osslgtm Jan 6, 2023
1a2c734
feat: remove jest
osslgtm Jan 9, 2023
4fc6793
fix: linting
osslgtm Jan 11, 2023
3a61c96
fix: check for valid token-registry
osslgtm Jan 18, 2023
6a4313d
feat: e2e tests
osslgtm Jan 18, 2023
a5973f2
fix: lint
osslgtm Jan 18, 2023
c2cda9e
fix: restore jest serial
osslgtm Jan 18, 2023
530cb40
Merge branch 'feat/token-registry-v4' into feat/e2e-tests
osslgtm Jan 19, 2023
5b4be44
Merge branch 'master' into feat/token-registry-v4
osslgtm Jan 20, 2023
82b228e
Merge branch 'feat/token-registry-v4' into feat/e2e-tests
osslgtm Jan 20, 2023
2e5c66a
feat: validation
osslgtm Jan 27, 2023
a6639c5
fix: lint
osslgtm Jan 27, 2023
e6bd493
feat: update jest tests for validation (wip)
osslgtm Jan 30, 2023
a070e2c
feat: fix jest tests
osslgtm Feb 1, 2023
0c823f5
fix: renaming and scope changes
osslgtm Feb 1, 2023
49137d7
fix: rename e2e functions
osslgtm Feb 1, 2023
bd75393
Merge branch 'master' into EIP-1559
osslgtm Mar 22, 2023
8fd1aa9
Merge branch 'master' into feat/e2e-tests
osslgtm Apr 11, 2023
e7745f4
feat: input validation
osslgtm Apr 12, 2023
674d816
Merge branch 'master' into feat/validation
osslgtm Apr 12, 2023
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
13 changes: 4 additions & 9 deletions src/commands/config/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { create } from "../../implementations/config/create";
import { getLogger } from "../../logger";
import { highlight } from "../../utils";
import { supportedNetwork } from "../networks";
import { withWalletOption } from "../shared";
import { CreateConfigCommand } from "./config.type";

const { trace } = getLogger("config:create");
Expand All @@ -15,20 +16,14 @@ export const command = "create [options]";
export const describe = "Create a config file";

export const builder = (yargs: Argv): Argv =>
yargs
.option("output-dir", {
withWalletOption(
yargs.option("output-dir", {
alias: "od",
description: "Write output to a directory",
type: "string",
demandOption: true,
})
// encrypted wallet path is referenced from command.shared.ts as we need additional properties for this instance.
.option("encrypted-wallet-path", {
type: "string",
description: "Path to wallet.json file",
normalize: true,
demandOption: true,
});
);

export const handler = async (args: CreateConfigCommand): Promise<void> => {
trace(`Args: ${JSON.stringify(args, null, 2)}`);
Expand Down
127 changes: 64 additions & 63 deletions src/implementations/deploy/token-registry/token-registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,77 +12,78 @@ const deployParams: DeployTokenRegistryCommand = {
dryRun: false,
};

describe("deploy Token Registry", () => {
const mockedEthersContract: jest.Mock<Contract> = Contract as any;
// eslint-disable-next-line jest/prefer-spy-on
mockedEthersContract.prototype.deploy = jest.fn();
const mockedDeploy: jest.Mock = mockedEthersContract.prototype.deploy;
describe("token-registry", () => {
describe("deployTokenRegistry", () => {
const mockedEthersContract: jest.Mock<Contract> = Contract as any;
// eslint-disable-next-line jest/prefer-spy-on
mockedEthersContract.prototype.deploy = jest.fn();
const mockedDeploy: jest.Mock = mockedEthersContract.prototype.deploy;

// increase timeout because ethers is throttling
jest.setTimeout(30000);
// increase timeout because ethers is throttling
jest.setTimeout(30000);

beforeEach(() => {
mockedDeploy.mockReset();
mockedDeploy.mockResolvedValue({
hash: "hash",
blockNumber: "blockNumber",
wait: () =>
Promise.resolve({
events: [
{
topics: [
"0x3588ebb5c75fdf91927f8472318f41513ee567c2612a5ce52ac840dcf6f162f5", // deployment
"0x000000000000000000000000426c58c2b29111eafc53bdcb9c99dc7714fdb262",
"0x000000000000000000000000e5c75026d5f636c89cc77583b6bce7c99f512763",
"0x0000000000000000000000008d366250a96debe81c8619459a503a0eebe33ca6",
],
data: "0x000000000000000000000000878a327daa390bc602ae259d3a374610356b6485000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008d366250a96debe81c8619459a503a0eebe33ca60000000000000000000000000000000000000000000000000000000000000011563420546f6b656e20526567697374727900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d54540000000000000000000000000000000000000000000000000000000000",
args: [
"0xd6C249d0756059E21Ef4Aef4711B69b76927BEA7",
"0xC78BA1a49663Ef8b920F36B036E91Ab40D8F26D6",
"0x8d366250A96deBE81C8619459a503a0eEBE33ca6",
"0x878A327daA390Bc602Ae259D3A374610356b6485",
"0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008d366250a96debe81c8619459a503a0eebe33ca60000000000000000000000000000000000000000000000000000000000000011563420546f6b656e20526567697374727900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d54540000000000000000000000000000000000000000000000000000000000",
] as unknown as DeploymentEvent,
},
],
}),
beforeEach(() => {
mockedDeploy.mockReset();
mockedDeploy.mockResolvedValue({
hash: "hash",
blockNumber: "blockNumber",
wait: () =>
Promise.resolve({
events: [
{
topics: [
"0x3588ebb5c75fdf91927f8472318f41513ee567c2612a5ce52ac840dcf6f162f5", // deployment
"0x000000000000000000000000426c58c2b29111eafc53bdcb9c99dc7714fdb262",
"0x000000000000000000000000e5c75026d5f636c89cc77583b6bce7c99f512763",
"0x0000000000000000000000008d366250a96debe81c8619459a503a0eebe33ca6",
],
data: "0x000000000000000000000000878a327daa390bc602ae259d3a374610356b6485000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008d366250a96debe81c8619459a503a0eebe33ca60000000000000000000000000000000000000000000000000000000000000011563420546f6b656e20526567697374727900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d54540000000000000000000000000000000000000000000000000000000000",
args: [
"0xd6C249d0756059E21Ef4Aef4711B69b76927BEA7",
"0xC78BA1a49663Ef8b920F36B036E91Ab40D8F26D6",
"0x8d366250A96deBE81C8619459a503a0eEBE33ca6",
"0x878A327daA390Bc602Ae259D3A374610356b6485",
"0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008d366250a96debe81c8619459a503a0eebe33ca60000000000000000000000000000000000000000000000000000000000000011563420546f6b656e20526567697374727900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d54540000000000000000000000000000000000000000000000000000000000",
] as unknown as DeploymentEvent,
},
],
}),
});
});
});

it("should pass in the correct params and return the deployed instance", async () => {
await deployTokenRegistry(deployParams);
it("should pass in the correct params and return the deployed instance", async () => {
await deployTokenRegistry(deployParams);

const expectedInitParams = encodeInitParams({
name: deployParams.registryName,
symbol: deployParams.registrySymbol,
deployer: "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf",
});
const expectedInitParams = encodeInitParams({
name: deployParams.registryName,
symbol: deployParams.registrySymbol,
deployer: "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf",
});

expect(mockedDeploy.mock.calls[0][0]).toEqual("0xC78BA1a49663Ef8b920F36B036E91Ab40D8F26D6");
expect(mockedDeploy.mock.calls[0][1]).toEqual(expectedInitParams);
expect(mockedDeploy.mock.calls[0][0]).toEqual("0xC78BA1a49663Ef8b920F36B036E91Ab40D8F26D6");
expect(mockedDeploy.mock.calls[0][1]).toEqual(expectedInitParams);

// price should be any length string of digits
// expect(mockedDeploy.mock.calls[0][2].gasPrice.toString()).toStrictEqual(expect.stringMatching(/\d+/));
// expect(instance.contractAddress).toBe("contractAddress"); // TODO
});
// price should be any length string of digits
// expect(mockedDeploy.mock.calls[0][2].gasPrice.toString()).toStrictEqual(expect.stringMatching(/\d+/));
// expect(instance.contractAddress).toBe("contractAddress"); // TODO
});

it("should allow errors to bubble up", async () => {
mockedDeploy.mockRejectedValue(new Error("An Error"));
await expect(deployTokenRegistry(deployParams)).rejects.toThrow("An Error");
});
it("should allow errors to bubble up", async () => {
mockedDeploy.mockRejectedValue(new Error("An Error"));
await expect(deployTokenRegistry(deployParams)).rejects.toThrow("An Error");
});

it("should throw when keys are not found anywhere", async () => {
delete process.env.OA_PRIVATE_KEY;
await expect(
deployTokenRegistry({
registryName: "Test",
registrySymbol: "Tst",
network: "goerli",
dryRun: false,
})
).rejects.toThrow(
"No private key found in OA_PRIVATE_KEY, key, key-file, please supply at least one or supply an encrypted wallet path, or provide aws kms signer information"
);
it("should throw when keys are not found anywhere", async () => {
await expect(
deployTokenRegistry({
registryName: "Test",
registrySymbol: "Tst",
network: "goerli",
dryRun: false,
})
).rejects.toThrow(
"No private key found in OA_PRIVATE_KEY, key, key-file, please supply at least one or supply an encrypted wallet path, or provide aws kms signer information"
);
});
});
});
136 changes: 51 additions & 85 deletions src/implementations/document-store/issue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Wallet } from "ethers";
import { DocumentStoreFactory } from "@govtechsg/document-store";
import { DocumentStoreIssueCommand } from "../../commands/document-store/document-store-command.type";
import { addAddressPrefix } from "../../utils";
import { join } from "path";

jest.mock("@govtechsg/document-store");

Expand All @@ -15,103 +14,70 @@ const deployParams: DocumentStoreIssueCommand = {
dryRun: false,
};

// TODO the following test is very fragile and might break on every interface change of DocumentStoreFactory
// ideally must setup ganache, and run the function over it
describe("issue document-store", () => {
describe("document-store", () => {
// increase timeout because ethers is throttling
jest.setTimeout(30000);
const mockedDocumentStoreFactory: jest.Mock<DocumentStoreFactory> = DocumentStoreFactory as any;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore mock static method
const mockedConnect: jest.Mock = mockedDocumentStoreFactory.connect;
const mockedIssue = jest.fn();
const mockCallStaticIssue = jest.fn().mockResolvedValue(undefined);

beforeEach(() => {
delete process.env.OA_PRIVATE_KEY;
mockedDocumentStoreFactory.mockReset();
mockedConnect.mockReset();
mockCallStaticIssue.mockClear();
mockedConnect.mockReturnValue({
issue: mockedIssue,
callStatic: {
issue: mockCallStaticIssue,
},
});
mockedIssue.mockReturnValue({
hash: "hash",
wait: () => Promise.resolve({ transactionHash: "transactionHash" }),
describe("issueDocumentStore", () => {
const mockedDocumentStoreFactory: jest.Mock<DocumentStoreFactory> = DocumentStoreFactory as any;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore mock static method
const mockedConnect: jest.Mock = mockedDocumentStoreFactory.connect;
const mockedIssue = jest.fn();
const mockCallStaticIssue = jest.fn().mockResolvedValue(undefined);

beforeEach(() => {
delete process.env.OA_PRIVATE_KEY;
mockedDocumentStoreFactory.mockReset();
mockedConnect.mockReset();
mockCallStaticIssue.mockClear();
mockedConnect.mockReturnValue({
issue: mockedIssue,
callStatic: {
issue: mockCallStaticIssue,
},
});
mockedIssue.mockReturnValue({
hash: "hash",
wait: () => Promise.resolve({ transactionHash: "transactionHash" }),
});
});
});

it("should take in the key from environment variable", async () => {
process.env.OA_PRIVATE_KEY = "0000000000000000000000000000000000000000000000000000000000000002";
it("should take in the key from environment variable", async () => {
process.env.OA_PRIVATE_KEY = "0000000000000000000000000000000000000000000000000000000000000002";

await issueToDocumentStore({
hash: "0xabcd",
address: "0x1234",
network: "goerli",
dryRun: false,
});

const passedSigner: Wallet = mockedConnect.mock.calls[0][1];
expect(passedSigner.privateKey).toBe(`0x${process.env.OA_PRIVATE_KEY}`);
});
await issueToDocumentStore({
hash: "0xabcd",
address: "0x1234",
network: "goerli",
dryRun: false,
});

it("should pass in the correct params and return the deployed instance", async () => {
const instance = await issueToDocumentStore(deployParams);
const passedSigner: Wallet = mockedConnect.mock.calls[0][1];
expect(passedSigner.privateKey).toBe(`0x${process.env.OA_PRIVATE_KEY}`);
});

const passedSigner: Wallet = mockedConnect.mock.calls[0][1];
it("should pass in the correct params and return the deployed instance", async () => {
const instance = await issueToDocumentStore(deployParams);

expect(passedSigner.privateKey).toBe(`0x${deployParams.key}`);
expect(mockedConnect.mock.calls[0][0]).toEqual(deployParams.address);
expect(mockCallStaticIssue).toHaveBeenCalledTimes(1);
expect(mockedIssue.mock.calls[0][0]).toEqual(deployParams.hash);
expect(instance).toStrictEqual({ transactionHash: "transactionHash" });
});
const passedSigner: Wallet = mockedConnect.mock.calls[0][1];

it("should take in the key from key file", async () => {
await issueToDocumentStore({
hash: "0xabcd",
address: "0x1234",
network: "goerli",
keyFile: join(__dirname, "..", "..", "..", "examples", "sample-key"),
dryRun: false,
expect(passedSigner.privateKey).toBe(`0x${deployParams.key}`);
expect(mockedConnect.mock.calls[0][0]).toEqual(deployParams.address);
expect(mockCallStaticIssue).toHaveBeenCalledTimes(1);
expect(mockedIssue.mock.calls[0][0]).toEqual(deployParams.hash);
expect(instance).toStrictEqual({ transactionHash: "transactionHash" });
});

const passedSigner: Wallet = mockedConnect.mock.calls[0][1];
expect(passedSigner.privateKey).toBe(`0x0000000000000000000000000000000000000000000000000000000000000003`);
});

it("should accept hash without 0x prefix and return deployed instance", async () => {
const instance = await issueToDocumentStore({ ...deployParams, hash: addAddressPrefix("abcd") });
it("should accept hash without 0x prefix and return deployed instance", async () => {
const instance = await issueToDocumentStore({ ...deployParams, hash: addAddressPrefix("abcd") });

const passedSigner: Wallet = mockedConnect.mock.calls[0][1];
const passedSigner: Wallet = mockedConnect.mock.calls[0][1];

expect(passedSigner.privateKey).toBe(`0x${deployParams.key}`);
expect(mockedConnect.mock.calls[0][0]).toEqual(deployParams.address);
expect(mockCallStaticIssue).toHaveBeenCalledTimes(1);
expect(mockedIssue.mock.calls[0][0]).toEqual(deployParams.hash);
expect(instance).toStrictEqual({ transactionHash: "transactionHash" });
});

it("should allow errors to bubble up", async () => {
mockedConnect.mockImplementation(() => {
throw new Error("An Error");
expect(passedSigner.privateKey).toBe(`0x${deployParams.key}`);
expect(mockedConnect.mock.calls[0][0]).toEqual(deployParams.address);
expect(mockCallStaticIssue).toHaveBeenCalledTimes(1);
expect(mockedIssue.mock.calls[0][0]).toEqual(deployParams.hash);
expect(instance).toStrictEqual({ transactionHash: "transactionHash" });
});
await expect(issueToDocumentStore(deployParams)).rejects.toThrow("An Error");
});

it("should throw when keys are not found anywhere", async () => {
await expect(
issueToDocumentStore({
hash: "0xabcd",
address: "0x1234",
network: "goerli",
dryRun: false,
})
).rejects.toThrow(
"No private key found in OA_PRIVATE_KEY, key, key-file, please supply at least one or supply an encrypted wallet path, or provide aws kms signer information"
);
});
});
Loading