On-Chain Integration
Your on-chain smart contract has to check for a valid Civic Pass during program execution and reject transactions from non-compliant users (i.e. those without an active Civic Pass).
For each blockchain supported by Civic Pass, we provide you with a library that is tailored to the programming model of that chain.
Solana
Ethereum / Polygon / Arbitrum / XDC
Import the
solana_gateway
Rust crate from crates.io and call Gateway::verify_gateway_token_account_info
For your program to be able to call the integration library, the following parameters must be passed as inputs to your dApp's transaction:
userWallet
: The wallet account for the dApp user. A Civic Pass must have already been issued to this wallet.gateway_token
: The address of the Civic Pass. This address can be accessed in the dApp through theuseGateway
hook on the Civic React Component once the user has passed verification.gatekeeper_network
: The Gatekeeper Network on which the Civic Pass has been issued.
use solana_gateway::Gateway;
// This check happens before the dApp transaction is processed
fn process() -> ProgramResult {
// The owner of the gateway token
let user_wallet: AccountInfo;
// The gateway token presented by the owner
let gateway_token: AccountInfo;
// The gatekeeper network key
let gatekeeper_network: Pubkey;
// Check the token is valid. An error here means the token
// is not valid for the user's wallet on the gateway network.
Gateway::verify_gateway_token_account_info(
&gateway_token_account_info, &userWallet.key, &gatekeeper
)?;
Ok(())
}
If something goes wrong or the token it invalid, the Gateway call will return a
GatewayError
. The possible values can be seen in error.rs. For error cases, the dApp smart contract should reject the transaction.Integrating a Civic Pass check in your EVM smart contract is simple:
First, import the contract dependencies:
npm install @identity.com/gateway-protocol-eth
Then, in your smart contract, inherit the Gated contract, and add the 'gated' modifier to any function. The function can only be called by a msg.sender that has a valid gateway token.
import "@identity.com/gateway-protocol-eth/contracts/Gated.sol";
// Your contract
contract MyContract is Gated {
constructor(address gatewayTokenContract, uint256 gatekeeperNetwork)
Gated(gatewayTokenContract, gatekeeperNetwork) {
}
function myFunction() external gated {
}
}
The gateway token contract address is
0xF65b6396dF6B7e2D8a6270E3AB6c7BB08BAEF22E
If you want more control over the verification process on-chain, you can use the following code instead of the Gated contract:
import "@identity.com/gateway-protocol-eth/contracts/interfaces/IGatewayTokenVerifier.sol";
...
IGatewayTokenVerifier verifier = IGatewayTokenVerifier(gatewayTokenContract);
if (!verifier.verifyToken(addressToVerify, gatekeeperNetwork)) {
// some logic
}
Last modified 19d ago