RuleBuilder
The RuleBuilder provides a fluent API for constructing individual rules within a policy.
RuleBuilder uses the builder pattern to create rules step-by-step with method chaining. This provides a more intuitive and type-safe way to construct rules compared to manually creating rule objects. The builder ensures that rules are constructed correctly and validates certain constraints at build time.
Examples
// Basic permit rule
const rule = new RuleBuilder()
.permit('USE')
.withDescription('Allow general usage')
.build();
// Time-limited reproduction with payment
const reproductionRule = new RuleBuilder()
.permit('REPRODUCE')
.withDescription('Allow reproduction for one year with payment')
.withConstraint({
type: 'TIME_PERIOD',
value: {
start: Math.floor(Date.now() / 1000),
end: Math.floor(Date.now() / 1000) + 31536000 // One year
}
})
.withDuty({
type: 'PAYMENT',
value: {
amount: '100.00',
currency: 'USD',
recipient: '0xCreatorAddress'
}
})
.build();
// Prohibition rule
const prohibitRule = new RuleBuilder()
.prohibit('COMMERCIALIZE')
.withDescription('No commercial use allowed')
.build();
// Complex rule with multiple constraints and duties
const complexRule = new RuleBuilder()
.permit('MODIFY')
.withDescription('Token holders can modify with attribution')
.withConstraint({
type: 'TOKEN_GATED',
value: {
chainId: 1,
contractAddress: '0xNFTContract',
minBalance: 1
}
})
.withConstraint({
type: 'USAGE_COUNT',
value: 10
})
.withDuty({
type: 'ATTRIBUTION',
value: 'Based on original work by Artist Name'
})
.withDuty({
type: 'SHARE_ALIKE',
value: 'ipfs://QmOriginalPolicy...'
})
.build();
Definition
class RuleBuilder {
constructor();
permit(action: string): this;
prohibit(action: string): this;
withDescription(description: string): this;
withConstraint(constraint: Constraint): this;
withDuty(duty: Duty): this;
withPaymentSplit(options: PaymentSplitOptions): this;
withPaymentSplitPercentage(total: string | number, currency: string, splits: Record): this;
}
Constructor
Methods
permit
Sets the action and a 'permit' effect for the rule.
This method creates a permission rule that allows the specified action.
Cannot be used together with prohibit() on the same builder instance.
permit(action: string): this
Parameters:
action(string) - The action to permit. Use values from Action or custom URIs.
Returns: this
This RuleBuilder instance for method chaining
Examples
// Using standard action
builder.permit('USE');
builder.permit('TRANSFER');
// Using custom action URI
builder.permit('https://example.com/actions/download');
prohibit
Sets the action and a 'prohibit' effect for the rule.
This method creates a prohibition rule that forbids the specified action.
Prohibition rules cannot have duties attached to them.
Cannot be used together with permit() on the same builder instance.
prohibit(action: string): this
Parameters:
action(string) - The action to prohibit. Use values from Action or custom URIs.
Returns: this
This RuleBuilder instance for method chaining
Examples
// Prohibit commercial use
builder.prohibit('COMMERCIALIZE');
// Prohibit custom action
builder.prohibit('https://example.com/actions/resell');
withDescription
Adds a human-readable description to the rule.
Descriptions help explain the intent and purpose of a rule. They are particularly useful for complex rules with multiple constraints or duties, or when the rule logic needs clarification.
withDescription(description: string): this
Parameters:
description(string) - A clear, concise description of the rule's purpose
Returns: this
This RuleBuilder instance for method chaining
Examples
builder
.permit('REPRODUCE')
.withDescription('Allow reproduction for educational purposes only');
builder
.prohibit('TRANSFER')
.withDescription('Asset cannot be transferred or sold to third parties');
withConstraint
Adds a constraint to the rule.
Constraints define conditions that must be met for the rule to apply. Multiple constraints can be added, and ALL must be satisfied (AND logic). Constraints can be standard types from the vocabulary or custom URIs.
withConstraint(constraint: Constraint): this
Parameters:
constraint(Constraint) - The constraint object with type and value
Returns: this
This RuleBuilder instance for method chaining
Examples
// Add time period constraint
builder.withConstraint({
type: 'TIME_PERIOD',
value: {
start: 1704067200, // Jan 1, 2024
end: 1735689599 // Dec 31, 2024
}
});
// Add token gate constraint
builder.withConstraint({
type: 'TOKEN_GATED',
value: {
chainId: 1,
contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
minBalance: 1
}
});
// Add multiple constraints
builder
.withConstraint({ type: 'USAGE_COUNT', value: 100 })
.withConstraint({ type: 'SPATIAL', value: 'US' });
withDuty
Adds a duty to the rule. Only applicable to 'permit' rules.
Duties are obligations that must be fulfilled to exercise a permission. Multiple duties can be added, and ALL must be fulfilled. Attempting to add duties to a 'prohibit' rule will throw an error.
withDuty(duty: Duty): this
Parameters:
duty(Duty) - The duty object with type and value
Returns: this
This RuleBuilder instance for method chaining
Throws:
- If attempting to add a duty to a 'prohibit' rule
Examples
// Add payment duty
builder.withDuty({
type: 'PAYMENT',
value: {
amount: '50.00',
currency: 'USD',
recipient: '0xCreatorWallet'
}
});
// Add attribution duty
builder.withDuty({
type: 'ATTRIBUTION',
value: 'Original artwork by Jane Doe'
});
// Add multiple duties
builder
.permit('MODIFY')
.withDuty({
type: 'ATTRIBUTION',
value: 'Based on work by Original Creator'
})
.withDuty({
type: 'SHARE_ALIKE',
value: 'ipfs://QmOriginalPolicyHash'
});
// Error example - cannot add duty to prohibit rule
try {
builder
.prohibit('USE')
.withDuty({ type: 'PAYMENT', value: {...} }); // Throws error!
} catch (error) {
console.error(error.message); // "Duties can only be added to 'permit' rules."
}
withPaymentSplit
Adds multiple PAYMENT duties representing a split payment.
This is a convenience method that generates multiple payment duties from a split configuration. Each recipient becomes a separate duty, maintaining semantic correctness where each duty is an independent obligation.
withPaymentSplit(options: PaymentSplitOptions): this
Parameters:
options(PaymentSplitOptions) - The payment split configuration
Returns: this
This RuleBuilder instance for method chaining
Throws:
- If attempting to add to a 'prohibit' rule
- If splits don't sum to total
Examples
// Split $100 among three recipients
builder.withPaymentSplit({
total: '100',
currency: 'USDC',
splits: [
{ recipient: 'worker', amount: '70' },
{ recipient: 'platform', amount: '20' },
{ recipient: 'creator', amount: '10' }
]
});
// This generates three separate PAYMENT duties:
// 1. { type: 'PAYMENT', value: { amount: '70', currency: 'USDC', recipient: 'worker' }}
// 2. { type: 'PAYMENT', value: { amount: '20', currency: 'USDC', recipient: 'platform' }}
// 3. { type: 'PAYMENT', value: { amount: '10', currency: 'USDC', recipient: 'creator' }}
withPaymentSplitPercentage
Adds payment duties based on percentage splits.
withPaymentSplitPercentage(total: string | number, currency: string, splits: Record): this
Parameters:
total(string | number) - The total payment amountcurrency(string) - The payment currencysplits(Record) - Object mapping recipients to percentages (must sum to 100)
Returns: this
This RuleBuilder instance for method chaining
Examples
builder.withPaymentSplitPercentage('1000', 'USDC', {
'treasury': 50,
'developer': 30,
'designer': 20
});
See Also
-
- Rule for the structure being built
- PolicyBuilder.addRule for how to use with PolicyBuilder
Since
Version 1.0.0