Skip to content

Commit

Permalink
Add cli commands to allow gatekeepers to manage tokens (#59)
Browse files Browse the repository at this point in the history
* add command to allow gatekeeper to issue tokens on a given network

* Command to verify an address on a network

* Make input to refresh partial

* Refresh token cli command

* Add freeze and unfreeze commands

* add cli call to fetch token

* Added command to fetch token data

* Add integration test for a gatekeeper issuing a token via cli

* Generate did if not initialized

* Final test for token operations

---------

Robert Leonard
  • Loading branch information
Robert-H-Leonard authored Jul 16, 2024
1 parent 73bd5dd commit 7761f2e
Show file tree
Hide file tree
Showing 12 changed files with 718 additions and 3 deletions.
58 changes: 58 additions & 0 deletions gatekeeper-cli/src/commands/fetch-token-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {
confirmationsFlag,
feesFlag, gatekeeperNetworkFlag,
gatewayTokenAddressFlag,
chainFlag, parseFlagsWithPrivateKey,
privateKeyFlag, gasLimitFlag,
gatewayNetworkAddressFlag,
} from '../utils/oclif/flags'
import {Args, Command, Flags} from '@oclif/core'
import {makeGatewayNetworkTs, makeGatewayTs} from '../utils/oclif/utils'
import { utils } from 'ethers';

export default class FetchTokenId extends Command {
static description = 'Fetch the token id for a given address on a given gateway network';

static examples = [
`$ gateway-eth freeze-token 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 = {
tokenOwner: Args.string({name: 'tokenOwner', required: true, description: 'Owner of the specified gateway token'}),
networkName: Args.string({name: 'networkName', required: true, description: 'Name of the network'}),
onlyActive: Args.boolean({name: 'onlyActive', required: false, description: "Flag to indicate only fetching an active token id"})
}

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

const tokenOwner: string = args.tokenOwner
const parsedFlags = parseFlagsWithPrivateKey(flags)


const gatewayNetwork = await makeGatewayNetworkTs(parsedFlags)
const gatewayTokenTs = await makeGatewayTs(parsedFlags)

const networkId = await gatewayNetwork.getNetworkId(args.networkName);
const tokenId = await gatewayTokenTs.getTokenId(tokenOwner, networkId.valueOf() as bigint, args.onlyActive);


this.log(
`Fetched token id ${tokenId}`
)
}
}

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

export default class FetchTokenId extends Command {
static description = 'Fetch the token id for a given address on a given gateway network';

static examples = [
`$ gateway-eth freeze-token 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 = {
tokenOwner: Args.string({name: 'tokenOwner', required: true, description: 'Owner of the specified gateway token'}),
networkName: Args.string({name: 'networkName', required: true, description: 'Name of the network'}),
onlyActive: Args.boolean({name: 'onlyActive', required: false, description: "Flag to indicate only fetching an active token id"})
}

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

const tokenOwner: string = args.tokenOwner
const parsedFlags = parseFlagsWithPrivateKey(flags)


const gatewayNetwork = await makeGatewayNetworkTs(parsedFlags)
const gatewayTokenTs = await makeGatewayTs(parsedFlags)

const networkId = await gatewayNetwork.getNetworkId(utils.formatBytes32String(args.networkName));
const tokenData = await gatewayTokenTs.getFirstTokenOnNetwork(tokenOwner, networkId.valueOf() as bigint, args.onlyActive);


this.log(
`Fetched token ${JSON.stringify(tokenData)}`
)
}
}

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

export default class FreezeToken extends Command {
static description = 'Gatekeeper can freeze tokens they issued';

static examples = [
`$ gateway-eth freeze-token 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 = {
tokenOwner: Args.string({name: 'tokenOwner', required: true, description: 'Owner of the specified gateway token'}),
networkName: Args.string({name: 'networkName', required: true, description: 'Name of the network'}),
}

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

const tokenOwner: string = args.tokenOwner
const parsedFlags = parseFlagsWithPrivateKey(flags)


const gatewayNetwork = await makeGatewayNetworkTs(parsedFlags)
const gatewayTokenTs = await makeGatewayTs(parsedFlags)

const networkId = await gatewayNetwork.getNetworkId(args.networkName);
const sendableTransaction = await gatewayTokenTs.freeze(tokenOwner, networkId.valueOf() as bigint)

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

this.log(
`Froze gateway token. TxHash: ${receipt.transactionHash}`,
)
}
}

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

export default class IssueToken extends Command {
static description = 'Gatekeepers can issue tokens on their respective networks';

static examples = [
`$ gateway-eth issue-token 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 = {
tokenOwner: Args.string({name: 'tokenOwner', required: true, description: 'Owner of the specified gateway token'}),
networkName: Args.string({name: 'networkName', required: true, description: 'Name of the network'}),
expirationTimeInSeconds: Args.integer({name: 'expirationTimeInSeconds', required: true, description: "The amount of time in seconds before a token expires. Default value is set to 0. Network primary authority can override this value"}),
feeSender: Args.string({name: 'feeSender', required: true, description: "Address that will be paying the fee"}),
chargeType: Args.string({name: "chargeType", required: true, description: "Supproted types are: NONE, ETH and ERC20. This is set by the network"}),
feeValue: Args.integer({name: "feeValue", required: true, description: "Value charged to fee sender. They must approve before hand"})
}

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

const tokenOwner: string = args.tokenOwner
const parsedFlags = parseFlagsWithPrivateKey(flags)

this.log(`Issuing token for address: ${tokenOwner} on network ${args.networkName}`)



const gatewayNetwork = await makeGatewayNetworkTs(parsedFlags)
const gatewayTokenTs = await makeGatewayTs(parsedFlags)

const networkId = await gatewayNetwork.getNetworkId(args.networkName);
const feeRecipient = (new Wallet(parsedFlags.privateKey)).address

this.log(`Issuing token for address: ${tokenOwner} on network ${args.networkName}`)
const sendableTransaction = await gatewayTokenTs.issue(
tokenOwner,
networkId.valueOf() as bigint,
args.expirationTimeInSeconds,
0,
{feeRecipient , feeSender: args.feeSender},
{
tokenSender: args.feeSender,
recipient: feeRecipient
}
)

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

this.log(
`Issued gateway token to use. TxHash: ${receipt.transactionHash}`,
)
}
}

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

export default class RefreshToken extends Command {
static description = 'Gatekeepers can refresh tokens (such as setting a new expire time) on their respective networks';

static examples = [
`$ gateway-eth issue-token 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 = {
tokenOwner: Args.string({name: 'tokenOwner', required: true, description: 'Owner of the specified gateway token'}),
networkName: Args.string({name: 'networkName', required: true, description: 'Name of the network'}),
expirationTimeInSeconds: Args.integer({name: 'expirationTimeInSeconds', required: true, description: "The amount of time in seconds before a token expires. Default value is set to 0. Network primary authority can override this value"}),
feeSender: Args.string({name: 'feeSender', required: true, description: "Address that will be paying the fee"}),
chargeType: Args.string({name: "chargeType", required: true, description: "Supproted types are: NONE, ETH and ERC20. This is set by the network"}),
feeValue: Args.integer({name: "feeValue", required: true, description: "Value charged to fee sender. They must approve before hand"})
}

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

const tokenOwner: string = args.tokenOwner
const parsedFlags = parseFlagsWithPrivateKey(flags)


const gatewayNetwork = await makeGatewayNetworkTs(parsedFlags)
const gatewayTokenTs = await makeGatewayTs(parsedFlags)

const networkId = await gatewayNetwork.getNetworkId(args.networkName);
const feeRecipient = (new Wallet(parsedFlags.privateKey)).address
const sendableTransaction = await gatewayTokenTs.refresh(
tokenOwner,
networkId.valueOf() as bigint,
{feeRecipient , feeSender: args.feeSender},
args.expirationTimeInSeconds,
{
tokenSender: args.feeSender,
recipient: feeRecipient
}
)

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

this.log(
`Refreshed gateway token. TxHash: ${receipt.transactionHash}`,
)
}
}

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

export default class RevokeToken extends Command {
static description = 'Gatekeeper can revoke tokens they issued';

static examples = [
`$ gateway-eth revoke-token 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 = {
tokenOwner: Args.string({name: 'tokenOwner', required: true, description: 'Owner of the specified gateway token'}),
networkName: Args.string({name: 'networkName', required: true, description: 'Name of the network'}),
}

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

const tokenOwner: string = args.tokenOwner
const parsedFlags = parseFlagsWithPrivateKey(flags)


const gatewayNetwork = await makeGatewayNetworkTs(parsedFlags)
const gatewayTokenTs = await makeGatewayTs(parsedFlags)

const networkId = await gatewayNetwork.getNetworkId(args.networkName);
const sendableTransaction = await gatewayTokenTs.revoke(tokenOwner, networkId.valueOf() as bigint)

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

this.log(
`Revoked gateway token. TxHash: ${receipt.transactionHash}`,
)
}
}

Loading

0 comments on commit 7761f2e

Please sign in to comment.