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

initial gatekeeper config cli commands #58

Merged
merged 2 commits into from
Jul 8, 2024
Merged
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
4 changes: 2 additions & 2 deletions gatekeeper-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@ethersproject/web": "^5.7.1",
"@identity.com/gateway-eth-ts": "0.8.1-alpha.3",
"@identity.com/gateway-evm-ts-client": "^0.1.3",
"@identity.com/did-bnb-client": "^2.0.2-beta",
"@oclif/core": "^4.0.6",
"@oclif/dev-cli": "^1.26.10",
"@oclif/plugin-help": "^5",
Expand Down Expand Up @@ -59,9 +60,8 @@
]
},
"scripts": {
"build": "rm -rf dist && tsc -b && oclif-dev manifest && oclif-dev readme",
"build": "rm -rf dist && tsc -b && oclif-dev manifest",
"postpack": "shx rm -f oclif.manifest.json",
"posttest": "yarn lint",
"prepack": "yarn build && oclif manifest && oclif readme",
"test": "mocha --forbid-only \"src/**/*.spec.ts\"",
"version": "oclif readme && git add README.md"
Expand Down
59 changes: 59 additions & 0 deletions gatekeeper-cli/src/commands/update-gatekeeper-fees.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {
confirmationsFlag,
feesFlag, gatekeeperNetworkFlag,
gatewayTokenAddressFlag,
chainFlag, parseFlagsWithPrivateKey,
privateKeyFlag, gasLimitFlag,
gatewayNetworkAddressFlag,
gatekeeperContractAddressFlag,
} from '../utils/oclif/flags'
import {Args, Command, Flags} from '@oclif/core'
import {makeGatekeeperTs} from '../utils/oclif/utils'
import { utils } from 'ethers';

export default class UpdateGatekeeperFees extends Command {
static description = 'Update the fee amount a gatekeeper charges on a given network. Can only be changed once every 7 days.';

static examples = [
`$ gateway-eth add-gatekeeper 0x893F4Be53274353CD3379C87C8fd1cb4f8458F94 -n 123
`,
];

static flags = {
help: Flags.help({char: 'h'}),
privateKey: privateKeyFlag(),
gatewayTokenAddress: gatewayTokenAddressFlag(),
gatekeeperNetwork: gatekeeperNetworkFlag(),
gatewayNetworkAddress: gatewayNetworkAddressFlag(),
gatekeeperContractAddress: gatekeeperContractAddressFlag(),
chain: chainFlag(),
fees: feesFlag(),
gasLimit: gasLimitFlag(),
confirmations: confirmationsFlag(),
};

static args = {
networkName: Args.string({name: 'networkName', required: true, description: 'Name of the network'}),
issueFee: Args.integer({name: 'issueFee', required: true, description: 'Fee amount on pass issuance'}),
refreshFee: Args.integer({name: 'expireFee', required: true, description: 'Fee amount to refresh an expired token'}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy paste bloops?

freezeFee: Args.integer({name: 'freezeFee', required: true, description: 'Fee amount to freeze a pass'}),
expireFee: Args.integer({name: 'expireFee', required: true, description: 'Fee amount to expire a token'})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace

}

async run(): Promise<void> {
const {args, flags} = await this.parse(UpdateGatekeeperFees)

const parsedFlags = parseFlagsWithPrivateKey(flags)


const gatewayGatekeeperClient = await makeGatekeeperTs(parsedFlags.provider, parsedFlags.privateKey, parsedFlags.gatekeeperContractAddress as string)
const sendableTransaction = await gatewayGatekeeperClient.updateFeeConfig({issueFee: args.issueFee, expireFee: args.expireFee, freezeFee: args.freezeFee, refreshFee: args.refreshFee}, utils.formatBytes32String(args.networkName))
this.log(`Confirmation is: ${flags.confirmations}`)
const receipt = await sendableTransaction.wait(flags.confirmations)

this.log(
`Updated gatekeeper fees. TxHash: ${receipt.transactionHash}`,
)
}
}

70 changes: 70 additions & 0 deletions gatekeeper-cli/src/commands/upload-gatekeeper-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {
confirmationsFlag,
feesFlag, gatekeeperNetworkFlag,
gatewayTokenAddressFlag,
chainFlag, parseFlagsWithPrivateKey,
privateKeyFlag, gasLimitFlag,
gatewayNetworkAddressFlag,
} from '../utils/oclif/flags'
import {Args, Command, Flags} from '@oclif/core'
import {makeDidRegistryClient, makeGatewayNetworkTs} from '../utils/oclif/utils'
import { utils } from 'ethers';

export default class UploadGatekeeperConfig extends Command {
static description = 'Uploads issuer.config file to the associated did';

static examples = [
`$ gateway-eth upload-gatekeeper-config 0x893F4Be53274353CD3379C87C8fd1cb4f8458F94 -n 123
`,
];

static flags = {
help: Flags.help({char: 'h'}),
privateKey: privateKeyFlag(),
gatewayTokenAddress: gatewayTokenAddressFlag(),
gatekeeperNetwork: gatekeeperNetworkFlag(),
gatewayNetworkAddress: gatewayNetworkAddressFlag(),
chain: chainFlag(),
fees: feesFlag(),
gasLimit: gasLimitFlag(),
confirmations: confirmationsFlag(),
};

static args = {
didRegistryContractAddress: Args.string({name: 'didRegistryContractAddress', required: true, description: 'Contract address of the did registry (currently only support did-bnb)'}),
serviceEndpointUrl: Args.string({name: 'serviceEndpointUrl', required: true, description: 'Url gatekeeper owns that users will be redirected to for token issuance'})
}

async run(): Promise<void> {
const {args, flags} = await this.parse(UploadGatekeeperConfig)


const parsedFlags = parseFlagsWithPrivateKey(flags)

const didRegistry = await makeDidRegistryClient(args.didRegistryContractAddress, parsedFlags.privateKey, parsedFlags.provider);

// Check is did already initialized
const isDidInitialized = didRegistry.isGenerativeDidState(didRegistry.getDid())

if(!isDidInitialized) {
this.log(` Initializing did state`)
const initilizeTx = await didRegistry.initializeDidState();
const initilizeReceipt = await initilizeTx.wait(flags.confirmations);

this.log(`Initialized did. TxHash: ${initilizeReceipt.transactionHash}`)
}

const sendableTransaction = await didRegistry.addService({
fragment: 'gateway-issuer',
service_type: "gateway-issuer",
service_endpoint: args.serviceEndpointUrl
})

const receipt = await sendableTransaction.wait(flags.confirmations)

this.log(
`Added gateway-issuer service endpoint for gatekeeper. TxHash: ${receipt.transactionHash}`,
)
}
}

6 changes: 3 additions & 3 deletions gatekeeper-cli/src/test/integration/add-gatekeeper.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BaseProvider } from "@ethersproject/providers";
import * as dotenv from "dotenv";
import { ethers, utils, Wallet } from "ethers";
import {runCommand} from '@oclif/test'
import { BNB_TESTNET_CONTRACT_ADDRESSES, createRandomString, FOUNDRY_DEFAULT_WALLET_ONE, GatewayNetworkClient } from "../../utils";
import { BNB_TESTNET_CONTRACT_ADDRESSES, createRandomString, FOUNDRY_DEFAULT_WALLET_ONE, FOUNDRY_DEFAULT_WALLET_TWO, GatewayNetworkClient, RANDOM_NETWORK_NAME, RANDOM_WALLET } from "../../utils";
import assert = require('assert');
import { GatewayNetworkClass } from "@identity.com/gateway-evm-ts-client/dist/service/GatewayNetwork";

Expand All @@ -19,12 +19,12 @@ describe("Command: Add gatekeeper to network", function () {
provider = new ethers.providers.JsonRpcProvider("http://127.0.0.1:8545"); // Test run against local node forked

testWallet = FOUNDRY_DEFAULT_WALLET_ONE.connect(provider);
gatekeeper = Wallet.createRandom();
gatekeeper = FOUNDRY_DEFAULT_WALLET_TWO.connect(provider);
networkClient = GatewayNetworkClient(testWallet, BNB_TESTNET_CONTRACT_ADDRESSES.gatewayNetwork)
});

it("add a new gatekeeper to a network", async function () {
const networkName = createRandomString(8)
const networkName = RANDOM_NETWORK_NAME;
await runCommand([
"create-gatekeeper-network",
networkName,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { BaseProvider } from "@ethersproject/providers";
import * as dotenv from "dotenv";
import { ethers, utils, Wallet } from "ethers";
import {runCommand} from '@oclif/test'
import { BNB_TESTNET_CONTRACT_ADDRESSES, createRandomString, FOUNDRY_DEFAULT_WALLET_ONE, FOUNDRY_DEFAULT_WALLET_TWO, GATEKEEPER_ON_TESTNET, GatewayNetworkClient, RANDOM_NETWORK_NAME, RANDOM_WALLET, testNetworkName } from "../../utils";
import assert = require('assert');
import { GatewayNetworkClass } from "@identity.com/gateway-evm-ts-client/dist/service/GatewayNetwork";
import { GatewayGatekeeper } from "@identity.com/gateway-evm-ts-client/dist/service/GatewayGatekeeper";
import "./add-gatekeeper.spec";
import { DidRegistry } from "@identity.com/did-bnb-client";

dotenv.config();

describe("Command: Upload gatekeeper service url config", function () {
let provider: BaseProvider;
let gatekeeper: Wallet;
let networkClient: GatewayNetworkClass;
let gatekeeperClient: GatewayGatekeeper;
let networkName: string;
let didRegistry: DidRegistry;

before("Initialize wallet", async function () {
this.timeout(20000);
provider = new ethers.providers.JsonRpcProvider("http://127.0.0.1:8545"); // Test run against local node forked

gatekeeper = FOUNDRY_DEFAULT_WALLET_ONE.connect(provider);
networkName = testNetworkName;
networkClient = GatewayNetworkClient(gatekeeper, BNB_TESTNET_CONTRACT_ADDRESSES.gatewayNetwork)
gatekeeperClient = new GatewayGatekeeper(gatekeeper, BNB_TESTNET_CONTRACT_ADDRESSES.gatekeeper);
didRegistry = new DidRegistry(gatekeeper, BNB_TESTNET_CONTRACT_ADDRESSES.didRegistry, { chainEnvironment: "testnet", gasLimit: 500000});
});

it("upload gatekeeper service url config", async function () {;

let data = await gatekeeperClient.getGatekeeperNetworkData(utils.formatBytes32String(networkName), gatekeeper.address);

console.log(`Gatekeeper on network ${networkName} : ${JSON.stringify(data)}`);

const testUrl = `http://${createRandomString(8)}.com`;

const result = await runCommand([
"update-gatekeeper-fees",
BNB_TESTNET_CONTRACT_ADDRESSES.didRegistry,
testUrl,
`--privateKey=${gatekeeper.privateKey}`,
`--gatewayKeeperContractAddress=${BNB_TESTNET_CONTRACT_ADDRESSES.gatekeeper}`,
`--chain=localhost`
])


console.log(`output: ${result.stdout}`)

const wasTxConfirmed = result.stdout.includes("Added gatekeeper to Gateway Token contract. TxHash:")
assert.equal(wasTxConfirmed, true, "Transaction should be confirmed on node")
assert.equal(result.error, undefined, "No errors should occur when creating network")

let did = await didRegistry.resolve();

let containsNewServiceUrl = did.service?.includes({
id: 'gateway-issuer',
type: "gateway-issuer",
serviceEndpoint: testUrl
})

assert.equal(did.service?.length! > 1, true, "gatekeeper should have more than 1 service")
assert.equal(containsNewServiceUrl, true, "gatekeeper should have new service url")
})
})
63 changes: 63 additions & 0 deletions gatekeeper-cli/src/test/integration/update-gatekeeper-fees.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { BaseProvider } from "@ethersproject/providers";
import * as dotenv from "dotenv";
import { ethers, utils, Wallet } from "ethers";
import {runCommand} from '@oclif/test'
import { BNB_TESTNET_CONTRACT_ADDRESSES, createRandomString, FOUNDRY_DEFAULT_WALLET_ONE, FOUNDRY_DEFAULT_WALLET_TWO, GATEKEEPER_ON_TESTNET, GatewayNetworkClient, RANDOM_NETWORK_NAME, RANDOM_WALLET, testNetworkName } from "../../utils";
import assert = require('assert');
import { GatewayNetworkClass } from "@identity.com/gateway-evm-ts-client/dist/service/GatewayNetwork";
import { GatewayGatekeeper } from "@identity.com/gateway-evm-ts-client/dist/service/GatewayGatekeeper";
import "./add-gatekeeper.spec";

dotenv.config();

describe("Command: Update gatekeeper fee configuration", function () {
let provider: BaseProvider;
let gatekeeper: Wallet;
let networkClient: GatewayNetworkClass;
let gatekeeperClient: GatewayGatekeeper;
let networkName: string;

before("Initialize wallet", async function () {
this.timeout(20000);
provider = new ethers.providers.JsonRpcProvider("http://127.0.0.1:8545"); // Test run against local node forked

gatekeeper = FOUNDRY_DEFAULT_WALLET_ONE.connect(provider);
networkName = testNetworkName;
networkClient = GatewayNetworkClient(gatekeeper, BNB_TESTNET_CONTRACT_ADDRESSES.gatewayNetwork)
gatekeeperClient = new GatewayGatekeeper(gatekeeper, BNB_TESTNET_CONTRACT_ADDRESSES.gatekeeper);
});

it("update gatekeeper fees for each operation on network", async function () {;

let data = await gatekeeperClient.getGatekeeperNetworkData(utils.formatBytes32String(networkName), gatekeeper.address);

console.log(`Gatekeeper on network ${networkName} : ${JSON.stringify(data)}`);

const result = await runCommand([
"update-gatekeeper-fees",
networkName,
`2500`,
"2500",
'2500',
`2500`,
`--privateKey=${gatekeeper.privateKey}`,
`--gatewayKeeperContractAddress=${BNB_TESTNET_CONTRACT_ADDRESSES.gatekeeper}`,
`--chain=localhost`
])


console.log(`output: ${result.stdout}`)

const wasTxConfirmed = result.stdout.includes("Added gatekeeper to Gateway Token contract. TxHash:")
assert.equal(wasTxConfirmed, true, "Transaction should be confirmed on node")
assert.equal(result.error, undefined, "No errors should occur when creating network")

data = await gatekeeperClient.getGatekeeperNetworkData(utils.formatBytes32String(networkName), gatekeeper.address);

console.log(JSON.stringify(data));

const answer = await networkClient.isGatekeeper(utils.formatBytes32String(networkName), gatekeeper.address);

assert.equal(answer, true, "gatekeeper should be on network")
})
})
11 changes: 9 additions & 2 deletions gatekeeper-cli/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ interface GatewayProtocolContractAddresses {
gatewayStaking: string,
erc20: string,
gatewayToken: string,
forwarder: string
forwarder: string,
didRegistry: string
}

export const BNB_TESTNET_CONTRACT_ADDRESSES: GatewayProtocolContractAddresses = {
Expand All @@ -21,12 +22,18 @@ export const BNB_TESTNET_CONTRACT_ADDRESSES: GatewayProtocolContractAddresses =
gatewayStaking: "0xf1311706736cf9e75992252e2ab2824f530f847b",
erc20: "0xf380c37eFf6c5ab0593927dFf4Bc7AF6428D541F",
gatewayToken: "0xc25e8e4fd1a892e6c6883ea8e6f3c3eb3b115f44",
forwarder: "0x96b905fF1eDfAdAEc03879450f3DC35a8124dc05"
forwarder: "0x96b905fF1eDfAdAEc03879450f3DC35a8124dc05",
didRegistry: "0x88a05b4370BbB90c9F3EEa72A65c77131a7bc18d"
}

export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
export const FOUNDRY_DEFAULT_WALLET_ONE = new Wallet("0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d") // 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
export const FOUNDRY_DEFAULT_WALLET_TWO = new Wallet("0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"); // 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC
export const RANDOM_WALLET = Wallet.createRandom();
export const GATEKEEPER_ON_TESTNET = new Wallet("0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6") // 0xa0ee7a142d267c1f36714e4a8f75612f20a79720

export const RANDOM_NETWORK_NAME = createRandomString(8);
export const testNetworkName = "Identity.com KYC Verification";
/////// Gateway Protocol Helps

///// Smart contract clients
Expand Down
15 changes: 15 additions & 0 deletions gatekeeper-cli/src/utils/oclif/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ export const gatewayNetworkAddressFlag = Flags.custom<string>({
description: 'GatewayNetwork address to target (or set GATEWAY_NETWORK_ADDRESS environment variable)',
})

export const gatekeeperContractAddressFlag = Flags.custom<string>({
char: 'a',
name: 'gateway-keeper-contract-address',
env: 'GATEWAY_GATEKEEPER_CONTRACT_ADDRESS',
parse: async (input: string) => {
if (!isAddress(input)) throw new Error('Invalid Gateway Gatekeeper contract address')
return input
},
required: false,
description: 'GatewayGatekeeper contract address to target (or set GATEWAY_GATEKEEPER_CONTRACT_ADDRESS environment variable)',
})

export const chainFlag = Flags.custom<BaseProvider>({
char: 'c',
name: 'chain',
Expand Down Expand Up @@ -104,6 +116,7 @@ type Flags = {
gatewayTokenAddress: string | undefined
gatewayNetworkAddress: string | undefined
gatekeeperNetwork: number | undefined
gatekeeperContractAddress?: string | undefined
fees?: GasPriceKey | undefined
gasLimit?: BigNumber | undefined
readOnly?: boolean | undefined
Expand All @@ -113,6 +126,7 @@ export const parseFlags = (flags: Flags) => {
const provider = flags.chain as Provider
const gatewayTokenAddress = flags.gatewayTokenAddress as string
const gatewayNetworkAddress = flags.gatewayNetworkAddress as string
const gatekeeperContractAddress = flags.gatekeeperContractAddress ? flags.gatekeeperContractAddress as string : undefined
const gatekeeperNetwork = BigInt(flags.gatekeeperNetwork as number)

return {
Expand All @@ -123,6 +137,7 @@ export const parseFlags = (flags: Flags) => {
fees: flags.fees,
gasLimit: flags.gasLimit,
readOnly: false,
gatekeeperContractAddress
}
}

Expand Down
Loading