Skip to content

Commit

Permalink
Merge pull request #472 from identity-com/develop
Browse files Browse the repository at this point in the history
Gateway Ethereum: Post Audit 2 Upgrade
  • Loading branch information
dankelleher authored Nov 15, 2023
2 parents 05d49c7 + f3a5087 commit 24ee1b3
Show file tree
Hide file tree
Showing 542 changed files with 129,143 additions and 2,519 deletions.
8 changes: 5 additions & 3 deletions .github/workflows/solana-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
matrix:
# This should match rust-toolchain.toml ( actions-rs/toolchain@v1 does not pick it up directly in monorepos )
rust: [ '1.66' ]
rust: [ '1.69' ]
os: [ ubuntu-latest ]

steps:
Expand Down Expand Up @@ -58,8 +58,8 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
rust: [ '1.66' ] # This should match rust-toolchain.toml ( actions-rs/toolchain@v1 does not pick it up directly in monorepos )
solana: [ 'v1.14.17' ]
rust: [ '1.69' ] # This should match rust-toolchain.toml ( actions-rs/toolchain@v1 does not pick it up directly in monorepos )
solana: [ 'edge' ]
os: [ ubuntu-latest ]

steps:
Expand Down Expand Up @@ -92,6 +92,8 @@ jobs:
run: |
sh -c "$(curl -sSfL https://release.solana.com/${{ matrix.solana }}/install)"
echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH
export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH"
solana --version
- name: Run unit tests
uses: actions-rs/cargo@v1
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/solana-ts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ jobs:
strategy:
matrix:
# This should match rust-toolchain.toml ( actions-rs/toolchain@v1 does not pick it up directly in monorepos )
rust: ["1.66"]
rust: ["1.69"]
node: ["16.x"]
solana: ["v1.14.17"]
solana: ["edge"]
os: [ubuntu-latest]

defaults:
Expand Down Expand Up @@ -92,6 +92,8 @@ jobs:
run: |
sh -c "$(curl -sSfL https://release.solana.com/${{ matrix.solana }}/install)"
echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH
export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH"
solana --version
- name: Build Solana program
uses: actions-rs/cargo@v1
Expand Down
24 changes: 24 additions & 0 deletions ethereum/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,30 @@ Of the upgradeability standards available, the EIP-1822 (UUPS) standard was chos
The upgrade key (the key used to upgrade the protocol) is set to an Identity.com key on deployment. It can be rotated by a
superadmin. The superadmin can also disable upgradeability.

## Additional Features

### Token Flags

The Gateway Protocol includes a global namespace of token flags, which can be set by the gatekeeper when issuing a token.

The flags are stored as a bitmask, and can be used to indicate additional information about the token.

Examples are:
- a "negative reputation" flag, which indicates that the token should be treated as a form of blacklist
- a "verified human" flag, which indicates that the token holder has been verified to be a human
- a "verified over 18" flag, which indicates that the token holder has been verified to be over 18 years of age
- a region flag, which indicates that the token holder is a resident of a particular region

This model has two advantages over storing this information in the token type:
- it allows gatekeepers to issue tokens with multiple flags,
without needing to create a new token type for each combination
- it allows clients to accept tokens from multiple gatekeeper networks,
if those tokens share common properties.

The flag namespace is managed by Identity.com. Gatekeepers can set and unset flags on their tokens at any time.

To request a new flag be added to the namespace, please contact identity.com via [www.identity.com](www.identity.com).

## Glossary

- Gateway Token
Expand Down
240 changes: 159 additions & 81 deletions ethereum/gatekeeper-cli/README.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions ethereum/gatekeeper-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@identity.com/gateway-eth-cli",
"version": "0.1.1",
"version": "0.2.2-alpha.1",
"description": "Identity.com Gateway Protocol EVM CLI",
"author": "dankelleher @dankelleher",
"bin": {
Expand All @@ -25,7 +25,7 @@
"@ethersproject/units": "^5.7.0",
"@ethersproject/wallet": "^5.7.0",
"@ethersproject/web": "^5.7.1",
"@identity.com/gateway-eth-ts": "0.7.1",
"@identity.com/gateway-eth-ts": "0.8.1-alpha.3",
"@oclif/core": "^1.23.2",
"@oclif/dev-cli": "^1.26.10",
"@oclif/plugin-help": "^5",
Expand Down Expand Up @@ -65,7 +65,7 @@
"version": "oclif readme && git add README.md"
},
"engines": {
"node": ">=14.0.0"
"node": ">=16.14.0"
},
"bugs": "https://github.com/identity-com/on-chain-identity-gateway/issues",
"keywords": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class CreateGatekeeperNetwork extends Command {
static description = 'Create a new gatekeeper network';

static examples = [
`$ gateway-eth create-gatekeeper-network <name> <number>
`$ gateway-eth create-gatekeeper-network <number> <name>
`,
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default class GetGatekeeperNetwork extends Command {
async run(): Promise<void> {
const {args, flags} = await this.parse(GetGatekeeperNetwork)

const parsedFlags = parseFlags({...flags, gatekeeperNetwork: DEFAULT_GATEKEEPER_NETWORK})
const parsedFlags = parseFlags({...flags, readOnly: true, gatekeeperNetwork: DEFAULT_GATEKEEPER_NETWORK})

const gateway = await makeGatewayTs(parsedFlags)
const name = await gateway.getGatekeeperNetwork(args.id)
Expand Down
2 changes: 1 addition & 1 deletion ethereum/gatekeeper-cli/src/commands/get-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default class GetToken extends Command {
const {args, flags} = await this.parse(GetToken)

const ownerAddress = args.address as string
const parsedFlags = parseFlags(flags)
const parsedFlags = parseFlags({...flags, readOnly: true})

this.log(`Getting token for ${ownerAddress}`)

Expand Down
30 changes: 30 additions & 0 deletions ethereum/gatekeeper-cli/src/commands/issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
import {makeGatewayTs} from '../utils/oclif/utils'
import {addressArg} from '../utils/oclif/args'
import {BigNumber} from '@ethersproject/bignumber'
import {makeWeiCharge} from '@identity.com/gateway-eth-ts/dist/utils/charge'
import {Wallet} from '@ethersproject/wallet'

export default class IssueToken extends Command {
static description =
Expand All @@ -34,6 +36,19 @@ export default class IssueToken extends Command {
required: false,
description: 'TokenURI to link with the issued token',
}),
forwarder: Flags.string({
char: 'x',
name: 'forwarder',
required: false,
description: 'Forward the transaction to the forwarder contract',
}),
charge: Flags.custom<BigNumber>({
char: 'a',
name: 'charge',
required: false,
parse: async (input: string) => BigNumber.from(input),
description: 'Charge in native tokens for the transaction',
})(),
};

static args = [
Expand All @@ -58,6 +73,21 @@ export default class IssueToken extends Command {

const gateway = await makeGatewayTs(parsedFlags)

if (flags.forwarder) {
const charge = (flags.charge) ?
makeWeiCharge(flags.charge, (gateway.providerOrWallet as Wallet).address) :
undefined

const tx = await gateway
.forward(flags.forwarder)
.issue(ownerAddress, parsedFlags.gatekeeperNetwork, expiry, bitmask, charge)

this.log(`Transaction data: ${tx.data}`)
this.log(`Recipient: ${tx.to}`)
this.log(`Value: ${tx.value}`)
return
}

const sendableTransaction = await gateway.issue(
ownerAddress, parsedFlags.gatekeeperNetwork, expiry, bitmask,
)
Expand Down
2 changes: 1 addition & 1 deletion ethereum/gatekeeper-cli/src/commands/listen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default class GetToken extends Command {
const {args, flags} = await this.parse(GetToken)

const ownerAddress = args.address as string
const parsedFlags = parseFlags(flags)
const parsedFlags = parseFlags({...flags, readOnly: true})

this.log(`Getting token for ${ownerAddress}`)

Expand Down
53 changes: 53 additions & 0 deletions ethereum/gatekeeper-cli/src/commands/rename-gatekeeper-network.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {Command, Flags} from '@oclif/core'

import {makeGatewayTs} from '../utils/oclif/utils'
import {
confirmationsFlag, DEFAULT_GATEKEEPER_NETWORK,
feesFlag, gatewayTokenAddressFlag, chainFlag, parseFlagsWithPrivateKey,
privateKeyFlag, gasLimitFlag,
} from '../utils/oclif/flags'

export default class RenameGatekeeperNetwork extends Command {
static description = 'Rename a gatekeeper network';

static examples = [
`$ gateway-eth rename-gatekeeper-network <name> <number>
`,
];

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

static args = [
{name: 'id', required: true, description: 'ID of the new network'},
{name: 'name', required: true, description: 'New name of the new network'},
];

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

const confirmations = flags.confirmations

const parsedFlags = parseFlagsWithPrivateKey({...flags, gatekeeperNetwork: DEFAULT_GATEKEEPER_NETWORK})

this.log(`Renaming gatekeeper network:
id ${args.id}
name ${args.name}`)

const gateway = await makeGatewayTs(parsedFlags)
const sendableTransaction = await gateway.renameNetwork(args.name, BigInt(args.id))

const receipt = await sendableTransaction.wait(confirmations)

this.log(
`Renamed Gatekeeper Network. TxHash: ${receipt.transactionHash}`,
)
}
}
2 changes: 2 additions & 0 deletions ethereum/gatekeeper-cli/src/utils/oclif/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ type Flags = {
gatekeeperNetwork: number | undefined
fees?: GasPriceKey | undefined
gasLimit?: BigNumber | undefined
readOnly?: boolean | undefined
};
export const parseFlags = (flags: Flags) => {
// These all have defaults and can therefore be safely cast
Expand All @@ -106,6 +107,7 @@ export const parseFlags = (flags: Flags) => {
gatekeeperNetwork,
fees: flags.fees,
gasLimit: flags.gasLimit,
readOnly: false,
}
}

Expand Down
16 changes: 16 additions & 0 deletions ethereum/gatekeeper-cli/src/utils/oclif/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export const networks = {
url: 'https://arbitrum-goerli.infura.io/v3/',
chainId: 421_613,
},
arbitrumSepolia: {
url: 'https://sepolia-rollup.arbitrum.io/rpc',
chainId: 421_614,
},
arbitrum: {
url: 'https://arbitrum-mainnet.infura.io/v3/',
chainId: 42_161,
Expand Down Expand Up @@ -109,6 +113,10 @@ export const networks = {
url: 'https://rpc.fantom.network',
chainId: 250,
},
fantomTestnet: {
url: 'https://rpc.testnet.fantom.network',
chainId: 4002,
},
gnosis: {
url: 'https://rpc.gnosischain.com',
chainId: 100,
Expand All @@ -129,6 +137,14 @@ export const networks = {
url: 'https://zkevm-rpc.com',
chainId: 1101,
},
baseSepolia: {
url: 'https://sepolia.base.org',
chainId: 84_532,
},
base: {
url: 'https://base.llamarpc.com',
chainId: 8453,
},
}

class ExtendedInfuraProvider extends InfuraProvider {
Expand Down
8 changes: 5 additions & 3 deletions ethereum/gatekeeper-cli/src/utils/oclif/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ export const makeGatewayTs = async ({
gatewayTokenAddress,
fees,
gasLimit,
}: { provider: Provider, privateKey?: string, gatewayTokenAddress: string, fees?: GasPriceKey, gasLimit?: BigNumber }):Promise<GatewayTs> => {
readOnly = false,
}: { provider: Provider, privateKey?: string, gatewayTokenAddress: string, fees?: GasPriceKey, gasLimit?: BigNumber, readOnly: boolean }):Promise<GatewayTs> => {
const signer = privateKey ? getSigner(privateKey, provider) : undefined
const feeAmount = await estimateGasPrice(provider, fees)
return new GatewayTs(signer || provider, gatewayTokenAddress, {...feeAmount, gasLimit})
const feeAmount = readOnly ? {} : await estimateGasPrice(provider, fees)
const providerOrWallet = readOnly ? provider : signer || provider
return new GatewayTs(providerOrWallet, gatewayTokenAddress, {...feeAmount, gasLimit})
}

export const checkedGetToken = async (
Expand Down
8 changes: 4 additions & 4 deletions ethereum/gatekeeper-cli/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -600,10 +600,10 @@
resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz"
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==

"@identity.com/gateway-eth-ts@0.7.1":
version "0.7.1"
resolved "https://registry.yarnpkg.com/@identity.com/gateway-eth-ts/-/gateway-eth-ts-0.7.1.tgz#56f8e93d47a789bfcbb615fe6cb97c00ee0eb958"
integrity sha512-fMCsVYOGEylttA+ZcWtt/SnOw+O1o+D6Kgsy1yKX7Vo3tQhACjk4VNxF6c7/bkuaYrh0shGoRYCGEKPDqbR00w==
"@identity.com/gateway-eth-ts@0.8.1-alpha.3":
version "0.8.1-alpha.3"
resolved "https://registry.yarnpkg.com/@identity.com/gateway-eth-ts/-/gateway-eth-ts-0.8.1-alpha.3.tgz#d08e27d16d4de376f08c4ffe111d15295a320b0e"
integrity sha512-GtqQ5tpy3oPBYgHCRke+gpZQCId9ck3dDSSWzzdu7gOMJ/2CzjKmZXU2WeRHqvJsxXCh5/FSGLpcDyrloXl8pw==
dependencies:
"@ethersproject/abi" "^5.7.0"
"@ethersproject/abstract-signer" "^5.7.0"
Expand Down
13 changes: 8 additions & 5 deletions ethereum/gateway-eth-ts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,15 @@ const charge = makeERC20Charge(
);
const approvalTx = await approveERC20Charge(
charge,
provider,
DEFAULT_GATEWAY_TOKEN_ADDRESS
provider
);

// send approvalTx to the user to sign
// once the user has signed the above
const internalApproveTx = await approveInternalERC20Charge(
charge,
gatekeeperNetwork,
provider
);
// send approvalTx and approveInternalTx to the user to sign
// once the user has signed the above transactions

const gateway = new GatewayTs(
gatekeeper,
Expand Down
2 changes: 1 addition & 1 deletion ethereum/gateway-eth-ts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@identity.com/gateway-eth-ts",
"version": "0.7.1",
"version": "0.8.1-alpha.3",
"description": "Adapter library for Identity.com gateway token system on Ethereum",
"main": "dist/index.js",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"_format": "hh-sol-dbg-1",
"buildInfo": "../../build-info/ef6a6ff54ef252fafc7b6ec8743a33dc.json"
"buildInfo": "../../build-info/b3a5313a52c225a35e47d8376069d6d0.json"
}
Loading

0 comments on commit 24ee1b3

Please sign in to comment.