Quick start
The safest integration pattern is: create or select an immutable policy, create an exact intent, evaluate it through consensus, wait for the lifecycle point your application requires, then rely on authorization only after an exact currentness read.
1. Install the matching client
npm install genlayer-jsFor Studio Dev / Consensus v0.6 preview, use the explicit v2.0 release candidate published by GenLayer rather than assuming the default npm tag resolves to a prerelease.
2. Create a Studio Dev client
For browser writes, use the connected wallet address with its EIP-1193 provider and ensure the wallet is on the same Studio Dev chain definition before signing.
import { createClient, isSuccessful } from 'genlayer-js';
import { studioDevnet } from 'genlayer-js/chains';
const client = createClient({
chain: studioDevnet,
account: walletAddress,
provider: window.ethereum,
});
const POLICYFUSE = '0xF5066aE61456b1ADEC4871Da1650F64F1aE5C43F';estimateTransactionFeesForWrite is appropriate for development/profiling. For production application flows, GenLayer recommends a measured, checked-in fee profile or Transaction Kit rather than simulating every user click.3. Create an exact intent
The action core should contain only the consequence-bearing data your policy is written to evaluate. Keep clarification separate so repair can add context without silently replacing the action.
const call = {
address: POLICYFUSE,
functionName: 'create_intent',
args: [policyId, consumer, 'VERIFY', actionCoreJson, clarification, deadline],
};
const estimate = await client.estimateTransactionFeesForWrite(call);
const txId = await client.writeContract({
...call,
fees: { distribution: estimate.distribution, feeValue: estimate.feeValue },
});
const createReceipt = await client.waitForFinalization({ hash: txId });
if (!isSuccessful(createReceipt)) {
throw new Error(`Intent creation failed: ${createReceipt.statusName} / ${createReceipt.txExecutionResultName}`);
}4. Evaluate through consensus
const evaluate = {
address: POLICYFUSE,
functionName: 'evaluate_intent',
args: [intentId],
};
const fees = await client.estimateTransactionFeesForWrite(evaluate);
const evaluationTx = await client.writeContract({
...evaluate,
fees: { distribution: fees.distribution, feeValue: fees.feeValue },
});
const evaluationReceipt = await client.waitForFinalization({ hash: evaluationTx });
if (!isSuccessful(evaluationReceipt)) {
throw new Error(`Evaluation failed: ${evaluationReceipt.statusName} / ${evaluationReceipt.txExecutionResultName}`);
}5. Read the verdict from durable state
import { TransactionHashVariant } from 'genlayer-js/types';
const verdict = await client.readContract({
address: POLICYFUSE,
functionName: 'get_verdict',
args: [intentId],
transactionHashVariant: TransactionHashVariant.LATEST_FINAL,
});6. Before acting, verify exact currentness
const current = await client.readContract({
address: POLICYFUSE,
functionName: 'is_authorization_current_for',
args: [authorizationId, consumer, actionCoreDigest],
transactionHashVariant: TransactionHashVariant.LATEST_FINAL,
});
if (!current) {
throw new Error('PolicyFuse authorization is not current');
}
// Only now attach your application's consequence.