Condition Context
A ConditionContext
is a container for dynamic values to be used in conditions at verification time. A ConditionContext
contains ContextVariables
and their corresponding values.
Context Variables
Context variables can be recognized by the :
prefix. They act as placeholders within conditions to be specified at the condition definition, whose value is provided at verifiction time.
Context variables are broken up into two groups:
Reserved context variables: these have special functionality within
taco
:which requires the use of Authentication Providers to provide verifiable proof of wallet address ownership specified by the data consumer. Applications should be cognizant of which reserved context variable they use based on their needs.
Custom context variables: these are application-specific, simple key-value pairs where the data consumer can directly specify the values without any verification.
:userAddress
:userAddress
Whenever the :userAddress
context variable is present in a condition, the requester must use one of the following authentication providers for proof of wallet ownership:
EIP4361AuthProvider
: Prompts the user to sign an EIP-4361 (Sign-in With Ethereum) message to authenticate the data consumer's wallet address at verification time.
SingleSignOnEIP4361AuthProvider
: Designed for applications that have already integrated Sign-in With Ethereum (SIWE), this provider leverages the existing login signature and message. It enables users to authenticate once with the application and seamlessly reuse that authentication with TACo, eliminating the need to sign multiple messages during execution.
TACo requires that Sign-In With Ethereum (SIWE) messages be issued within the last 2 hours based on the "Issued At" timestamp. For single sign-on usage, the application should refresh the user's cached SIWE login accordingly.
EIP1271AuthProvider
: Intended for scenarios where the user account is a smart contract wallet that implements EIP-1271.
This signature produced by the authentication providers are provided to nodes to prove wallet address ownership when evaluating conditions.
Illustrative Example
Let's take a look at this ContractConditon
example:
import { conditions } from '@nucypher/taco';
const ownsNFTRaw = new conditions.contract.ContractCondition({
method: 'balanceOf',
parameters: [':userAddress'], // <- A context variable
standardContractType: 'ERC721',
contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77',
chain: 1,
returnValueTest: {
comparator: '>',
value: ':selectedBalance', // <- Another context variable
},
});
In this example, we can see two different context variables
:userAddress
- A reserved context variable:selectedBalance
- A custom context variable
To replace the :userAddress
context variable with an actual wallet address during verification, TACo needs to be provided with an AuthProvider
to confirm wallet ownership at the condition verification time.
Additionally, the :selectedBalance
custom context variable has to be provided to the TACo operation by the requester.
Both context variables need to be provided to a ConditionContext
which is then used by the node during verification.
import { conditions } from '@nucypher/taco';
import { SingleSignOnEIP4361AuthProvider, USER_ADDRESS_PARAM_DEFAULT } from '@nucypher/taco-auth';
const web3Provider = new ethers.providers.Web3Provider(window.ethereum);
const conditionContext =
conditions.context.ConditionContext.fromMessageKit(messageKit);
// satisfy ":userAddress"
const {messageStr, signature} = ...; // existing SIWE information from application
const authProvider = SingleSignOnEIP4361AuthProvider.fromExistingSiweInfo(
messageStr,
signature,
);
conditionContext.addAuthProvider(USER_ADDRESS_PARAM_DEFAULT, authProvider);
// satisfy ":selectedBalance"; simple key-value pair
const customParameters: Record<string, conditions.CustomContextParam> = {
':selectedBalance': 2,
};
conditionContext.addCustomContextParameterValues(customParameters);
// TACo operation
With those context parameters, the condition will be evaluated by nodes at verification time to be:
{
method: 'balanceOf',
parameters: ['0x...'], // The address of requester's wallet (verified via signature)
standardContractType: 'ERC721',
contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77',
chain: 1,
returnValueTest: {
comparator: '>',
value: 2, // Concrete value to be used in comparison
},
}
Checking for required context variables
If your application utilizes many different conditions each with different context variables, the required context variables for verification can be queried.
The requestedContextParameters
property of the ConditionContext
object can be used to identify the necessary context variables for verification. By querying this property, the application can understand the context variables required for the relevant condition.
In this way, the application doesn't need prior knowledge of the condition used but can dynamically determine the context variables needed based on the specific condition being handled.
// create condition context
const conditionContext = conditions.context.ConditionContext.fromMessageKit(messageKit);
// illustrative optional example of checking what context parameters are required
if (
conditionContext.requestedContextParameters.has(USER_ADDRESS_PARAM_DEFAULT)
) {
// add authentication for ":userAddress" in condition
const authProvider = ...;
conditionContext.addAuthProvider(USER_ADDRESS_PARAM_DEFAULT, authProvider);
}
if (
conditionContext.requestedContextParameters.has(":selectedBalance")
) {
// satisfy ":selectedBalance"; simple key-value pair
const customParameters: Record<string, conditions.CustomContextParam> = {
':selectedBalance': 2,
};
conditionContext.addCustomContextParameterValues(customParameters);
}
// other context variable checks ...
Learn more
Last updated